#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 */

/* Variables and functions */
int /*<<< orphan*/ printf(char *);
int /*<<< orphan*/ sprintf(char *, char *, char);
unsigned char writeChar(char c, int section) {
  char splitChar[2];
  unsigned char ret;
  sprintf(splitChar, "%x", c);
  switch (splitChar[section]) {
  case '0':
    ret = 16;
    break;
  case '1':
    ret = 24;
    break;
  case '2':
    ret = 20;
    break;
  case '3':
    ret = 28;
    break;
  case '4':
    ret = 18;
    break;
  case '5':
    ret = 26;
    break;
  case '6':
    ret = 22;
    break;
  case '7':
    ret = 30;
    break;
  case '8':
    ret = 17;
    break;
  case '9':
    ret = 25;
    break;
  case 'A':
  case 'a':
    ret = 21;
    break;
  case 'B':
  case 'b':
    ret = 29;
    break;
  case 'C':
  case 'c':
    ret = 19;
    break;
  case 'D':
  case 'd':
    ret = 27;
    break;
  case 'E':
  case 'e':
    ret = 23;
    break;
  case 'F':
  case 'f':
    ret = 31;
    break;
  default:
    printf("Character invalid\n");
  }
  return ret;
}


x86 assembly (clang, -O0):
<writeChar>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %dil,%al
mov    %al,-0x1(%rbp)
mov    %esi,-0x8(%rbp)
movsbl -0x1(%rbp),%edx
lea    0xfa0(%rip),%rsi
lea    -0xa(%rbp),%rdi
call   1040 <sprintf@plt>
movslq -0x8(%rbp),%rax
movsbl -0xa(%rbp,%rax,1),%eax
add    $0xffffffd0,%eax
mov    %eax,%ecx
mov    %rcx,-0x18(%rbp)
sub    $0x36,%eax
ja     1204 <writeChar+0xe4>
mov    -0x18(%rbp),%rax
lea    0xe95(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
movb   $0x10,-0xb(%rbp)
jmp    1210 <writeChar+0xf0>
movb   $0x18,-0xb(%rbp)
jmp    1210 <writeChar+0xf0>
movb   $0x14,-0xb(%rbp)
jmp    1210 <writeChar+0xf0>
movb   $0x1c,-0xb(%rbp)
jmp    1210 <writeChar+0xf0>
movb   $0x12,-0xb(%rbp)
jmp    1210 <writeChar+0xf0>
movb   $0x1a,-0xb(%rbp)
jmp    1210 <writeChar+0xf0>
movb   $0x16,-0xb(%rbp)
jmp    1210 <writeChar+0xf0>
movb   $0x1e,-0xb(%rbp)
jmp    1210 <writeChar+0xf0>
movb   $0x11,-0xb(%rbp)
jmp    1210 <writeChar+0xf0>
movb   $0x19,-0xb(%rbp)
jmp    1210 <writeChar+0xf0>
movb   $0x15,-0xb(%rbp)
jmp    1210 <writeChar+0xf0>
movb   $0x1d,-0xb(%rbp)
jmp    1210 <writeChar+0xf0>
movb   $0x13,-0xb(%rbp)
jmp    1210 <writeChar+0xf0>
movb   $0x1b,-0xb(%rbp)
jmp    1210 <writeChar+0xf0>
movb   $0x17,-0xb(%rbp)
jmp    1210 <writeChar+0xf0>
movb   $0x1f,-0xb(%rbp)
jmp    1210 <writeChar+0xf0>
lea    0xed4(%rip),%rdi
call   1030 <printf@plt>
movzbl -0xb(%rbp),%eax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<writeChar>:
push   %rbx
sub    $0x10,%rsp
mov    %esi,%ebx
mov    %edi,%edx
lea    0xed0(%rip),%rsi
lea    0xe(%rsp),%rdi
call   1040 <sprintf@plt>
movslq %ebx,%rax
movsbq 0xe(%rsp,%rax,1),%rax
add    $0xffffffffffffffd0,%rax
cmp    $0x37,%eax
jae    115c <writeChar+0x3c>
movabs $0x7e0000007e03ff,%rcx
bt     %rax,%rcx
jb     116a <writeChar+0x4a>
lea    0xea0(%rip),%rdi
call   1030 <puts@plt>
jmp    1174 <writeChar+0x54>
lea    0xea4(%rip),%rcx
mov    (%rax,%rcx,1),%al
add    $0x10,%rsp
pop    %rbx
ret

LLVM IR (-O0):
@.str = [3 x i8] c"%x\00"
@.str.1 = [19 x i8] c"Character invalid\0A\00"
define zeroext i8 @writeChar(i8 signext %0, i32 %1) {
%3 = alloca i8
%4 = alloca i32
%5 = alloca [2 x i8]
%6 = alloca i8
store i8 %0, i8* %3
store i32 %1, i32* %4
%7 = getelementptr inbounds [2 x i8], [2 x i8]* %5, i64 0, i64 0
%8 = load i8, i8* %3
%9 = call i32 @sprintf(i8* %7, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0), i8 signext %8)
%10 = load i32, i32* %4
%11 = sext i32 %10 to i64
%12 = getelementptr inbounds [2 x i8], [2 x i8]* %5, i64 0, i64 %11
%13 = load i8, i8* %12
%14 = sext i8 %13 to i32
switch i32 %14, label %31 [
i32 48, label %15
i32 49, label %16
i32 50, label %17
i32 51, label %18
i32 52, label %19
i32 53, label %20
i32 54, label %21
i32 55, label %22
i32 56, label %23
i32 57, label %24
i32 65, label %25
i32 97, label %25
i32 66, label %26
i32 98, label %26
i32 67, label %27
i32 99, label %27
i32 68, label %28
i32 100, label %28
i32 69, label %29
i32 101, label %29
i32 70, label %30
i32 102, label %30
]
15: ; preds = %2
store i8 16, i8* %6
br label %33
16: ; preds = %2
store i8 24, i8* %6
br label %33
17: ; preds = %2
store i8 20, i8* %6
br label %33
18: ; preds = %2
store i8 28, i8* %6
br label %33
19: ; preds = %2
store i8 18, i8* %6
br label %33
20: ; preds = %2
store i8 26, i8* %6
br label %33
21: ; preds = %2
store i8 22, i8* %6
br label %33
22: ; preds = %2
store i8 30, i8* %6
br label %33
23: ; preds = %2
store i8 17, i8* %6
br label %33
24: ; preds = %2
store i8 25, i8* %6
br label %33
25: ; preds = %2, %2
store i8 21, i8* %6
br label %33
26: ; preds = %2, %2
store i8 29, i8* %6
br label %33
27: ; preds = %2, %2
store i8 19, i8* %6
br label %33
28: ; preds = %2, %2
store i8 27, i8* %6
br label %33
29: ; preds = %2, %2
store i8 23, i8* %6
br label %33
30: ; preds = %2, %2
store i8 31, i8* %6
br label %33
31: ; preds = %2
%32 = call i32 @printf(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str.1, i64 0, i64 0))
br label %33
33: ; preds = %31, %30, %29, %28, %27, %26, %25, %24, %23, %22, %21, %20, %19, %18, %17, %16, %15
%34 = load i8, i8* %6
ret i8 %34
}

