#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 scalar_t__ uint32_t;
typedef int /*<<< orphan*/ tests;
typedef int int32_t;

/* Variables and functions */
int /*<<< orphan*/ fprintf(int /*<<< orphan*/, char *, int, scalar_t__, int,
                           scalar_t__);
int /*<<< orphan*/ printf(char *);
int /*<<< orphan*/ stderr;
int subtilis_arm_encode_imm(int, scalar_t__ *);
int prv_test_encode_imm(void) {
  struct test {
    int32_t num;
    uint32_t encoded;
    bool ok;
  };
  size_t i;
  struct test tests[] = {
      {173, 173, true},
      {257, 0, false},
      {19968, 0xc4e, true},
      {0x3FC00, 0xbff, true},
      {0x102, 0, false},
      {(int32_t)0xFF0000FF, 0, false},
      {(int32_t)0xC0000034, 0x1d3, true},
  };
  uint32_t encoded;
  bool ok;
  printf("arm_core_encode_imm");
  for (i = 0; i < sizeof(tests) / sizeof(struct test); i++) {
    encoded = 0;
    ok = subtilis_arm_encode_imm(tests[i].num, &encoded);
    if (ok != tests[i].ok || encoded != tests[i].encoded) {
      fprintf(stderr, "Expected %d %u got %d %u\n", tests[i].ok,
              tests[i].encoded, ok, encoded);
      goto fail;
    }
  }
  printf(": [OK]\n");
  return 0;
fail:
  printf(": [FAIL]\n");
  return 1;
}


