#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
typedef int uint16_t;

/* Variables and functions */
int /*<<< orphan*/ print_addr(int, char *, int);
int /*<<< orphan*/ print_invalid(int, int);
int /*<<< orphan*/ print_noarg(int, char *, int);
int /*<<< orphan*/ print_ophead(int, char *, int);
int /*<<< orphan*/ print_vx(int, char *, int);
int /*<<< orphan*/ print_vx_nn(int, char *, int);
int /*<<< orphan*/ print_vx_vy(int, char *, int);
int /*<<< orphan*/ print_vx_vy_n(int, char *, int);
int /*<<< orphan*/ printf(char *);
void print_opcode(uint16_t op, int index) {
  switch ((op & 0xF000) >> 12) {
  case 0x0:
    if (op == 0x00E0)
      print_noarg(op, "CLS", index);
    else if (op == 0x00EE)
      print_noarg(op, "RET", index);
    else
      print_addr(op, "SYS", index);
    break;
  case 0x1:
    print_addr(op, "JMP", index);
    break;
  case 0x2:
    print_addr(op, "CALL", index);
    break;
  case 0x3:
    print_vx_nn(op, "SE", index);
    break;
  case 0x4:
    print_vx_nn(op, "SNE", index);
    break;
  case 0x5:
    if ((op & 0x000F) == 0)
      print_vx_vy(op, "SE", index);
    else
      print_invalid(op, index);
    break;
  case 0x6:
    print_vx_nn(op, "LD", index);
    break;
  case 0x7:
    print_vx_nn(op, "ADD", index);
    break;
  case 0x8:
    switch (op & 0x000F) {
    case 0x0:
      print_vx_vy(op, "LD", index);
      break;
    case 0x1:
      print_vx_vy(op, "OR", index);
      break;
    case 0x2:
      print_vx_vy(op, "AND", index);
      break;
    case 0x3:
      print_vx_vy(op, "XOR", index);
      break;
    case 0x4:
      print_vx_vy(op, "ADD", index);
      break;
    case 0x5:
      print_vx_vy(op, "SUB", index);
      break;
    case 0x6:
      print_vx_vy(op, "SHR", index);
      break;
    case 0x7:
      print_vx_vy(op, "SUBN", index);
      break;
    case 0xE:
      print_vx_vy(op, "SHL", index);
      break;
    default:
      print_invalid(op, index);
    }
    break;
  case 0x9:
    print_vx_vy(op, "SNE", index);
    break;
  case 0xA:
    print_addr(op, "LDI", index);
    break;
  case 0xB:
    print_addr(op, "JPO", index);
    break;
  case 0xC:
    print_vx_nn(op, "RND", index);
    break;
  case 0xD:
    print_vx_vy_n(op, "DRW", index);
    break;
  case 0xE:
    if ((op & 0x00FF) == 0x009E)
      print_vx(op, "SKP", index);
    else if ((op & 0x00FF) == 0x00A1)
      print_vx(op, "SKNP", index);
    else
      print_invalid(op, index);
    break;
  case 0xF:
    print_ophead(op, "LD", index);
    printf("NOT IMPLEMENTED\n");
    break;
  }
}


