#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
typedef int uint8_t;
typedef int uint64_t;

/* Variables and functions */
int /*<<< orphan*/ memcpy(int *, int const *, int);
int /*<<< orphan*/ memset(int *, int, int);
int /*<<< orphan*/ morus_stateupdate(int *, int **);
void morus_initialization(const uint8_t *key, const uint8_t *iv,
                          uint64_t state[][4]) {
  int i;
  uint64_t temp[4] = {0, 0, 0, 0};
  uint8_t con[32] = {0x0,  0x1,  0x01, 0x02, 0x03, 0x05, 0x08, 0x0d,
                     0x15, 0x22, 0x37, 0x59, 0x90, 0xe9, 0x79, 0x62,
                     0xdb, 0x3d, 0x18, 0x55, 0x6d, 0xc2, 0x2f, 0xf1,
                     0x20, 0x11, 0x31, 0x42, 0x73, 0xb5, 0x28, 0xdd};
  uint64_t ekey[4];
  memcpy(ekey, key, 16);
  ekey[3] = ekey[1];
  ekey[2] = ekey[0];
  memcpy(state[0], iv, 16);
  memset(state[0] + 2, 0, 16);
  memcpy(state[1], ekey, 32);
  memset(state[2], 0xff, 32);
  memset(state[3], 0, 32);
  memcpy(state[4], con, 32);
  for (i = 0; i < 4; i++)
    temp[i] = 0;
  for (i = 0; i < 16; i++)
    morus_stateupdate(temp, state);
  for (i = 0; i < 4; i++)
    state[1][i] ^= ((uint64_t *)ekey)[i];
}


