unsigned char *NextLine(unsigned char *p) {
  unsigned char op;
  while (!((op = *p) & 0x80)) {
    p += 2;
    if (op > 20)
      p++;
  }
  while (((op = *p) & 0x80)) {
    op &= 0x3F;
    p++;
    if (op > 8)
      p++;
    if (op > 21)
      p++;
  }
  return p;
}


x86 assembly (clang, -O0):
<NextLine>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    -0x8(%rbp),%rax
mov    (%rax),%al
mov    %al,-0x9(%rbp)
movzbl %al,%eax
and    $0x80,%eax
cmp    $0x0,%eax
setne  %al
xor    $0xff,%al
test   $0x1,%al
jne    112e <NextLine+0x2e>
jmp    1158 <NextLine+0x58>
mov    -0x8(%rbp),%rax
add    $0x2,%rax
mov    %rax,-0x8(%rbp)
movzbl -0x9(%rbp),%eax
cmp    $0x14,%eax
jle    1153 <NextLine+0x53>
mov    -0x8(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
jmp    1108 <NextLine+0x8>
jmp    115d <NextLine+0x5d>
mov    -0x8(%rbp),%rax
mov    (%rax),%al
mov    %al,-0x9(%rbp)
movzbl %al,%eax
and    $0x80,%eax
cmp    $0x0,%eax
je     11c4 <NextLine+0xc4>
movzbl -0x9(%rbp),%eax
and    $0x3f,%eax
mov    %al,-0x9(%rbp)
mov    -0x8(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
movzbl -0x9(%rbp),%eax
cmp    $0x8,%eax
jle    11a6 <NextLine+0xa6>
mov    -0x8(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
movzbl -0x9(%rbp),%eax
cmp    $0x15,%eax
jle    11bf <NextLine+0xbf>
mov    -0x8(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
jmp    115d <NextLine+0x5d>
mov    -0x8(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<NextLine>:
mov    %rdi,%rax
mov    (%rdi),%cl
test   %cl,%cl
js     1130 <NextLine+0x30>
nopl   0x0(%rax)
cmp    $0x15,%cl
sbb    $0xffffffffffffffff,%rax
movzbl 0x2(%rax),%ecx
add    $0x2,%rax
test   %cl,%cl
jns    1110 <NextLine+0x10>
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
and    $0x3f,%cl
cmp    $0x9,%cl
sbb    $0xffffffffffffffff,%rax
cmp    $0x16,%cl
sbb    $0xffffffffffffffff,%rax
movzbl 0x1(%rax),%ecx
add    $0x1,%rax
test   %cl,%cl
js     1130 <NextLine+0x30>
ret

LLVM IR (-O0):
define i8* @NextLine(i8* %0) {
%2 = alloca i8*
%3 = alloca i8
store i8* %0, i8** %2
br label %4
4: ; preds = %20, %1
%5 = load i8*, i8** %2
%6 = load i8, i8* %5
store i8 %6, i8* %3
%7 = zext i8 %6 to i32
%8 = and i32 %7, 128
%9 = icmp ne i32 %8, 0
%10 = xor i1 %9, true
br i1 %10, label %11, label %21
11: ; preds = %4
%12 = load i8*, i8** %2
%13 = getelementptr inbounds i8, i8* %12, i64 2
store i8* %13, i8** %2
%14 = load i8, i8* %3
%15 = zext i8 %14 to i32
%16 = icmp sgt i32 %15, 20
br i1 %16, label %17, label %20
17: ; preds = %11
%18 = load i8*, i8** %2
%19 = getelementptr inbounds i8, i8* %18, i32 1
store i8* %19, i8** %2
br label %20
20: ; preds = %17, %11
br label %4
21: ; preds = %4
br label %22
22: ; preds = %48, %21
%23 = load i8*, i8** %2
%24 = load i8, i8* %23
store i8 %24, i8* %3
%25 = zext i8 %24 to i32
%26 = and i32 %25, 128
%27 = icmp ne i32 %26, 0
br i1 %27, label %28, label %49
28: ; preds = %22
%29 = load i8, i8* %3
%30 = zext i8 %29 to i32
%31 = and i32 %30, 63
%32 = trunc i32 %31 to i8
store i8 %32, i8* %3
%33 = load i8*, i8** %2
%34 = getelementptr inbounds i8, i8* %33, i32 1
store i8* %34, i8** %2
%35 = load i8, i8* %3
%36 = zext i8 %35 to i32
%37 = icmp sgt i32 %36, 8
br i1 %37, label %38, label %41
38: ; preds = %28
%39 = load i8*, i8** %2
%40 = getelementptr inbounds i8, i8* %39, i32 1
store i8* %40, i8** %2
br label %41
41: ; preds = %38, %28
%42 = load i8, i8* %3
%43 = zext i8 %42 to i32
%44 = icmp sgt i32 %43, 21
br i1 %44, label %45, label %48
45: ; preds = %41
%46 = load i8*, i8** %2
%47 = getelementptr inbounds i8, i8* %46, i32 1
store i8* %47, i8** %2
br label %48
48: ; preds = %45, %41
br label %22
49: ; preds = %22
%50 = load i8*, i8** %2
ret i8* %50
}

LLVM IR (-O2):
define i8* @NextLine(i8* %0) {
%2 = load i8, i8* %0
%3 = icmp sgt i8 %2, -1
br i1 %3, label %4, label %12
4: ; preds = %1, %4
%5 = phi i8 [ %10, %4 ], [ %2, %1 ]
%6 = phi i8* [ %9, %4 ], [ %0, %1 ]
%7 = icmp ugt i8 %5, 20
%8 = select i1 %7, i64 3, i64 2
%9 = getelementptr inbounds i8, i8* %6, i64 %8
%10 = load i8, i8* %9
%11 = icmp sgt i8 %10, -1
br i1 %11, label %4, label %12
12: ; preds = %4, %1
%13 = phi i8* [ %0, %1 ], [ %9, %4 ]
%14 = phi i8 [ %2, %1 ], [ %10, %4 ]
br label %15
15: ; preds = %12, %15
%16 = phi i8* [ %24, %15 ], [ %13, %12 ]
%17 = phi i8 [ %25, %15 ], [ %14, %12 ]
%18 = and i8 %17, 63
%19 = icmp ugt i8 %18, 8
%20 = select i1 %19, i64 2, i64 1
%21 = getelementptr inbounds i8, i8* %16, i64 %20
%22 = icmp ugt i8 %18, 21
%23 = zext i1 %22 to i64
%24 = getelementptr i8, i8* %21, i64 %23
%25 = load i8, i8* %24
%26 = icmp sgt i8 %25, -1
br i1 %26, label %27, label %15
27: ; preds = %15
ret i8* %24
}