int dec_hex(int i, int bcd_mode) {
  i--;
  if (bcd_mode) {
    if ((i & 0x000f) > 0x0009)
      i = (i & 0xfff0) + 0x0009;
    if ((i & 0x00f0) > 0x0090)
      i = (i & 0xff00) + 0x0099;
    if ((i & 0x0f00) > 0x0900)
      i = (i & 0xf000) + 0x0999;
  }
  return i;
}


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

x86 assembly (clang, -O2):
<dec_hex>:
mov    %edi,%eax
add    $0xffffffff,%eax
test   %esi,%esi
je     1156 <dec_hex+0x56>
mov    %eax,%ecx
and    $0xe,%ecx
mov    %eax,%edx
and    $0xfff0,%edx
or     $0x9,%edx
cmp    $0xa,%ecx
cmovb  %eax,%edx
mov    %edx,%ecx
and    $0xf0,%ecx
mov    %edx,%eax
and    $0xff00,%eax
or     $0x99,%eax
cmp    $0x91,%ecx
cmovb  %edx,%eax
mov    %eax,%ecx
and    $0xf00,%ecx
cmp    $0x901,%ecx
jb     1156 <dec_hex+0x56>
and    $0xf000,%eax
or     $0x999,%eax
ret

LLVM IR (-O0):
define i32 @dec_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 = and i32 %14, 65520
%16 = add nsw i32 %15, 9
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 = and i32 %22, 65280
%24 = add nsw i32 %23, 153
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 = and i32 %30, 61440
%32 = add nsw i32 %31, 2457
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 @dec_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 = and i32 %3, 65520
%9 = or i32 %8, 9
%10 = select i1 %7, i32 %9, i32 %3
%11 = and i32 %10, 240
%12 = icmp ugt i32 %11, 144
%13 = and i32 %10, 65280
%14 = or i32 %13, 153
%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 = and i32 %15, 61440
%20 = or i32 %19, 2457
br label %21
21: ; preds = %5, %18, %2
%22 = phi i32 [ %20, %18 ], [ %15, %5 ], [ %3, %2 ]
ret i32 %22
}