x86 assembly (clang, -O0):
<print_opcode>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
movzwl -0x4(%rbp),%eax
shr    $0xc,%eax
mov    %eax,%ecx
mov    %rcx,-0x10(%rbp)
sub    $0xf,%eax
ja     14ec <print_opcode+0x35c>
mov    -0x10(%rbp),%rax
lea    0xe41(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
cmpl   $0xe0,-0x4(%rbp)
jne    11ec <print_opcode+0x5c>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%edx
lea    0xe9a(%rip),%rsi
call   1050 <print_noarg@plt>
jmp    1227 <print_opcode+0x97>
cmpl   $0xee,-0x4(%rbp)
jne    1210 <print_opcode+0x80>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%edx
lea    0xe7a(%rip),%rsi
call   1050 <print_noarg@plt>
jmp    1222 <print_opcode+0x92>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%edx
lea    0xe67(%rip),%rsi
call   1060 <print_addr@plt>
jmp    1227 <print_opcode+0x97>
jmp    14ec <print_opcode+0x35c>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%edx
lea    0xe4f(%rip),%rsi
call   1060 <print_addr@plt>
jmp    14ec <print_opcode+0x35c>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%edx
lea    0xe3c(%rip),%rsi
call   1060 <print_addr@plt>
jmp    14ec <print_opcode+0x35c>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%edx
lea    0xe2a(%rip),%rsi
call   10b0 <print_vx_nn@plt>
jmp    14ec <print_opcode+0x35c>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%edx
lea    0xe16(%rip),%rsi
call   10b0 <print_vx_nn@plt>
jmp    14ec <print_opcode+0x35c>
mov    -0x4(%rbp),%eax
and    $0xf,%eax
cmp    $0x0,%eax
jne    12ae <print_opcode+0x11e>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%edx
lea    0xded(%rip),%rsi
call   10a0 <print_vx_vy@plt>
jmp    12b9 <print_opcode+0x129>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%esi
call   1030 <print_invalid@plt>
jmp    14ec <print_opcode+0x35c>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%edx
lea    0xdcd(%rip),%rsi
call   10b0 <print_vx_nn@plt>
jmp    14ec <print_opcode+0x35c>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%edx
lea    0xdb9(%rip),%rsi
call   10b0 <print_vx_nn@plt>
jmp    14ec <print_opcode+0x35c>
mov    -0x4(%rbp),%eax
and    $0xf,%eax
mov    %rax,-0x18(%rbp)
sub    $0xe,%eax
ja     13e2 <print_opcode+0x252>
mov    -0x18(%rbp),%rax
lea    0xd36(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%edx
lea    0xd78(%rip),%rsi
call   10a0 <print_vx_vy@plt>
jmp    13ed <print_opcode+0x25d>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%edx
lea    0xd6d(%rip),%rsi
call   10a0 <print_vx_vy@plt>
jmp    13ed <print_opcode+0x25d>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%edx
lea    0xd51(%rip),%rsi
call   10a0 <print_vx_vy@plt>
jmp    13ed <print_opcode+0x25d>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%edx
lea    0xd3e(%rip),%rsi
call   10a0 <print_vx_vy@plt>
jmp    13ed <print_opcode+0x25d>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%edx
lea    0xd1f(%rip),%rsi
call   10a0 <print_vx_vy@plt>
jmp    13ed <print_opcode+0x25d>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%edx
lea    0xd14(%rip),%rsi
call   10a0 <print_vx_vy@plt>
jmp    13ed <print_opcode+0x25d>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%edx
lea    0xd01(%rip),%rsi
call   10a0 <print_vx_vy@plt>
jmp    13ed <print_opcode+0x25d>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%edx
lea    0xcee(%rip),%rsi
call   10a0 <print_vx_vy@plt>
jmp    13ed <print_opcode+0x25d>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%edx
lea    0xcdc(%rip),%rsi
call   10a0 <print_vx_vy@plt>
jmp    13ed <print_opcode+0x25d>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%esi
call   1030 <print_invalid@plt>
jmp    14ec <print_opcode+0x35c>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%edx
lea    0xc95(%rip),%rsi
call   10a0 <print_vx_vy@plt>
jmp    14ec <print_opcode+0x35c>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%edx
lea    0xca2(%rip),%rsi
call   1060 <print_addr@plt>
jmp    14ec <print_opcode+0x35c>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%edx
lea    0xc8f(%rip),%rsi
call   1060 <print_addr@plt>
jmp    14ec <print_opcode+0x35c>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%edx
lea    0xc7c(%rip),%rsi
call   10b0 <print_vx_nn@plt>
jmp    14ec <print_opcode+0x35c>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%edx
lea    0xc69(%rip),%rsi
call   1040 <print_vx_vy_n@plt>
jmp    14ec <print_opcode+0x35c>
mov    -0x4(%rbp),%eax
and    $0xff,%eax
cmp    $0x9e,%eax
jne    148f <print_opcode+0x2ff>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%edx
lea    0xc43(%rip),%rsi
call   1070 <print_vx@plt>
jmp    14c9 <print_opcode+0x339>
mov    -0x4(%rbp),%eax
and    $0xff,%eax
cmp    $0xa1,%eax
jne    14b9 <print_opcode+0x329>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%edx
lea    0xc1d(%rip),%rsi
call   1070 <print_vx@plt>
jmp    14c4 <print_opcode+0x334>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%esi
call   1030 <print_invalid@plt>
jmp    14c9 <print_opcode+0x339>
jmp    14ec <print_opcode+0x35c>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%edx
lea    0xbbd(%rip),%rsi
call   1090 <print_ophead@plt>
lea    0xbea(%rip),%rdi
call   1080 <printf@plt>
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<print_opcode>:
push   %rax
mov    %esi,%edx
mov    %edi,%eax
shr    $0xc,%eax
and    $0xf,%eax
lea    0xe5e(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
cmp    $0xee,%edi
je     12dc <print_opcode+0x14c>
cmp    $0xe0,%edi
jne    12ee <print_opcode+0x15e>
lea    0xeb2(%rip),%rsi
mov    $0xe0,%edi
pop    %rax
jmp    1050 <print_noarg@plt>
lea    0xeac(%rip),%rsi
pop    %rax
jmp    1070 <print_addr@plt>
lea    0xea3(%rip),%rsi
pop    %rax
jmp    1070 <print_addr@plt>
lea    0xe9b(%rip),%rsi
pop    %rax
jmp    10b0 <print_vx_nn@plt>
lea    0xe91(%rip),%rsi
pop    %rax
jmp    10b0 <print_vx_nn@plt>
test   $0xf,%dil
jne    12bb <print_opcode+0x12b>
lea    0xe77(%rip),%rsi
pop    %rax
jmp    10a0 <print_vx_vy@plt>
lea    0xe71(%rip),%rsi
pop    %rax
jmp    10b0 <print_vx_nn@plt>
lea    0xe67(%rip),%rsi
pop    %rax
jmp    10b0 <print_vx_nn@plt>
mov    %edi,%eax
and    $0xf,%eax
cmp    $0xe,%eax
ja     12bb <print_opcode+0x12b>
lea    0xdf5(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
lea    0xe3d(%rip),%rsi
pop    %rax
jmp    10a0 <print_vx_vy@plt>
lea    0xe2c(%rip),%rsi
pop    %rax
jmp    10a0 <print_vx_vy@plt>
lea    0xe43(%rip),%rsi
pop    %rax
jmp    1070 <print_addr@plt>
lea    0xe3a(%rip),%rsi
pop    %rax
jmp    1070 <print_addr@plt>
lea    0xe31(%rip),%rsi
pop    %rax
jmp    10b0 <print_vx_nn@plt>
lea    0xe28(%rip),%rsi
pop    %rax
jmp    1040 <print_vx_vy_n@plt>
cmp    $0xa1,%dil
je     12fb <print_opcode+0x16b>
cmp    $0x9e,%dil
jne    12bb <print_opcode+0x12b>
lea    0xe13(%rip),%rsi
pop    %rax
jmp    1080 <print_vx@plt>
mov    %edx,%esi
pop    %rax
jmp    1030 <print_invalid@plt>
lea    0xdce(%rip),%rsi
call   1090 <print_ophead@plt>
lea    0xdfb(%rip),%rdi
pop    %rax
jmp    1060 <puts@plt>
lea    0xd9d(%rip),%rsi
mov    $0xee,%edi
pop    %rax
jmp    1050 <print_noarg@plt>
lea    0xd8f(%rip),%rsi
pop    %rax
jmp    1070 <print_addr@plt>
lea    0xdca(%rip),%rsi
pop    %rax
jmp    1080 <print_vx@plt>
lea    0xd95(%rip),%rsi
pop    %rax
jmp    10a0 <print_vx_vy@plt>
lea    0xd83(%rip),%rsi
pop    %rax
jmp    10a0 <print_vx_vy@plt>
lea    0xd7a(%rip),%rsi
pop    %rax
jmp    10a0 <print_vx_vy@plt>
lea    0xd65(%rip),%rsi
pop    %rax
jmp    10a0 <print_vx_vy@plt>
lea    0xd64(%rip),%rsi
pop    %rax
jmp    10a0 <print_vx_vy@plt>
lea    0xd5b(%rip),%rsi
pop    %rax
jmp    10a0 <print_vx_vy@plt>
lea    0xd52(%rip),%rsi
pop    %rax
jmp    10a0 <print_vx_vy@plt>
lea    0xd4a(%rip),%rsi
pop    %rax
jmp    10a0 <print_vx_vy@plt>

LLVM IR (-O0):
@.str = [4 x i8] c"CLS\00"
@.str.1 = [4 x i8] c"RET\00"
@.str.2 = [4 x i8] c"SYS\00"
@.str.3 = [4 x i8] c"JMP\00"
@.str.4 = [5 x i8] c"CALL\00"
@.str.5 = [3 x i8] c"SE\00"
@.str.6 = [4 x i8] c"SNE\00"
@.str.7 = [3 x i8] c"LD\00"
@.str.8 = [4 x i8] c"ADD\00"
@.str.9 = [3 x i8] c"OR\00"
@.str.10 = [4 x i8] c"AND\00"
@.str.11 = [4 x i8] c"XOR\00"
@.str.12 = [4 x i8] c"SUB\00"
@.str.13 = [4 x i8] c"SHR\00"
@.str.14 = [5 x i8] c"SUBN\00"
@.str.15 = [4 x i8] c"SHL\00"
@.str.16 = [4 x i8] c"LDI\00"
@.str.17 = [4 x i8] c"JPO\00"
@.str.18 = [4 x i8] c"RND\00"
@.str.19 = [4 x i8] c"DRW\00"
@.str.20 = [4 x i8] c"SKP\00"
@.str.21 = [5 x i8] c"SKNP\00"
@.str.22 = [17 x i8] c"NOT IMPLEMENTED\0A\00"
define void @print_opcode(i32 %0, i32 %1) {
%3 = alloca i32
%4 = alloca i32
store i32 %0, i32* %3
store i32 %1, i32* %4
%5 = load i32, i32* %3
%6 = and i32 %5, 61440
%7 = ashr i32 %6, 12
switch i32 %7, label %156 [
i32 0, label %8
i32 1, label %28
i32 2, label %32
i32 3, label %36
i32 4, label %40
i32 5, label %44
i32 6, label %57
i32 7, label %61
i32 8, label %65
i32 9, label %109
i32 10, label %113
i32 11, label %117
i32 12, label %121
i32 13, label %125
i32 14, label %129
i32 15, label %151
]
8: ; preds = %2
%9 = load i32, i32* %3
%10 = icmp eq i32 %9, 224
br i1 %10, label %11, label %15
11: ; preds = %8
%12 = load i32, i32* %3
%13 = load i32, i32* %4
%14 = call i32 @print_noarg(i32 %12, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32 %13)
br label %27
15: ; preds = %8
%16 = load i32, i32* %3
%17 = icmp eq i32 %16, 238
br i1 %17, label %18, label %22
18: ; preds = %15
%19 = load i32, i32* %3
%20 = load i32, i32* %4
%21 = call i32 @print_noarg(i32 %19, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.1, i64 0, i64 0), i32 %20)
br label %26
22: ; preds = %15
%23 = load i32, i32* %3
%24 = load i32, i32* %4
%25 = call i32 @print_addr(i32 %23, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.2, i64 0, i64 0), i32 %24)
br label %26
26: ; preds = %22, %18
br label %27
27: ; preds = %26, %11
br label %156
28: ; preds = %2
%29 = load i32, i32* %3
%30 = load i32, i32* %4
%31 = call i32 @print_addr(i32 %29, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.3, i64 0, i64 0), i32 %30)
br label %156
32: ; preds = %2
%33 = load i32, i32* %3
%34 = load i32, i32* %4
%35 = call i32 @print_addr(i32 %33, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.4, i64 0, i64 0), i32 %34)
br label %156
36: ; preds = %2
%37 = load i32, i32* %3
%38 = load i32, i32* %4
%39 = call i32 @print_vx_nn(i32 %37, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.5, i64 0, i64 0), i32 %38)
br label %156
40: ; preds = %2
%41 = load i32, i32* %3
%42 = load i32, i32* %4
%43 = call i32 @print_vx_nn(i32 %41, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.6, i64 0, i64 0), i32 %42)
br label %156
44: ; preds = %2
%45 = load i32, i32* %3
%46 = and i32 %45, 15
%47 = icmp eq i32 %46, 0
br i1 %47, label %48, label %52
48: ; preds = %44
%49 = load i32, i32* %3
%50 = load i32, i32* %4
%51 = call i32 @print_vx_vy(i32 %49, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.5, i64 0, i64 0), i32 %50)
br label %56
52: ; preds = %44
%53 = load i32, i32* %3
%54 = load i32, i32* %4
%55 = call i32 @print_invalid(i32 %53, i32 %54)
br label %56
56: ; preds = %52, %48
br label %156
57: ; preds = %2
%58 = load i32, i32* %3
%59 = load i32, i32* %4
%60 = call i32 @print_vx_nn(i32 %58, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.7, i64 0, i64 0), i32 %59)
br label %156
61: ; preds = %2
%62 = load i32, i32* %3
%63 = load i32, i32* %4
%64 = call i32 @print_vx_nn(i32 %62, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.8, i64 0, i64 0), i32 %63)
br label %156
65: ; preds = %2
%66 = load i32, i32* %3
%67 = and i32 %66, 15
switch i32 %67, label %104 [
i32 0, label %68
i32 1, label %72
i32 2, label %76
i32 3, label %80
i32 4, label %84
i32 5, label %88
i32 6, label %92
i32 7, label %96
i32 14, label %100
]
68: ; preds = %65
%69 = load i32, i32* %3
%70 = load i32, i32* %4
%71 = call i32 @print_vx_vy(i32 %69, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.7, i64 0, i64 0), i32 %70)
br label %108
72: ; preds = %65
%73 = load i32, i32* %3
%74 = load i32, i32* %4
%75 = call i32 @print_vx_vy(i32 %73, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.9, i64 0, i64 0), i32 %74)
br label %108
76: ; preds = %65
%77 = load i32, i32* %3
%78 = load i32, i32* %4
%79 = call i32 @print_vx_vy(i32 %77, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.10, i64 0, i64 0), i32 %78)
br label %108
80: ; preds = %65
%81 = load i32, i32* %3
%82 = load i32, i32* %4
%83 = call i32 @print_vx_vy(i32 %81, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.11, i64 0, i64 0), i32 %82)
br label %108
84: ; preds = %65
%85 = load i32, i32* %3
%86 = load i32, i32* %4
%87 = call i32 @print_vx_vy(i32 %85, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.8, i64 0, i64 0), i32 %86)
br label %108
88: ; preds = %65
%89 = load i32, i32* %3
%90 = load i32, i32* %4
%91 = call i32 @print_vx_vy(i32 %89, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.12, i64 0, i64 0), i32 %90)
br label %108
92: ; preds = %65
%93 = load i32, i32* %3
%94 = load i32, i32* %4
%95 = call i32 @print_vx_vy(i32 %93, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.13, i64 0, i64 0), i32 %94)
br label %108
96: ; preds = %65
%97 = load i32, i32* %3
%98 = load i32, i32* %4
%99 = call i32 @print_vx_vy(i32 %97, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.14, i64 0, i64 0), i32 %98)
br label %108
100: ; preds = %65
%101 = load i32, i32* %3
%102 = load i32, i32* %4
%103 = call i32 @print_vx_vy(i32 %101, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.15, i64 0, i64 0), i32 %102)
br label %108
104: ; preds = %65
%105 = load i32, i32* %3
%106 = load i32, i32* %4
%107 = call i32 @print_invalid(i32 %105, i32 %106)
br label %108
108: ; preds = %104, %100, %96, %92, %88, %84, %80, %76, %72, %68
br label %156
109: ; preds = %2
%110 = load i32, i32* %3
%111 = load i32, i32* %4
%112 = call i32 @print_vx_vy(i32 %110, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.6, i64 0, i64 0), i32 %111)
br label %156
113: ; preds = %2
%114 = load i32, i32* %3
%115 = load i32, i32* %4
%116 = call i32 @print_addr(i32 %114, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.16, i64 0, i64 0), i32 %115)
br label %156
117: ; preds = %2
%118 = load i32, i32* %3
%119 = load i32, i32* %4
%120 = call i32 @print_addr(i32 %118, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.17, i64 0, i64 0), i32 %119)
br label %156
121: ; preds = %2
%122 = load i32, i32* %3
%123 = load i32, i32* %4
%124 = call i32 @print_vx_nn(i32 %122, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.18, i64 0, i64 0), i32 %123)
br label %156
125: ; preds = %2
%126 = load i32, i32* %3
%127 = load i32, i32* %4
%128 = call i32 @print_vx_vy_n(i32 %126, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.19, i64 0, i64 0), i32 %127)
br label %156
129: ; preds = %2
%130 = load i32, i32* %3
%131 = and i32 %130, 255
%132 = icmp eq i32 %131, 158
br i1 %132, label %133, label %137
133: ; preds = %129
%134 = load i32, i32* %3
%135 = load i32, i32* %4
%136 = call i32 @print_vx(i32 %134, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.20, i64 0, i64 0), i32 %135)
br label %150
137: ; preds = %129
%138 = load i32, i32* %3
%139 = and i32 %138, 255
%140 = icmp eq i32 %139, 161
br i1 %140, label %141, label %145
141: ; preds = %137
%142 = load i32, i32* %3
%143 = load i32, i32* %4
%144 = call i32 @print_vx(i32 %142, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.21, i64 0, i64 0), i32 %143)
br label %149
145: ; preds = %137
%146 = load i32, i32* %3
%147 = load i32, i32* %4
%148 = call i32 @print_invalid(i32 %146, i32 %147)
br label %149
149: ; preds = %145, %141
br label %150
150: ; preds = %149, %133
br label %156
151: ; preds = %2
%152 = load i32, i32* %3
%153 = load i32, i32* %4
%154 = call i32 @print_ophead(i32 %152, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.7, i64 0, i64 0), i32 %153)
%155 = call i32 @printf(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.22, i64 0, i64 0))
br label %156
156: ; preds = %2, %151, %150, %125, %121, %117, %113, %109, %108, %61, %57, %56, %40, %36, %32, %28, %27
ret void
}

