#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 /*<<< orphan*/ fprintf(int /*<<< orphan*/, char *, short);
int /*<<< orphan*/ stderr;
volatile char *build_mov_register_to_memory(short mov_size, int src_reg,
                                            int offset, int dest_reg,
                                            volatile char *tgt_addr) {
  if (mov_size == 2) {
    (*tgt_addr++) = 0x66;
  }
  switch (mov_size) {
  case 1:
    (*(short *)tgt_addr) =
        (offset << 16) + ((0x40) + (dest_reg << 0x3) + src_reg) | 0x88;
    tgt_addr += 0x2;
    break;
  case 2:
    (*(short *)tgt_addr) =
        (offset << 16) + ((0x80) + (dest_reg << 0x3) + src_reg) | 0x89;
    tgt_addr += 0x2;
    break;
  case 4:
    (*(short *)tgt_addr) =
        (offset << 16) + ((0x80) + (dest_reg << 0x3) + src_reg) | 0x89;
    tgt_addr += 0x2;
    break;
  default:
    fprintf(stderr,
            "ERROR: Incorrect size (%d) passed to register to register move\n",
            mov_size);
    return (NULL);
  }
  return (tgt_addr);
}


x86 assembly (clang, -O0):
<build_mov_register_to_memory>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %di,%ax
mov    %ax,-0xa(%rbp)
mov    %esi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    %ecx,-0x18(%rbp)
mov    %r8,-0x20(%rbp)
movswl -0xa(%rbp),%eax
cmp    $0x2,%eax
jne    114b <build_mov_register_to_memory+0x3b>
mov    -0x20(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x20(%rbp)
movb   $0x66,(%rax)
movswl -0xa(%rbp),%eax
mov    %eax,-0x24(%rbp)
sub    $0x1,%eax
je     1182 <build_mov_register_to_memory+0x72>
jmp    1160 <build_mov_register_to_memory+0x50>
mov    -0x24(%rbp),%eax
sub    $0x2,%eax
je     11b6 <build_mov_register_to_memory+0xa6>
jmp    1171 <build_mov_register_to_memory+0x61>
mov    -0x24(%rbp),%eax
sub    $0x4,%eax
je     11ed <build_mov_register_to_memory+0xdd>
jmp    1224 <build_mov_register_to_memory+0x114>
mov    -0x14(%rbp),%eax
shl    $0x10,%eax
mov    -0x18(%rbp),%ecx
shl    $0x3,%ecx
add    $0x40,%ecx
add    -0x10(%rbp),%ecx
add    %ecx,%eax
or     $0x88,%eax
mov    %ax,%cx
mov    -0x20(%rbp),%rax
mov    %cx,(%rax)
mov    -0x20(%rbp),%rax
add    $0x2,%rax
mov    %rax,-0x20(%rbp)
jmp    124a <build_mov_register_to_memory+0x13a>
mov    -0x14(%rbp),%eax
shl    $0x10,%eax
mov    -0x18(%rbp),%ecx
shl    $0x3,%ecx
add    $0x80,%ecx
add    -0x10(%rbp),%ecx
add    %ecx,%eax
or     $0x89,%eax
mov    %ax,%cx
mov    -0x20(%rbp),%rax
mov    %cx,(%rax)
mov    -0x20(%rbp),%rax
add    $0x2,%rax
mov    %rax,-0x20(%rbp)
jmp    124a <build_mov_register_to_memory+0x13a>
mov    -0x14(%rbp),%eax
shl    $0x10,%eax
mov    -0x18(%rbp),%ecx
shl    $0x3,%ecx
add    $0x80,%ecx
add    -0x10(%rbp),%ecx
add    %ecx,%eax
or     $0x89,%eax
mov    %ax,%cx
mov    -0x20(%rbp),%rax
mov    %cx,(%rax)
mov    -0x20(%rbp),%rax
add    $0x2,%rax
mov    %rax,-0x20(%rbp)
jmp    124a <build_mov_register_to_memory+0x13a>
mov    0x2db5(%rip),%rax
mov    (%rax),%edi
lea    0xdcc(%rip),%rsi
movswl -0xa(%rbp),%edx
call   1030 <fprintf@plt>
movq   $0x0,-0x8(%rbp)
jmp    1252 <build_mov_register_to_memory+0x142>
mov    -0x20(%rbp),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<build_mov_register_to_memory>:
push   %rax
mov    %r8,%rax
cmp    $0x2,%di
jne    1123 <build_mov_register_to_memory+0x13>
movb   $0x66,(%rax)
add    $0x1,%rax
jmp    1135 <build_mov_register_to_memory+0x25>
movswl %di,%edx
cmp    $0x1,%edx
je     1151 <build_mov_register_to_memory+0x41>
cmp    $0x4,%edx
je     1135 <build_mov_register_to_memory+0x25>
cmp    $0x2,%edx
jne    115c <build_mov_register_to_memory+0x4c>
mov    $0x89,%dx
mov    $0x80,%edi
add    %esi,%edi
lea    (%rdi,%rcx,8),%ecx
movzwl %dx,%edx
or     %ecx,%edx
mov    %dx,(%rax)
add    $0x2,%rax
pop    %rcx
ret
mov    $0x88,%dx
mov    $0x40,%edi
jmp    113e <build_mov_register_to_memory+0x2e>
mov    0x2e7d(%rip),%rax
mov    (%rax),%edi
lea    0xe94(%rip),%rsi
call   1030 <fprintf@plt>
xor    %eax,%eax
pop    %rcx
ret

LLVM IR (-O0):
@stderr = global i32 0
@.str = [64 x i8] c"ERROR: Incorrect size (%d) passed to register to register move\0A\00"
define i8* @build_mov_register_to_memory(i16 signext %0, i32 %1, i32 %2, i32 %3, i8* %4) {
%6 = alloca i8*
%7 = alloca i16
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
%11 = alloca i8*
store i16 %0, i16* %7
store i32 %1, i32* %8
store i32 %2, i32* %9
store i32 %3, i32* %10
store i8* %4, i8** %11
%12 = load i16, i16* %7
%13 = sext i16 %12 to i32
%14 = icmp eq i32 %13, 2
br i1 %14, label %15, label %18
15: ; preds = %5
%16 = load i8*, i8** %11
%17 = getelementptr inbounds i8, i8* %16, i32 1
store i8* %17, i8** %11
store volatile i8 102, i8* %16
br label %18
18: ; preds = %15, %5
%19 = load i16, i16* %7
%20 = sext i16 %19 to i32
switch i32 %20, label %66 [
i32 1, label %21
i32 2, label %36
i32 4, label %51
]
21: ; preds = %18
%22 = load i32, i32* %9
%23 = shl i32 %22, 16
%24 = load i32, i32* %10
%25 = shl i32 %24, 3
%26 = add nsw i32 64, %25
%27 = load i32, i32* %8
%28 = add nsw i32 %26, %27
%29 = add nsw i32 %23, %28
%30 = or i32 %29, 136
%31 = trunc i32 %30 to i16
%32 = load i8*, i8** %11
%33 = bitcast i8* %32 to i16*
store i16 %31, i16* %33
%34 = load i8*, i8** %11
%35 = getelementptr inbounds i8, i8* %34, i64 2
store i8* %35, i8** %11
br label %70
36: ; preds = %18
%37 = load i32, i32* %9
%38 = shl i32 %37, 16
%39 = load i32, i32* %10
%40 = shl i32 %39, 3
%41 = add nsw i32 128, %40
%42 = load i32, i32* %8
%43 = add nsw i32 %41, %42
%44 = add nsw i32 %38, %43
%45 = or i32 %44, 137
%46 = trunc i32 %45 to i16
%47 = load i8*, i8** %11
%48 = bitcast i8* %47 to i16*
store i16 %46, i16* %48
%49 = load i8*, i8** %11
%50 = getelementptr inbounds i8, i8* %49, i64 2
store i8* %50, i8** %11
br label %70
51: ; preds = %18
%52 = load i32, i32* %9
%53 = shl i32 %52, 16
%54 = load i32, i32* %10
%55 = shl i32 %54, 3
%56 = add nsw i32 128, %55
%57 = load i32, i32* %8
%58 = add nsw i32 %56, %57
%59 = add nsw i32 %53, %58
%60 = or i32 %59, 137
%61 = trunc i32 %60 to i16
%62 = load i8*, i8** %11
%63 = bitcast i8* %62 to i16*
store i16 %61, i16* %63
%64 = load i8*, i8** %11
%65 = getelementptr inbounds i8, i8* %64, i64 2
store i8* %65, i8** %11
br label %70
66: ; preds = %18
%67 = load i32, i32* @stderr
%68 = load i16, i16* %7
%69 = call i32 @fprintf(i32 %67, i8* getelementptr inbounds ([64 x i8], [64 x i8]* @.str, i64 0, i64 0), i16 signext %68)
store i8* null, i8** %6
br label %72
70: ; preds = %51, %36, %21
%71 = load i8*, i8** %11
store i8* %71, i8** %6
br label %72
72: ; preds = %70, %66
%73 = load i8*, i8** %6
ret i8* %73
}

LLVM IR (-O2):
@stderr = global i32 0
@.str = [64 x i8] c"ERROR: Incorrect size (%d) passed to register to register move\0A\00"
define i8* @build_mov_register_to_memory(i16 signext %0, i32 %1, i32 %2, i32 %3, i8* %4) {
%6 = icmp eq i16 %0, 2
br i1 %6, label %7, label %9
7: ; preds = %5
%8 = getelementptr inbounds i8, i8* %4, i64 1
store volatile i8 102, i8* %4
br label %11
9: ; preds = %5
%10 = sext i16 %0 to i32
switch i32 %10, label %14 [
i32 1, label %17
i32 2, label %11
i32 4, label %13
]
11: ; preds = %7, %9
%12 = phi i8* [ %8, %7 ], [ %4, %9 ]
br label %17
13: ; preds = %9
br label %17
14: ; preds = %9
%15 = load i32, i32* @stderr
%16 = tail call i32 @fprintf(i32 %15, i8* getelementptr inbounds ([64 x i8], [64 x i8]* @.str, i64 0, i64 0), i16 signext %0)
br label %28
17: ; preds = %9, %13, %11
%18 = phi i32 [ 128, %13 ], [ 128, %11 ], [ 64, %9 ]
%19 = phi i16 [ 137, %13 ], [ 137, %11 ], [ 136, %9 ]
%20 = phi i8* [ %4, %13 ], [ %12, %11 ], [ %4, %9 ]
%21 = shl i32 %3, 3
%22 = add i32 %18, %1
%23 = add i32 %22, %21
%24 = trunc i32 %23 to i16
%25 = or i16 %19, %24
%26 = bitcast i8* %20 to i16*
store i16 %25, i16* %26
%27 = getelementptr inbounds i8, i8* %20, i64 2
br label %28
28: ; preds = %17, %14
%29 = phi i8* [ null, %14 ], [ %27, %17 ]
ret i8* %29
}