x86 assembly (clang, -O0):
<prv_test_encode_imm>:
push   %rbp
mov    %rsp,%rbp
sub    $0xd0,%rsp
lea    -0xc0(%rbp),%rdi
lea    0xea7(%rip),%rsi
mov    $0xa8,%edx
call   1060 <memcpy@plt>
lea    0xf3e(%rip),%rdi
call   1030 <printf@plt>
movq   $0x0,-0x10(%rbp)
cmpq   $0x7,-0x10(%rbp)
jae    1251 <prv_test_encode_imm+0x111>
movq   $0x0,-0xc8(%rbp)
lea    -0xc0(%rbp),%rax
imul   $0x18,-0x10(%rbp),%rcx
add    %rcx,%rax
mov    (%rax),%edi
lea    -0xc8(%rbp),%rsi
call   1040 <subtilis_arm_encode_imm@plt>
mov    %eax,-0xcc(%rbp)
mov    -0xcc(%rbp),%eax
lea    -0xc0(%rbp),%rcx
imul   $0x18,-0x10(%rbp),%rdx
add    %rdx,%rcx
cmp    0x10(%rcx),%eax
jne    11ee <prv_test_encode_imm+0xae>
mov    -0xc8(%rbp),%rax
lea    -0xc0(%rbp),%rcx
imul   $0x18,-0x10(%rbp),%rdx
add    %rdx,%rcx
cmp    0x8(%rcx),%rax
je     123b <prv_test_encode_imm+0xfb>
mov    0x2deb(%rip),%rax
mov    (%rax),%edi
lea    -0xc0(%rbp),%rax
imul   $0x18,-0x10(%rbp),%rcx
add    %rcx,%rax
mov    0x10(%rax),%edx
lea    -0xc0(%rbp),%rax
imul   $0x18,-0x10(%rbp),%rcx
add    %rcx,%rax
mov    0x8(%rax),%rcx
mov    -0xcc(%rbp),%r8d
mov    -0xc8(%rbp),%r9
lea    0xe8b(%rip),%rsi
call   1050 <fprintf@plt>
jmp    1269 <prv_test_encode_imm+0x129>
jmp    1240 <prv_test_encode_imm+0x100>
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
jmp    1177 <prv_test_encode_imm+0x37>
lea    0xe7e(%rip),%rdi
call   1030 <printf@plt>
movl   $0x0,-0x4(%rbp)
jmp    127c <prv_test_encode_imm+0x13c>
lea    0xe6e(%rip),%rdi
call   1030 <printf@plt>
movl   $0x1,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0xd0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<prv_test_encode_imm>:
push   %rbp
push   %rbx
push   %rax
lea    0xf5e(%rip),%rdi
call   1040 <printf@plt>
movq   $0x0,(%rsp)
mov    %rsp,%rsi
mov    $0xad,%edi
call   1050 <subtilis_arm_encode_imm@plt>
mov    $0x1,%ebp
cmp    $0x1,%eax
jne    11a5 <prv_test_encode_imm+0x65>
xor    %ebx,%ebx
cmpq   $0xad,(%rsp)
jne    11a9 <prv_test_encode_imm+0x69>
movq   $0x0,(%rsp)
mov    %rsp,%rsi
mov    $0x101,%edi
call   1050 <subtilis_arm_encode_imm@plt>
mov    $0x1,%ecx
test   %eax,%eax
jne    11b5 <prv_test_encode_imm+0x75>
xor    %ebx,%ebx
cmpq   $0x0,(%rsp)
je     11f8 <prv_test_encode_imm+0xb8>
xor    %eax,%eax
jmp    11b5 <prv_test_encode_imm+0x75>
xor    %ecx,%ecx
jmp    11b0 <prv_test_encode_imm+0x70>
xor    %ecx,%ecx
mov    $0x1,%eax
mov    $0x1,%ebx
mov    0x2e24(%rip),%rdx
mov    (%rdx),%edi
lea    (%rcx,%rcx,2),%rcx
lea    0xe37(%rip),%rdx
mov    0x8(%rdx,%rcx,8),%rcx
mov    (%rsp),%r9
lea    0xee3(%rip),%rsi
mov    %ebx,%edx
mov    %eax,%r8d
call   1060 <fprintf@plt>
lea    0xef3(%rip),%rdi
call   1030 <puts@plt>
mov    %ebp,%eax
add    $0x8,%rsp
pop    %rbx
pop    %rbp
ret
movq   $0x0,(%rsp)
mov    %rsp,%rsi
mov    $0x4e00,%edi
call   1050 <subtilis_arm_encode_imm@plt>
mov    $0x2,%ecx
cmp    $0x1,%eax
jne    11b0 <prv_test_encode_imm+0x70>
cmpq   $0xc4e,(%rsp)
jne    11ab <prv_test_encode_imm+0x6b>
movq   $0x0,(%rsp)
mov    %rsp,%rsi
mov    $0x3fc00,%edi
call   1050 <subtilis_arm_encode_imm@plt>
mov    $0x3,%ecx
cmp    $0x1,%eax
jne    11b0 <prv_test_encode_imm+0x70>
cmpq   $0xbff,(%rsp)
jne    11ab <prv_test_encode_imm+0x6b>
movq   $0x0,(%rsp)
mov    %rsp,%rsi
mov    $0x102,%edi
call   1050 <subtilis_arm_encode_imm@plt>
mov    $0x4,%ecx
test   %eax,%eax
jne    11b5 <prv_test_encode_imm+0x75>
cmpq   $0x0,(%rsp)
jne    11a1 <prv_test_encode_imm+0x61>
movq   $0x0,(%rsp)
mov    %rsp,%rsi
mov    $0xff0000ff,%edi
call   1050 <subtilis_arm_encode_imm@plt>
mov    $0x5,%ecx
test   %eax,%eax
jne    11b5 <prv_test_encode_imm+0x75>
cmpq   $0x0,(%rsp)
mov    $0x0,%eax
jne    11b5 <prv_test_encode_imm+0x75>
movq   $0x0,(%rsp)
mov    %rsp,%rsi
mov    $0xc0000034,%edi
call   1050 <subtilis_arm_encode_imm@plt>
mov    $0x6,%ecx
cmp    $0x1,%eax
jne    11b0 <prv_test_encode_imm+0x70>
cmpq   $0x1d3,(%rsp)
mov    $0x1,%eax
mov    $0x1,%ebx
jne    11b5 <prv_test_encode_imm+0x75>
xor    %ebp,%ebp
lea    0xde1(%rip),%rdi
jmp    11ea <prv_test_encode_imm+0xaa>

