unsigned char BCD2Byte(char h, char l) {
  unsigned char byte;
  if (l >= '0' && l <= '9') {
    l = l - '0';
  } else if (l >= 'a' && l <= 'f') {
    l = l - 'a' + 0xa;
  } else if (l >= 'A' && l <= 'F') {
    l = l - 'A' + 0xa;
  } else {
    l = 0x00;
  }
  if (h >= '0' && h <= '9') {
    h = h - '0';
  } else if (h >= 'a' && h <= 'f') {
    h = h - 'a' + 0xa;
  } else if (h >= 'A' && h <= 'F') {
    h = h - 'A' + 0xa;
  } else {
    h = 0x00;
  }
  byte = (h * 16 + l);
  return byte;
}


x86 assembly (clang, -O0):
<BCD2Byte>:
push   %rbp
mov    %rsp,%rbp
mov    %sil,%al
mov    %dil,%cl
mov    %cl,-0x1(%rbp)
mov    %al,-0x2(%rbp)
movsbl -0x2(%rbp),%eax
cmp    $0x30,%eax
jl     1139 <BCD2Byte+0x39>
movsbl -0x2(%rbp),%eax
cmp    $0x39,%eax
jg     1139 <BCD2Byte+0x39>
movsbl -0x2(%rbp),%eax
sub    $0x30,%eax
mov    %al,-0x2(%rbp)
jmp    119f <BCD2Byte+0x9f>
movsbl -0x2(%rbp),%eax
cmp    $0x61,%eax
jl     1165 <BCD2Byte+0x65>
movsbl -0x2(%rbp),%eax
cmp    $0x66,%eax
jg     1165 <BCD2Byte+0x65>
movsbl -0x2(%rbp),%eax
sub    $0x61,%eax
add    $0xa,%eax
mov    %al,-0x2(%rbp)
jmp    119a <BCD2Byte+0x9a>
movsbl -0x2(%rbp),%eax
cmp    $0x41,%eax
jl     1191 <BCD2Byte+0x91>
movsbl -0x2(%rbp),%eax
cmp    $0x46,%eax
jg     1191 <BCD2Byte+0x91>
movsbl -0x2(%rbp),%eax
sub    $0x41,%eax
add    $0xa,%eax
mov    %al,-0x2(%rbp)
jmp    1195 <BCD2Byte+0x95>
movb   $0x0,-0x2(%rbp)
jmp    119a <BCD2Byte+0x9a>
jmp    119f <BCD2Byte+0x9f>
movsbl -0x1(%rbp),%eax
cmp    $0x30,%eax
jl     11c8 <BCD2Byte+0xc8>
movsbl -0x1(%rbp),%eax
cmp    $0x39,%eax
jg     11c8 <BCD2Byte+0xc8>
movsbl -0x1(%rbp),%eax
sub    $0x30,%eax
mov    %al,-0x1(%rbp)
jmp    122e <BCD2Byte+0x12e>
movsbl -0x1(%rbp),%eax
cmp    $0x61,%eax
jl     11f4 <BCD2Byte+0xf4>
movsbl -0x1(%rbp),%eax
cmp    $0x66,%eax
jg     11f4 <BCD2Byte+0xf4>
movsbl -0x1(%rbp),%eax
sub    $0x61,%eax
add    $0xa,%eax
mov    %al,-0x1(%rbp)
jmp    1229 <BCD2Byte+0x129>
movsbl -0x1(%rbp),%eax
cmp    $0x41,%eax
jl     1220 <BCD2Byte+0x120>
movsbl -0x1(%rbp),%eax
cmp    $0x46,%eax
jg     1220 <BCD2Byte+0x120>
movsbl -0x1(%rbp),%eax
sub    $0x41,%eax
add    $0xa,%eax
mov    %al,-0x1(%rbp)
jmp    1224 <BCD2Byte+0x124>
movb   $0x0,-0x1(%rbp)
jmp    1229 <BCD2Byte+0x129>
jmp    122e <BCD2Byte+0x12e>
movsbl -0x1(%rbp),%eax
shl    $0x4,%eax
movsbl -0x2(%rbp),%ecx
add    %ecx,%eax
mov    %al,-0x3(%rbp)
movzbl -0x3(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<BCD2Byte>:
lea    -0x30(%rsi),%ecx
cmp    $0xa,%cl
jb     1129 <BCD2Byte+0x29>
lea    -0x61(%rsi),%eax
cmp    $0x5,%al
ja     1117 <BCD2Byte+0x17>
add    $0xa9,%sil
mov    %esi,%ecx
jmp    1129 <BCD2Byte+0x29>
lea    -0x41(%rsi),%eax
add    $0xc9,%sil
xor    %edx,%edx
cmp    $0x6,%al
movzbl %sil,%ecx
cmovae %edx,%ecx
lea    -0x30(%rdi),%eax
cmp    $0xa,%al
jb     1151 <BCD2Byte+0x51>
lea    -0x61(%rdi),%eax
cmp    $0x5,%al
ja     113f <BCD2Byte+0x3f>
add    $0xa9,%dil
mov    %edi,%eax
jmp    1151 <BCD2Byte+0x51>
lea    -0x41(%rdi),%eax
add    $0xc9,%dil
xor    %edx,%edx
cmp    $0x6,%al
movzbl %dil,%eax
cmovae %edx,%eax
shl    $0x4,%al
add    %cl,%al
ret

LLVM IR (-O0):
define zeroext i8 @BCD2Byte(i8 signext %0, i8 signext %1) {
%3 = alloca i8
%4 = alloca i8
%5 = alloca i8
store i8 %0, i8* %3
store i8 %1, i8* %4
%6 = load i8, i8* %4
%7 = sext i8 %6 to i32
%8 = icmp sge i32 %7, 48
br i1 %8, label %9, label %18
9: ; preds = %2
%10 = load i8, i8* %4
%11 = sext i8 %10 to i32
%12 = icmp sle i32 %11, 57
br i1 %12, label %13, label %18
13: ; preds = %9
%14 = load i8, i8* %4
%15 = sext i8 %14 to i32
%16 = sub nsw i32 %15, 48
%17 = trunc i32 %16 to i8
store i8 %17, i8* %4
br label %49
18: ; preds = %9, %2
%19 = load i8, i8* %4
%20 = sext i8 %19 to i32
%21 = icmp sge i32 %20, 97
br i1 %21, label %22, label %32
22: ; preds = %18
%23 = load i8, i8* %4
%24 = sext i8 %23 to i32
%25 = icmp sle i32 %24, 102
br i1 %25, label %26, label %32
26: ; preds = %22
%27 = load i8, i8* %4
%28 = sext i8 %27 to i32
%29 = sub nsw i32 %28, 97
%30 = add nsw i32 %29, 10
%31 = trunc i32 %30 to i8
store i8 %31, i8* %4
br label %48
32: ; preds = %22, %18
%33 = load i8, i8* %4
%34 = sext i8 %33 to i32
%35 = icmp sge i32 %34, 65
br i1 %35, label %36, label %46
36: ; preds = %32
%37 = load i8, i8* %4
%38 = sext i8 %37 to i32
%39 = icmp sle i32 %38, 70
br i1 %39, label %40, label %46
40: ; preds = %36
%41 = load i8, i8* %4
%42 = sext i8 %41 to i32
%43 = sub nsw i32 %42, 65
%44 = add nsw i32 %43, 10
%45 = trunc i32 %44 to i8
store i8 %45, i8* %4
br label %47
46: ; preds = %36, %32
store i8 0, i8* %4
br label %47
47: ; preds = %46, %40
br label %48
48: ; preds = %47, %26
br label %49
49: ; preds = %48, %13
%50 = load i8, i8* %3
%51 = sext i8 %50 to i32
%52 = icmp sge i32 %51, 48
br i1 %52, label %53, label %62
53: ; preds = %49
%54 = load i8, i8* %3
%55 = sext i8 %54 to i32
%56 = icmp sle i32 %55, 57
br i1 %56, label %57, label %62
57: ; preds = %53
%58 = load i8, i8* %3
%59 = sext i8 %58 to i32
%60 = sub nsw i32 %59, 48
%61 = trunc i32 %60 to i8
store i8 %61, i8* %3
br label %93
62: ; preds = %53, %49
%63 = load i8, i8* %3
%64 = sext i8 %63 to i32
%65 = icmp sge i32 %64, 97
br i1 %65, label %66, label %76
66: ; preds = %62
%67 = load i8, i8* %3
%68 = sext i8 %67 to i32
%69 = icmp sle i32 %68, 102
br i1 %69, label %70, label %76
70: ; preds = %66
%71 = load i8, i8* %3
%72 = sext i8 %71 to i32
%73 = sub nsw i32 %72, 97
%74 = add nsw i32 %73, 10
%75 = trunc i32 %74 to i8
store i8 %75, i8* %3
br label %92
76: ; preds = %66, %62
%77 = load i8, i8* %3
%78 = sext i8 %77 to i32
%79 = icmp sge i32 %78, 65
br i1 %79, label %80, label %90
80: ; preds = %76
%81 = load i8, i8* %3
%82 = sext i8 %81 to i32
%83 = icmp sle i32 %82, 70
br i1 %83, label %84, label %90
84: ; preds = %80
%85 = load i8, i8* %3
%86 = sext i8 %85 to i32
%87 = sub nsw i32 %86, 65
%88 = add nsw i32 %87, 10
%89 = trunc i32 %88 to i8
store i8 %89, i8* %3
br label %91
90: ; preds = %80, %76
store i8 0, i8* %3
br label %91
91: ; preds = %90, %84
br label %92
92: ; preds = %91, %70
br label %93
93: ; preds = %92, %57
%94 = load i8, i8* %3
%95 = sext i8 %94 to i32
%96 = mul nsw i32 %95, 16
%97 = load i8, i8* %4
%98 = sext i8 %97 to i32
%99 = add nsw i32 %96, %98
%100 = trunc i32 %99 to i8
store i8 %100, i8* %5
%101 = load i8, i8* %5
ret i8 %101
}

LLVM IR (-O2):
define zeroext i8 @BCD2Byte(i8 signext %0, i8 signext %1) {
%3 = add i8 %1, -48
%4 = icmp ult i8 %3, 10
br i1 %4, label %15, label %5
5: ; preds = %2
%6 = add i8 %1, -97
%7 = icmp ult i8 %6, 6
br i1 %7, label %8, label %10
8: ; preds = %5
%9 = add nsw i8 %1, -87
br label %15
10: ; preds = %5
%11 = add i8 %1, -65
%12 = icmp ult i8 %11, 6
%13 = add i8 %1, -55
%14 = select i1 %12, i8 %13, i8 0
br label %15
15: ; preds = %2, %10, %8
%16 = phi i8 [ %9, %8 ], [ %14, %10 ], [ %3, %2 ]
%17 = add i8 %0, -48
%18 = icmp ult i8 %17, 10
br i1 %18, label %29, label %19
19: ; preds = %15
%20 = add i8 %0, -97
%21 = icmp ult i8 %20, 6
br i1 %21, label %22, label %24
22: ; preds = %19
%23 = add nsw i8 %0, -87
br label %29
24: ; preds = %19
%25 = add i8 %0, -65
%26 = icmp ult i8 %25, 6
%27 = add i8 %0, -55
%28 = select i1 %26, i8 %27, i8 0
br label %29
29: ; preds = %15, %24, %22
%30 = phi i8 [ %23, %22 ], [ %28, %24 ], [ %17, %15 ]
%31 = shl i8 %30, 4
%32 = add i8 %31, %16
ret i8 %32
}