unsigned char aes_mul4(unsigned char in) {
  unsigned char out = 0x0;
  out |= (((in >> 6) & 0x1)) << 0;
  out |= (((in >> 7) & 0x1) ^ ((in >> 6) & 0x1)) << 1;
  out |= (((in >> 0) & 0x1) ^ ((in >> 7) & 0x1)) << 2;
  out |= (((in >> 1) & 0x1) ^ ((in >> 6) & 0x1)) << 3;
  out |= (((in >> 2) & 0x1) ^ ((in >> 7) & 0x1) ^ ((in >> 6) & 0x1)) << 4;
  out |= (((in >> 3) & 0x1) ^ ((in >> 7) & 0x1)) << 5;
  out |= (((in >> 4) & 0x1)) << 6;
  out |= (((in >> 5) & 0x1)) << 7;
  return out;
}


x86 assembly (clang, -O0):
<aes_mul4>:
push   %rbp
mov    %rsp,%rbp
mov    %dil,%al
mov    %al,-0x1(%rbp)
movb   $0x0,-0x2(%rbp)
movzbl -0x1(%rbp),%ecx
sar    $0x6,%ecx
and    $0x1,%ecx
shl    $0x0,%ecx
movzbl -0x2(%rbp),%eax
or     %ecx,%eax
mov    %al,-0x2(%rbp)
movzbl -0x1(%rbp),%ecx
sar    $0x7,%ecx
and    $0x1,%ecx
movzbl -0x1(%rbp),%eax
sar    $0x6,%eax
and    $0x1,%eax
xor    %eax,%ecx
shl    $0x1,%ecx
movzbl -0x2(%rbp),%eax
or     %ecx,%eax
mov    %al,-0x2(%rbp)
movzbl -0x1(%rbp),%ecx
sar    $0x0,%ecx
and    $0x1,%ecx
movzbl -0x1(%rbp),%eax
sar    $0x7,%eax
and    $0x1,%eax
xor    %eax,%ecx
shl    $0x2,%ecx
movzbl -0x2(%rbp),%eax
or     %ecx,%eax
mov    %al,-0x2(%rbp)
movzbl -0x1(%rbp),%ecx
sar    $0x1,%ecx
and    $0x1,%ecx
movzbl -0x1(%rbp),%eax
sar    $0x6,%eax
and    $0x1,%eax
xor    %eax,%ecx
shl    $0x3,%ecx
movzbl -0x2(%rbp),%eax
or     %ecx,%eax
mov    %al,-0x2(%rbp)
movzbl -0x1(%rbp),%ecx
sar    $0x2,%ecx
and    $0x1,%ecx
movzbl -0x1(%rbp),%eax
sar    $0x7,%eax
and    $0x1,%eax
xor    %eax,%ecx
movzbl -0x1(%rbp),%eax
sar    $0x6,%eax
and    $0x1,%eax
xor    %eax,%ecx
shl    $0x4,%ecx
movzbl -0x2(%rbp),%eax
or     %ecx,%eax
mov    %al,-0x2(%rbp)
movzbl -0x1(%rbp),%ecx
sar    $0x3,%ecx
and    $0x1,%ecx
movzbl -0x1(%rbp),%eax
sar    $0x7,%eax
and    $0x1,%eax
xor    %eax,%ecx
shl    $0x5,%ecx
movzbl -0x2(%rbp),%eax
or     %ecx,%eax
mov    %al,-0x2(%rbp)
movzbl -0x1(%rbp),%ecx
sar    $0x4,%ecx
and    $0x1,%ecx
shl    $0x6,%ecx
movzbl -0x2(%rbp),%eax
or     %ecx,%eax
mov    %al,-0x2(%rbp)
movzbl -0x1(%rbp),%ecx
sar    $0x5,%ecx
and    $0x1,%ecx
shl    $0x7,%ecx
movzbl -0x2(%rbp),%eax
or     %ecx,%eax
mov    %al,-0x2(%rbp)
movzbl -0x2(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<aes_mul4>:
mov    %edi,%ecx
shr    $0x6,%ecx
and    $0x1,%ecx
mov    %edi,%eax
shr    $0x7,%eax
mov    %ecx,%edx
xor    %eax,%edx
lea    (%rcx,%rdx,2),%r8d
mov    %edi,%esi
and    $0x1,%esi
xor    %eax,%esi
lea    (%r8,%rsi,4),%r8d
mov    %edi,%esi
shr    %esi
and    $0x1,%esi
xor    %ecx,%esi
mov    %edi,%ecx
shr    $0x2,%ecx
and    $0x1,%ecx
xor    %edx,%ecx
shl    $0x4,%ecx
mov    %edi,%edx
shr    $0x3,%edx
and    $0x1,%edx
xor    %eax,%edx
shl    $0x5,%edx
lea    (%r8,%rsi,8),%esi
and    $0x30,%edi
lea    (%rdx,%rdi,4),%eax
or     %ecx,%eax
or     %esi,%eax
ret

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

LLVM IR (-O2):
define zeroext i8 @aes_mul4(i8 zeroext %0) {
%2 = zext i8 %0 to i32
%3 = lshr i32 %2, 6
%4 = and i32 %3, 1
%5 = lshr i32 %2, 7
%6 = xor i32 %4, %5
%7 = shl nuw nsw i32 %6, 1
%8 = or i32 %7, %4
%9 = and i32 %2, 1
%10 = xor i32 %9, %5
%11 = shl nuw nsw i32 %10, 2
%12 = or i32 %8, %11
%13 = lshr i32 %2, 1
%14 = and i32 %13, 1
%15 = xor i32 %14, %4
%16 = shl nuw nsw i32 %15, 3
%17 = lshr i32 %2, 2
%18 = and i32 %17, 1
%19 = xor i32 %6, %18
%20 = shl nuw nsw i32 %19, 4
%21 = lshr i32 %2, 3
%22 = and i32 %21, 1
%23 = xor i32 %22, %5
%24 = shl nuw nsw i32 %23, 5
%25 = shl nuw nsw i32 %2, 2
%26 = or i32 %12, %16
%27 = and i32 %25, 192
%28 = or i32 %27, %24
%29 = or i32 %28, %20
%30 = or i32 %29, %26
%31 = trunc i32 %30 to i8
ret i8 %31
}