int test(int a, int b, char flags[], int g1, int g2) {
  int ret;
  __asm__ __volatile__("mov %3, %%edx\n\t"
                       "mov %4, %%eax\n\t"
                       "mov %5, %%ecx\n\t"
                       "movb %b1, %%al\n\t"
                       "movb %b2, %%cl\n\t"
                       "subb %%cl, %%al\n\t"
                       "mov $1, %%ebx\n\t"
                       "mov $0, %%ecx\n\t"
                       "cmovo %%ebx, %%ecx\n\t"
                       "movb %%cl, (%%edx)\n\t"
                       "mov $0, %%ecx\n\t"
                       "cmovs %%ebx, %%ecx\n\t"
                       "movb %%cl, 1(%%edx)\n\t"
                       "mov $0, %%ecx\n\t"
                       "cmovz %%ebx, %%ecx\n\t"
                       "movb %%cl, 2(%%edx)\n\t"
                       "mov $0, %%ecx\n\t"
                       "cmovp %%ebx, %%ecx\n\t"
                       "movb %%cl, 3(%%edx)\n\t"
                       "mov $0, %%ecx\n\t"
                       "cmovc %%ebx, %%ecx\n\t"
                       "movb %%cl, 4(%%edx)\n\t"
                       "movzbl %%al, %%eax\n\t"
                       "mov %%eax, %0\n\t"
                       : "=m"(ret)
                       : "m"(a), "m"(b), "m"(flags), "m"(g1), "m"(g2)
                       : "eax", "ecx", "edx", "ebx", "memory");
  return ret;
}


x86 assembly (clang, -O0):
<test>:
push   %rbp
mov    %rsp,%rbp
push   %rbx
mov    %edi,-0xc(%rbp)
mov    %esi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %ecx,-0x1c(%rbp)
mov    %r8d,-0x20(%rbp)
mov    -0x18(%rbp),%edx
mov    -0x1c(%rbp),%eax
mov    -0x20(%rbp),%ecx
mov    -0xc(%rbp),%al
mov    -0x10(%rbp),%cl
sub    %cl,%al
mov    $0x1,%ebx
mov    $0x0,%ecx
cmovo  %ebx,%ecx
mov    %cl,(%edx)
mov    $0x0,%ecx
cmovs  %ebx,%ecx
mov    %cl,0x1(%edx)
mov    $0x0,%ecx
cmove  %ebx,%ecx
mov    %cl,0x2(%edx)
mov    $0x0,%ecx
cmovp  %ebx,%ecx
mov    %cl,0x3(%edx)
mov    $0x0,%ecx
cmovb  %ebx,%ecx
mov    %cl,0x4(%edx)
movzbl %al,%eax
mov    %eax,-0x24(%rbp)
mov    -0x24(%rbp),%eax
pop    %rbx
pop    %rbp
ret

x86 assembly (clang, -O2):
<test>:
push   %rbx
mov    %edi,-0xc(%rsp)
mov    %esi,-0x10(%rsp)
mov    %rdx,-0x8(%rsp)
mov    %ecx,-0x14(%rsp)
mov    %r8d,-0x18(%rsp)
mov    -0x8(%rsp),%edx
mov    -0x14(%rsp),%eax
mov    -0x18(%rsp),%ecx
mov    -0xc(%rsp),%al
mov    -0x10(%rsp),%cl
sub    %cl,%al
mov    $0x1,%ebx
mov    $0x0,%ecx
cmovo  %ebx,%ecx
mov    %cl,(%edx)
mov    $0x0,%ecx
cmovs  %ebx,%ecx
mov    %cl,0x1(%edx)
mov    $0x0,%ecx
cmove  %ebx,%ecx
mov    %cl,0x2(%edx)
mov    $0x0,%ecx
cmovp  %ebx,%ecx
mov    %cl,0x3(%edx)
mov    $0x0,%ecx
cmovb  %ebx,%ecx
mov    %cl,0x4(%edx)
movzbl %al,%eax
mov    %eax,-0x1c(%rsp)
mov    -0x1c(%rsp),%eax
pop    %rbx
ret

LLVM IR (-O0):
define i32 @test(i32 %0, i32 %1, i8* %2, i32 %3, i32 %4) {
%6 = alloca i32
%7 = alloca i32
%8 = alloca i8*
%9 = alloca i32
%10 = alloca i32
%11 = alloca i32
store i32 %0, i32* %6
store i32 %1, i32* %7
store i8* %2, i8** %8
store i32 %3, i32* %9
store i32 %4, i32* %10
%12 = load i32, i32* %11
ret i32 %12
}

LLVM IR (-O2):
define i32 @test(i32 %0, i32 %1, i8* %2, i32 %3, i32 %4) {
%6 = alloca i32
%7 = alloca i32
%8 = alloca i8*
%9 = alloca i32
%10 = alloca i32
%11 = alloca i32
store i32 %0, i32* %6
store i32 %1, i32* %7
store i8* %2, i8** %8
store i32 %3, i32* %9
store i32 %4, i32* %10
%12 = bitcast i32* %11 to i8*
%13 = load i32, i32* %11
ret i32 %13
}