void unescape(char *source, char *target) {
  while (*source != '\0') {
    if (*source != '\\')
      *target++ = *source;
    else {
      switch (*(++source)) {
      case 'a':
        *target++ = '\a';
        break;
      case 'b':
        *target++ = '\b';
        break;
      case 'f':
        *target++ = '\f';
        break;
      case 'n':
        *target++ = '\n';
        break;
      case 'r':
        *target++ = '\r';
        break;
      case 't':
        *target++ = '\t';
        break;
      case 'v':
        *target++ = '\v';
        break;
      case '\'':
        *target++ = '\'';
        break;
      case '"':
        *target++ = '\"';
        break;
      case '?':
        *target++ = '\?';
        break;
      default:
        *target++ = *source;
      }
    }
    *target = '\0';
    source++;
  }
}


x86 assembly (clang, -O0):
<unescape>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x0,%eax
je     129b <unescape+0x19b>
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x5c,%eax
je     1148 <unescape+0x48>
mov    -0x8(%rbp),%rax
mov    (%rax),%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
jmp    1283 <unescape+0x183>
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x8(%rbp)
movsbl 0x1(%rax),%eax
add    $0xffffffde,%eax
mov    %eax,%ecx
mov    %rcx,-0x18(%rbp)
sub    $0x54,%eax
ja     1267 <unescape+0x167>
mov    -0x18(%rbp),%rax
lea    0xe88(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
movb   $0x7,(%rax)
jmp    127e <unescape+0x17e>
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
movb   $0x8,(%rax)
jmp    127e <unescape+0x17e>
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
movb   $0xc,(%rax)
jmp    127e <unescape+0x17e>
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
movb   $0xa,(%rax)
jmp    127e <unescape+0x17e>
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
movb   $0xd,(%rax)
jmp    127e <unescape+0x17e>
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
movb   $0x9,(%rax)
jmp    127e <unescape+0x17e>
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
movb   $0xb,(%rax)
jmp    127e <unescape+0x17e>
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
movb   $0x27,(%rax)
jmp    127e <unescape+0x17e>
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
movb   $0x22,(%rax)
jmp    127e <unescape+0x17e>
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
movb   $0x3f,(%rax)
jmp    127e <unescape+0x17e>
mov    -0x8(%rbp),%rax
mov    (%rax),%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
jmp    1283 <unescape+0x183>
mov    -0x10(%rbp),%rax
movb   $0x0,(%rax)
mov    -0x8(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
jmp    110c <unescape+0xc>
pop    %rbp
ret

x86 assembly (clang, -O2):
<unescape>:
add    $0x1,%rsi
lea    0xef5(%rip),%r8
jmp    1122 <unescape+0x22>
nopl   (%rax)
test   %cl,%cl
je     116d <unescape+0x6d>
mov    %cl,-0x1(%rsi)
movb   $0x0,(%rsi)
add    $0x1,%rdi
add    $0x1,%rsi
movzbl (%rdi),%ecx
cmp    $0x5c,%cl
jne    1110 <unescape+0x10>
movsbl 0x1(%rdi),%edx
add    $0x1,%rdi
lea    -0x22(%rdx),%eax
cmp    $0x54,%eax
ja     1149 <unescape+0x49>
mov    $0x7,%cl
movslq (%r8,%rax,4),%rax
add    %r8,%rax
jmp    *%rax
mov    $0x22,%cl
jmp    1114 <unescape+0x14>
mov    %edx,%ecx
jmp    1114 <unescape+0x14>
mov    $0x27,%cl
jmp    1114 <unescape+0x14>
mov    $0x3f,%cl
jmp    1114 <unescape+0x14>
mov    $0x8,%cl
jmp    1114 <unescape+0x14>
mov    $0xc,%cl
jmp    1114 <unescape+0x14>
mov    $0xa,%cl
jmp    1114 <unescape+0x14>
mov    $0xd,%cl
jmp    1114 <unescape+0x14>
mov    $0x9,%cl
jmp    1114 <unescape+0x14>
mov    $0xb,%cl
jmp    1114 <unescape+0x14>
ret

LLVM IR (-O0):
define void @unescape(i8* %0, i8* %1) {
%3 = alloca i8*
%4 = alloca i8*
store i8* %0, i8** %3
store i8* %1, i8** %4
br label %5
5: ; preds = %61, %2
%6 = load i8*, i8** %3
%7 = load i8, i8* %6
%8 = sext i8 %7 to i32
%9 = icmp ne i32 %8, 0
br i1 %9, label %10, label %65
10: ; preds = %5
%11 = load i8*, i8** %3
%12 = load i8, i8* %11
%13 = sext i8 %12 to i32
%14 = icmp ne i32 %13, 92
br i1 %14, label %15, label %20
15: ; preds = %10
%16 = load i8*, i8** %3
%17 = load i8, i8* %16
%18 = load i8*, i8** %4
%19 = getelementptr inbounds i8, i8* %18, i32 1
store i8* %19, i8** %4
store i8 %17, i8* %18
br label %61
20: ; preds = %10
%21 = load i8*, i8** %3
%22 = getelementptr inbounds i8, i8* %21, i32 1
store i8* %22, i8** %3
%23 = load i8, i8* %22
%24 = sext i8 %23 to i32
switch i32 %24, label %55 [
i32 97, label %25
i32 98, label %28
i32 102, label %31
i32 110, label %34
i32 114, label %37
i32 116, label %40
i32 118, label %43
i32 39, label %46
i32 34, label %49
i32 63, label %52
]
25: ; preds = %20
%26 = load i8*, i8** %4
%27 = getelementptr inbounds i8, i8* %26, i32 1
store i8* %27, i8** %4
store i8 7, i8* %26
br label %60
28: ; preds = %20
%29 = load i8*, i8** %4
%30 = getelementptr inbounds i8, i8* %29, i32 1
store i8* %30, i8** %4
store i8 8, i8* %29
br label %60
31: ; preds = %20
%32 = load i8*, i8** %4
%33 = getelementptr inbounds i8, i8* %32, i32 1
store i8* %33, i8** %4
store i8 12, i8* %32
br label %60
34: ; preds = %20
%35 = load i8*, i8** %4
%36 = getelementptr inbounds i8, i8* %35, i32 1
store i8* %36, i8** %4
store i8 10, i8* %35
br label %60
37: ; preds = %20
%38 = load i8*, i8** %4
%39 = getelementptr inbounds i8, i8* %38, i32 1
store i8* %39, i8** %4
store i8 13, i8* %38
br label %60
40: ; preds = %20
%41 = load i8*, i8** %4
%42 = getelementptr inbounds i8, i8* %41, i32 1
store i8* %42, i8** %4
store i8 9, i8* %41
br label %60
43: ; preds = %20
%44 = load i8*, i8** %4
%45 = getelementptr inbounds i8, i8* %44, i32 1
store i8* %45, i8** %4
store i8 11, i8* %44
br label %60
46: ; preds = %20
%47 = load i8*, i8** %4
%48 = getelementptr inbounds i8, i8* %47, i32 1
store i8* %48, i8** %4
store i8 39, i8* %47
br label %60
49: ; preds = %20
%50 = load i8*, i8** %4
%51 = getelementptr inbounds i8, i8* %50, i32 1
store i8* %51, i8** %4
store i8 34, i8* %50
br label %60
52: ; preds = %20
%53 = load i8*, i8** %4
%54 = getelementptr inbounds i8, i8* %53, i32 1
store i8* %54, i8** %4
store i8 63, i8* %53
br label %60
55: ; preds = %20
%56 = load i8*, i8** %3
%57 = load i8, i8* %56
%58 = load i8*, i8** %4
%59 = getelementptr inbounds i8, i8* %58, i32 1
store i8* %59, i8** %4
store i8 %57, i8* %58
br label %60
60: ; preds = %55, %52, %49, %46, %43, %40, %37, %34, %31, %28, %25
br label %61
61: ; preds = %60, %15
%62 = load i8*, i8** %4
store i8 0, i8* %62
%63 = load i8*, i8** %3
%64 = getelementptr inbounds i8, i8* %63, i32 1
store i8* %64, i8** %3
br label %5
65: ; preds = %5
ret void
}

LLVM IR (-O2):
define void @unescape(i8* nocapture %0, i8* nocapture writeonly %1) {
br label %3
3: ; preds = %21, %2
%4 = phi i8* [ %0, %2 ], [ %25, %21 ]
%5 = phi i8* [ %1, %2 ], [ %24, %21 ]
%6 = load i8, i8* %4
switch i8 %6, label %21 [
i8 0, label %26
i8 92, label %7
]
7: ; preds = %3
%8 = getelementptr inbounds i8, i8* %4, i64 1
%9 = load i8, i8* %8
%10 = sext i8 %9 to i32
switch i32 %10, label %20 [
i32 97, label %21
i32 98, label %11
i32 102, label %12
i32 110, label %13
i32 114, label %14
i32 116, label %15
i32 118, label %16
i32 39, label %17
i32 34, label %18
i32 63, label %19
]
11: ; preds = %7
br label %21
12: ; preds = %7
br label %21
13: ; preds = %7
br label %21
14: ; preds = %7
br label %21
15: ; preds = %7
br label %21
16: ; preds = %7
br label %21
17: ; preds = %7
br label %21
18: ; preds = %7
br label %21
19: ; preds = %7
br label %21
20: ; preds = %7
br label %21
21: ; preds = %7, %3, %11, %12, %13, %14, %15, %16, %17, %18, %19, %20
%22 = phi i8 [ 8, %11 ], [ 12, %12 ], [ 10, %13 ], [ 13, %14 ], [ 9, %15 ], [ 11, %16 ], [ 39, %17 ], [ 34, %18 ], [ 63, %19 ], [ %9, %20 ], [ %6, %3 ], [ 7, %7 ]
%23 = phi i8* [ %8, %11 ], [ %8, %12 ], [ %8, %13 ], [ %8, %14 ], [ %8, %15 ], [ %8, %16 ], [ %8, %17 ], [ %8, %18 ], [ %8, %19 ], [ %8, %20 ], [ %4, %3 ], [ %8, %7 ]
store i8 %22, i8* %5
%24 = getelementptr inbounds i8, i8* %5, i64 1
store i8 0, i8* %24
%25 = getelementptr inbounds i8, i8* %23, i64 1
br label %3
26: ; preds = %3
ret void
}