LLVM IR (-O2):
@.str = [4 x i8] c"CLS\00"
@.str.1 = [4 x i8] c"RET\00"
@.str.2 = [4 x i8] c"SYS\00"
@.str.3 = [4 x i8] c"JMP\00"
@.str.4 = [5 x i8] c"CALL\00"
@.str.5 = [3 x i8] c"SE\00"
@.str.6 = [4 x i8] c"SNE\00"
@.str.7 = [3 x i8] c"LD\00"
@.str.8 = [4 x i8] c"ADD\00"
@.str.9 = [3 x i8] c"OR\00"
@.str.10 = [4 x i8] c"AND\00"
@.str.11 = [4 x i8] c"XOR\00"
@.str.12 = [4 x i8] c"SUB\00"
@.str.13 = [4 x i8] c"SHR\00"
@.str.14 = [5 x i8] c"SUBN\00"
@.str.15 = [4 x i8] c"SHL\00"
@.str.16 = [4 x i8] c"LDI\00"
@.str.17 = [4 x i8] c"JPO\00"
@.str.18 = [4 x i8] c"RND\00"
@.str.19 = [4 x i8] c"DRW\00"
@.str.20 = [4 x i8] c"SKP\00"
@.str.21 = [5 x i8] c"SKNP\00"
@str = [16 x i8] c"NOT IMPLEMENTED\00"
define void @print_opcode(i32 %0, i32 %1) {
%3 = lshr i32 %0, 12
%4 = and i32 %3, 15
switch i32 %4, label %74 [
i32 0, label %5
i32 1, label %12
i32 2, label %14
i32 3, label %16
i32 4, label %18
i32 5, label %20
i32 6, label %27
i32 7, label %29
i32 8, label %31
i32 9, label %53
i32 10, label %55
i32 11, label %57
i32 12, label %59
i32 13, label %61
i32 14, label %63
i32 15, label %71
]
5: ; preds = %2
switch i32 %0, label %10 [
i32 224, label %6
i32 238, label %8
]
6: ; preds = %5
%7 = tail call i32 @print_noarg(i32 224, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32 %1)
br label %75
8: ; preds = %5
%9 = tail call i32 @print_noarg(i32 238, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.1, i64 0, i64 0), i32 %1)
br label %75
10: ; preds = %5
%11 = tail call i32 @print_addr(i32 %0, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.2, i64 0, i64 0), i32 %1)
br label %75
12: ; preds = %2
%13 = tail call i32 @print_addr(i32 %0, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.3, i64 0, i64 0), i32 %1)
br label %75
14: ; preds = %2
%15 = tail call i32 @print_addr(i32 %0, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.4, i64 0, i64 0), i32 %1)
br label %75
16: ; preds = %2
%17 = tail call i32 @print_vx_nn(i32 %0, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.5, i64 0, i64 0), i32 %1)
br label %75
18: ; preds = %2
%19 = tail call i32 @print_vx_nn(i32 %0, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.6, i64 0, i64 0), i32 %1)
br label %75
20: ; preds = %2
%21 = and i32 %0, 15
%22 = icmp eq i32 %21, 0
br i1 %22, label %23, label %25
23: ; preds = %20
%24 = tail call i32 @print_vx_vy(i32 %0, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.5, i64 0, i64 0), i32 %1)
br label %75
25: ; preds = %20
%26 = tail call i32 @print_invalid(i32 %0, i32 %1)
br label %75
27: ; preds = %2
%28 = tail call i32 @print_vx_nn(i32 %0, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.7, i64 0, i64 0), i32 %1)
br label %75
29: ; preds = %2
%30 = tail call i32 @print_vx_nn(i32 %0, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.8, i64 0, i64 0), i32 %1)
br label %75
31: ; preds = %2
%32 = and i32 %0, 15
switch i32 %32, label %51 [
i32 0, label %33
i32 1, label %35
i32 2, label %37
i32 3, label %39
i32 4, label %41
i32 5, label %43
i32 6, label %45
i32 7, label %47
i32 14, label %49
]
33: ; preds = %31
%34 = tail call i32 @print_vx_vy(i32 %0, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.7, i64 0, i64 0), i32 %1)
br label %75
35: ; preds = %31
%36 = tail call i32 @print_vx_vy(i32 %0, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.9, i64 0, i64 0), i32 %1)
br label %75
37: ; preds = %31
%38 = tail call i32 @print_vx_vy(i32 %0, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.10, i64 0, i64 0), i32 %1)
br label %75
39: ; preds = %31
%40 = tail call i32 @print_vx_vy(i32 %0, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.11, i64 0, i64 0), i32 %1)
br label %75
41: ; preds = %31
%42 = tail call i32 @print_vx_vy(i32 %0, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.8, i64 0, i64 0), i32 %1)
br label %75
43: ; preds = %31
%44 = tail call i32 @print_vx_vy(i32 %0, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.12, i64 0, i64 0), i32 %1)
br label %75
45: ; preds = %31
%46 = tail call i32 @print_vx_vy(i32 %0, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.13, i64 0, i64 0), i32 %1)
br label %75
47: ; preds = %31
%48 = tail call i32 @print_vx_vy(i32 %0, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.14, i64 0, i64 0), i32 %1)
br label %75
49: ; preds = %31
%50 = tail call i32 @print_vx_vy(i32 %0, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.15, i64 0, i64 0), i32 %1)
br label %75
51: ; preds = %31
%52 = tail call i32 @print_invalid(i32 %0, i32 %1)
br label %75
53: ; preds = %2
%54 = tail call i32 @print_vx_vy(i32 %0, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.6, i64 0, i64 0), i32 %1)
br label %75
55: ; preds = %2
%56 = tail call i32 @print_addr(i32 %0, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.16, i64 0, i64 0), i32 %1)
br label %75
57: ; preds = %2
%58 = tail call i32 @print_addr(i32 %0, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.17, i64 0, i64 0), i32 %1)
br label %75
59: ; preds = %2
%60 = tail call i32 @print_vx_nn(i32 %0, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.18, i64 0, i64 0), i32 %1)
br label %75
61: ; preds = %2
%62 = tail call i32 @print_vx_vy_n(i32 %0, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.19, i64 0, i64 0), i32 %1)
br label %75
63: ; preds = %2
%64 = trunc i32 %0 to i8
switch i8 %64, label %69 [
i8 -98, label %65
i8 -95, label %67
]
65: ; preds = %63
%66 = tail call i32 @print_vx(i32 %0, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.20, i64 0, i64 0), i32 %1)
br label %75
67: ; preds = %63
%68 = tail call i32 @print_vx(i32 %0, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.21, i64 0, i64 0), i32 %1)
br label %75
69: ; preds = %63
%70 = tail call i32 @print_invalid(i32 %0, i32 %1)
br label %75
71: ; preds = %2
%72 = tail call i32 @print_ophead(i32 %0, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.7, i64 0, i64 0), i32 %1)
%73 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([16 x i8], [16 x i8]* @str, i64 0, i64 0))
br label %75
74: ; preds = %2
unreachable
75: ; preds = %65, %69, %67, %33, %35, %37, %39, %41, %43, %45, %47, %49, %51, %23, %25, %6, %10, %8, %71, %61, %59, %57, %55, %53, %29, %27, %18, %16, %14, %12
ret void
}