#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__ uint8_t;
typedef int /*<<< orphan*/ tests;

/* Variables and functions */
int /*<<< orphan*/ fprintf(int /*<<< orphan*/, char *, int, scalar_t__, int,
                           scalar_t__);
int /*<<< orphan*/ printf(char *);
int /*<<< orphan*/ stderr;
int subtilis_fpa_encode_real(double, scalar_t__ *);
int prv_test_encode_imm(void) {
  struct test {
    double num;
    uint8_t encoded;
    bool ok;
  };
  size_t i;
  struct test tests[] = {
      {0.0, 0x8, true}, {1.0, 0x9, true}, {3.0, 0xB, true},  {4.0, 0xC, true},
      {5.0, 0xD, true}, {0.5, 0xE, true}, {10.0, 0xF, true}, {-1.0, 0, false},
      {11.0, 0, false}, {1.1, 0, false},
  };
  uint8_t encoded;
  bool ok;
  printf("fpa_encode_imm");
  for (i = 0; i < sizeof(tests) / sizeof(struct test); i++) {
    encoded = 0;
    ok = subtilis_fpa_encode_real(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    $0x110,%rsp
lea    -0x100(%rbp),%rdi
lea    0xea7(%rip),%rsi
mov    $0xf0,%edx
call   1050 <memcpy@plt>
lea    0xf86(%rip),%rdi
call   1030 <printf@plt>
movq   $0x0,-0x10(%rbp)
cmpq   $0xa,-0x10(%rbp)
jae    1253 <prv_test_encode_imm+0x113>
movq   $0x0,-0x108(%rbp)
lea    -0x100(%rbp),%rax
imul   $0x18,-0x10(%rbp),%rcx
add    %rcx,%rax
movsd  (%rax),%xmm0
lea    -0x108(%rbp),%rdi
call   1060 <subtilis_fpa_encode_real@plt>
mov    %eax,-0x10c(%rbp)
mov    -0x10c(%rbp),%eax
lea    -0x100(%rbp),%rcx
imul   $0x18,-0x10(%rbp),%rdx
add    %rdx,%rcx
cmp    0x10(%rcx),%eax
jne    11f0 <prv_test_encode_imm+0xb0>
mov    -0x108(%rbp),%rax
lea    -0x100(%rbp),%rcx
imul   $0x18,-0x10(%rbp),%rdx
add    %rdx,%rcx
cmp    0x8(%rcx),%rax
je     123d <prv_test_encode_imm+0xfd>
mov    0x2de9(%rip),%rax
mov    (%rax),%edi
lea    -0x100(%rbp),%rax
imul   $0x18,-0x10(%rbp),%rcx
add    %rcx,%rax
mov    0x10(%rax),%edx
lea    -0x100(%rbp),%rax
imul   $0x18,-0x10(%rbp),%rcx
add    %rcx,%rax
mov    0x8(%rax),%rcx
mov    -0x10c(%rbp),%r8d
mov    -0x108(%rbp),%r9
lea    0xecc(%rip),%rsi
call   1040 <fprintf@plt>
jmp    126b <prv_test_encode_imm+0x12b>
jmp    1242 <prv_test_encode_imm+0x102>
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
jmp    1177 <prv_test_encode_imm+0x37>
lea    0xebf(%rip),%rdi
call   1030 <printf@plt>
movl   $0x0,-0x4(%rbp)
jmp    127e <prv_test_encode_imm+0x13e>
lea    0xeaf(%rip),%rdi
call   1030 <printf@plt>
movl   $0x1,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x110,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<prv_test_encode_imm>:
push   %r15
push   %r14
push   %r12
push   %rbx
push   %rax
lea    0xfa1(%rip),%rdi
call   1040 <printf@plt>
mov    $0x10,%ebx
lea    0xea0(%rip),%r12
mov    %rsp,%r15
lea    0xfaf(%rip),%r14
nopw   0x0(%rax,%rax,1)
movq   $0x0,(%rsp)
movsd  -0x10(%rbx,%r12,1),%xmm0
mov    %r15,%rdi
call   1060 <subtilis_fpa_encode_real@plt>
mov    (%rbx,%r12,1),%edx
cmp    %edx,%eax
jne    11ae <prv_test_encode_imm+0x6e>
mov    (%rsp),%r9
mov    -0x8(%rbx,%r12,1),%rcx
cmp    %rcx,%r9
jne    11b9 <prv_test_encode_imm+0x79>
add    $0x18,%rbx
cmp    $0x100,%rbx
jne    1170 <prv_test_encode_imm+0x30>
xor    %ebx,%ebx
jmp    11df <prv_test_encode_imm+0x9f>
mov    -0x8(%rbx,%r12,1),%rcx
mov    (%rsp),%r9
jmp    11bb <prv_test_encode_imm+0x7b>
mov    %eax,%edx
mov    0x2e1e(%rip),%rsi
mov    (%rsi),%edi
lea    0xf34(%rip),%rsi
mov    %eax,%r8d
call   1050 <fprintf@plt>
mov    $0x1,%ebx
lea    0xf41(%rip),%r14
mov    %r14,%rdi
call   1030 <puts@plt>
mov    %ebx,%eax
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
%struct.test = type { double, i64, i32 }
@__const.prv_test_encode_imm.tests = [10 x %struct.test] [%struct.test { double 0.000000e+00, i64 8, i32 1 }, %struct.test { double 1.000000e+00, i64 9, i32 1 }, %struct.test { double 3.000000e+00, i64 11, i32 1 }, %struct.test { double 4.000000e+00, i64 12, i32 1 }, %struct.test { double 5.000000e+00, i64 13, i32 1 }, %struct.test { double 5.000000e-01, i64 14, i32 1 }, %struct.test { double 1.000000e+01, i64 15, i32 1 }, %struct.test { double -1.000000e+00, i64 0, i32 0 }, %struct.test { double 1.100000e+01, i64 0, i32 0 }, %struct.test { double 1.100000e+00, i64 0, i32 0 }]
@.str = [15 x i8] c"fpa_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 [10 x %struct.test]
%4 = alloca i64
%5 = alloca i32
%6 = bitcast [10 x %struct.test]* %3 to i8*
%7 = call i32 @printf(i8* getelementptr inbounds ([15 x i8], [15 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, 10
br i1 %10, label %11, label %47
11: ; preds = %8
store i64 0, i64* %4
%12 = load i64, i64* %2
%13 = getelementptr inbounds [10 x %struct.test], [10 x %struct.test]* %3, i64 0, i64 %12
%14 = getelementptr inbounds %struct.test, %struct.test* %13, i32 0, i32 0
%15 = load double, double* %14
%16 = call i32 @subtilis_fpa_encode_real(double %15, i64* %4)
store i32 %16, i32* %5
%17 = load i32, i32* %5
%18 = load i64, i64* %2
%19 = getelementptr inbounds [10 x %struct.test], [10 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 [10 x %struct.test], [10 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 [10 x %struct.test], [10 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 [10 x %struct.test], [10 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 { double, i64, i32 }
@__const.prv_test_encode_imm.tests = [10 x %struct.test] [%struct.test { double 0.000000e+00, i64 8, i32 1 }, %struct.test { double 1.000000e+00, i64 9, i32 1 }, %struct.test { double 3.000000e+00, i64 11, i32 1 }, %struct.test { double 4.000000e+00, i64 12, i32 1 }, %struct.test { double 5.000000e+00, i64 13, i32 1 }, %struct.test { double 5.000000e-01, i64 14, i32 1 }, %struct.test { double 1.000000e+01, i64 15, i32 1 }, %struct.test { double -1.000000e+00, i64 0, i32 0 }, %struct.test { double 1.100000e+01, i64 0, i32 0 }, %struct.test { double 1.100000e+00, i64 0, i32 0 }]
@.str = [15 x i8] c"fpa_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 ([15 x i8], [15 x i8]* @.str, i64 0, i64 0))
br label %4
4: ; preds = %0, %27
%5 = phi i64 [ 0, %0 ], [ %28, %27 ]
store i64 0, i64* %1
%6 = getelementptr inbounds [10 x %struct.test], [10 x %struct.test]* @__const.prv_test_encode_imm.tests, i64 0, i64 %5, i32 0
%7 = load double, double* %6
%8 = call i32 @subtilis_fpa_encode_real(double %7, i64* %1)
%9 = getelementptr inbounds [10 x %struct.test], [10 x %struct.test]* @__const.prv_test_encode_imm.tests, i64 0, i64 %5, i32 2
%10 = load i32, i32* %9
%11 = icmp eq i32 %8, %10
br i1 %11, label %16, label %12
12: ; preds = %4
%13 = getelementptr inbounds [10 x %struct.test], [10 x %struct.test]* @__const.prv_test_encode_imm.tests, i64 0, i64 %5, i32 1
%14 = load i64, i64* %13
%15 = load i64, i64* %1
br label %21
16: ; preds = %4
%17 = load i64, i64* %1
%18 = getelementptr inbounds [10 x %struct.test], [10 x %struct.test]* @__const.prv_test_encode_imm.tests, i64 0, i64 %5, i32 1
%19 = load i64, i64* %18
%20 = icmp eq i64 %17, %19
br i1 %20, label %27, label %21
21: ; preds = %16, %12
%22 = phi i64 [ %15, %12 ], [ %17, %16 ]
%23 = phi i64 [ %14, %12 ], [ %19, %16 ]
%24 = phi i32 [ %10, %12 ], [ %8, %16 ]
%25 = load i32, i32* @stderr
%26 = call i32 @fprintf(i32 %25, i8* getelementptr inbounds ([26 x i8], [26 x i8]* @.str.1, i64 0, i64 0), i32 %24, i64 %23, i32 %8, i64 %22)
br label %30
27: ; preds = %16
%28 = add nuw nsw i64 %5, 1
%29 = icmp eq i64 %28, 10
br i1 %29, label %30, label %4
30: ; preds = %27, %21
%31 = phi i8* [ getelementptr inbounds ([9 x i8], [9 x i8]* @str.4, i64 0, i64 0), %21 ], [ getelementptr inbounds ([7 x i8], [7 x i8]* @str, i64 0, i64 0), %27 ]
%32 = phi i32 [ 1, %21 ], [ 0, %27 ]
%33 = call i32 @puts(i8* dereferenceable(1) %31)
ret i32 %32
}