void test_adc(int a, int b, int cf) {
  long flags = cf ? 0x0001 : 0;
  long out_flags;
  int out;
  __asm__ volatile("pushf\n"
                   "push %%rax\n"
                   "popf\n"
                   "adcl %[a], %[b]\n"
                   "pushf\n"
                   "pop %%rax\n"
                   "popf\n"
                   : "=a"(out_flags), [b] "=r"(out)
                   : [a] "r"(a), "1"(b), "a"(flags));
  printf("%08x:%08x:%x:%08x:%x:%x\n", a, b, cf, out,
         (out_flags & 0x0001) ? 1 : 0, (out_flags & 0x0800) ? 1 : 0);
}


x86 assembly (clang, -O0):
<test_adc>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
mov    %edx,-0xc(%rbp)
mov    -0xc(%rbp),%edx
xor    %eax,%eax
mov    $0x1,%ecx
cmp    $0x0,%edx
cmovne %ecx,%eax
cltq
mov    %rax,-0x18(%rbp)
mov    -0x4(%rbp),%edx
mov    -0x8(%rbp),%ecx
mov    -0x18(%rbp),%rax
pushf
push   %rax
popf
adc    %edx,%ecx
pushf
pop    %rax
popf
mov    %ecx,-0x28(%rbp)
mov    %rax,%rcx
mov    -0x28(%rbp),%eax
mov    %rcx,-0x20(%rbp)
mov    %eax,-0x24(%rbp)
mov    -0x4(%rbp),%esi
mov    -0x8(%rbp),%edx
mov    -0xc(%rbp),%ecx
mov    -0x24(%rbp),%r8d
mov    -0x20(%rbp),%rdi
and    $0x1,%rdi
xor    %r9d,%r9d
mov    $0x1,%eax
cmp    $0x0,%rdi
cmovne %eax,%r9d
mov    -0x20(%rbp),%r10
and    $0x800,%r10
xor    %eax,%eax
mov    $0x1,%edi
cmp    $0x0,%r10
cmovne %edi,%eax
lea    0xe62(%rip),%rdi
mov    %eax,(%rsp)
mov    $0x0,%al
call   1030 <printf@plt>
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<test_adc>:
push   %rax
mov    %edx,%ecx
mov    %esi,%edx
mov    %edi,%esi
xor    %eax,%eax
test   %ecx,%ecx
setne  %al
mov    %edx,%r8d
pushf
push   %rax
popf
adc    %edi,%r8d
pushf
pop    %rax
popf
mov    %eax,%r9d
and    $0x1,%r9d
shr    $0xb,%eax
and    $0x1,%eax
mov    %eax,(%rsp)
lea    0xebf(%rip),%rdi
xor    %eax,%eax
call   1030 <printf@plt>
pop    %rax
ret

LLVM IR (-O0):
@.str = [25 x i8] c"%08x:%08x:%x:%08x:%x:%x\0A\00"
define void @test_adc(i32 %0, i32 %1, i32 %2) {
%4 = alloca i32
%5 = alloca i32
%6 = alloca i32
%7 = alloca i64
%8 = alloca i64
%9 = alloca i32
store i32 %0, i32* %4
store i32 %1, i32* %5
store i32 %2, i32* %6
%10 = load i32, i32* %6
%11 = icmp ne i32 %10, 0
%12 = zext i1 %11 to i64
%13 = select i1 %11, i32 1, i32 0
%14 = sext i32 %13 to i64
store i64 %14, i64* %7
%15 = load i32, i32* %4
%16 = load i32, i32* %5
%17 = load i64, i64* %7
%18 = call { i64, i32 } asm sideeffect "pushf\0Apush %rax\0Apopf\0Aadcl $2, $1\0Apushf\0Apop %rax\0Apopf\0A", "={ax},=r,r,1,{ax},~{dirflag},~{fpsr},~{flags}"(i32 %15, i32 %16, i64 %17)
%19 = extractvalue { i64, i32 } %18, 0
%20 = extractvalue { i64, i32 } %18, 1
store i64 %19, i64* %8
store i32 %20, i32* %9
%21 = load i32, i32* %4
%22 = load i32, i32* %5
%23 = load i32, i32* %6
%24 = load i32, i32* %9
%25 = load i64, i64* %8
%26 = and i64 %25, 1
%27 = icmp ne i64 %26, 0
%28 = zext i1 %27 to i64
%29 = select i1 %27, i32 1, i32 0
%30 = load i64, i64* %8
%31 = and i64 %30, 2048
%32 = icmp ne i64 %31, 0
%33 = zext i1 %32 to i64
%34 = select i1 %32, i32 1, i32 0
%35 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([25 x i8], [25 x i8]* @.str, i64 0, i64 0), i32 %21, i32 %22, i32 %23, i32 %24, i32 %29, i32 %34)
ret void
}

LLVM IR (-O2):
@.str = [25 x i8] c"%08x:%08x:%x:%08x:%x:%x\0A\00"
define void @test_adc(i32 %0, i32 %1, i32 %2) {
%4 = icmp ne i32 %2, 0
%5 = zext i1 %4 to i64
%6 = tail call { i64, i32 } asm sideeffect "pushf\0Apush %rax\0Apopf\0Aadcl $2, $1\0Apushf\0Apop %rax\0Apopf\0A", "={ax},=r,r,1,{ax},~{dirflag},~{fpsr},~{flags}"(i32 %0, i32 %1, i64 %5)
%7 = extractvalue { i64, i32 } %6, 0
%8 = extractvalue { i64, i32 } %6, 1
%9 = trunc i64 %7 to i32
%10 = and i32 %9, 1
%11 = lshr i32 %9, 11
%12 = and i32 %11, 1
%13 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([25 x i8], [25 x i8]* @.str, i64 0, i64 0), i32 %0, i32 %1, i32 %2, i32 %8, i32 %10, i32 %12)
ret void
}