#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 */
unsigned char gf_mulinv(unsigned char);
unsigned char rj_sbox_inv(unsigned char x) {
  unsigned char y, sb;
  y = x ^ 0x63;
  sb = y = (y << 1) | (y >> 7);
  y = (y << 2) | (y >> 6);
  sb ^= y;
  y = (y << 3) | (y >> 5);
  sb ^= y;
  return gf_mulinv(sb);
}


x86 assembly (clang, -O0):
<rj_sbox_inv>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
mov    %dil,%al
mov    %al,-0x1(%rbp)
movzbl -0x1(%rbp),%eax
xor    $0x63,%eax
mov    %al,-0x2(%rbp)
movzbl -0x2(%rbp),%eax
shl    $0x1,%eax
movzbl -0x2(%rbp),%ecx
sar    $0x7,%ecx
or     %ecx,%eax
mov    %al,-0x2(%rbp)
mov    %al,-0x3(%rbp)
movzbl -0x2(%rbp),%eax
shl    $0x2,%eax
movzbl -0x2(%rbp),%ecx
sar    $0x6,%ecx
or     %ecx,%eax
mov    %al,-0x2(%rbp)
movzbl -0x2(%rbp),%ecx
movzbl -0x3(%rbp),%eax
xor    %ecx,%eax
mov    %al,-0x3(%rbp)
movzbl -0x2(%rbp),%eax
shl    $0x3,%eax
movzbl -0x2(%rbp),%ecx
sar    $0x5,%ecx
or     %ecx,%eax
mov    %al,-0x2(%rbp)
movzbl -0x2(%rbp),%ecx
movzbl -0x3(%rbp),%eax
xor    %ecx,%eax
mov    %al,-0x3(%rbp)
movzbl -0x3(%rbp),%edi
call   1030 <gf_mulinv@plt>
movzbl %al,%eax
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<rj_sbox_inv>:
mov    %edi,%eax
xor    $0x63,%al
shr    $0x7,%dil
add    %al,%al
or     %dil,%al
mov    %eax,%ecx
rol    $0x2,%cl
xor    %al,%cl
rol    $0x5,%al
xor    %cl,%al
movzbl %al,%edi
jmp    1030 <gf_mulinv@plt>

LLVM IR (-O0):
define zeroext i8 @rj_sbox_inv(i8 zeroext %0) {
%2 = alloca i8
%3 = alloca i8
%4 = alloca i8
store i8 %0, i8* %2
%5 = load i8, i8* %2
%6 = zext i8 %5 to i32
%7 = xor i32 %6, 99
%8 = trunc i32 %7 to i8
store i8 %8, i8* %3
%9 = load i8, i8* %3
%10 = zext i8 %9 to i32
%11 = shl i32 %10, 1
%12 = load i8, i8* %3
%13 = zext i8 %12 to i32
%14 = ashr i32 %13, 7
%15 = or i32 %11, %14
%16 = trunc i32 %15 to i8
store i8 %16, i8* %3
store i8 %16, i8* %4
%17 = load i8, i8* %3
%18 = zext i8 %17 to i32
%19 = shl i32 %18, 2
%20 = load i8, i8* %3
%21 = zext i8 %20 to i32
%22 = ashr i32 %21, 6
%23 = or i32 %19, %22
%24 = trunc i32 %23 to i8
store i8 %24, i8* %3
%25 = load i8, i8* %3
%26 = zext i8 %25 to i32
%27 = load i8, i8* %4
%28 = zext i8 %27 to i32
%29 = xor i32 %28, %26
%30 = trunc i32 %29 to i8
store i8 %30, i8* %4
%31 = load i8, i8* %3
%32 = zext i8 %31 to i32
%33 = shl i32 %32, 3
%34 = load i8, i8* %3
%35 = zext i8 %34 to i32
%36 = ashr i32 %35, 5
%37 = or i32 %33, %36
%38 = trunc i32 %37 to i8
store i8 %38, i8* %3
%39 = load i8, i8* %3
%40 = zext i8 %39 to i32
%41 = load i8, i8* %4
%42 = zext i8 %41 to i32
%43 = xor i32 %42, %40
%44 = trunc i32 %43 to i8
store i8 %44, i8* %4
%45 = load i8, i8* %4
%46 = call zeroext i8 @gf_mulinv(i8 zeroext %45)
ret i8 %46
}

LLVM IR (-O2):
define zeroext i8 @rj_sbox_inv(i8 zeroext %0) {
%2 = xor i8 %0, 99
%3 = tail call i8 @llvm.fshl.i8(i8 %2, i8 %0, i8 1)
%4 = tail call i8 @llvm.fshl.i8(i8 %3, i8 %3, i8 2)
%5 = xor i8 %4, %3
%6 = tail call i8 @llvm.fshl.i8(i8 %4, i8 %4, i8 3)
%7 = xor i8 %5, %6
%8 = tail call zeroext i8 @gf_mulinv(i8 zeroext %7)
ret i8 %8
}