#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 */

/* Variables and functions */
int /*<<< orphan*/ morus_stateupdate(unsigned int *, unsigned int **);
void morus_enc_aut_step(const unsigned char *plaintextblock,
                        unsigned char *ciphertextblock,
                        unsigned int state[][4]) {
  ((unsigned int *)ciphertextblock)[0] = ((unsigned int *)plaintextblock)[0] ^
                                         state[0][0] ^ state[1][1] ^
                                         (state[2][0] & state[3][0]);
  ((unsigned int *)ciphertextblock)[1] = ((unsigned int *)plaintextblock)[1] ^
                                         state[0][1] ^ state[1][2] ^
                                         (state[2][1] & state[3][1]);
  ((unsigned int *)ciphertextblock)[2] = ((unsigned int *)plaintextblock)[2] ^
                                         state[0][2] ^ state[1][3] ^
                                         (state[2][2] & state[3][2]);
  ((unsigned int *)ciphertextblock)[3] = ((unsigned int *)plaintextblock)[3] ^
                                         state[0][3] ^ state[1][0] ^
                                         (state[2][3] & state[3][3]);
  morus_stateupdate(((unsigned int *)plaintextblock), state);
}


x86 assembly (clang, -O0):
<morus_enc_aut_step>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0x8(%rbp),%rax
mov    (%rax),%ecx
mov    -0x18(%rbp),%rax
xor    (%rax),%ecx
mov    -0x18(%rbp),%rax
xor    0x14(%rax),%ecx
mov    -0x18(%rbp),%rax
mov    0x20(%rax),%eax
mov    -0x18(%rbp),%rdx
and    0x30(%rdx),%eax
xor    %eax,%ecx
mov    -0x10(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x8(%rbp),%rax
mov    0x4(%rax),%ecx
mov    -0x18(%rbp),%rax
xor    0x4(%rax),%ecx
mov    -0x18(%rbp),%rax
xor    0x18(%rax),%ecx
mov    -0x18(%rbp),%rax
mov    0x24(%rax),%eax
mov    -0x18(%rbp),%rdx
and    0x34(%rdx),%eax
xor    %eax,%ecx
mov    -0x10(%rbp),%rax
mov    %ecx,0x4(%rax)
mov    -0x8(%rbp),%rax
mov    0x8(%rax),%ecx
mov    -0x18(%rbp),%rax
xor    0x8(%rax),%ecx
mov    -0x18(%rbp),%rax
xor    0x1c(%rax),%ecx
mov    -0x18(%rbp),%rax
mov    0x28(%rax),%eax
mov    -0x18(%rbp),%rdx
and    0x38(%rdx),%eax
xor    %eax,%ecx
mov    -0x10(%rbp),%rax
mov    %ecx,0x8(%rax)
mov    -0x8(%rbp),%rax
mov    0xc(%rax),%ecx
mov    -0x18(%rbp),%rax
xor    0xc(%rax),%ecx
mov    -0x18(%rbp),%rax
xor    0x10(%rax),%ecx
mov    -0x18(%rbp),%rax
mov    0x2c(%rax),%eax
mov    -0x18(%rbp),%rdx
and    0x3c(%rdx),%eax
xor    %eax,%ecx
mov    -0x10(%rbp),%rax
mov    %ecx,0xc(%rax)
mov    -0x8(%rbp),%rdi
mov    -0x18(%rbp),%rsi
call   1030 <morus_stateupdate@plt>
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<morus_enc_aut_step>:
mov    (%rdx),%eax
mov    0x30(%rdx),%ecx
xor    (%rdi),%eax
xor    0x14(%rdx),%eax
and    0x20(%rdx),%ecx
xor    %eax,%ecx
mov    %ecx,(%rsi)
mov    0x4(%rdx),%eax
mov    0x34(%rdx),%ecx
xor    0x4(%rdi),%eax
xor    0x18(%rdx),%eax
and    0x24(%rdx),%ecx
xor    %eax,%ecx
mov    %ecx,0x4(%rsi)
mov    0x8(%rdx),%eax
mov    0x38(%rdx),%ecx
xor    0x8(%rdi),%eax
xor    0x1c(%rdx),%eax
and    0x28(%rdx),%ecx
xor    %eax,%ecx
mov    %ecx,0x8(%rsi)
mov    0xc(%rdx),%eax
mov    0x3c(%rdx),%ecx
xor    0xc(%rdi),%eax
xor    0x10(%rdx),%eax
and    0x2c(%rdx),%ecx
xor    %eax,%ecx
mov    %ecx,0xc(%rsi)
mov    %rdx,%rsi
jmp    1030 <morus_stateupdate@plt>

LLVM IR (-O0):
define void @morus_enc_aut_step(i8* %0, i8* %1, [4 x i32]* %2) {
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca [4 x i32]*
store i8* %0, i8** %4
store i8* %1, i8** %5
store [4 x i32]* %2, [4 x i32]** %6
%7 = load i8*, i8** %4
%8 = bitcast i8* %7 to i32*
%9 = getelementptr inbounds i32, i32* %8, i64 0
%10 = load i32, i32* %9
%11 = load [4 x i32]*, [4 x i32]** %6
%12 = getelementptr inbounds [4 x i32], [4 x i32]* %11, i64 0
%13 = getelementptr inbounds [4 x i32], [4 x i32]* %12, i64 0, i64 0
%14 = load i32, i32* %13
%15 = xor i32 %10, %14
%16 = load [4 x i32]*, [4 x i32]** %6
%17 = getelementptr inbounds [4 x i32], [4 x i32]* %16, i64 1
%18 = getelementptr inbounds [4 x i32], [4 x i32]* %17, i64 0, i64 1
%19 = load i32, i32* %18
%20 = xor i32 %15, %19
%21 = load [4 x i32]*, [4 x i32]** %6
%22 = getelementptr inbounds [4 x i32], [4 x i32]* %21, i64 2
%23 = getelementptr inbounds [4 x i32], [4 x i32]* %22, i64 0, i64 0
%24 = load i32, i32* %23
%25 = load [4 x i32]*, [4 x i32]** %6
%26 = getelementptr inbounds [4 x i32], [4 x i32]* %25, i64 3
%27 = getelementptr inbounds [4 x i32], [4 x i32]* %26, i64 0, i64 0
%28 = load i32, i32* %27
%29 = and i32 %24, %28
%30 = xor i32 %20, %29
%31 = load i8*, i8** %5
%32 = bitcast i8* %31 to i32*
%33 = getelementptr inbounds i32, i32* %32, i64 0
store i32 %30, i32* %33
%34 = load i8*, i8** %4
%35 = bitcast i8* %34 to i32*
%36 = getelementptr inbounds i32, i32* %35, i64 1
%37 = load i32, i32* %36
%38 = load [4 x i32]*, [4 x i32]** %6
%39 = getelementptr inbounds [4 x i32], [4 x i32]* %38, i64 0
%40 = getelementptr inbounds [4 x i32], [4 x i32]* %39, i64 0, i64 1
%41 = load i32, i32* %40
%42 = xor i32 %37, %41
%43 = load [4 x i32]*, [4 x i32]** %6
%44 = getelementptr inbounds [4 x i32], [4 x i32]* %43, i64 1
%45 = getelementptr inbounds [4 x i32], [4 x i32]* %44, i64 0, i64 2
%46 = load i32, i32* %45
%47 = xor i32 %42, %46
%48 = load [4 x i32]*, [4 x i32]** %6
%49 = getelementptr inbounds [4 x i32], [4 x i32]* %48, i64 2
%50 = getelementptr inbounds [4 x i32], [4 x i32]* %49, i64 0, i64 1
%51 = load i32, i32* %50
%52 = load [4 x i32]*, [4 x i32]** %6
%53 = getelementptr inbounds [4 x i32], [4 x i32]* %52, i64 3
%54 = getelementptr inbounds [4 x i32], [4 x i32]* %53, i64 0, i64 1
%55 = load i32, i32* %54
%56 = and i32 %51, %55
%57 = xor i32 %47, %56
%58 = load i8*, i8** %5
%59 = bitcast i8* %58 to i32*
%60 = getelementptr inbounds i32, i32* %59, i64 1
store i32 %57, i32* %60
%61 = load i8*, i8** %4
%62 = bitcast i8* %61 to i32*
%63 = getelementptr inbounds i32, i32* %62, i64 2
%64 = load i32, i32* %63
%65 = load [4 x i32]*, [4 x i32]** %6
%66 = getelementptr inbounds [4 x i32], [4 x i32]* %65, i64 0
%67 = getelementptr inbounds [4 x i32], [4 x i32]* %66, i64 0, i64 2
%68 = load i32, i32* %67
%69 = xor i32 %64, %68
%70 = load [4 x i32]*, [4 x i32]** %6
%71 = getelementptr inbounds [4 x i32], [4 x i32]* %70, i64 1
%72 = getelementptr inbounds [4 x i32], [4 x i32]* %71, i64 0, i64 3
%73 = load i32, i32* %72
%74 = xor i32 %69, %73
%75 = load [4 x i32]*, [4 x i32]** %6
%76 = getelementptr inbounds [4 x i32], [4 x i32]* %75, i64 2
%77 = getelementptr inbounds [4 x i32], [4 x i32]* %76, i64 0, i64 2
%78 = load i32, i32* %77
%79 = load [4 x i32]*, [4 x i32]** %6
%80 = getelementptr inbounds [4 x i32], [4 x i32]* %79, i64 3
%81 = getelementptr inbounds [4 x i32], [4 x i32]* %80, i64 0, i64 2
%82 = load i32, i32* %81
%83 = and i32 %78, %82
%84 = xor i32 %74, %83
%85 = load i8*, i8** %5
%86 = bitcast i8* %85 to i32*
%87 = getelementptr inbounds i32, i32* %86, i64 2
store i32 %84, i32* %87
%88 = load i8*, i8** %4
%89 = bitcast i8* %88 to i32*
%90 = getelementptr inbounds i32, i32* %89, i64 3
%91 = load i32, i32* %90
%92 = load [4 x i32]*, [4 x i32]** %6
%93 = getelementptr inbounds [4 x i32], [4 x i32]* %92, i64 0
%94 = getelementptr inbounds [4 x i32], [4 x i32]* %93, i64 0, i64 3
%95 = load i32, i32* %94
%96 = xor i32 %91, %95
%97 = load [4 x i32]*, [4 x i32]** %6
%98 = getelementptr inbounds [4 x i32], [4 x i32]* %97, i64 1
%99 = getelementptr inbounds [4 x i32], [4 x i32]* %98, i64 0, i64 0
%100 = load i32, i32* %99
%101 = xor i32 %96, %100
%102 = load [4 x i32]*, [4 x i32]** %6
%103 = getelementptr inbounds [4 x i32], [4 x i32]* %102, i64 2
%104 = getelementptr inbounds [4 x i32], [4 x i32]* %103, i64 0, i64 3
%105 = load i32, i32* %104
%106 = load [4 x i32]*, [4 x i32]** %6
%107 = getelementptr inbounds [4 x i32], [4 x i32]* %106, i64 3
%108 = getelementptr inbounds [4 x i32], [4 x i32]* %107, i64 0, i64 3
%109 = load i32, i32* %108
%110 = and i32 %105, %109
%111 = xor i32 %101, %110
%112 = load i8*, i8** %5
%113 = bitcast i8* %112 to i32*
%114 = getelementptr inbounds i32, i32* %113, i64 3
store i32 %111, i32* %114
%115 = load i8*, i8** %4
%116 = bitcast i8* %115 to i32*
%117 = load [4 x i32]*, [4 x i32]** %6
%118 = bitcast [4 x i32]* %117 to i32**
%119 = call i32 @morus_stateupdate(i32* %116, i32** %118)
ret void
}

LLVM IR (-O2):
define void @morus_enc_aut_step(i8* %0, i8* nocapture writeonly %1, [4 x i32]* %2) {
%4 = bitcast i8* %0 to i32*
%5 = load i32, i32* %4
%6 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i64 0, i64 0
%7 = load i32, i32* %6
%8 = xor i32 %7, %5
%9 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i64 1, i64 1
%10 = load i32, i32* %9
%11 = xor i32 %8, %10
%12 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i64 2, i64 0
%13 = load i32, i32* %12
%14 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i64 3, i64 0
%15 = load i32, i32* %14
%16 = and i32 %15, %13
%17 = xor i32 %11, %16
%18 = bitcast i8* %1 to i32*
store i32 %17, i32* %18
%19 = getelementptr inbounds i8, i8* %0, i64 4
%20 = bitcast i8* %19 to i32*
%21 = load i32, i32* %20
%22 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i64 0, i64 1
%23 = load i32, i32* %22
%24 = xor i32 %23, %21
%25 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i64 1, i64 2
%26 = load i32, i32* %25
%27 = xor i32 %24, %26
%28 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i64 2, i64 1
%29 = load i32, i32* %28
%30 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i64 3, i64 1
%31 = load i32, i32* %30
%32 = and i32 %31, %29
%33 = xor i32 %27, %32
%34 = getelementptr inbounds i8, i8* %1, i64 4
%35 = bitcast i8* %34 to i32*
store i32 %33, i32* %35
%36 = getelementptr inbounds i8, i8* %0, i64 8
%37 = bitcast i8* %36 to i32*
%38 = load i32, i32* %37
%39 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i64 0, i64 2
%40 = load i32, i32* %39
%41 = xor i32 %40, %38
%42 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i64 1, i64 3
%43 = load i32, i32* %42
%44 = xor i32 %41, %43
%45 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i64 2, i64 2
%46 = load i32, i32* %45
%47 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i64 3, i64 2
%48 = load i32, i32* %47
%49 = and i32 %48, %46
%50 = xor i32 %44, %49
%51 = getelementptr inbounds i8, i8* %1, i64 8
%52 = bitcast i8* %51 to i32*
store i32 %50, i32* %52
%53 = getelementptr inbounds i8, i8* %0, i64 12
%54 = bitcast i8* %53 to i32*
%55 = load i32, i32* %54
%56 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i64 0, i64 3
%57 = load i32, i32* %56
%58 = xor i32 %57, %55
%59 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i64 1, i64 0
%60 = load i32, i32* %59
%61 = xor i32 %58, %60
%62 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i64 2, i64 3
%63 = load i32, i32* %62
%64 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i64 3, i64 3
%65 = load i32, i32* %64
%66 = and i32 %65, %63
%67 = xor i32 %61, %66
%68 = getelementptr inbounds i8, i8* %1, i64 12
%69 = bitcast i8* %68 to i32*
store i32 %67, i32* %69
%70 = bitcast [4 x i32]* %2 to i32**
%71 = tail call i32 @morus_stateupdate(i32* %4, i32** %70)
ret void
}