int escape_char(int c) {
  struct {
    char from, to;
  } escapechars[] = {{'n', '\n'},  {'t', '\t'},  {'b', '\b'},  {'r', '\r'},
                     {'v', '\v'},  {'f', '\f'},  {'0', '\0'},  {'a', '\a'},
                     {'e', '\33'}, {'\\', '\\'}, {'\'', '\''}, {'?', '?'},
                     {'"', '"'}};
  unsigned int i;
  for (i = 0; i < (sizeof(escapechars) / sizeof((escapechars)[0])); i++)
    if (escapechars[i].from == c)
      return escapechars[i].to;
  return -1;
}


x86 assembly (clang, -O0):
<escape_char>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x8(%rbp)
mov    0xef2(%rip),%rax
mov    %rax,-0x30(%rbp)
mov    0xeef(%rip),%rax
mov    %rax,-0x28(%rbp)
mov    0xeec(%rip),%rax
mov    %rax,-0x20(%rbp)
mov    0xee9(%rip),%ax
mov    %ax,-0x18(%rbp)
movl   $0x0,-0x34(%rbp)
mov    -0x34(%rbp),%eax
cmp    $0xd,%rax
jae    117b <escape_char+0x7b>
mov    -0x34(%rbp),%eax
movsbl -0x30(%rbp,%rax,2),%eax
cmp    -0x8(%rbp),%eax
jne    1168 <escape_char+0x68>
mov    -0x34(%rbp),%eax
movsbl -0x2f(%rbp,%rax,2),%eax
mov    %eax,-0x4(%rbp)
jmp    1182 <escape_char+0x82>
jmp    116d <escape_char+0x6d>
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    113a <escape_char+0x3a>
movl   $0xffffffff,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<escape_char>:
mov    $0xffffffff,%eax
add    $0xffffffde,%edi
cmp    $0x54,%edi
ja     117d <escape_char+0x7d>
xor    %ecx,%ecx
lea    0xeea(%rip),%rdx
movslq (%rdx,%rdi,4),%rsi
add    %rdx,%rsi
jmp    *%rsi
mov    $0xc,%ecx
jmp    1171 <escape_char+0x71>
mov    $0xa,%ecx
jmp    1171 <escape_char+0x71>
mov    $0x6,%ecx
jmp    1171 <escape_char+0x71>
mov    $0xb,%ecx
jmp    1171 <escape_char+0x71>
mov    $0x9,%ecx
jmp    1171 <escape_char+0x71>
mov    $0x7,%ecx
jmp    1171 <escape_char+0x71>
mov    $0x2,%ecx
jmp    1171 <escape_char+0x71>
mov    $0x8,%ecx
jmp    1171 <escape_char+0x71>
mov    $0x5,%ecx
jmp    1171 <escape_char+0x71>
mov    $0x3,%ecx
jmp    1171 <escape_char+0x71>
mov    $0x1,%ecx
jmp    1171 <escape_char+0x71>
mov    $0x4,%ecx
lea    0xfe8(%rip),%rax
movsbl 0x1(%rax,%rcx,2),%eax
ret

