#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 */

/* Variables and functions */
int getch();
char get_key() {
  char signal;
  char key;
  bool escape;
  signal = getch();
  if (0x1b == signal) {
    escape = true;
    if (0x5b == getch())
      signal = getch();
  } else
    escape = false;
  if (escape)
    switch (signal) {
    case 'A':
      key = 'U';
      break;
    case 'B':
      key = 'D';
      break;
    case 'C':
      key = 'R';
      break;
    case 'D':
      key = 'L';
      break;
    default:
      key = 'x';
      break;
    }
  else
    switch (signal) {
    case 'w':
    case 'W':
      key = 'U';
      break;
    case 's':
    case 'S':
      key = 'D';
      break;
    case 'd':
    case 'D':
      key = 'R';
      break;
    case 'a':
    case 'A':
      key = 'L';
      break;
    case 'r':
    case 'R':
      key = 'r';
      break;
    case 'q':
    case 'Q':
      key = 'q';
      break;
    case 'i':
    case 'I':
    case 'h':
    case 'H':
      key = 'h';
      break;
    default:
      key = 'x';
      break;
    }
  return key;
}


x86 assembly (clang, -O0):
<get_key>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    $0x0,%al
call   1030 <getch@plt>
mov    %al,-0x1(%rbp)
movsbl -0x1(%rbp),%ecx
mov    $0x1b,%eax
cmp    %ecx,%eax
jne    115f <get_key+0x4f>
movl   $0x1,-0x8(%rbp)
mov    $0x0,%al
call   1030 <getch@plt>
mov    %eax,%ecx
mov    $0x5b,%eax
cmp    %ecx,%eax
jne    115a <get_key+0x4a>
mov    $0x0,%al
call   1030 <getch@plt>
mov    %al,-0x1(%rbp)
jmp    1166 <get_key+0x56>
movl   $0x0,-0x8(%rbp)
cmpl   $0x0,-0x8(%rbp)
je     11c7 <get_key+0xb7>
movsbl -0x1(%rbp),%eax
add    $0xffffffbf,%eax
mov    %eax,%ecx
mov    %rcx,-0x10(%rbp)
sub    $0x3,%eax
ja     11be <get_key+0xae>
mov    -0x10(%rbp),%rax
lea    0xf4b(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
movb   $0x55,-0x2(%rbp)
jmp    11c2 <get_key+0xb2>
movb   $0x44,-0x2(%rbp)
jmp    11c2 <get_key+0xb2>
movb   $0x52,-0x2(%rbp)
jmp    11c2 <get_key+0xb2>
movb   $0x4c,-0x2(%rbp)
jmp    11c2 <get_key+0xb2>
movb   $0x78,-0x2(%rbp)
jmp    1239 <get_key+0x129>
movsbl -0x1(%rbp),%eax
add    $0xffffffbf,%eax
mov    %eax,%ecx
mov    %rcx,-0x18(%rbp)
sub    $0x36,%eax
ja     1230 <get_key+0x120>
mov    -0x18(%rbp),%rax
lea    0xe18(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
movb   $0x55,-0x2(%rbp)
jmp    1234 <get_key+0x124>
movb   $0x44,-0x2(%rbp)
jmp    1234 <get_key+0x124>
movb   $0x52,-0x2(%rbp)
jmp    1234 <get_key+0x124>
movb   $0x4c,-0x2(%rbp)
jmp    1234 <get_key+0x124>
movb   $0x72,-0x2(%rbp)
jmp    1234 <get_key+0x124>
movb   $0x71,-0x2(%rbp)
jmp    1234 <get_key+0x124>
movb   $0x68,-0x2(%rbp)
jmp    1234 <get_key+0x124>
movb   $0x78,-0x2(%rbp)
jmp    1239 <get_key+0x129>
movsbl -0x2(%rbp),%eax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<get_key>:
push   %rbx
xor    %eax,%eax
call   1030 <getch@plt>
mov    %eax,%ebx
cmp    $0x1b,%bl
jne    114d <get_key+0x3d>
xor    %eax,%eax
call   1030 <getch@plt>
cmp    $0x5b,%eax
jne    1134 <get_key+0x24>
xor    %eax,%eax
call   1030 <getch@plt>
mov    %eax,%ebx
movsbl %bl,%ecx
add    $0xffffffbf,%ecx
mov    $0x78,%al
cmp    $0x4,%ecx
jae    114b <get_key+0x3b>
shl    $0x3,%ecx
mov    $0x4c524455,%eax
shr    %cl,%eax
pop    %rbx
ret
movsbl %bl,%ecx
add    $0xffffffbf,%ecx
cmp    $0x36,%ecx
ja     1182 <get_key+0x72>
mov    $0x55,%al
lea    0xe9f(%rip),%rdx
movslq (%rdx,%rcx,4),%rcx
add    %rdx,%rcx
jmp    *%rcx
mov    $0x68,%al
pop    %rbx
ret
mov    $0x4c,%al
pop    %rbx
ret
mov    $0x52,%al
pop    %rbx
ret
mov    $0x71,%al
pop    %rbx
ret
mov    $0x72,%al
pop    %rbx
ret
mov    $0x44,%al
pop    %rbx
ret
mov    $0x78,%al
pop    %rbx
ret

LLVM IR (-O0):
define signext i8 @get_key() {
%1 = alloca i8
%2 = alloca i8
%3 = alloca i32
%4 = call i32 (...) @getch()
%5 = trunc i32 %4 to i8
store i8 %5, i8* %1
%6 = load i8, i8* %1
%7 = sext i8 %6 to i32
%8 = icmp eq i32 27, %7
br i1 %8, label %9, label %16
9: ; preds = %0
store i32 1, i32* %3
%10 = call i32 (...) @getch()
%11 = icmp eq i32 91, %10
br i1 %11, label %12, label %15
12: ; preds = %9
%13 = call i32 (...) @getch()
%14 = trunc i32 %13 to i8
store i8 %14, i8* %1
br label %15
15: ; preds = %12, %9
br label %17
16: ; preds = %0
store i32 0, i32* %3
br label %17
17: ; preds = %16, %15
%18 = load i32, i32* %3
%19 = icmp ne i32 %18, 0
br i1 %19, label %20, label %29
20: ; preds = %17
%21 = load i8, i8* %1
%22 = sext i8 %21 to i32
switch i32 %22, label %27 [
i32 65, label %23
i32 66, label %24
i32 67, label %25
i32 68, label %26
]
23: ; preds = %20
store i8 85, i8* %2
br label %28
24: ; preds = %20
store i8 68, i8* %2
br label %28
25: ; preds = %20
store i8 82, i8* %2
br label %28
26: ; preds = %20
store i8 76, i8* %2
br label %28
27: ; preds = %20
store i8 120, i8* %2
br label %28
28: ; preds = %27, %26, %25, %24, %23
br label %41
29: ; preds = %17
%30 = load i8, i8* %1
%31 = sext i8 %30 to i32
switch i32 %31, label %39 [
i32 119, label %32
i32 87, label %32
i32 115, label %33
i32 83, label %33
i32 100, label %34
i32 68, label %34
i32 97, label %35
i32 65, label %35
i32 114, label %36
i32 82, label %36
i32 113, label %37
i32 81, label %37
i32 105, label %38
i32 73, label %38
i32 104, label %38
i32 72, label %38
]
32: ; preds = %29, %29
store i8 85, i8* %2
br label %40
33: ; preds = %29, %29
store i8 68, i8* %2
br label %40
34: ; preds = %29, %29
store i8 82, i8* %2
br label %40
35: ; preds = %29, %29
store i8 76, i8* %2
br label %40
36: ; preds = %29, %29
store i8 114, i8* %2
br label %40
37: ; preds = %29, %29
store i8 113, i8* %2
br label %40
38: ; preds = %29, %29, %29, %29
store i8 104, i8* %2
br label %40
39: ; preds = %29
store i8 120, i8* %2
br label %40
40: ; preds = %39, %38, %37, %36, %35, %34, %33, %32
br label %41
41: ; preds = %40, %28
%42 = load i8, i8* %2
ret i8 %42
}

LLVM IR (-O2):
define signext i8 @get_key() {
%1 = tail call i32 (...) @getch()
%2 = and i32 %1, 255
%3 = icmp eq i32 %2, 27
br i1 %3, label %4, label %15
4: ; preds = %0
%5 = tail call i32 (...) @getch()
%6 = icmp eq i32 %5, 91
br i1 %6, label %7, label %9
7: ; preds = %4
%8 = tail call i32 (...) @getch()
br label %9
9: ; preds = %7, %4
%10 = phi i32 [ %1, %4 ], [ %8, %7 ]
%11 = shl i32 %10, 24
%12 = ashr exact i32 %11, 24
%13 = add nsw i32 %12, -65
%14 = icmp ult i32 %13, 4
br i1 %14, label %25, label %29
15: ; preds = %0
%16 = shl i32 %1, 24
%17 = ashr exact i32 %16, 24
switch i32 %17, label %24 [
i32 119, label %29
i32 87, label %29
i32 115, label %18
i32 83, label %18
i32 100, label %19
i32 68, label %19
i32 97, label %20
i32 65, label %20
i32 114, label %21
i32 82, label %21
i32 113, label %22
i32 81, label %22
i32 105, label %23
i32 73, label %23
i32 104, label %23
i32 72, label %23
]
18: ; preds = %15, %15
br label %29
19: ; preds = %15, %15
br label %29
20: ; preds = %15, %15
br label %29
21: ; preds = %15, %15
br label %29
22: ; preds = %15, %15
br label %29
23: ; preds = %15, %15, %15, %15
br label %29
24: ; preds = %15
br label %29
25: ; preds = %9
%26 = shl nsw i32 %13, 3
%27 = lshr i32 1280459861, %26
%28 = trunc i32 %27 to i8
br label %29
29: ; preds = %9, %25, %15, %15, %18, %19, %20, %21, %22, %23, %24
%30 = phi i8 [ 120, %24 ], [ 104, %23 ], [ 113, %22 ], [ 114, %21 ], [ 76, %20 ], [ 82, %19 ], [ 68, %18 ], [ 85, %15 ], [ 85, %15 ], [ %28, %25 ], [ 120, %9 ]
ret i8 %30
}