LLVM IR (-O0):
%struct.test = type { i32, i64, i32 }
@__const.prv_test_encode_imm.tests = [7 x %struct.test] [%struct.test { i32 173, i64 173, i32 1 }, %struct.test { i32 257, i64 0, i32 0 }, %struct.test { i32 19968, i64 3150, i32 1 }, %struct.test { i32 261120, i64 3071, i32 1 }, %struct.test { i32 258, i64 0, i32 0 }, %struct.test { i32 -16776961, i64 0, i32 0 }, %struct.test { i32 -1073741772, i64 467, i32 1 }]
@.str = [20 x i8] c"arm_core_encode_imm\00"
@stderr = global i32 0
@.str.1 = [26 x i8] c"Expected %d %u got %d %u\0A\00"
@.str.2 = [8 x i8] c": [OK]\0A\00"
@.str.3 = [10 x i8] c": [FAIL]\0A\00"
define i32 @prv_test_encode_imm() {
%1 = alloca i32
%2 = alloca i64
%3 = alloca [7 x %struct.test]
%4 = alloca i64
%5 = alloca i32
%6 = bitcast [7 x %struct.test]* %3 to i8*
%7 = call i32 @printf(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str, i64 0, i64 0))
store i64 0, i64* %2
br label %8
8: ; preds = %44, %0
%9 = load i64, i64* %2
%10 = icmp ult i64 %9, 7
br i1 %10, label %11, label %47
11: ; preds = %8
store i64 0, i64* %4
%12 = load i64, i64* %2
%13 = getelementptr inbounds [7 x %struct.test], [7 x %struct.test]* %3, i64 0, i64 %12
%14 = getelementptr inbounds %struct.test, %struct.test* %13, i32 0, i32 0
%15 = load i32, i32* %14
%16 = call i32 @subtilis_arm_encode_imm(i32 %15, i64* %4)
store i32 %16, i32* %5
%17 = load i32, i32* %5
%18 = load i64, i64* %2
%19 = getelementptr inbounds [7 x %struct.test], [7 x %struct.test]* %3, i64 0, i64 %18
%20 = getelementptr inbounds %struct.test, %struct.test* %19, i32 0, i32 2
%21 = load i32, i32* %20
%22 = icmp ne i32 %17, %21
br i1 %22, label %30, label %23
23: ; preds = %11
%24 = load i64, i64* %4
%25 = load i64, i64* %2
%26 = getelementptr inbounds [7 x %struct.test], [7 x %struct.test]* %3, i64 0, i64 %25
%27 = getelementptr inbounds %struct.test, %struct.test* %26, i32 0, i32 1
%28 = load i64, i64* %27
%29 = icmp ne i64 %24, %28
br i1 %29, label %30, label %43
30: ; preds = %23, %11
%31 = load i32, i32* @stderr
%32 = load i64, i64* %2
%33 = getelementptr inbounds [7 x %struct.test], [7 x %struct.test]* %3, i64 0, i64 %32
%34 = getelementptr inbounds %struct.test, %struct.test* %33, i32 0, i32 2
%35 = load i32, i32* %34
%36 = load i64, i64* %2
%37 = getelementptr inbounds [7 x %struct.test], [7 x %struct.test]* %3, i64 0, i64 %36
%38 = getelementptr inbounds %struct.test, %struct.test* %37, i32 0, i32 1
%39 = load i64, i64* %38
%40 = load i32, i32* %5
%41 = load i64, i64* %4
%42 = call i32 @fprintf(i32 %31, i8* getelementptr inbounds ([26 x i8], [26 x i8]* @.str.1, i64 0, i64 0), i32 %35, i64 %39, i32 %40, i64 %41)
br label %49
43: ; preds = %23
br label %44
44: ; preds = %43
%45 = load i64, i64* %2
%46 = add i64 %45, 1
store i64 %46, i64* %2
br label %8
47: ; preds = %8
%48 = call i32 @printf(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.2, i64 0, i64 0))
store i32 0, i32* %1
br label %51
49: ; preds = %30
%50 = call i32 @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.3, i64 0, i64 0))
store i32 1, i32* %1
br label %51
51: ; preds = %49, %47
%52 = load i32, i32* %1
ret i32 %52
}

