int inc_hex(int i, int bcd_mode) {
  i++;
  if (bcd_mode) {
    if ((i & 0x000f) > 0x0009)
      i = (i + 0x0010) & 0x0ff0;
    if ((i & 0x00f0) > 0x090)
      i = (i + 0x0100) & 0x0f00;
    if ((i & 0x0f00) > 0x0900)
      i = (i + 0x1000) & 0xf000;
  }
  return i;
}


x86 assembly (clang, -O0):
<inc_hex>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
mov    -0x4(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x4(%rbp)
cmpl   $0x0,-0x8(%rbp)
je     1185 <inc_hex+0x85>
mov    -0x4(%rbp),%eax
and    $0xf,%eax
cmp    $0x9,%eax
jle    113a <inc_hex+0x3a>
mov    -0x4(%rbp),%eax
add    $0x10,%eax
and    $0xff0,%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
and    $0xf0,%eax
cmp    $0x90,%eax
jle    115d <inc_hex+0x5d>
mov    -0x4(%rbp),%eax
add    $0x100,%eax
and    $0xf00,%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
and    $0xf00,%eax
cmp    $0x900,%eax
jle    1180 <inc_hex+0x80>
mov    -0x4(%rbp),%eax
add    $0x1000,%eax
and    $0xf000,%eax
mov    %eax,-0x4(%rbp)
jmp    1185 <inc_hex+0x85>
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<inc_hex>:
lea    0x1(%rdi),%eax
test   %esi,%esi
je     1151 <inc_hex+0x51>
mov    %eax,%ecx
and    $0xe,%ecx
add    $0x11,%edi
and    $0xff0,%edi
cmp    $0xa,%ecx
cmovb  %eax,%edi
mov    %edi,%ecx
and    $0xf0,%ecx
lea    0x100(%rdi),%eax
and    $0xf00,%eax
cmp    $0x91,%ecx
cmovb  %edi,%eax
mov    %eax,%ecx
and    $0xf00,%ecx
cmp    $0x901,%ecx
jb     1151 <inc_hex+0x51>
add    $0x1000,%eax
and    $0xf000,%eax
ret

LLVM IR (-O0):
define i32 @inc_hex(i32 %0, i32 %1) {
%3 = alloca i32
%4 = alloca i32
store i32 %0, i32* %3
store i32 %1, i32* %4
%5 = load i32, i32* %3
%6 = add nsw i32 %5, 1
store i32 %6, i32* %3
%7 = load i32, i32* %4
%8 = icmp ne i32 %7, 0
br i1 %8, label %9, label %34
9: ; preds = %2
%10 = load i32, i32* %3
%11 = and i32 %10, 15
%12 = icmp sgt i32 %11, 9
br i1 %12, label %13, label %17
13: ; preds = %9
%14 = load i32, i32* %3
%15 = add nsw i32 %14, 16
%16 = and i32 %15, 4080
store i32 %16, i32* %3
br label %17
17: ; preds = %13, %9
%18 = load i32, i32* %3
%19 = and i32 %18, 240
%20 = icmp sgt i32 %19, 144
br i1 %20, label %21, label %25
21: ; preds = %17
%22 = load i32, i32* %3
%23 = add nsw i32 %22, 256
%24 = and i32 %23, 3840
store i32 %24, i32* %3
br label %25
25: ; preds = %21, %17
%26 = load i32, i32* %3
%27 = and i32 %26, 3840
%28 = icmp sgt i32 %27, 2304
br i1 %28, label %29, label %33
29: ; preds = %25
%30 = load i32, i32* %3
%31 = add nsw i32 %30, 4096
%32 = and i32 %31, 61440
store i32 %32, i32* %3
br label %33
33: ; preds = %29, %25
br label %34
34: ; preds = %33, %2
%35 = load i32, i32* %3
ret i32 %35
}

LLVM IR (-O2):
define i32 @inc_hex(i32 %0, i32 %1) {
%3 = add nsw i32 %0, 1
%4 = icmp eq i32 %1, 0
br i1 %4, label %21, label %5
5: ; preds = %2
%6 = and i32 %3, 14
%7 = icmp ugt i32 %6, 9
%8 = add nsw i32 %0, 17
%9 = and i32 %8, 4080
%10 = select i1 %7, i32 %9, i32 %3
%11 = and i32 %10, 240
%12 = icmp ugt i32 %11, 144
%13 = add nsw i32 %10, 256
%14 = and i32 %13, 3840
%15 = select i1 %12, i32 %14, i32 %10
%16 = and i32 %15, 3840
%17 = icmp ugt i32 %16, 2304
br i1 %17, label %18, label %21
18: ; preds = %5
%19 = add nsw i32 %15, 4096
%20 = and i32 %19, 61440
br label %21
21: ; preds = %5, %18, %2
%22 = phi i32 [ %20, %18 ], [ %15, %5 ], [ %3, %2 ]
ret i32 %22
}