unsigned char OpcodeLen(unsigned int p, const unsigned char *Opcodes) {
  unsigned char len = 1;
  switch (Opcodes[p]) {
  case 0x06:
  case 0x0E:
  case 0x10:
  case 0x16:
  case 0x18:
  case 0x1E:
  case 0x20:
  case 0x26:
  case 0x28:
  case 0x2E:
  case 0x30:
  case 0x36:
  case 0x38:
  case 0x3E:
  case 0xC6:
  case 0xCE:
  case 0xD3:
  case 0xD6:
  case 0xDB:
  case 0xDE:
  case 0xE6:
  case 0xEE:
  case 0xF6:
  case 0xFE:
  case 0xCB:
    len = 2;
    break;
  case 0x01:
  case 0x11:
  case 0x21:
  case 0x22:
  case 0x2A:
  case 0x31:
  case 0x32:
  case 0x3A:
  case 0xC2:
  case 0xC3:
  case 0xC4:
  case 0xCA:
  case 0xCC:
  case 0xCD:
  case 0xD2:
  case 0xD4:
  case 0xDA:
  case 0xDC:
  case 0xE2:
  case 0xE4:
  case 0xEA:
  case 0xEC:
  case 0xF2:
  case 0xF4:
  case 0xFA:
  case 0xFC:
    len = 3;
    break;
  case 0xDD:
    len = 2;
    switch (Opcodes[p + 1]) {
    case 0x34:
    case 0x35:
    case 0x46:
    case 0x4E:
    case 0x56:
    case 0x5E:
    case 0x66:
    case 0x6E:
    case 0x70:
    case 0x71:
    case 0x72:
    case 0x73:
    case 0x74:
    case 0x75:
    case 0x77:
    case 0x7E:
    case 0x86:
    case 0x8E:
    case 0x96:
    case 0x9E:
    case 0xA6:
    case 0xAE:
    case 0xB6:
    case 0xBE:
      len = 3;
      break;
    case 0x21:
    case 0x22:
    case 0x2A:
    case 0x36:
    case 0xCB:
      len = 4;
      break;
    }
    break;
  case 0xED:
    len = 2;
    switch (Opcodes[p + 1]) {
    case 0x43:
    case 0x4B:
    case 0x53:
    case 0x5B:
    case 0x73:
    case 0x7B:
      len = 4;
      break;
    }
    break;
  case 0xFD:
    len = 2;
    switch (Opcodes[p + 1]) {
    case 0x34:
    case 0x35:
    case 0x46:
    case 0x4E:
    case 0x56:
    case 0x5E:
    case 0x66:
    case 0x6E:
    case 0x70:
    case 0x71:
    case 0x72:
    case 0x73:
    case 0x74:
    case 0x75:
    case 0x77:
    case 0x7E:
    case 0x86:
    case 0x8E:
    case 0x96:
    case 0x9E:
    case 0xA6:
    case 0xAE:
    case 0xB6:
    case 0xBE:
      len = 3;
      break;
    case 0x21:
    case 0x22:
    case 0x2A:
    case 0x36:
    case 0xCB:
      len = 4;
      break;
    }
    break;
  }
  return (len);
}