LLVM IR (-O2):
%struct.test = type { i32, i64, i32 }
@__const.prv_test_encode_imm.tests = [7 x %struct.test] [%struct.test { i32 173, i64 173, i32 1 }, %struct.test { i32 257, i64 0, i32 0 }, %struct.test { i32 19968, i64 3150, i32 1 }, %struct.test { i32 261120, i64 3071, i32 1 }, %struct.test { i32 258, i64 0, i32 0 }, %struct.test { i32 -16776961, i64 0, i32 0 }, %struct.test { i32 -1073741772, i64 467, i32 1 }]
@.str = [20 x i8] c"arm_core_encode_imm\00"
@stderr = global i32 0
@.str.1 = [26 x i8] c"Expected %d %u got %d %u\0A\00"
@str = [7 x i8] c": [OK]\00"
@str.4 = [9 x i8] c": [FAIL]\00"
define i32 @prv_test_encode_imm() {
%1 = alloca i64
%2 = bitcast i64* %1 to i8*
%3 = tail call i32 @printf(i8* dereferenceable(1) getelementptr inbounds ([20 x i8], [20 x i8]* @.str, i64 0, i64 0))
store i64 0, i64* %1
%4 = call i32 @subtilis_arm_encode_imm(i32 173, i64* %1)
%5 = icmp eq i32 %4, 1
br i1 %5, label %6, label %9
6: ; preds = %0
%7 = load i64, i64* %1
%8 = icmp eq i64 %7, 173
br i1 %8, label %18, label %9
9: ; preds = %51, %48, %45, %42, %39, %36, %33, %30, %27, %24, %21, %18, %6, %0
%10 = phi i64 [ 0, %6 ], [ 0, %0 ], [ 1, %18 ], [ 1, %21 ], [ 2, %24 ], [ 2, %27 ], [ 3, %30 ], [ 3, %33 ], [ 4, %36 ], [ 4, %39 ], [ 5, %42 ], [ 5, %45 ], [ 6, %48 ], [ 6, %51 ]
%11 = phi i32 [ 1, %6 ], [ %4, %0 ], [ %19, %18 ], [ 0, %21 ], [ %25, %24 ], [ 1, %27 ], [ %31, %30 ], [ 1, %33 ], [ %37, %36 ], [ 0, %39 ], [ %43, %42 ], [ 0, %45 ], [ %49, %48 ], [ 1, %51 ]
%12 = phi i32 [ 1, %6 ], [ 1, %0 ], [ 0, %18 ], [ 0, %21 ], [ 1, %24 ], [ 1, %27 ], [ 1, %30 ], [ 1, %33 ], [ 0, %36 ], [ 0, %39 ], [ 0, %42 ], [ 0, %45 ], [ 1, %48 ], [ 1, %51 ]
%13 = load i32, i32* @stderr
%14 = getelementptr inbounds [7 x %struct.test], [7 x %struct.test]* @__const.prv_test_encode_imm.tests, i64 0, i64 %10, i32 1
%15 = load i64, i64* %14
%16 = load i64, i64* %1
%17 = call i32 @fprintf(i32 %13, i8* getelementptr inbounds ([26 x i8], [26 x i8]* @.str.1, i64 0, i64 0), i32 %12, i64 %15, i32 %11, i64 %16)
br label %54
18: ; preds = %6
store i64 0, i64* %1
%19 = call i32 @subtilis_arm_encode_imm(i32 257, i64* %1)
%20 = icmp eq i32 %19, 0
br i1 %20, label %21, label %9
21: ; preds = %18
%22 = load i64, i64* %1
%23 = icmp eq i64 %22, 0
br i1 %23, label %24, label %9
24: ; preds = %21
store i64 0, i64* %1
%25 = call i32 @subtilis_arm_encode_imm(i32 19968, i64* %1)
%26 = icmp eq i32 %25, 1
br i1 %26, label %27, label %9
27: ; preds = %24
%28 = load i64, i64* %1
%29 = icmp eq i64 %28, 3150
br i1 %29, label %30, label %9
30: ; preds = %27
store i64 0, i64* %1
%31 = call i32 @subtilis_arm_encode_imm(i32 261120, i64* %1)
%32 = icmp eq i32 %31, 1
br i1 %32, label %33, label %9
33: ; preds = %30
%34 = load i64, i64* %1
%35 = icmp eq i64 %34, 3071
br i1 %35, label %36, label %9
36: ; preds = %33
store i64 0, i64* %1
%37 = call i32 @subtilis_arm_encode_imm(i32 258, i64* %1)
%38 = icmp eq i32 %37, 0
br i1 %38, label %39, label %9
39: ; preds = %36
%40 = load i64, i64* %1
%41 = icmp eq i64 %40, 0
br i1 %41, label %42, label %9
42: ; preds = %39
store i64 0, i64* %1
%43 = call i32 @subtilis_arm_encode_imm(i32 -16776961, i64* %1)
%44 = icmp eq i32 %43, 0
br i1 %44, label %45, label %9
45: ; preds = %42
%46 = load i64, i64* %1
%47 = icmp eq i64 %46, 0
br i1 %47, label %48, label %9
48: ; preds = %45
store i64 0, i64* %1
%49 = call i32 @subtilis_arm_encode_imm(i32 -1073741772, i64* %1)
%50 = icmp eq i32 %49, 1
br i1 %50, label %51, label %9
51: ; preds = %48
%52 = load i64, i64* %1
%53 = icmp eq i64 %52, 467
br i1 %53, label %54, label %9
54: ; preds = %51, %9
%55 = phi i8* [ getelementptr inbounds ([9 x i8], [9 x i8]* @str.4, i64 0, i64 0), %9 ], [ getelementptr inbounds ([7 x i8], [7 x i8]* @str, i64 0, i64 0), %51 ]
%56 = phi i32 [ 1, %9 ], [ 0, %51 ]
%57 = call i32 @puts(i8* dereferenceable(1) %55)
ret i32 %56
}