unsigned int getStringAndHash(char *start, char **first, char **last,
                              unsigned int *hash) {
  unsigned char state = 0;
  char delimiter = '\0';
  unsigned int currentHash = 0x811c9dc5;
  while (start[0] != '\0') {
    switch (state) {
    case 0:
      if (start[0] == '"' || start[0] == '\'') {
        state = 1;
        delimiter = start[0];
        *first = start + 1;
      } else if (start[0] == '}') {
        return 100;
      } else if (!(start[0] == ' ' || start[0] == '\t' || start[0] == '\n' ||
                   start[0] == '\t')) {
        return 202;
      }
      break;
    case 1:
      if (start[0] == delimiter) {
        *last = start;
        *hash = currentHash;
        return 0;
      } else if (start[0] == '\\') {
        state = 2;
      }
      currentHash ^= (*start);
      currentHash *= 16777619;
      break;
    case 2:
      state = 1;
      currentHash ^= (*start);
      currentHash *= 16777619;
      break;
    }
    ++start;
  }
  return 202;
}


x86 assembly (clang, -O0):
<getStringAndHash>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
mov    %rcx,-0x28(%rbp)
movb   $0x0,-0x29(%rbp)
movb   $0x0,-0x2a(%rbp)
movl   $0x811c9dc5,-0x30(%rbp)
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x0,%eax
je     12b5 <getStringAndHash+0x1b5>
movzbl -0x29(%rbp),%eax
mov    %eax,-0x34(%rbp)
test   %eax,%eax
je     1169 <getStringAndHash+0x69>
jmp    1147 <getStringAndHash+0x47>
mov    -0x34(%rbp),%eax
sub    $0x1,%eax
je     1221 <getStringAndHash+0x121>
jmp    1158 <getStringAndHash+0x58>
mov    -0x34(%rbp),%eax
sub    $0x2,%eax
je     1289 <getStringAndHash+0x189>
jmp    12a4 <getStringAndHash+0x1a4>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x22,%eax
je     1189 <getStringAndHash+0x89>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x27,%eax
jne    11aa <getStringAndHash+0xaa>
movb   $0x1,-0x29(%rbp)
mov    -0x10(%rbp),%rax
mov    (%rax),%al
mov    %al,-0x2a(%rbp)
mov    -0x10(%rbp),%rcx
add    $0x1,%rcx
mov    -0x18(%rbp),%rax
mov    %rcx,(%rax)
jmp    121c <getStringAndHash+0x11c>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x7d,%eax
jne    11c6 <getStringAndHash+0xc6>
movl   $0x64,-0x4(%rbp)
jmp    12bc <getStringAndHash+0x1bc>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x20,%eax
je     1212 <getStringAndHash+0x112>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x9,%eax
je     1212 <getStringAndHash+0x112>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0xa,%eax
je     1212 <getStringAndHash+0x112>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x9,%eax
je     1212 <getStringAndHash+0x112>
movl   $0xca,-0x4(%rbp)
jmp    12bc <getStringAndHash+0x1bc>
jmp    1217 <getStringAndHash+0x117>
jmp    121c <getStringAndHash+0x11c>
jmp    12a4 <getStringAndHash+0x1a4>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
movsbl -0x2a(%rbp),%ecx
cmp    %ecx,%eax
jne    1254 <getStringAndHash+0x154>
mov    -0x10(%rbp),%rcx
mov    -0x20(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x30(%rbp),%ecx
mov    -0x28(%rbp),%rax
mov    %ecx,(%rax)
movl   $0x0,-0x4(%rbp)
jmp    12bc <getStringAndHash+0x1bc>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x5c,%eax
jne    1268 <getStringAndHash+0x168>
movb   $0x2,-0x29(%rbp)
jmp    126d <getStringAndHash+0x16d>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
xor    -0x30(%rbp),%eax
mov    %eax,-0x30(%rbp)
imul   $0x1000193,-0x30(%rbp),%eax
mov    %eax,-0x30(%rbp)
jmp    12a4 <getStringAndHash+0x1a4>
movb   $0x1,-0x29(%rbp)
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
xor    -0x30(%rbp),%eax
mov    %eax,-0x30(%rbp)
imul   $0x1000193,-0x30(%rbp),%eax
mov    %eax,-0x30(%rbp)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
jmp    1123 <getStringAndHash+0x23>
movl   $0xca,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<getStringAndHash>:
push   %rbp
push   %r14
push   %rbx
mov    (%rdi),%bl
mov    $0xca,%eax
test   %bl,%bl
je     11b9 <getStringAndHash+0xb9>
add    $0x1,%rdi
mov    $0x811c9dc5,%r8d
xor    %r11d,%r11d
movabs $0x100000600,%r9
movabs $0x8400000000,%r10
xor    %ebp,%ebp
jmp    1158 <getStringAndHash+0x58>
nopl   0x0(%rax,%rax,1)
xor    %r14d,%r8d
imul   $0x1000193,%r8d,%r8d
mov    $0x1,%bpl
movzbl (%rdi),%ebx
add    $0x1,%rdi
test   %bl,%bl
je     11b9 <getStringAndHash+0xb9>
movsbl %bl,%r14d
cmp    $0x2,%bpl
je     1140 <getStringAndHash+0x40>
cmp    $0x1,%bpl
je     1180 <getStringAndHash+0x80>
test   %bpl,%bpl
jne    114d <getStringAndHash+0x4d>
cmp    $0x27,%bl
ja     11be <getStringAndHash+0xbe>
movzbl %bl,%ebp
bt     %rbp,%r9
jae    119c <getStringAndHash+0x9c>
xor    %ebp,%ebp
jmp    114d <getStringAndHash+0x4d>
nop
cmp    %r11b,%bl
je     11ad <getStringAndHash+0xad>
cmp    $0x5c,%bl
sete   %bpl
add    $0x1,%bpl
xor    %r14d,%r8d
imul   $0x1000193,%r8d,%r8d
jmp    114d <getStringAndHash+0x4d>
bt     %rbp,%r10
jae    11be <getStringAndHash+0xbe>
mov    %rdi,(%rsi)
mov    $0x1,%bpl
mov    %ebx,%r11d
jmp    114d <getStringAndHash+0x4d>
add    $0xffffffffffffffff,%rdi
mov    %rdi,(%rdx)
mov    %r8d,(%rcx)
xor    %eax,%eax
pop    %rbx
pop    %r14
pop    %rbp
ret
mov    $0x64,%eax
cmp    $0x7d,%bl
je     11b9 <getStringAndHash+0xb9>
mov    $0xca,%eax
jmp    11b9 <getStringAndHash+0xb9>

LLVM IR (-O0):
define i32 @getStringAndHash(i8* %0, i8** %1, i8** %2, i32* %3) {
%5 = alloca i32
%6 = alloca i8*
%7 = alloca i8**
%8 = alloca i8**
%9 = alloca i32*
%10 = alloca i8
%11 = alloca i8
%12 = alloca i32
store i8* %0, i8** %6
store i8** %1, i8*** %7
store i8** %2, i8*** %8
store i32* %3, i32** %9
store i8 0, i8* %10
store i8 0, i8* %11
store i32 -2128831035, i32* %12
br label %13
13: ; preds = %113, %4
%14 = load i8*, i8** %6
%15 = getelementptr inbounds i8, i8* %14, i64 0
%16 = load i8, i8* %15
%17 = sext i8 %16 to i32
%18 = icmp ne i32 %17, 0
br i1 %18, label %19, label %116
19: ; preds = %13
%20 = load i8, i8* %10
%21 = zext i8 %20 to i32
switch i32 %21, label %113 [
i32 0, label %22
i32 1, label %76
i32 2, label %105
]
22: ; preds = %19
%23 = load i8*, i8** %6
%24 = getelementptr inbounds i8, i8* %23, i64 0
%25 = load i8, i8* %24
%26 = sext i8 %25 to i32
%27 = icmp eq i32 %26, 34
br i1 %27, label %34, label %28
28: ; preds = %22
%29 = load i8*, i8** %6
%30 = getelementptr inbounds i8, i8* %29, i64 0
%31 = load i8, i8* %30
%32 = sext i8 %31 to i32
%33 = icmp eq i32 %32, 39
br i1 %33, label %34, label %41
34: ; preds = %28, %22
store i8 1, i8* %10
%35 = load i8*, i8** %6
%36 = getelementptr inbounds i8, i8* %35, i64 0
%37 = load i8, i8* %36
store i8 %37, i8* %11
%38 = load i8*, i8** %6
%39 = getelementptr inbounds i8, i8* %38, i64 1
%40 = load i8**, i8*** %7
store i8* %39, i8** %40
br label %75
41: ; preds = %28
%42 = load i8*, i8** %6
%43 = getelementptr inbounds i8, i8* %42, i64 0
%44 = load i8, i8* %43
%45 = sext i8 %44 to i32
%46 = icmp eq i32 %45, 125
br i1 %46, label %47, label %48
47: ; preds = %41
store i32 100, i32* %5
br label %117
48: ; preds = %41
%49 = load i8*, i8** %6
%50 = getelementptr inbounds i8, i8* %49, i64 0
%51 = load i8, i8* %50
%52 = sext i8 %51 to i32
%53 = icmp eq i32 %52, 32
br i1 %53, label %73, label %54
54: ; preds = %48
%55 = load i8*, i8** %6
%56 = getelementptr inbounds i8, i8* %55, i64 0
%57 = load i8, i8* %56
%58 = sext i8 %57 to i32
%59 = icmp eq i32 %58, 9
br i1 %59, label %73, label %60
60: ; preds = %54
%61 = load i8*, i8** %6
%62 = getelementptr inbounds i8, i8* %61, i64 0
%63 = load i8, i8* %62
%64 = sext i8 %63 to i32
%65 = icmp eq i32 %64, 10
br i1 %65, label %73, label %66
66: ; preds = %60
%67 = load i8*, i8** %6
%68 = getelementptr inbounds i8, i8* %67, i64 0
%69 = load i8, i8* %68
%70 = sext i8 %69 to i32
%71 = icmp eq i32 %70, 9
br i1 %71, label %73, label %72
72: ; preds = %66
store i32 202, i32* %5
br label %117
73: ; preds = %66, %60, %54, %48
br label %74
74: ; preds = %73
br label %75
75: ; preds = %74, %34
br label %113
76: ; preds = %19
%77 = load i8*, i8** %6
%78 = getelementptr inbounds i8, i8* %77, i64 0
%79 = load i8, i8* %78
%80 = sext i8 %79 to i32
%81 = load i8, i8* %11
%82 = sext i8 %81 to i32
%83 = icmp eq i32 %80, %82
br i1 %83, label %84, label %89
84: ; preds = %76
%85 = load i8*, i8** %6
%86 = load i8**, i8*** %8
store i8* %85, i8** %86
%87 = load i32, i32* %12
%88 = load i32*, i32** %9
store i32 %87, i32* %88
store i32 0, i32* %5
br label %117
89: ; preds = %76
%90 = load i8*, i8** %6
%91 = getelementptr inbounds i8, i8* %90, i64 0
%92 = load i8, i8* %91
%93 = sext i8 %92 to i32
%94 = icmp eq i32 %93, 92
br i1 %94, label %95, label %96
95: ; preds = %89
store i8 2, i8* %10
br label %96
96: ; preds = %95, %89
br label %97
97: ; preds = %96
%98 = load i8*, i8** %6
%99 = load i8, i8* %98
%100 = sext i8 %99 to i32
%101 = load i32, i32* %12
%102 = xor i32 %101, %100
store i32 %102, i32* %12
%103 = load i32, i32* %12
%104 = mul i32 %103, 16777619
store i32 %104, i32* %12
br label %113
105: ; preds = %19
store i8 1, i8* %10
%106 = load i8*, i8** %6
%107 = load i8, i8* %106
%108 = sext i8 %107 to i32
%109 = load i32, i32* %12
%110 = xor i32 %109, %108
store i32 %110, i32* %12
%111 = load i32, i32* %12
%112 = mul i32 %111, 16777619
store i32 %112, i32* %12
br label %113
113: ; preds = %19, %105, %97, %75
%114 = load i8*, i8** %6
%115 = getelementptr inbounds i8, i8* %114, i32 1
store i8* %115, i8** %6
br label %13
116: ; preds = %13
store i32 202, i32* %5
br label %117
117: ; preds = %116, %84, %72, %47
%118 = load i32, i32* %5
ret i32 %118
}

LLVM IR (-O2):
define i32 @getStringAndHash(i8* %0, i8** nocapture writeonly %1, i8** nocapture writeonly %2, i32* nocapture writeonly %3) {
%5 = load i8, i8* %0
%6 = icmp eq i8 %5, 0
br i1 %6, label %37, label %7
7: ; preds = %4, %28
%8 = phi i8 [ %33, %28 ], [ %5, %4 ]
%9 = phi i32 [ %31, %28 ], [ -2128831035, %4 ]
%10 = phi i8 [ %30, %28 ], [ 0, %4 ]
%11 = phi i8 [ %29, %28 ], [ 0, %4 ]
%12 = phi i8* [ %32, %28 ], [ %0, %4 ]
%13 = sext i8 %8 to i32
switch i8 %11, label %28 [
i8 0, label %14
i8 1, label %17
i8 2, label %25
]
14: ; preds = %7
switch i8 %8, label %37 [
i8 34, label %15
i8 39, label %15
i8 125, label %35
i8 32, label %28
i8 9, label %28
i8 10, label %28
]
15: ; preds = %14, %14
%16 = getelementptr inbounds i8, i8* %12, i64 1
store i8* %16, i8** %1
br label %28
17: ; preds = %7
%18 = icmp eq i8 %8, %10
br i1 %18, label %19, label %20
19: ; preds = %17
store i8* %12, i8** %2
store i32 %9, i32* %3
br label %37
20: ; preds = %17
%21 = icmp eq i8 %8, 92
%22 = select i1 %21, i8 2, i8 1
%23 = xor i32 %9, %13
%24 = mul i32 %23, 16777619
br label %28
25: ; preds = %7
%26 = xor i32 %9, %13
%27 = mul i32 %26, 16777619
br label %28
28: ; preds = %14, %14, %14, %15, %7, %25, %20
%29 = phi i8 [ %11, %7 ], [ 1, %25 ], [ %22, %20 ], [ 1, %15 ], [ 0, %14 ], [ 0, %14 ], [ 0, %14 ]
%30 = phi i8 [ %10, %7 ], [ %10, %25 ], [ %10, %20 ], [ %8, %15 ], [ %10, %14 ], [ %10, %14 ], [ %10, %14 ]
%31 = phi i32 [ %9, %7 ], [ %27, %25 ], [ %24, %20 ], [ %9, %15 ], [ %9, %14 ], [ %9, %14 ], [ %9, %14 ]
%32 = getelementptr inbounds i8, i8* %12, i64 1
%33 = load i8, i8* %32
%34 = icmp eq i8 %33, 0
br i1 %34, label %35, label %7
35: ; preds = %28, %14
%36 = phi i32 [ 202, %28 ], [ 100, %14 ]
br label %37
37: ; preds = %14, %35, %4, %19
%38 = phi i32 [ 0, %19 ], [ 202, %4 ], [ %36, %35 ], [ 202, %14 ]
ret i32 %38
}