x86 assembly (clang, -O0):
<OpcodeLen>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %rsi,-0x10(%rbp)
movb   $0x1,-0x11(%rbp)
mov    -0x10(%rbp),%rax
mov    -0x4(%rbp),%ecx
movzbl (%rax,%rcx,1),%eax
add    $0xffffffff,%eax
mov    %eax,%ecx
mov    %rcx,-0x20(%rbp)
sub    $0xfd,%eax
ja     126d <OpcodeLen+0x16d>
mov    -0x20(%rbp),%rax
lea    0xec7(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
movb   $0x2,-0x11(%rbp)
jmp    126d <OpcodeLen+0x16d>
movb   $0x3,-0x11(%rbp)
jmp    126d <OpcodeLen+0x16d>
movb   $0x2,-0x11(%rbp)
mov    -0x10(%rbp),%rax
mov    -0x4(%rbp),%ecx
add    $0x1,%ecx
movzbl (%rax,%rcx,1),%eax
add    $0xffffffdf,%eax
mov    %eax,%ecx
mov    %rcx,-0x28(%rbp)
sub    $0xaa,%eax
ja     119b <OpcodeLen+0x9b>
mov    -0x28(%rbp),%rax
lea    0x151f(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
movb   $0x3,-0x11(%rbp)
jmp    119b <OpcodeLen+0x9b>
movb   $0x4,-0x11(%rbp)
jmp    126d <OpcodeLen+0x16d>
movb   $0x2,-0x11(%rbp)
mov    -0x10(%rbp),%rax
mov    -0x4(%rbp),%ecx
add    $0x1,%ecx
movzbl (%rax,%rcx,1),%eax
mov    %eax,-0x2c(%rbp)
sub    $0x43,%eax
je     1218 <OpcodeLen+0x118>
jmp    11c3 <OpcodeLen+0xc3>
mov    -0x2c(%rbp),%eax
sub    $0x4b,%eax
je     1218 <OpcodeLen+0x118>
jmp    11d4 <OpcodeLen+0xd4>
mov    -0x2c(%rbp),%eax
sub    $0x53,%eax
je     1218 <OpcodeLen+0x118>
jmp    11e5 <OpcodeLen+0xe5>
mov    -0x2c(%rbp),%eax
sub    $0x5b,%eax
je     1218 <OpcodeLen+0x118>
jmp    11f6 <OpcodeLen+0xf6>
mov    -0x2c(%rbp),%eax
sub    $0x73,%eax
je     1218 <OpcodeLen+0x118>
jmp    1207 <OpcodeLen+0x107>
mov    -0x2c(%rbp),%eax
sub    $0x7b,%eax
jne    121c <OpcodeLen+0x11c>
jmp    1218 <OpcodeLen+0x118>
movb   $0x4,-0x11(%rbp)
jmp    126d <OpcodeLen+0x16d>
movb   $0x2,-0x11(%rbp)
mov    -0x10(%rbp),%rax
mov    -0x4(%rbp),%ecx
add    $0x1,%ecx
movzbl (%rax,%rcx,1),%eax
add    $0xffffffdf,%eax
mov    %eax,%ecx
mov    %rcx,-0x38(%rbp)
sub    $0xaa,%eax
ja     1268 <OpcodeLen+0x168>
mov    -0x38(%rbp),%rax
lea    0x11a6(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
movb   $0x3,-0x11(%rbp)
jmp    1268 <OpcodeLen+0x168>
movb   $0x4,-0x11(%rbp)
jmp    126d <OpcodeLen+0x16d>
movzbl -0x11(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<OpcodeLen>:
mov    %edi,%eax
mov    (%rsi,%rax,1),%cl
mov    $0x1,%al
add    $0x3e,%cl
cmp    $0x7c,%cl
ja     116f <OpcodeLen+0x6f>
movzbl %cl,%ecx
lea    0xee7(%rip),%rdx
movslq (%rdx,%rcx,4),%rcx
add    %rdx,%rcx
jmp    *%rcx
mov    $0x3,%al
ret
mov    $0x2,%al
ret
add    $0x1,%edi
mov    (%rsi,%rdi,1),%cl
mov    $0x2,%al
add    $0x7a,%cl
cmp    $0xf8,%cl
ja     116f <OpcodeLen+0x6f>
movzbl %cl,%ecx
lea    0x1496(%rip),%rdx
movslq (%rdx,%rcx,4),%rcx
add    %rdx,%rcx
jmp    *%rcx
add    $0x1,%edi
movzbl (%rsi,%rdi,1),%ecx
add    $0xffffffbd,%ecx
rol    $0x1d,%ecx
mov    $0x2,%al
cmp    $0x8,%ecx
jae    116f <OpcodeLen+0x6f>
shl    $0x3,%ecx
movabs $0x404020204040404,%rax
02 04 04
shr    %cl,%rax
ret
add    $0x1,%edi
mov    (%rsi,%rdi,1),%cl
mov    $0x2,%al
add    $0x7a,%cl
cmp    $0xf8,%cl
ja     116f <OpcodeLen+0x6f>
movzbl %cl,%ecx
lea    0x106a(%rip),%rdx
movslq (%rdx,%rcx,4),%rcx
add    %rdx,%rcx
jmp    *%rcx
mov    $0x4,%al
ret

LLVM IR (-O0):
define zeroext i8 @OpcodeLen(i32 %0, i8* %1) {
%3 = alloca i32
%4 = alloca i8*
%5 = alloca i8
store i32 %0, i32* %3
store i8* %1, i8** %4
store i8 1, i8* %5
%6 = load i8*, i8** %4
%7 = load i32, i32* %3
%8 = zext i32 %7 to i64
%9 = getelementptr inbounds i8, i8* %6, i64 %8
%10 = load i8, i8* %9
%11 = zext i8 %10 to i32
switch i32 %11, label %46 [
i32 6, label %12
i32 14, label %12
i32 16, label %12
i32 22, label %12
i32 24, label %12
i32 30, label %12
i32 32, label %12
i32 38, label %12
i32 40, label %12
i32 46, label %12
i32 48, label %12
i32 54, label %12
i32 56, label %12
i32 62, label %12
i32 198, label %12
i32 206, label %12
i32 211, label %12
i32 214, label %12
i32 219, label %12
i32 222, label %12
i32 230, label %12
i32 238, label %12
i32 246, label %12
i32 254, label %12
i32 203, label %12
i32 1, label %13
i32 17, label %13
i32 33, label %13
i32 34, label %13
i32 42, label %13
i32 49, label %13
i32 50, label %13
i32 58, label %13
i32 194, label %13
i32 195, label %13
i32 196, label %13
i32 202, label %13
i32 204, label %13
i32 205, label %13
i32 210, label %13
i32 212, label %13
i32 218, label %13
i32 220, label %13
i32 226, label %13
i32 228, label %13
i32 234, label %13
i32 236, label %13
i32 242, label %13
i32 244, label %13
i32 250, label %13
i32 252, label %13
i32 221, label %14
i32 237, label %25
i32 253, label %35
]
12: ; preds = %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2
store i8 2, i8* %5
br label %46
13: ; preds = %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2
store i8 3, i8* %5
br label %46
14: ; preds = %2
store i8 2, i8* %5
%15 = load i8*, i8** %4
%16 = load i32, i32* %3
%17 = add i32 %16, 1
%18 = zext i32 %17 to i64
%19 = getelementptr inbounds i8, i8* %15, i64 %18
%20 = load i8, i8* %19
%21 = zext i8 %20 to i32
switch i32 %21, label %24 [
i32 52, label %22
i32 53, label %22
i32 70, label %22
i32 78, label %22
i32 86, label %22
i32 94, label %22
i32 102, label %22
i32 110, label %22
i32 112, label %22
i32 113, label %22
i32 114, label %22
i32 115, label %22
i32 116, label %22
i32 117, label %22
i32 119, label %22
i32 126, label %22
i32 134, label %22
i32 142, label %22
i32 150, label %22
i32 158, label %22
i32 166, label %22
i32 174, label %22
i32 182, label %22
i32 190, label %22
i32 33, label %23
i32 34, label %23
i32 42, label %23
i32 54, label %23
i32 203, label %23
]
22: ; preds = %14, %14, %14, %14, %14, %14, %14, %14, %14, %14, %14, %14, %14, %14, %14, %14, %14, %14, %14, %14, %14, %14, %14, %14
store i8 3, i8* %5
br label %24
23: ; preds = %14, %14, %14, %14, %14
store i8 4, i8* %5
br label %24
24: ; preds = %14, %23, %22
br label %46
25: ; preds = %2
store i8 2, i8* %5
%26 = load i8*, i8** %4
%27 = load i32, i32* %3
%28 = add i32 %27, 1
%29 = zext i32 %28 to i64
%30 = getelementptr inbounds i8, i8* %26, i64 %29
%31 = load i8, i8* %30
%32 = zext i8 %31 to i32
switch i32 %32, label %34 [
i32 67, label %33
i32 75, label %33
i32 83, label %33
i32 91, label %33
i32 115, label %33
i32 123, label %33
]
33: ; preds = %25, %25, %25, %25, %25, %25
store i8 4, i8* %5
br label %34
34: ; preds = %25, %33
br label %46
35: ; preds = %2
store i8 2, i8* %5
%36 = load i8*, i8** %4
%37 = load i32, i32* %3
%38 = add i32 %37, 1
%39 = zext i32 %38 to i64
%40 = getelementptr inbounds i8, i8* %36, i64 %39
%41 = load i8, i8* %40
%42 = zext i8 %41 to i32
switch i32 %42, label %45 [
i32 52, label %43
i32 53, label %43
i32 70, label %43
i32 78, label %43
i32 86, label %43
i32 94, label %43
i32 102, label %43
i32 110, label %43
i32 112, label %43
i32 113, label %43
i32 114, label %43
i32 115, label %43
i32 116, label %43
i32 117, label %43
i32 119, label %43
i32 126, label %43
i32 134, label %43
i32 142, label %43
i32 150, label %43
i32 158, label %43
i32 166, label %43
i32 174, label %43
i32 182, label %43
i32 190, label %43
i32 33, label %44
i32 34, label %44
i32 42, label %44
i32 54, label %44
i32 203, label %44
]
43: ; preds = %35, %35, %35, %35, %35, %35, %35, %35, %35, %35, %35, %35, %35, %35, %35, %35, %35, %35, %35, %35, %35, %35, %35, %35
store i8 3, i8* %5
br label %45
44: ; preds = %35, %35, %35, %35, %35
store i8 4, i8* %5
br label %45
45: ; preds = %35, %44, %43
br label %46
46: ; preds = %2, %45, %34, %24, %13, %12
%47 = load i8, i8* %5
ret i8 %47
}

LLVM IR (-O2):
define zeroext i8 @OpcodeLen(i32 %0, i8* nocapture %1) {
%3 = zext i32 %0 to i64
%4 = getelementptr inbounds i8, i8* %1, i64 %3
%5 = load i8, i8* %4
switch i8 %5, label %36 [
i8 6, label %6
i8 14, label %6
i8 16, label %6
i8 22, label %6
i8 24, label %6
i8 30, label %6
i8 32, label %6
i8 38, label %6
i8 40, label %6
i8 46, label %6
i8 48, label %6
i8 54, label %6
i8 56, label %6
i8 62, label %6
i8 -58, label %6
i8 -50, label %6
i8 -45, label %6
i8 -42, label %6
i8 -37, label %6
i8 -34, label %6
i8 -26, label %6
i8 -18, label %6
i8 -10, label %6
i8 -2, label %6
i8 -53, label %6
i8 1, label %7
i8 17, label %7
i8 33, label %7
i8 34, label %7
i8 42, label %7
i8 49, label %7
i8 50, label %7
i8 58, label %7
i8 -62, label %7
i8 -61, label %7
i8 -60, label %7
i8 -54, label %7
i8 -52, label %7
i8 -51, label %7
i8 -46, label %7
i8 -44, label %7
i8 -38, label %7
i8 -36, label %7
i8 -30, label %7
i8 -28, label %7
i8 -22, label %7
i8 -20, label %7
i8 -14, label %7
i8 -12, label %7
i8 -6, label %7
i8 -4, label %7
i8 -35, label %8
i8 -19, label %15
i8 -3, label %24
]
6: ; preds = %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2
br label %36
7: ; preds = %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2, %2
br label %36
8: ; preds = %2
%9 = add i32 %0, 1
%10 = zext i32 %9 to i64
%11 = getelementptr inbounds i8, i8* %1, i64 %10
%12 = load i8, i8* %11
switch i8 %12, label %36 [
i8 52, label %13
i8 53, label %13
i8 70, label %13
i8 78, label %13
i8 86, label %13
i8 94, label %13
i8 102, label %13
i8 110, label %13
i8 112, label %13
i8 113, label %13
i8 114, label %13
i8 115, label %13
i8 116, label %13
i8 117, label %13
i8 119, label %13
i8 126, label %13
i8 -122, label %13
i8 -114, label %13
i8 -106, label %13
i8 -98, label %13
i8 -90, label %13
i8 -82, label %13
i8 -74, label %13
i8 -66, label %13
i8 33, label %14
i8 34, label %14
i8 42, label %14
i8 54, label %14
i8 -53, label %14
]
13: ; preds = %8, %8, %8, %8, %8, %8, %8, %8, %8, %8, %8, %8, %8, %8, %8, %8, %8, %8, %8, %8, %8, %8, %8, %8
br label %36
14: ; preds = %8, %8, %8, %8, %8
br label %36
15: ; preds = %2
%16 = add i32 %0, 1
%17 = zext i32 %16 to i64
%18 = getelementptr inbounds i8, i8* %1, i64 %17
%19 = load i8, i8* %18
%20 = zext i8 %19 to i32
%21 = add nsw i32 %20, -67
%22 = tail call i32 @llvm.fshl.i32(i32 %21, i32 %21, i32 29)
%23 = icmp ult i32 %22, 8
br i1 %23, label %31, label %36
24: ; preds = %2
%25 = add i32 %0, 1
%26 = zext i32 %25 to i64
%27 = getelementptr inbounds i8, i8* %1, i64 %26
%28 = load i8, i8* %27
switch i8 %28, label %36 [
i8 52, label %29
i8 53, label %29
i8 70, label %29
i8 78, label %29
i8 86, label %29
i8 94, label %29
i8 102, label %29
i8 110, label %29
i8 112, label %29
i8 113, label %29
i8 114, label %29
i8 115, label %29
i8 116, label %29
i8 117, label %29
i8 119, label %29
i8 126, label %29
i8 -122, label %29
i8 -114, label %29
i8 -106, label %29
i8 -98, label %29
i8 -90, label %29
i8 -82, label %29
i8 -74, label %29
i8 -66, label %29
i8 33, label %30
i8 34, label %30
i8 42, label %30
i8 54, label %30
i8 -53, label %30
]
29: ; preds = %24, %24, %24, %24, %24, %24, %24, %24, %24, %24, %24, %24, %24, %24, %24, %24, %24, %24, %24, %24, %24, %24, %24, %24
br label %36
30: ; preds = %24, %24, %24, %24, %24
br label %36
31: ; preds = %15
%32 = zext i32 %22 to i64
%33 = shl nuw nsw i64 %32, 3
%34 = lshr i64 289358483739116548, %33
%35 = trunc i64 %34 to i8
br label %36
36: ; preds = %31, %15, %29, %30, %24, %13, %14, %8, %2, %7, %6
%37 = phi i8 [ 1, %2 ], [ 2, %24 ], [ 4, %30 ], [ 3, %29 ], [ 2, %15 ], [ 2, %8 ], [ 4, %14 ], [ 3, %13 ], [ 3, %7 ], [ 2, %6 ], [ %35, %31 ]
ret i8 %37
}