#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
typedef char uint8_t;

/* Variables and functions */
bool unhexlify(uint8_t *hex, uint8_t *bin, size_t len) {
  size_t i;
  uint8_t c;
  for (i = 0; i < len / 2; i++) {
    c = hex[2 * i];
    if (c >= '0' && c <= '9') {
      bin[i] = (c - '0') << 4;
    } else if (c >= 'a' && c <= 'f') {
      bin[i] = (c - 'a' + 10) << 4;
    } else if (c >= 'A' && c <= 'F') {
      bin[i] = (c - 'A' + 10) << 4;
    } else {
      return false;
    }
    c = hex[2 * i + 1];
    if (c >= '0' && c <= '9') {
      bin[i] += c - '0';
    } else if (c >= 'a' && c <= 'f') {
      bin[i] += c - 'a' + 10;
    } else if (c >= 'A' && c <= 'F') {
      bin[i] += c - 'A' + 10;
    } else {
      return false;
    }
  }
  return true;
}


x86 assembly (clang, -O0):
<unhexlify>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
movq   $0x0,-0x28(%rbp)
mov    -0x28(%rbp),%rax
mov    -0x20(%rbp),%rcx
shr    $0x1,%rcx
cmp    %rcx,%rax
jae    12e7 <unhexlify+0x1e7>
mov    -0x10(%rbp),%rax
mov    -0x28(%rbp),%rcx
shl    $0x1,%rcx
mov    (%rax,%rcx,1),%al
mov    %al,-0x29(%rbp)
movsbl -0x29(%rbp),%eax
cmp    $0x30,%eax
jl     1175 <unhexlify+0x75>
movsbl -0x29(%rbp),%eax
cmp    $0x39,%eax
jg     1175 <unhexlify+0x75>
movsbl -0x29(%rbp),%eax
sub    $0x30,%eax
shl    $0x4,%eax
mov    %al,%dl
mov    -0x18(%rbp),%rax
mov    -0x28(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
jmp    11fd <unhexlify+0xfd>
movsbl -0x29(%rbp),%eax
cmp    $0x61,%eax
jl     11ae <unhexlify+0xae>
movsbl -0x29(%rbp),%eax
cmp    $0x66,%eax
jg     11ae <unhexlify+0xae>
movsbl -0x29(%rbp),%eax
sub    $0x61,%eax
add    $0xa,%eax
shl    $0x4,%eax
mov    %al,%dl
mov    -0x18(%rbp),%rax
mov    -0x28(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
jmp    11f8 <unhexlify+0xf8>
movsbl -0x29(%rbp),%eax
cmp    $0x41,%eax
jl     11e7 <unhexlify+0xe7>
movsbl -0x29(%rbp),%eax
cmp    $0x46,%eax
jg     11e7 <unhexlify+0xe7>
movsbl -0x29(%rbp),%eax
sub    $0x41,%eax
add    $0xa,%eax
shl    $0x4,%eax
mov    %al,%dl
mov    -0x18(%rbp),%rax
mov    -0x28(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
jmp    11f3 <unhexlify+0xf3>
movl   $0x0,-0x4(%rbp)
jmp    12ee <unhexlify+0x1ee>
jmp    11f8 <unhexlify+0xf8>
jmp    11fd <unhexlify+0xfd>
mov    -0x10(%rbp),%rax
mov    -0x28(%rbp),%rcx
shl    $0x1,%rcx
mov    0x1(%rax,%rcx,1),%al
mov    %al,-0x29(%rbp)
movsbl -0x29(%rbp),%eax
cmp    $0x30,%eax
jl     1247 <unhexlify+0x147>
movsbl -0x29(%rbp),%eax
cmp    $0x39,%eax
jg     1247 <unhexlify+0x147>
movsbl -0x29(%rbp),%esi
sub    $0x30,%esi
mov    -0x18(%rbp),%rax
mov    -0x28(%rbp),%rcx
movsbl (%rax,%rcx,1),%edx
add    %esi,%edx
mov    %dl,(%rax,%rcx,1)
jmp    12d1 <unhexlify+0x1d1>
movsbl -0x29(%rbp),%eax
cmp    $0x61,%eax
jl     1281 <unhexlify+0x181>
movsbl -0x29(%rbp),%eax
cmp    $0x66,%eax
jg     1281 <unhexlify+0x181>
movsbl -0x29(%rbp),%esi
sub    $0x61,%esi
add    $0xa,%esi
mov    -0x18(%rbp),%rax
mov    -0x28(%rbp),%rcx
movsbl (%rax,%rcx,1),%edx
add    %esi,%edx
mov    %dl,(%rax,%rcx,1)
jmp    12cc <unhexlify+0x1cc>
movsbl -0x29(%rbp),%eax
cmp    $0x41,%eax
jl     12bb <unhexlify+0x1bb>
movsbl -0x29(%rbp),%eax
cmp    $0x46,%eax
jg     12bb <unhexlify+0x1bb>
movsbl -0x29(%rbp),%esi
sub    $0x41,%esi
add    $0xa,%esi
mov    -0x18(%rbp),%rax
mov    -0x28(%rbp),%rcx
movsbl (%rax,%rcx,1),%edx
add    %esi,%edx
mov    %dl,(%rax,%rcx,1)
jmp    12c7 <unhexlify+0x1c7>
movl   $0x0,-0x4(%rbp)
jmp    12ee <unhexlify+0x1ee>
jmp    12cc <unhexlify+0x1cc>
jmp    12d1 <unhexlify+0x1d1>
jmp    12d6 <unhexlify+0x1d6>
mov    -0x28(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x28(%rbp)
jmp    1118 <unhexlify+0x18>
movl   $0x1,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<unhexlify>:
mov    $0x1,%eax
cmp    $0x2,%rdx
jb     11a8 <unhexlify+0xa8>
shr    %rdx
xor    %r11d,%r11d
jmp    1130 <unhexlify+0x30>
nopw   0x0(%rax,%rax,1)
add    %r10b,%r8b
mov    %r8b,(%rsi,%r11,1)
add    $0x1,%r11
cmp    %r11,%rdx
je     11a8 <unhexlify+0xa8>
movzbl (%rdi,%r11,2),%r8d
lea    -0x30(%r8),%ecx
cmp    $0x9,%cl
ja     1150 <unhexlify+0x50>
shl    $0x4,%r8b
jmp    116a <unhexlify+0x6a>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
lea    -0x61(%r8),%ecx
cmp    $0x5,%cl
jbe    1162 <unhexlify+0x62>
lea    -0x41(%r8),%ecx
cmp    $0x5,%cl
ja     11a6 <unhexlify+0xa6>
shl    $0x4,%r8b
add    $0x90,%r8b
mov    %r8b,(%rsi,%r11,1)
movzbl 0x1(%rdi,%r11,2),%r9d
lea    -0x30(%r9),%r10d
cmp    $0x9,%r10b
jbe    1120 <unhexlify+0x20>
lea    -0x61(%r9),%ecx
cmp    $0x5,%cl
ja     1190 <unhexlify+0x90>
add    %r8b,%r9b
add    $0xa9,%r9b
jmp    11a0 <unhexlify+0xa0>
lea    -0x41(%r9),%ecx
cmp    $0x5,%cl
ja     11a6 <unhexlify+0xa6>
add    %r8b,%r9b
add    $0xc9,%r9b
mov    %r9b,(%rsi,%r11,1)
jmp    1127 <unhexlify+0x27>
xor    %eax,%eax
ret

LLVM IR (-O0):
define i32 @unhexlify(i8* %0, i8* %1, i64 %2) {
%4 = alloca i32
%5 = alloca i8*
%6 = alloca i8*
%7 = alloca i64
%8 = alloca i64
%9 = alloca i8
store i8* %0, i8** %5
store i8* %1, i8** %6
store i64 %2, i64* %7
store i64 0, i64* %8
br label %10
10: ; preds = %145, %3
%11 = load i64, i64* %8
%12 = load i64, i64* %7
%13 = udiv i64 %12, 2
%14 = icmp ult i64 %11, %13
br i1 %14, label %15, label %148
15: ; preds = %10
%16 = load i8*, i8** %5
%17 = load i64, i64* %8
%18 = mul i64 2, %17
%19 = getelementptr inbounds i8, i8* %16, i64 %18
%20 = load i8, i8* %19
store i8 %20, i8* %9
%21 = load i8, i8* %9
%22 = sext i8 %21 to i32
%23 = icmp sge i32 %22, 48
br i1 %23, label %24, label %37
24: ; preds = %15
%25 = load i8, i8* %9
%26 = sext i8 %25 to i32
%27 = icmp sle i32 %26, 57
br i1 %27, label %28, label %37
28: ; preds = %24
%29 = load i8, i8* %9
%30 = sext i8 %29 to i32
%31 = sub nsw i32 %30, 48
%32 = shl i32 %31, 4
%33 = trunc i32 %32 to i8
%34 = load i8*, i8** %6
%35 = load i64, i64* %8
%36 = getelementptr inbounds i8, i8* %34, i64 %35
store i8 %33, i8* %36
br label %76
37: ; preds = %24, %15
%38 = load i8, i8* %9
%39 = sext i8 %38 to i32
%40 = icmp sge i32 %39, 97
br i1 %40, label %41, label %55
41: ; preds = %37
%42 = load i8, i8* %9
%43 = sext i8 %42 to i32
%44 = icmp sle i32 %43, 102
br i1 %44, label %45, label %55
45: ; preds = %41
%46 = load i8, i8* %9
%47 = sext i8 %46 to i32
%48 = sub nsw i32 %47, 97
%49 = add nsw i32 %48, 10
%50 = shl i32 %49, 4
%51 = trunc i32 %50 to i8
%52 = load i8*, i8** %6
%53 = load i64, i64* %8
%54 = getelementptr inbounds i8, i8* %52, i64 %53
store i8 %51, i8* %54
br label %75
55: ; preds = %41, %37
%56 = load i8, i8* %9
%57 = sext i8 %56 to i32
%58 = icmp sge i32 %57, 65
br i1 %58, label %59, label %73
59: ; preds = %55
%60 = load i8, i8* %9
%61 = sext i8 %60 to i32
%62 = icmp sle i32 %61, 70
br i1 %62, label %63, label %73
63: ; preds = %59
%64 = load i8, i8* %9
%65 = sext i8 %64 to i32
%66 = sub nsw i32 %65, 65
%67 = add nsw i32 %66, 10
%68 = shl i32 %67, 4
%69 = trunc i32 %68 to i8
%70 = load i8*, i8** %6
%71 = load i64, i64* %8
%72 = getelementptr inbounds i8, i8* %70, i64 %71
store i8 %69, i8* %72
br label %74
73: ; preds = %59, %55
store i32 0, i32* %4
br label %149
74: ; preds = %63
br label %75
75: ; preds = %74, %45
br label %76
76: ; preds = %75, %28
%77 = load i8*, i8** %5
%78 = load i64, i64* %8
%79 = mul i64 2, %78
%80 = add i64 %79, 1
%81 = getelementptr inbounds i8, i8* %77, i64 %80
%82 = load i8, i8* %81
store i8 %82, i8* %9
%83 = load i8, i8* %9
%84 = sext i8 %83 to i32
%85 = icmp sge i32 %84, 48
br i1 %85, label %86, label %101
86: ; preds = %76
%87 = load i8, i8* %9
%88 = sext i8 %87 to i32
%89 = icmp sle i32 %88, 57
br i1 %89, label %90, label %101
90: ; preds = %86
%91 = load i8, i8* %9
%92 = sext i8 %91 to i32
%93 = sub nsw i32 %92, 48
%94 = load i8*, i8** %6
%95 = load i64, i64* %8
%96 = getelementptr inbounds i8, i8* %94, i64 %95
%97 = load i8, i8* %96
%98 = sext i8 %97 to i32
%99 = add nsw i32 %98, %93
%100 = trunc i32 %99 to i8
store i8 %100, i8* %96
br label %144
101: ; preds = %86, %76
%102 = load i8, i8* %9
%103 = sext i8 %102 to i32
%104 = icmp sge i32 %103, 97
br i1 %104, label %105, label %121
105: ; preds = %101
%106 = load i8, i8* %9
%107 = sext i8 %106 to i32
%108 = icmp sle i32 %107, 102
br i1 %108, label %109, label %121
109: ; preds = %105
%110 = load i8, i8* %9
%111 = sext i8 %110 to i32
%112 = sub nsw i32 %111, 97
%113 = add nsw i32 %112, 10
%114 = load i8*, i8** %6
%115 = load i64, i64* %8
%116 = getelementptr inbounds i8, i8* %114, i64 %115
%117 = load i8, i8* %116
%118 = sext i8 %117 to i32
%119 = add nsw i32 %118, %113
%120 = trunc i32 %119 to i8
store i8 %120, i8* %116
br label %143
121: ; preds = %105, %101
%122 = load i8, i8* %9
%123 = sext i8 %122 to i32
%124 = icmp sge i32 %123, 65
br i1 %124, label %125, label %141
125: ; preds = %121
%126 = load i8, i8* %9
%127 = sext i8 %126 to i32
%128 = icmp sle i32 %127, 70
br i1 %128, label %129, label %141
129: ; preds = %125
%130 = load i8, i8* %9
%131 = sext i8 %130 to i32
%132 = sub nsw i32 %131, 65
%133 = add nsw i32 %132, 10
%134 = load i8*, i8** %6
%135 = load i64, i64* %8
%136 = getelementptr inbounds i8, i8* %134, i64 %135
%137 = load i8, i8* %136
%138 = sext i8 %137 to i32
%139 = add nsw i32 %138, %133
%140 = trunc i32 %139 to i8
store i8 %140, i8* %136
br label %142
141: ; preds = %125, %121
store i32 0, i32* %4
br label %149
142: ; preds = %129
br label %143
143: ; preds = %142, %109
br label %144
144: ; preds = %143, %90
br label %145
145: ; preds = %144
%146 = load i64, i64* %8
%147 = add i64 %146, 1
store i64 %147, i64* %8
br label %10
148: ; preds = %10
store i32 1, i32* %4
br label %149
149: ; preds = %148, %141, %73
%150 = load i32, i32* %4
ret i32 %150
}

LLVM IR (-O2):
define i32 @unhexlify(i8* nocapture %0, i8* nocapture %1, i64 %2) {
%4 = icmp ult i64 %2, 2
br i1 %4, label %56, label %5
5: ; preds = %3
%6 = lshr i64 %2, 1
br label %7
7: ; preds = %5, %53
%8 = phi i64 [ %54, %53 ], [ 0, %5 ]
%9 = shl nuw i64 %8, 1
%10 = getelementptr inbounds i8, i8* %0, i64 %9
%11 = load i8, i8* %10
%12 = add i8 %11, -48
%13 = icmp ult i8 %12, 10
br i1 %13, label %14, label %16
14: ; preds = %7
%15 = shl i8 %11, 4
br label %28
16: ; preds = %7
%17 = add i8 %11, -97
%18 = icmp ult i8 %17, 6
br i1 %18, label %19, label %22
19: ; preds = %16
%20 = shl i8 %11, 4
%21 = add nuw nsw i8 %20, -112
br label %28
22: ; preds = %16
%23 = add i8 %11, -65
%24 = icmp ult i8 %23, 6
br i1 %24, label %25, label %56
25: ; preds = %22
%26 = shl i8 %11, 4
%27 = add nuw nsw i8 %26, -112
br label %28
28: ; preds = %19, %25, %14
%29 = phi i8 [ %21, %19 ], [ %27, %25 ], [ %15, %14 ]
%30 = getelementptr inbounds i8, i8* %1, i64 %8
store i8 %29, i8* %30
%31 = or i64 %9, 1
%32 = getelementptr inbounds i8, i8* %0, i64 %31
%33 = load i8, i8* %32
%34 = add i8 %33, -48
%35 = icmp ult i8 %34, 10
br i1 %35, label %36, label %39
36: ; preds = %28
%37 = getelementptr inbounds i8, i8* %1, i64 %8
%38 = add nuw i8 %29, %34
store i8 %38, i8* %37
br label %53
39: ; preds = %28
%40 = add i8 %33, -97
%41 = icmp ult i8 %40, 6
br i1 %41, label %42, label %46
42: ; preds = %39
%43 = add nsw i8 %33, -87
%44 = getelementptr inbounds i8, i8* %1, i64 %8
%45 = add nuw i8 %43, %29
store i8 %45, i8* %44
br label %53
46: ; preds = %39
%47 = add i8 %33, -65
%48 = icmp ult i8 %47, 6
br i1 %48, label %49, label %56
49: ; preds = %46
%50 = add nsw i8 %33, -55
%51 = getelementptr inbounds i8, i8* %1, i64 %8
%52 = add nuw i8 %50, %29
store i8 %52, i8* %51
br label %53
53: ; preds = %36, %49, %42
%54 = add nuw nsw i64 %8, 1
%55 = icmp eq i64 %54, %6
br i1 %55, label %56, label %7
56: ; preds = %22, %46, %53, %3
%57 = phi i32 [ 1, %3 ], [ 1, %53 ], [ 0, %46 ], [ 0, %22 ]
ret i32 %57
}