x86 assembly (clang, -O0):
<morus_initialization>:
push   %rbp
mov    %rsp,%rbp
sub    $0xc0,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
lea    -0x30(%rbp),%rdi
xor    %esi,%esi
mov    $0x10,%edx
call   1030 <memset@plt>
lea    -0xb0(%rbp),%rdi
lea    0xe9b(%rip),%rsi
mov    $0x80,%edx
call   1040 <memcpy@plt>
lea    -0xc0(%rbp),%rdi
mov    -0x8(%rbp),%rsi
mov    $0x10,%edx
call   1040 <memcpy@plt>
mov    -0xbc(%rbp),%eax
mov    %eax,-0xb4(%rbp)
mov    -0xc0(%rbp),%eax
mov    %eax,-0xb8(%rbp)
mov    -0x18(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    $0x10,%edx
call   1040 <memcpy@plt>
mov    -0x18(%rbp),%rdi
add    $0x8,%rdi
xor    %esi,%esi
mov    $0x10,%edx
call   1030 <memset@plt>
mov    -0x18(%rbp),%rdi
add    $0x10,%rdi
lea    -0xc0(%rbp),%rsi
mov    $0x20,%edx
call   1040 <memcpy@plt>
mov    -0x18(%rbp),%rdi
add    $0x20,%rdi
mov    $0xff,%esi
mov    $0x20,%edx
call   1030 <memset@plt>
mov    -0x18(%rbp),%rdi
add    $0x30,%rdi
xor    %esi,%esi
mov    $0x20,%edx
call   1030 <memset@plt>
mov    -0x18(%rbp),%rdi
add    $0x40,%rdi
lea    -0xb0(%rbp),%rsi
mov    $0x20,%edx
call   1040 <memcpy@plt>
movl   $0x0,-0x1c(%rbp)
cmpl   $0x4,-0x1c(%rbp)
jge    124a <morus_initialization+0x11a>
movslq -0x1c(%rbp),%rax
movl   $0x0,-0x30(%rbp,%rax,4)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1226 <morus_initialization+0xf6>
movl   $0x0,-0x1c(%rbp)
cmpl   $0x10,-0x1c(%rbp)
jge    1276 <morus_initialization+0x146>
lea    -0x30(%rbp),%rdi
mov    -0x18(%rbp),%rsi
call   1050 <morus_stateupdate@plt>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1251 <morus_initialization+0x121>
movl   $0x0,-0x1c(%rbp)
cmpl   $0x4,-0x1c(%rbp)
jge    12b0 <morus_initialization+0x180>
movslq -0x1c(%rbp),%rax
mov    -0xc0(%rbp,%rax,4),%edx
mov    -0x18(%rbp),%rax
movslq -0x1c(%rbp),%rcx
xor    0x10(%rax,%rcx,4),%edx
mov    %edx,0x10(%rax,%rcx,4)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    127d <morus_initialization+0x14d>
add    $0xc0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<morus_initialization>:
push   %r15
push   %r14
push   %rbx
sub    $0xa0,%rsp
mov    %rdx,%rbx
mov    %rsi,%r14
mov    %rdi,%rsi
movaps 0xf24(%rip),%xmm0
movaps %xmm0,0x90(%rsp)
movaps 0xf05(%rip),%xmm0
movaps %xmm0,0x80(%rsp)
movaps 0xee6(%rip),%xmm0
movaps %xmm0,0x70(%rsp)
movaps 0xeca(%rip),%xmm0
movaps %xmm0,0x60(%rsp)
movaps 0xeae(%rip),%xmm0
movaps %xmm0,0x50(%rsp)
movaps 0xe92(%rip),%xmm0
movaps %xmm0,0x40(%rsp)
movaps 0xe76(%rip),%xmm0
movaps %xmm0,0x30(%rsp)
movaps 0xe5a(%rip),%xmm0
movaps %xmm0,0x20(%rsp)
mov    %rsp,%r15
mov    %r15,%rdi
mov    $0x10,%edx
call   1040 <memcpy@plt>
mov    (%rsp),%rax
mov    %rax,0x8(%rsp)
mov    %rbx,%rdi
mov    %r14,%rsi
mov    $0x10,%edx
call   1040 <memcpy@plt>
lea    0x8(%rbx),%rdi
xor    %esi,%esi
mov    $0x10,%edx
call   1030 <memset@plt>
lea    0x10(%rbx),%rdi
mov    %r15,%rsi
mov    $0x20,%edx
call   1040 <memcpy@plt>
lea    0x20(%rbx),%rdi
mov    $0xff,%esi
mov    $0x20,%edx
call   1030 <memset@plt>
lea    0x30(%rbx),%rdi
xor    %esi,%esi
mov    $0x20,%edx
call   1030 <memset@plt>
lea    0x40(%rbx),%rdi
lea    0x20(%rsp),%rsi
mov    $0x20,%edx
call   1040 <memcpy@plt>
xorps  %xmm0,%xmm0
movaps %xmm0,0x10(%rsp)
lea    0x10(%rsp),%r14
mov    %r14,%rdi
mov    %rbx,%rsi
call   1050 <morus_stateupdate@plt>
mov    %r14,%rdi
mov    %rbx,%rsi
call   1050 <morus_stateupdate@plt>
mov    %r14,%rdi
mov    %rbx,%rsi
call   1050 <morus_stateupdate@plt>
mov    %r14,%rdi
mov    %rbx,%rsi
call   1050 <morus_stateupdate@plt>
mov    %r14,%rdi
mov    %rbx,%rsi
call   1050 <morus_stateupdate@plt>
mov    %r14,%rdi
mov    %rbx,%rsi
call   1050 <morus_stateupdate@plt>
mov    %r14,%rdi
mov    %rbx,%rsi
call   1050 <morus_stateupdate@plt>
mov    %r14,%rdi
mov    %rbx,%rsi
call   1050 <morus_stateupdate@plt>
mov    %r14,%rdi
mov    %rbx,%rsi
call   1050 <morus_stateupdate@plt>
mov    %r14,%rdi
mov    %rbx,%rsi
call   1050 <morus_stateupdate@plt>
mov    %r14,%rdi
mov    %rbx,%rsi
call   1050 <morus_stateupdate@plt>
mov    %r14,%rdi
mov    %rbx,%rsi
call   1050 <morus_stateupdate@plt>
mov    %r14,%rdi
mov    %rbx,%rsi
call   1050 <morus_stateupdate@plt>
mov    %r14,%rdi
mov    %rbx,%rsi
call   1050 <morus_stateupdate@plt>
mov    %r14,%rdi
mov    %rbx,%rsi
call   1050 <morus_stateupdate@plt>
mov    %r14,%rdi
mov    %rbx,%rsi
call   1050 <morus_stateupdate@plt>
movups 0x10(%rbx),%xmm0
xorps  (%rsp),%xmm0
movups %xmm0,0x10(%rbx)
add    $0xa0,%rsp
pop    %rbx
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
@__const.morus_initialization.con = [32 x i32] [i32 0, i32 1, i32 1, i32 2, i32 3, i32 5, i32 8, i32 13, i32 21, i32 34, i32 55, i32 89, i32 144, i32 233, i32 121, i32 98, i32 219, i32 61, i32 24, i32 85, i32 109, i32 194, i32 47, i32 241, i32 32, i32 17, i32 49, i32 66, i32 115, i32 181, i32 40, i32 221]
define void @morus_initialization(i32* %0, i32* %1, [4 x i32]* %2) {
%4 = alloca i32*
%5 = alloca i32*
%6 = alloca [4 x i32]*
%7 = alloca i32
%8 = alloca [4 x i32]
%9 = alloca [32 x i32]
%10 = alloca [4 x i32]
store i32* %0, i32** %4
store i32* %1, i32** %5
store [4 x i32]* %2, [4 x i32]** %6
%11 = bitcast [4 x i32]* %8 to i8*
%12 = bitcast [32 x i32]* %9 to i8*
%13 = getelementptr inbounds [4 x i32], [4 x i32]* %10, i64 0, i64 0
%14 = load i32*, i32** %4
%15 = call i32 @memcpy(i32* %13, i32* %14, i32 16)
%16 = getelementptr inbounds [4 x i32], [4 x i32]* %10, i64 0, i64 1
%17 = load i32, i32* %16
%18 = getelementptr inbounds [4 x i32], [4 x i32]* %10, i64 0, i64 3
store i32 %17, i32* %18
%19 = getelementptr inbounds [4 x i32], [4 x i32]* %10, i64 0, i64 0
%20 = load i32, i32* %19
%21 = getelementptr inbounds [4 x i32], [4 x i32]* %10, i64 0, i64 2
store i32 %20, i32* %21
%22 = load [4 x i32]*, [4 x i32]** %6
%23 = getelementptr inbounds [4 x i32], [4 x i32]* %22, i64 0
%24 = getelementptr inbounds [4 x i32], [4 x i32]* %23, i64 0, i64 0
%25 = load i32*, i32** %5
%26 = call i32 @memcpy(i32* %24, i32* %25, i32 16)
%27 = load [4 x i32]*, [4 x i32]** %6
%28 = getelementptr inbounds [4 x i32], [4 x i32]* %27, i64 0
%29 = getelementptr inbounds [4 x i32], [4 x i32]* %28, i64 0, i64 0
%30 = getelementptr inbounds i32, i32* %29, i64 2
%31 = call i32 @memset(i32* %30, i32 0, i32 16)
%32 = load [4 x i32]*, [4 x i32]** %6
%33 = getelementptr inbounds [4 x i32], [4 x i32]* %32, i64 1
%34 = getelementptr inbounds [4 x i32], [4 x i32]* %33, i64 0, i64 0
%35 = getelementptr inbounds [4 x i32], [4 x i32]* %10, i64 0, i64 0
%36 = call i32 @memcpy(i32* %34, i32* %35, i32 32)
%37 = load [4 x i32]*, [4 x i32]** %6
%38 = getelementptr inbounds [4 x i32], [4 x i32]* %37, i64 2
%39 = getelementptr inbounds [4 x i32], [4 x i32]* %38, i64 0, i64 0
%40 = call i32 @memset(i32* %39, i32 255, i32 32)
%41 = load [4 x i32]*, [4 x i32]** %6
%42 = getelementptr inbounds [4 x i32], [4 x i32]* %41, i64 3
%43 = getelementptr inbounds [4 x i32], [4 x i32]* %42, i64 0, i64 0
%44 = call i32 @memset(i32* %43, i32 0, i32 32)
%45 = load [4 x i32]*, [4 x i32]** %6
%46 = getelementptr inbounds [4 x i32], [4 x i32]* %45, i64 4
%47 = getelementptr inbounds [4 x i32], [4 x i32]* %46, i64 0, i64 0
%48 = getelementptr inbounds [32 x i32], [32 x i32]* %9, i64 0, i64 0
%49 = call i32 @memcpy(i32* %47, i32* %48, i32 32)
store i32 0, i32* %7
br label %50
50: ; preds = %57, %3
%51 = load i32, i32* %7
%52 = icmp slt i32 %51, 4
br i1 %52, label %53, label %60
53: ; preds = %50
%54 = load i32, i32* %7
%55 = sext i32 %54 to i64
%56 = getelementptr inbounds [4 x i32], [4 x i32]* %8, i64 0, i64 %55
store i32 0, i32* %56
br label %57
57: ; preds = %53
%58 = load i32, i32* %7
%59 = add nsw i32 %58, 1
store i32 %59, i32* %7
br label %50
60: ; preds = %50
store i32 0, i32* %7
br label %61
61: ; preds = %69, %60
%62 = load i32, i32* %7
%63 = icmp slt i32 %62, 16
br i1 %63, label %64, label %72
64: ; preds = %61
%65 = getelementptr inbounds [4 x i32], [4 x i32]* %8, i64 0, i64 0
%66 = load [4 x i32]*, [4 x i32]** %6
%67 = bitcast [4 x i32]* %66 to i32**
%68 = call i32 @morus_stateupdate(i32* %65, i32** %67)
br label %69
69: ; preds = %64
%70 = load i32, i32* %7
%71 = add nsw i32 %70, 1
store i32 %71, i32* %7
br label %61
72: ; preds = %61
store i32 0, i32* %7
br label %73
73: ; preds = %89, %72
%74 = load i32, i32* %7
%75 = icmp slt i32 %74, 4
br i1 %75, label %76, label %92
76: ; preds = %73
%77 = getelementptr inbounds [4 x i32], [4 x i32]* %10, i64 0, i64 0
%78 = load i32, i32* %7
%79 = sext i32 %78 to i64
%80 = getelementptr inbounds i32, i32* %77, i64 %79
%81 = load i32, i32* %80
%82 = load [4 x i32]*, [4 x i32]** %6
%83 = getelementptr inbounds [4 x i32], [4 x i32]* %82, i64 1
%84 = load i32, i32* %7
%85 = sext i32 %84 to i64
%86 = getelementptr inbounds [4 x i32], [4 x i32]* %83, i64 0, i64 %85
%87 = load i32, i32* %86
%88 = xor i32 %87, %81
store i32 %88, i32* %86
br label %89
89: ; preds = %76
%90 = load i32, i32* %7
%91 = add nsw i32 %90, 1
store i32 %91, i32* %7
br label %73
92: ; preds = %73
ret void
}

LLVM IR (-O2):
@__const.morus_initialization.con = [32 x i32] [i32 0, i32 1, i32 1, i32 2, i32 3, i32 5, i32 8, i32 13, i32 21, i32 34, i32 55, i32 89, i32 144, i32 233, i32 121, i32 98, i32 219, i32 61, i32 24, i32 85, i32 109, i32 194, i32 47, i32 241, i32 32, i32 17, i32 49, i32 66, i32 115, i32 181, i32 40, i32 221]
define void @morus_initialization(i32* %0, i32* %1, [4 x i32]* %2) {
%4 = alloca [4 x i32]
%5 = bitcast [4 x i32]* %4 to i8*
%6 = alloca [32 x i32]
%7 = alloca <4 x i32>
%8 = bitcast [32 x i32]* %6 to i8*
%9 = bitcast <4 x i32>* %7 to i8*
%10 = getelementptr inbounds <4 x i32>, <4 x i32>* %7, i64 0, i64 0
%11 = call i32 @memcpy(i32* %10, i32* %0, i32 16)
%12 = getelementptr inbounds <4 x i32>, <4 x i32>* %7, i64 0, i64 1
%13 = load i32, i32* %12
%14 = getelementptr inbounds <4 x i32>, <4 x i32>* %7, i64 0, i64 3
store i32 %13, i32* %14
%15 = load i32, i32* %10
%16 = getelementptr inbounds <4 x i32>, <4 x i32>* %7, i64 0, i64 2
store i32 %15, i32* %16
%17 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i64 0, i64 0
%18 = call i32 @memcpy(i32* %17, i32* %1, i32 16)
%19 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i64 0, i64 2
%20 = call i32 @memset(i32* %19, i32 0, i32 16)
%21 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i64 1, i64 0
%22 = call i32 @memcpy(i32* %21, i32* %10, i32 32)
%23 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i64 2, i64 0
%24 = call i32 @memset(i32* %23, i32 255, i32 32)
%25 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i64 3, i64 0
%26 = call i32 @memset(i32* %25, i32 0, i32 32)
%27 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i64 4, i64 0
%28 = getelementptr inbounds [32 x i32], [32 x i32]* %6, i64 0, i64 0
%29 = call i32 @memcpy(i32* %27, i32* %28, i32 32)
%30 = getelementptr inbounds [4 x i32], [4 x i32]* %4, i64 0, i64 0
%31 = bitcast [4 x i32]* %2 to i32**
%32 = call i32 @morus_stateupdate(i32* %30, i32** %31)
%33 = call i32 @morus_stateupdate(i32* %30, i32** %31)
%34 = call i32 @morus_stateupdate(i32* %30, i32** %31)
%35 = call i32 @morus_stateupdate(i32* %30, i32** %31)
%36 = call i32 @morus_stateupdate(i32* %30, i32** %31)
%37 = call i32 @morus_stateupdate(i32* %30, i32** %31)
%38 = call i32 @morus_stateupdate(i32* %30, i32** %31)
%39 = call i32 @morus_stateupdate(i32* %30, i32** %31)
%40 = call i32 @morus_stateupdate(i32* %30, i32** %31)
%41 = call i32 @morus_stateupdate(i32* %30, i32** %31)
%42 = call i32 @morus_stateupdate(i32* %30, i32** %31)
%43 = call i32 @morus_stateupdate(i32* %30, i32** %31)
%44 = call i32 @morus_stateupdate(i32* %30, i32** %31)
%45 = call i32 @morus_stateupdate(i32* %30, i32** %31)
%46 = call i32 @morus_stateupdate(i32* %30, i32** %31)
%47 = call i32 @morus_stateupdate(i32* %30, i32** %31)
%48 = load <4 x i32>, <4 x i32>* %7
%49 = bitcast i32* %21 to <4 x i32>*
%50 = load <4 x i32>, <4 x i32>* %49
%51 = xor <4 x i32> %50, %48
%52 = bitcast i32* %21 to <4 x i32>*
store <4 x i32> %51, <4 x i32>* %52
ret void
}