unsigned char decimalToBCD(unsigned char decimalByte) {
  unsigned char BCDByte = 0;
  while (decimalByte > 9) {
    BCDByte += 0x10;
    decimalByte -= 10;
  }
  BCDByte += decimalByte;
  return BCDByte;
}


x86 assembly (clang, -O0):
<decimalToBCD>:
push   %rbp
mov    %rsp,%rbp
mov    %dil,%al
mov    %al,-0x1(%rbp)
movb   $0x0,-0x2(%rbp)
movzbl -0x1(%rbp),%eax
cmp    $0x9,%eax
jle    1134 <decimalToBCD+0x34>
movzbl -0x2(%rbp),%eax
add    $0x10,%eax
mov    %al,-0x2(%rbp)
movzbl -0x1(%rbp),%eax
sub    $0xa,%eax
mov    %al,-0x1(%rbp)
jmp    110e <decimalToBCD+0xe>
movzbl -0x1(%rbp),%ecx
movzbl -0x2(%rbp),%eax
add    %ecx,%eax
mov    %al,-0x2(%rbp)
movzbl -0x2(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<decimalToBCD>:
mov    %edi,%eax
xor    %ecx,%ecx
cmp    $0xa,%al
jb     1175 <decimalToBCD+0x75>
lea    -0xa(%rax),%edx
movzbl %dl,%esi
imul   $0xcd,%esi,%edi
shr    $0xb,%edi
add    $0x1,%dil
mov    %edi,%edx
and    $0x7,%dl
cmp    $0x46,%sil
jae    1128 <decimalToBCD+0x28>
jmp    1145 <decimalToBCD+0x45>
and    $0x38,%dil
xor    %ecx,%ecx
xchg   %ax,%ax
add    $0x70,%ecx
movzbl %cl,%esi
add    $0x10,%esi
add    $0xb0,%al
movzbl %sil,%ecx
add    $0xf8,%dil
jne    1130 <decimalToBCD+0x30>
test   %dl,%dl
je     1173 <decimalToBCD+0x73>
movzbl %dl,%edx
add    %edx,%edx
lea    (%rdx,%rdx,4),%edi
xor    %edx,%edx
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
mov    %ecx,%esi
add    $0x10,%esi
movzbl %sil,%ecx
add    $0xa,%dl
cmp    %dl,%dil
jne    1160 <decimalToBCD+0x60>
sub    %dl,%al
mov    %esi,%ecx
add    %cl,%al
ret

LLVM IR (-O0):
define zeroext i8 @decimalToBCD(i8 zeroext %0) {
%2 = alloca i8
%3 = alloca i8
store i8 %0, i8* %2
store i8 0, i8* %3
br label %4
4: ; preds = %8, %1
%5 = load i8, i8* %2
%6 = zext i8 %5 to i32
%7 = icmp sgt i32 %6, 9
br i1 %7, label %8, label %17
8: ; preds = %4
%9 = load i8, i8* %3
%10 = zext i8 %9 to i32
%11 = add nsw i32 %10, 16
%12 = trunc i32 %11 to i8
store i8 %12, i8* %3
%13 = load i8, i8* %2
%14 = zext i8 %13 to i32
%15 = sub nsw i32 %14, 10
%16 = trunc i32 %15 to i8
store i8 %16, i8* %2
br label %4
17: ; preds = %4
%18 = load i8, i8* %2
%19 = zext i8 %18 to i32
%20 = load i8, i8* %3
%21 = zext i8 %20 to i32
%22 = add nsw i32 %21, %19
%23 = trunc i32 %22 to i8
store i8 %23, i8* %3
%24 = load i8, i8* %3
ret i8 %24
}

LLVM IR (-O2):
define zeroext i8 @decimalToBCD(i8 zeroext %0) {
%2 = icmp ugt i8 %0, 9
br i1 %2, label %3, label %41
3: ; preds = %1
%4 = add i8 %0, -10
%5 = udiv i8 %4, 10
%6 = add nuw nsw i8 %5, 1
%7 = and i8 %6, 7
%8 = icmp ult i8 %4, 70
br i1 %8, label %22, label %9
9: ; preds = %3
%10 = and i8 %6, 56
br label %11
11: ; preds = %11, %9
%12 = phi i32 [ 0, %9 ], [ %19, %11 ]
%13 = phi i8 [ %0, %9 ], [ %18, %11 ]
%14 = phi i8 [ 0, %9 ], [ %20, %11 ]
%15 = add nuw nsw i32 %12, 112
%16 = and i32 %15, 255
%17 = add nuw nsw i32 %16, 16
%18 = add i8 %13, -80
%19 = and i32 %17, 255
%20 = add i8 %14, 8
%21 = icmp eq i8 %20, %10
br i1 %21, label %22, label %11
22: ; preds = %11, %3
%23 = phi i32 [ undef, %3 ], [ %17, %11 ]
%24 = phi i8 [ undef, %3 ], [ %18, %11 ]
%25 = phi i32 [ 0, %3 ], [ %19, %11 ]
%26 = phi i8 [ %0, %3 ], [ %18, %11 ]
%27 = icmp eq i8 %7, 0
br i1 %27, label %37, label %28
28: ; preds = %22, %28
%29 = phi i32 [ %34, %28 ], [ %25, %22 ]
%30 = phi i8 [ %33, %28 ], [ %26, %22 ]
%31 = phi i8 [ %35, %28 ], [ 0, %22 ]
%32 = add nuw nsw i32 %29, 16
%33 = add i8 %30, -10
%34 = and i32 %32, 255
%35 = add i8 %31, 1
%36 = icmp eq i8 %35, %7
br i1 %36, label %37, label %28
37: ; preds = %28, %22
%38 = phi i32 [ %23, %22 ], [ %32, %28 ]
%39 = phi i8 [ %24, %22 ], [ %33, %28 ]
%40 = trunc i32 %38 to i8
br label %41
41: ; preds = %37, %1
%42 = phi i8 [ %0, %1 ], [ %39, %37 ]
%43 = phi i8 [ 0, %1 ], [ %40, %37 ]
%44 = add i8 %42, %43
ret i8 %44
}