int ChecksumNmeaLine(const char *in) {
  const char hexdigits[] = "0123456789ABCDEF";
  if (*in++ != '$') {
    return 0;
  }
  int val = 0;
  while (*in != '*' && *in != '\r') {
    val ^= *in++;
  }
  if (*in++ == '*') {
    if (*in++ != hexdigits[((val >> 4) & 0xf)]) {
      return 0;
    }
    if (*in++ != hexdigits[(val & 0xf)]) {
      return 0;
    }
    return 1;
  }
  return 0;
}


x86 assembly (clang, -O0):
<ChecksumNmeaLine>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    0xef1(%rip),%rax
mov    %rax,-0x30(%rbp)
mov    0xeee(%rip),%rax
mov    %rax,-0x28(%rbp)
mov    0xeec(%rip),%al
mov    %al,-0x20(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
movsbl (%rax),%eax
cmp    $0x24,%eax
je     114e <ChecksumNmeaLine+0x4e>
movl   $0x0,-0x4(%rbp)
jmp    1240 <ChecksumNmeaLine+0x140>
movl   $0x0,-0x34(%rbp)
mov    -0x10(%rbp),%rax
movsbl (%rax),%ecx
xor    %eax,%eax
cmp    $0x2a,%ecx
mov    %al,-0x35(%rbp)
je     117a <ChecksumNmeaLine+0x7a>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0xd,%eax
setne  %al
mov    %al,-0x35(%rbp)
mov    -0x35(%rbp),%al
test   $0x1,%al
jne    118a <ChecksumNmeaLine+0x8a>
jmp    11a7 <ChecksumNmeaLine+0xa7>
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
movsbl (%rax),%eax
xor    -0x34(%rbp),%eax
mov    %eax,-0x34(%rbp)
jmp    1155 <ChecksumNmeaLine+0x55>
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
movsbl (%rax),%eax
cmp    $0x2a,%eax
jne    1239 <ChecksumNmeaLine+0x139>
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
movsbl (%rax),%eax
mov    -0x34(%rbp),%ecx
sar    $0x4,%ecx
and    $0xf,%ecx
movslq %ecx,%rcx
movsbl -0x30(%rbp,%rcx,1),%ecx
cmp    %ecx,%eax
je     11f9 <ChecksumNmeaLine+0xf9>
movl   $0x0,-0x4(%rbp)
jmp    1240 <ChecksumNmeaLine+0x140>
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
movsbl (%rax),%eax
mov    -0x34(%rbp),%ecx
and    $0xf,%ecx
movslq %ecx,%rcx
movsbl -0x30(%rbp,%rcx,1),%ecx
cmp    %ecx,%eax
je     122d <ChecksumNmeaLine+0x12d>
movl   $0x0,-0x4(%rbp)
jmp    1240 <ChecksumNmeaLine+0x140>
movl   $0x1,-0x4(%rbp)
jmp    1240 <ChecksumNmeaLine+0x140>
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<ChecksumNmeaLine>:
xor    %eax,%eax
cmpb   $0x24,(%rdi)
jne    1150 <ChecksumNmeaLine+0x50>
add    $0x3,%rdi
xor    %ecx,%ecx
nopl   (%rax)
movzbl -0x2(%rdi),%eax
cmp    $0xd,%eax
je     114e <ChecksumNmeaLine+0x4e>
cmp    $0x2a,%al
je     1125 <ChecksumNmeaLine+0x25>
xor    %eax,%ecx
add    $0x1,%rdi
jmp    1110 <ChecksumNmeaLine+0x10>
mov    -0x1(%rdi),%dl
mov    %ecx,%esi
shr    $0x4,%esi
and    $0xf,%esi
lea    0xec9(%rip),%r8
xor    %eax,%eax
cmp    (%rsi,%r8,1),%dl
jne    1150 <ChecksumNmeaLine+0x50>
mov    (%rdi),%dl
and    $0xf,%ecx
xor    %eax,%eax
cmp    (%rcx,%r8,1),%dl
sete   %al
ret
xor    %eax,%eax
ret

LLVM IR (-O0):
@__const.ChecksumNmeaLine.hexdigits = [17 x i8] c"0123456789ABCDEF\00"
define i32 @ChecksumNmeaLine(i8* %0) {
%2 = alloca i32
%3 = alloca i8*
%4 = alloca [17 x i8]
%5 = alloca i32
store i8* %0, i8** %3
%6 = bitcast [17 x i8]* %4 to i8*
%7 = load i8*, i8** %3
%8 = getelementptr inbounds i8, i8* %7, i32 1
store i8* %8, i8** %3
%9 = load i8, i8* %7
%10 = sext i8 %9 to i32
%11 = icmp ne i32 %10, 36
br i1 %11, label %12, label %13
12: ; preds = %1
store i32 0, i32* %2
br label %68
13: ; preds = %1
store i32 0, i32* %5
br label %14
14: ; preds = %26, %13
%15 = load i8*, i8** %3
%16 = load i8, i8* %15
%17 = sext i8 %16 to i32
%18 = icmp ne i32 %17, 42
br i1 %18, label %19, label %24
19: ; preds = %14
%20 = load i8*, i8** %3
%21 = load i8, i8* %20
%22 = sext i8 %21 to i32
%23 = icmp ne i32 %22, 13
br label %24
24: ; preds = %19, %14
%25 = phi i1 [ false, %14 ], [ %23, %19 ]
br i1 %25, label %26, label %33
26: ; preds = %24
%27 = load i8*, i8** %3
%28 = getelementptr inbounds i8, i8* %27, i32 1
store i8* %28, i8** %3
%29 = load i8, i8* %27
%30 = sext i8 %29 to i32
%31 = load i32, i32* %5
%32 = xor i32 %31, %30
store i32 %32, i32* %5
br label %14
33: ; preds = %24
%34 = load i8*, i8** %3
%35 = getelementptr inbounds i8, i8* %34, i32 1
store i8* %35, i8** %3
%36 = load i8, i8* %34
%37 = sext i8 %36 to i32
%38 = icmp eq i32 %37, 42
br i1 %38, label %39, label %67
39: ; preds = %33
%40 = load i8*, i8** %3
%41 = getelementptr inbounds i8, i8* %40, i32 1
store i8* %41, i8** %3
%42 = load i8, i8* %40
%43 = sext i8 %42 to i32
%44 = load i32, i32* %5
%45 = ashr i32 %44, 4
%46 = and i32 %45, 15
%47 = sext i32 %46 to i64
%48 = getelementptr inbounds [17 x i8], [17 x i8]* %4, i64 0, i64 %47
%49 = load i8, i8* %48
%50 = sext i8 %49 to i32
%51 = icmp ne i32 %43, %50
br i1 %51, label %52, label %53
52: ; preds = %39
store i32 0, i32* %2
br label %68
53: ; preds = %39
%54 = load i8*, i8** %3
%55 = getelementptr inbounds i8, i8* %54, i32 1
store i8* %55, i8** %3
%56 = load i8, i8* %54
%57 = sext i8 %56 to i32
%58 = load i32, i32* %5
%59 = and i32 %58, 15
%60 = sext i32 %59 to i64
%61 = getelementptr inbounds [17 x i8], [17 x i8]* %4, i64 0, i64 %60
%62 = load i8, i8* %61
%63 = sext i8 %62 to i32
%64 = icmp ne i32 %57, %63
br i1 %64, label %65, label %66
65: ; preds = %53
store i32 0, i32* %2
br label %68
66: ; preds = %53
store i32 1, i32* %2
br label %68
67: ; preds = %33
store i32 0, i32* %2
br label %68
68: ; preds = %67, %66, %65, %52, %12
%69 = load i32, i32* %2
ret i32 %69
}

LLVM IR (-O2):
@__const.ChecksumNmeaLine.hexdigits = [17 x i8] c"0123456789ABCDEF\00"
define i32 @ChecksumNmeaLine(i8* nocapture %0) {
%2 = load i8, i8* %0
%3 = icmp eq i8 %2, 36
br i1 %3, label %4, label %30
4: ; preds = %1, %9
%5 = phi i8* [ %7, %9 ], [ %0, %1 ]
%6 = phi i32 [ %11, %9 ], [ 0, %1 ]
%7 = getelementptr inbounds i8, i8* %5, i64 1
%8 = load i8, i8* %7
switch i8 %8, label %9 [
i8 42, label %12
i8 13, label %30
]
9: ; preds = %4
%10 = zext i8 %8 to i32
%11 = xor i32 %6, %10
br label %4
12: ; preds = %4
%13 = getelementptr inbounds i8, i8* %5, i64 2
%14 = load i8, i8* %13
%15 = lshr i32 %6, 4
%16 = and i32 %15, 15
%17 = zext i32 %16 to i64
%18 = getelementptr inbounds [17 x i8], [17 x i8]* @__const.ChecksumNmeaLine.hexdigits, i64 0, i64 %17
%19 = load i8, i8* %18
%20 = icmp eq i8 %14, %19
br i1 %20, label %21, label %30
21: ; preds = %12
%22 = getelementptr inbounds i8, i8* %5, i64 3
%23 = load i8, i8* %22
%24 = and i32 %6, 15
%25 = zext i32 %24 to i64
%26 = getelementptr inbounds [17 x i8], [17 x i8]* @__const.ChecksumNmeaLine.hexdigits, i64 0, i64 %25
%27 = load i8, i8* %26
%28 = icmp eq i8 %23, %27
%29 = zext i1 %28 to i32
br label %30
30: ; preds = %4, %12, %21, %1
%31 = phi i32 [ 0, %1 ], [ 0, %12 ], [ %29, %21 ], [ 0, %4 ]
ret i32 %31
}