void theta(unsigned char *A) {
  unsigned int x, y;
  unsigned char C[5], D[5];
  for (x = 0; x < 5; x++) {
    C[x] = A[x] ^ A[5 + x] ^ A[10 + x] ^ A[15 + x] ^ A[20 + x];
  }
  for (x = 0; x < 5; x++)
    D[x] = ((1 != 0) ? ((((unsigned char)C[(x + 1) % 5]) << 1) ^
                        (((unsigned char)C[(x + 1) % 5]) >>
                         (sizeof(unsigned char) * 8 - 1)))
                     : C[(x + 1) % 5]) ^
           C[(x + 4) % 5];
  for (x = 0; x < 5; x++)
    for (y = 0; y < 5; y++)
      A[(((x) % 5) + 5 * ((y) % 5))] ^= D[x];
}


x86 assembly (clang, -O0):
<theta>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
movl   $0x0,-0xc(%rbp)
cmpl   $0x5,-0xc(%rbp)
jae    1183 <theta+0x83>
mov    -0x8(%rbp),%rax
mov    -0xc(%rbp),%ecx
movzbl (%rax,%rcx,1),%eax
mov    -0x8(%rbp),%rcx
mov    -0xc(%rbp),%edx
add    $0x5,%edx
mov    %edx,%edx
movzbl (%rcx,%rdx,1),%ecx
xor    %ecx,%eax
mov    -0x8(%rbp),%rcx
mov    -0xc(%rbp),%edx
add    $0xa,%edx
mov    %edx,%edx
movzbl (%rcx,%rdx,1),%ecx
xor    %ecx,%eax
mov    -0x8(%rbp),%rcx
mov    -0xc(%rbp),%edx
add    $0xf,%edx
mov    %edx,%edx
movzbl (%rcx,%rdx,1),%ecx
xor    %ecx,%eax
mov    -0x8(%rbp),%rcx
mov    -0xc(%rbp),%edx
add    $0x14,%edx
mov    %edx,%edx
movzbl (%rcx,%rdx,1),%ecx
xor    %ecx,%eax
mov    %al,%cl
mov    -0xc(%rbp),%eax
mov    %cl,-0x15(%rbp,%rax,1)
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc(%rbp)
jmp    110f <theta+0xf>
movl   $0x0,-0xc(%rbp)
cmpl   $0x5,-0xc(%rbp)
jae    1203 <theta+0x103>
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    $0x5,%ecx
xor    %edx,%edx
div    %ecx
mov    %edx,%eax
movzbl -0x15(%rbp,%rax,1),%eax
shl    $0x1,%eax
mov    %eax,-0x24(%rbp)
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    $0x5,%ecx
xor    %edx,%edx
div    %ecx
mov    -0x24(%rbp),%eax
mov    %edx,%ecx
movzbl -0x15(%rbp,%rcx,1),%ecx
sar    $0x7,%ecx
xor    %ecx,%eax
mov    %eax,-0x20(%rbp)
mov    -0xc(%rbp),%eax
add    $0x4,%eax
mov    $0x5,%ecx
xor    %edx,%edx
div    %ecx
mov    -0x20(%rbp),%eax
mov    %edx,%ecx
movzbl -0x15(%rbp,%rcx,1),%ecx
xor    %ecx,%eax
mov    %al,%cl
mov    -0xc(%rbp),%eax
mov    %cl,-0x1a(%rbp,%rax,1)
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc(%rbp)
jmp    118a <theta+0x8a>
movl   $0x0,-0xc(%rbp)
cmpl   $0x5,-0xc(%rbp)
jae    128a <theta+0x18a>
movl   $0x0,-0x10(%rbp)
cmpl   $0x5,-0x10(%rbp)
jae    1277 <theta+0x177>
mov    -0xc(%rbp),%eax
movzbl -0x1a(%rbp,%rax,1),%esi
mov    -0x8(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0xc(%rbp),%eax
mov    $0x5,%ecx
xor    %edx,%edx
div    %ecx
mov    %edx,-0x28(%rbp)
mov    -0x10(%rbp),%eax
mov    $0x5,%ecx
xor    %edx,%edx
div    %ecx
mov    -0x30(%rbp),%rax
mov    %edx,%ecx
mov    -0x28(%rbp),%edx
imul   $0x5,%ecx,%ecx
add    %ecx,%edx
mov    %edx,%ecx
movzbl (%rax,%rcx,1),%edx
xor    %esi,%edx
mov    %dl,(%rax,%rcx,1)
mov    -0x10(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x10(%rbp)
jmp    121b <theta+0x11b>
jmp    127c <theta+0x17c>
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc(%rbp)
jmp    120a <theta+0x10a>
pop    %rbp
ret

x86 assembly (clang, -O2):
<theta>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
mov    0x5(%rdi),%bpl
mov    (%rdi),%r9b
mov    0x1(%rdi),%cl
mov    %cl,-0xe(%rsp)
mov    %ebp,%eax
xor    %r9b,%al
mov    0xa(%rdi),%bl
mov    0xf(%rdi),%r13b
mov    %ebx,%r11d
xor    %r13b,%r11b
xor    %al,%r11b
mov    0x6(%rdi),%r14b
mov    %r14d,%eax
xor    %cl,%al
mov    0xb(%rdi),%r15b
mov    0x10(%rdi),%cl
mov    %cl,-0xa(%rsp)
mov    %r15d,%r10d
xor    %cl,%r10b
xor    %al,%r10b
mov    0x2(%rdi),%cl
mov    %cl,-0xd(%rsp)
mov    0x7(%rdi),%al
mov    %al,-0x9(%rsp)
xor    %cl,%al
mov    0xc(%rdi),%sil
mov    %sil,-0xb(%rsp)
mov    0x11(%rdi),%cl
mov    %cl,-0x6(%rsp)
xor    %cl,%sil
xor    %al,%sil
mov    0x3(%rdi),%cl
mov    %cl,-0xc(%rsp)
mov    0x8(%rdi),%al
mov    %al,-0x5(%rsp)
xor    %cl,%al
mov    0xd(%rdi),%dl
mov    %dl,-0x7(%rsp)
mov    0x12(%rdi),%cl
mov    %cl,-0x3(%rsp)
xor    %cl,%dl
xor    %al,%dl
mov    0x4(%rdi),%al
mov    %al,-0x8(%rsp)
mov    0x9(%rdi),%cl
mov    %cl,-0x2(%rsp)
xor    %al,%cl
mov    0xe(%rdi),%al
mov    %al,-0x4(%rsp)
mov    0x13(%rdi),%r8b
mov    %r8b,-0x1(%rsp)
xor    %r8b,%al
xor    %cl,%al
mov    0x14(%rdi),%r8b
xor    %r8b,%r11b
mov    0x15(%rdi),%cl
mov    %cl,-0x12(%rsp)
xor    %cl,%r10b
mov    0x16(%rdi),%cl
mov    %cl,-0x11(%rsp)
xor    %cl,%sil
mov    0x17(%rdi),%cl
mov    %cl,-0x10(%rsp)
xor    %cl,%dl
mov    %edx,%ecx
rol    %cl
mov    0x18(%rdi),%r12b
mov    %r12b,-0xf(%rsp)
xor    %r12b,%al
xor    %r10b,%cl
rol    %r10b
xor    %al,%r10b
mov    %esi,%r12d
rol    %r12b
xor    %r11b,%r12b
rol    %al
rol    %r11b
xor    %sil,%al
xor    %dl,%r11b
xor    %r10b,%r9b
mov    %r9b,(%rdi)
xor    %r10b,%bpl
mov    %bpl,0x5(%rdi)
xor    %r10b,%bl
mov    %bl,0xa(%rdi)
xor    %r10b,%r13b
mov    %r13b,0xf(%rdi)
xor    %r8b,%r10b
mov    %r10b,0x14(%rdi)
mov    -0xe(%rsp),%dl
xor    %r12b,%dl
mov    %dl,0x1(%rdi)
xor    %r12b,%r14b
mov    %r14b,0x6(%rdi)
xor    %r12b,%r15b
mov    %r15b,0xb(%rdi)
mov    -0xa(%rsp),%dl
xor    %r12b,%dl
mov    %dl,0x10(%rdi)
xor    -0x12(%rsp),%r12b
mov    %r12b,0x15(%rdi)
mov    -0xd(%rsp),%dl
xor    %cl,%dl
mov    %dl,0x2(%rdi)
mov    -0x9(%rsp),%dl
xor    %cl,%dl
mov    %dl,0x7(%rdi)
mov    -0xb(%rsp),%dl
xor    %cl,%dl
mov    %dl,0xc(%rdi)
mov    -0x6(%rsp),%dl
xor    %cl,%dl
mov    %dl,0x11(%rdi)
xor    -0x11(%rsp),%cl
mov    %cl,0x16(%rdi)
mov    -0xc(%rsp),%cl
xor    %al,%cl
mov    %cl,0x3(%rdi)
mov    -0x5(%rsp),%cl
xor    %al,%cl
mov    %cl,0x8(%rdi)
mov    -0x7(%rsp),%cl
xor    %al,%cl
mov    %cl,0xd(%rdi)
mov    -0x3(%rsp),%cl
xor    %al,%cl
mov    %cl,0x12(%rdi)
xor    -0x10(%rsp),%al
mov    %al,0x17(%rdi)
mov    -0x8(%rsp),%al
xor    %r11b,%al
mov    %al,0x4(%rdi)
mov    -0x2(%rsp),%al
xor    %r11b,%al
mov    %al,0x9(%rdi)
mov    -0x4(%rsp),%al
xor    %r11b,%al
mov    %al,0xe(%rdi)
mov    -0x1(%rsp),%al
xor    %r11b,%al
mov    %al,0x13(%rdi)
xor    -0xf(%rsp),%r11b
mov    %r11b,0x18(%rdi)
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

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

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