LLVM IR (-O2):
@.str = [3 x i8] c"%x\00"
@str = [18 x i8] c"Character invalid\00"
@switch.table.writeChar = [55 x i8] c"\10\18\14\1C\12\1A\16\1E\11\19\10\10\10\10\10\10\10\15\1D\13\1B\17\1F\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\15\1D\13\1B\17\1F"
define zeroext i8 @writeChar(i8 signext %0, i32 %1) {
%3 = alloca [2 x i8]
%4 = getelementptr inbounds [2 x i8], [2 x i8]* %3, i64 0, i64 0
%5 = call i32 @sprintf(i8* %4, i8* dereferenceable(1) getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0), i8 signext %0)
%6 = sext i32 %1 to i64
%7 = getelementptr inbounds [2 x i8], [2 x i8]* %3, i64 0, i64 %6
%8 = load i8, i8* %7
%9 = sext i8 %8 to i32
%10 = add nsw i32 %9, -48
%11 = icmp ult i32 %10, 55
br i1 %11, label %14, label %12
12: ; preds = %14, %2
%13 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([18 x i8], [18 x i8]* @str, i64 0, i64 0))
br label %23
14: ; preds = %2
%15 = zext i32 %10 to i64
%16 = lshr i64 35465847073801215, %15
%17 = and i64 %16, 1
%18 = icmp eq i64 %17, 0
br i1 %18, label %12, label %19
19: ; preds = %14
%20 = sext i32 %10 to i64
%21 = getelementptr inbounds [55 x i8], [55 x i8]* @switch.table.writeChar, i64 0, i64 %20
%22 = load i8, i8* %21
br label %23
23: ; preds = %19, %12
%24 = phi i8 [ undef, %12 ], [ %22, %19 ]
ret i8 %24
}