LLVM IR (-O0):
%struct.anon = type { i8, i8 }
@__const.escape_char.escapechars = [13 x %struct.anon] [%struct.anon { i8 110, i8 10 }, %struct.anon { i8 116, i8 9 }, %struct.anon { i8 98, i8 8 }, %struct.anon { i8 114, i8 13 }, %struct.anon { i8 118, i8 11 }, %struct.anon { i8 102, i8 12 }, %struct.anon { i8 48, i8 0 }, %struct.anon { i8 97, i8 7 }, %struct.anon { i8 101, i8 27 }, %struct.anon { i8 92, i8 92 }, %struct.anon { i8 39, i8 39 }, %struct.anon { i8 63, i8 63 }, %struct.anon { i8 34, i8 34 }]
define i32 @escape_char(i32 %0) {
%2 = alloca i32
%3 = alloca i32
%4 = alloca [13 x %struct.anon]
%5 = alloca i32
store i32 %0, i32* %3
%6 = bitcast [13 x %struct.anon]* %4 to i8*
store i32 0, i32* %5
br label %7
7: ; preds = %28, %1
%8 = load i32, i32* %5
%9 = zext i32 %8 to i64
%10 = icmp ult i64 %9, 13
br i1 %10, label %11, label %31
11: ; preds = %7
%12 = load i32, i32* %5
%13 = zext i32 %12 to i64
%14 = getelementptr inbounds [13 x %struct.anon], [13 x %struct.anon]* %4, i64 0, i64 %13
%15 = getelementptr inbounds %struct.anon, %struct.anon* %14, i32 0, i32 0
%16 = load i8, i8* %15
%17 = sext i8 %16 to i32
%18 = load i32, i32* %3
%19 = icmp eq i32 %17, %18
br i1 %19, label %20, label %27
20: ; preds = %11
%21 = load i32, i32* %5
%22 = zext i32 %21 to i64
%23 = getelementptr inbounds [13 x %struct.anon], [13 x %struct.anon]* %4, i64 0, i64 %22
%24 = getelementptr inbounds %struct.anon, %struct.anon* %23, i32 0, i32 1
%25 = load i8, i8* %24
%26 = sext i8 %25 to i32
store i32 %26, i32* %2
br label %32
27: ; preds = %11
br label %28
28: ; preds = %27
%29 = load i32, i32* %5
%30 = add i32 %29, 1
store i32 %30, i32* %5
br label %7
31: ; preds = %7
store i32 -1, i32* %2
br label %32
32: ; preds = %31, %20
%33 = load i32, i32* %2
ret i32 %33
}

LLVM IR (-O2):
%struct.anon = type { i8, i8 }
@__const.escape_char.escapechars = [13 x %struct.anon] [%struct.anon { i8 110, i8 10 }, %struct.anon { i8 116, i8 9 }, %struct.anon { i8 98, i8 8 }, %struct.anon { i8 114, i8 13 }, %struct.anon { i8 118, i8 11 }, %struct.anon { i8 102, i8 12 }, %struct.anon { i8 48, i8 0 }, %struct.anon { i8 97, i8 7 }, %struct.anon { i8 101, i8 27 }, %struct.anon { i8 92, i8 92 }, %struct.anon { i8 39, i8 39 }, %struct.anon { i8 63, i8 63 }, %struct.anon { i8 34, i8 34 }]
define i32 @escape_char(i32 %0) {
switch i32 %0, label %19 [
i32 110, label %14
i32 116, label %2
i32 98, label %3
i32 114, label %4
i32 118, label %5
i32 102, label %6
i32 48, label %7
i32 97, label %8
i32 101, label %9
i32 92, label %10
i32 39, label %11
i32 63, label %12
i32 34, label %13
]
2: ; preds = %1
br label %14
3: ; preds = %1
br label %14
4: ; preds = %1
br label %14
5: ; preds = %1
br label %14
6: ; preds = %1
br label %14
7: ; preds = %1
br label %14
8: ; preds = %1
br label %14
9: ; preds = %1
br label %14
10: ; preds = %1
br label %14
11: ; preds = %1
br label %14
12: ; preds = %1
br label %14
13: ; preds = %1
br label %14
14: ; preds = %1, %13, %12, %11, %10, %9, %8, %7, %6, %5, %4, %3, %2
%15 = phi i64 [ 0, %1 ], [ 1, %2 ], [ 2, %3 ], [ 3, %4 ], [ 4, %5 ], [ 5, %6 ], [ 6, %7 ], [ 7, %8 ], [ 8, %9 ], [ 9, %10 ], [ 10, %11 ], [ 11, %12 ], [ 12, %13 ]
%16 = getelementptr inbounds [13 x %struct.anon], [13 x %struct.anon]* @__const.escape_char.escapechars, i64 0, i64 %15, i32 1
%17 = load i8, i8* %16
%18 = sext i8 %17 to i32
br label %19
19: ; preds = %1, %14
%20 = phi i32 [ %18, %14 ], [ -1, %1 ]
ret i32 %20
}