#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 */
struct uio_map {
  int dummy;
};

/* Variables and functions */
unsigned long read_reg(struct uio_map *, int);
int /*<<< orphan*/ write_reg(struct uio_map *, unsigned long, int);
void set_scale(struct uio_map *ump, int vertical, int size_in, int size_out) {
  unsigned long fixpoint, mant, frac, value, vb;
  fixpoint = (4096 * (size_in - 1)) / (size_out + 1);
  mant = fixpoint / 4096;
  frac = fixpoint - (mant * 4096);
  if (frac & 0x07) {
    frac &= ~0x07;
    if (size_out > size_in)
      frac -= 8;
    else
      frac += 8;
  }
  if (size_in == size_out) {
    mant = 0;
    frac = 0;
  }
  value = read_reg(ump, 0x54);
  if (vertical) {
    value &= ~0xffff0000;
    value |= ((mant << 12) | frac) << 16;
  } else {
    value &= ~0xffff;
    value |= (mant << 12) | frac;
  }
  write_reg(ump, value, 0x54);
  value = read_reg(ump, 0x58);
  if (vertical) {
    value &= ~0xffff0000;
    value |= size_out << 16;
  } else {
    value &= ~0xffff;
    value |= size_out;
  }
  write_reg(ump, value, 0x58);
  if (size_out >= size_in)
    vb = 64;
  else {
    if ((mant >= 8) && (mant < 16))
      value = 4;
    else if ((mant >= 4) && (mant < 8))
      value = 2;
    else
      value = 1;
    vb = 64 * 4096 * value;
    vb /= 4096 * mant + frac;
  }
  value = read_reg(ump, 0xc8);
  if (vertical) {
    value &= ~0xffff0000;
    value |= vb << 16;
  } else {
    value &= ~0xffff;
    value |= vb;
  }
  write_reg(ump, value, 0xc8);
}


x86 assembly (clang, -O0):
<set_scale>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
mov    %ecx,-0x14(%rbp)
mov    -0x10(%rbp),%eax
sub    $0x1,%eax
shl    $0xc,%eax
mov    -0x14(%rbp),%ecx
add    $0x1,%ecx
cltd
idiv   %ecx
cltq
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rax
shr    $0xc,%rax
mov    %rax,-0x28(%rbp)
mov    -0x20(%rbp),%rax
mov    -0x28(%rbp),%rcx
shl    $0xc,%rcx
sub    %rcx,%rax
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rax
and    $0x7,%rax
cmp    $0x0,%rax
je     11b8 <set_scale+0x98>
mov    -0x30(%rbp),%rax
and    $0xfffffffffffffff8,%rax
mov    %rax,-0x30(%rbp)
mov    -0x14(%rbp),%eax
cmp    -0x10(%rbp),%eax
jle    11a7 <set_scale+0x87>
mov    -0x30(%rbp),%rax
sub    $0x8,%rax
mov    %rax,-0x30(%rbp)
jmp    11b3 <set_scale+0x93>
mov    -0x30(%rbp),%rax
add    $0x8,%rax
mov    %rax,-0x30(%rbp)
jmp    11b8 <set_scale+0x98>
mov    -0x10(%rbp),%eax
cmp    -0x14(%rbp),%eax
jne    11d4 <set_scale+0xb4>
movq   $0x0,-0x28(%rbp)
movq   $0x0,-0x30(%rbp)
mov    -0x8(%rbp),%rdi
mov    $0x54,%esi
call   1040 <read_reg@plt>
mov    %rax,-0x38(%rbp)
cmpl   $0x0,-0xc(%rbp)
je     121b <set_scale+0xfb>
mov    -0x38(%rbp),%rax
and    $0xffff,%rax
mov    %rax,-0x38(%rbp)
mov    -0x28(%rbp),%rax
shl    $0xc,%rax
or     -0x30(%rbp),%rax
shl    $0x10,%rax
or     -0x38(%rbp),%rax
mov    %rax,-0x38(%rbp)
jmp    123d <set_scale+0x11d>
mov    -0x38(%rbp),%rax
and    $0xffffffffffff0000,%rax
mov    %rax,-0x38(%rbp)
mov    -0x28(%rbp),%rax
shl    $0xc,%rax
or     -0x30(%rbp),%rax
or     -0x38(%rbp),%rax
mov    %rax,-0x38(%rbp)
mov    -0x8(%rbp),%rdi
mov    -0x38(%rbp),%rsi
mov    $0x54,%edx
call   1030 <write_reg@plt>
mov    -0x8(%rbp),%rdi
mov    $0x58,%esi
call   1040 <read_reg@plt>
mov    %rax,-0x38(%rbp)
cmpl   $0x0,-0xc(%rbp)
je     128e <set_scale+0x16e>
mov    -0x38(%rbp),%rax
and    $0xffff,%rax
mov    %rax,-0x38(%rbp)
mov    -0x14(%rbp),%eax
shl    $0x10,%eax
cltq
or     -0x38(%rbp),%rax
mov    %rax,-0x38(%rbp)
jmp    12a8 <set_scale+0x188>
mov    -0x38(%rbp),%rax
and    $0xffffffffffff0000,%rax
mov    %rax,-0x38(%rbp)
movslq -0x14(%rbp),%rax
or     -0x38(%rbp),%rax
mov    %rax,-0x38(%rbp)
mov    -0x8(%rbp),%rdi
mov    -0x38(%rbp),%rsi
mov    $0x58,%edx
call   1030 <write_reg@plt>
mov    -0x14(%rbp),%eax
cmp    -0x10(%rbp),%eax
jl     12d3 <set_scale+0x1b3>
movq   $0x40,-0x40(%rbp)
jmp    134b <set_scale+0x22b>
cmpq   $0x8,-0x28(%rbp)
jb     12f6 <set_scale+0x1d6>
cmpq   $0x10,-0x28(%rbp)
jae    12f6 <set_scale+0x1d6>
movq   $0x4,-0x38(%rbp)
jmp    1326 <set_scale+0x206>
cmpq   $0x4,-0x28(%rbp)
jb     1319 <set_scale+0x1f9>
cmpq   $0x8,-0x28(%rbp)
jae    1319 <set_scale+0x1f9>
movq   $0x2,-0x38(%rbp)
jmp    1321 <set_scale+0x201>
movq   $0x1,-0x38(%rbp)
jmp    1326 <set_scale+0x206>
mov    -0x38(%rbp),%rax
shl    $0x12,%rax
mov    %rax,-0x40(%rbp)
mov    -0x28(%rbp),%rcx
shl    $0xc,%rcx
add    -0x30(%rbp),%rcx
mov    -0x40(%rbp),%rax
xor    %edx,%edx
div    %rcx
mov    %rax,-0x40(%rbp)
mov    -0x8(%rbp),%rdi
mov    $0xc8,%esi
call   1040 <read_reg@plt>
mov    %rax,-0x38(%rbp)
cmpl   $0x0,-0xc(%rbp)
je     138a <set_scale+0x26a>
mov    -0x38(%rbp),%rax
and    $0xffff,%rax
mov    %rax,-0x38(%rbp)
mov    -0x40(%rbp),%rax
shl    $0x10,%rax
or     -0x38(%rbp),%rax
mov    %rax,-0x38(%rbp)
jmp    13a4 <set_scale+0x284>
mov    -0x38(%rbp),%rax
and    $0xffffffffffff0000,%rax
mov    %rax,-0x38(%rbp)
mov    -0x40(%rbp),%rax
or     -0x38(%rbp),%rax
mov    %rax,-0x38(%rbp)
mov    -0x8(%rbp),%rdi
mov    -0x38(%rbp),%rsi
mov    $0xc8,%edx
call   1030 <write_reg@plt>
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<set_scale>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
push   %rax
mov    %ecx,%r13d
mov    %edx,%r12d
mov    %esi,0x4(%rsp)
mov    %rdi,%r15
mov    %edx,%eax
shl    $0xc,%eax
add    $0xfffff000,%eax
lea    0x1(%r13),%ecx
cltd
idiv   %ecx
mov    %eax,%ebp
cltq
mov    %rax,%r14
shr    $0xc,%r14
test   $0x7,%al
je     1169 <set_scale+0x49>
and    $0xff8,%ebp
cmp    %r12d,%r13d
jle    1171 <set_scale+0x51>
add    $0xfffffffffffffff8,%rbp
jmp    1175 <set_scale+0x55>
and    $0xfff,%ebp
jmp    1175 <set_scale+0x55>
add    $0x8,%rbp
xor    %eax,%eax
cmp    %r13d,%r12d
cmove  %rax,%r14
cmove  %rax,%rbp
mov    %r15,%rdi
mov    $0x54,%esi
call   1040 <read_reg@plt>
cmpl   $0x0,0x4(%rsp)
je     11b4 <set_scale+0x94>
movzwl %ax,%eax
mov    %r14,%rcx
shl    $0x1c,%rcx
mov    %rbp,%rsi
shl    $0x10,%rsi
or     %rcx,%rsi
or     %rax,%rsi
mov    $0xffff,%ebx
jmp    11ce <set_scale+0xae>
and    $0xffffffffffff0000,%rax
mov    %r14,%rsi
shl    $0xc,%rsi
or     %rbp,%rsi
or     %rax,%rsi
mov    $0xffffffffffff0000,%rbx
mov    %r15,%rdi
mov    $0x54,%edx
call   1030 <write_reg@plt>
mov    %r15,%rdi
mov    $0x58,%esi
call   1040 <read_reg@plt>
mov    %r13d,%ecx
shl    $0x10,%ecx
cmpl   $0x0,0x4(%rsp)
cmove  %r13d,%ecx
and    %rax,%rbx
movslq %ecx,%rsi
or     %rbx,%rsi
mov    %r15,%rdi
mov    $0x58,%edx
call   1030 <write_reg@plt>
mov    $0x40,%ebx
cmp    %r12d,%r13d
jge    1266 <set_scale+0x146>
mov    %r14,%rax
and    $0xfffffffffffffff8,%rax
movabs $0xffffffffffff8,%rcx
or     $0x4,%rcx
and    %r14,%rcx
xor    %edx,%edx
cmp    $0x4,%rcx
sete   %dl
shl    $0x12,%rdx
add    $0x40000,%rdx
cmp    $0x8,%rax
mov    $0x100000,%eax
cmovne %rdx,%rax
shl    $0xc,%r14
add    %r14,%rbp
cmp    %rbp,%rax
jb     1264 <set_scale+0x144>
xor    %edx,%edx
div    %ebp
mov    %eax,%ebx
jmp    1266 <set_scale+0x146>
xor    %ebx,%ebx
mov    %r15,%rdi
mov    $0xc8,%esi
call   1040 <read_reg@plt>
cmpl   $0x0,0x4(%rsp)
je     1283 <set_scale+0x163>
movzwl %ax,%eax
shl    $0x10,%rbx
jmp    1289 <set_scale+0x169>
and    $0xffffffffffff0000,%rax
or     %rax,%rbx
mov    %r15,%rdi
mov    %rbx,%rsi
mov    $0xc8,%edx
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
jmp    1030 <write_reg@plt>

LLVM IR (-O0):
%struct.uio_map = type { i32 }
define void @set_scale(%struct.uio_map* %0, i32 %1, i32 %2, i32 %3) {
%5 = alloca %struct.uio_map*
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
%9 = alloca i64
%10 = alloca i64
%11 = alloca i64
%12 = alloca i64
%13 = alloca i64
store %struct.uio_map* %0, %struct.uio_map** %5
store i32 %1, i32* %6
store i32 %2, i32* %7
store i32 %3, i32* %8
%14 = load i32, i32* %7
%15 = sub nsw i32 %14, 1
%16 = mul nsw i32 4096, %15
%17 = load i32, i32* %8
%18 = add nsw i32 %17, 1
%19 = sdiv i32 %16, %18
%20 = sext i32 %19 to i64
store i64 %20, i64* %9
%21 = load i64, i64* %9
%22 = udiv i64 %21, 4096
store i64 %22, i64* %10
%23 = load i64, i64* %9
%24 = load i64, i64* %10
%25 = mul i64 %24, 4096
%26 = sub i64 %23, %25
store i64 %26, i64* %11
%27 = load i64, i64* %11
%28 = and i64 %27, 7
%29 = icmp ne i64 %28, 0
br i1 %29, label %30, label %43
30: ; preds = %4
%31 = load i64, i64* %11
%32 = and i64 %31, -8
store i64 %32, i64* %11
%33 = load i32, i32* %8
%34 = load i32, i32* %7
%35 = icmp sgt i32 %33, %34
br i1 %35, label %36, label %39
36: ; preds = %30
%37 = load i64, i64* %11
%38 = sub i64 %37, 8
store i64 %38, i64* %11
br label %42
39: ; preds = %30
%40 = load i64, i64* %11
%41 = add i64 %40, 8
store i64 %41, i64* %11
br label %42
42: ; preds = %39, %36
br label %43
43: ; preds = %42, %4
%44 = load i32, i32* %7
%45 = load i32, i32* %8
%46 = icmp eq i32 %44, %45
br i1 %46, label %47, label %48
47: ; preds = %43
store i64 0, i64* %10
store i64 0, i64* %11
br label %48
48: ; preds = %47, %43
%49 = load %struct.uio_map*, %struct.uio_map** %5
%50 = call i64 @read_reg(%struct.uio_map* %49, i32 84)
store i64 %50, i64* %12
%51 = load i32, i32* %6
%52 = icmp ne i32 %51, 0
br i1 %52, label %53, label %63
53: ; preds = %48
%54 = load i64, i64* %12
%55 = and i64 %54, 65535
store i64 %55, i64* %12
%56 = load i64, i64* %10
%57 = shl i64 %56, 12
%58 = load i64, i64* %11
%59 = or i64 %57, %58
%60 = shl i64 %59, 16
%61 = load i64, i64* %12
%62 = or i64 %61, %60
store i64 %62, i64* %12
br label %72
63: ; preds = %48
%64 = load i64, i64* %12
%65 = and i64 %64, -65536
store i64 %65, i64* %12
%66 = load i64, i64* %10
%67 = shl i64 %66, 12
%68 = load i64, i64* %11
%69 = or i64 %67, %68
%70 = load i64, i64* %12
%71 = or i64 %70, %69
store i64 %71, i64* %12
br label %72
72: ; preds = %63, %53
%73 = load %struct.uio_map*, %struct.uio_map** %5
%74 = load i64, i64* %12
%75 = call i32 @write_reg(%struct.uio_map* %73, i64 %74, i32 84)
%76 = load %struct.uio_map*, %struct.uio_map** %5
%77 = call i64 @read_reg(%struct.uio_map* %76, i32 88)
store i64 %77, i64* %12
%78 = load i32, i32* %6
%79 = icmp ne i32 %78, 0
br i1 %79, label %80, label %88
80: ; preds = %72
%81 = load i64, i64* %12
%82 = and i64 %81, 65535
store i64 %82, i64* %12
%83 = load i32, i32* %8
%84 = shl i32 %83, 16
%85 = sext i32 %84 to i64
%86 = load i64, i64* %12
%87 = or i64 %86, %85
store i64 %87, i64* %12
br label %95
88: ; preds = %72
%89 = load i64, i64* %12
%90 = and i64 %89, -65536
store i64 %90, i64* %12
%91 = load i32, i32* %8
%92 = sext i32 %91 to i64
%93 = load i64, i64* %12
%94 = or i64 %93, %92
store i64 %94, i64* %12
br label %95
95: ; preds = %88, %80
%96 = load %struct.uio_map*, %struct.uio_map** %5
%97 = load i64, i64* %12
%98 = call i32 @write_reg(%struct.uio_map* %96, i64 %97, i32 88)
%99 = load i32, i32* %8
%100 = load i32, i32* %7
%101 = icmp sge i32 %99, %100
br i1 %101, label %102, label %103
102: ; preds = %95
store i64 64, i64* %13
br label %128
103: ; preds = %95
%104 = load i64, i64* %10
%105 = icmp uge i64 %104, 8
br i1 %105, label %106, label %110
106: ; preds = %103
%107 = load i64, i64* %10
%108 = icmp ult i64 %107, 16
br i1 %108, label %109, label %110
109: ; preds = %106
store i64 4, i64* %12
br label %119
110: ; preds = %106, %103
%111 = load i64, i64* %10
%112 = icmp uge i64 %111, 4
br i1 %112, label %113, label %117
113: ; preds = %110
%114 = load i64, i64* %10
%115 = icmp ult i64 %114, 8
br i1 %115, label %116, label %117
116: ; preds = %113
store i64 2, i64* %12
br label %118
117: ; preds = %113, %110
store i64 1, i64* %12
br label %118
118: ; preds = %117, %116
br label %119
119: ; preds = %118, %109
%120 = load i64, i64* %12
%121 = mul i64 262144, %120
store i64 %121, i64* %13
%122 = load i64, i64* %10
%123 = mul i64 4096, %122
%124 = load i64, i64* %11
%125 = add i64 %123, %124
%126 = load i64, i64* %13
%127 = udiv i64 %126, %125
store i64 %127, i64* %13
br label %128
128: ; preds = %119, %102
%129 = load %struct.uio_map*, %struct.uio_map** %5
%130 = call i64 @read_reg(%struct.uio_map* %129, i32 200)
store i64 %130, i64* %12
%131 = load i32, i32* %6
%132 = icmp ne i32 %131, 0
br i1 %132, label %133, label %140
133: ; preds = %128
%134 = load i64, i64* %12
%135 = and i64 %134, 65535
store i64 %135, i64* %12
%136 = load i64, i64* %13
%137 = shl i64 %136, 16
%138 = load i64, i64* %12
%139 = or i64 %138, %137
store i64 %139, i64* %12
br label %146
140: ; preds = %128
%141 = load i64, i64* %12
%142 = and i64 %141, -65536
store i64 %142, i64* %12
%143 = load i64, i64* %13
%144 = load i64, i64* %12
%145 = or i64 %144, %143
store i64 %145, i64* %12
br label %146
146: ; preds = %140, %133
%147 = load %struct.uio_map*, %struct.uio_map** %5
%148 = load i64, i64* %12
%149 = call i32 @write_reg(%struct.uio_map* %147, i64 %148, i32 200)
ret void
}

LLVM IR (-O2):
%struct.uio_map = type { i32 }
define void @set_scale(%struct.uio_map* %0, i32 %1, i32 %2, i32 %3) {
%5 = shl i32 %2, 12
%6 = add i32 %5, -4096
%7 = add nsw i32 %3, 1
%8 = sdiv i32 %6, %7
%9 = sext i32 %8 to i64
%10 = lshr i64 %9, 12
%11 = and i64 %9, 4095
%12 = and i64 %9, 7
%13 = icmp eq i64 %12, 0
br i1 %13, label %21, label %14
14: ; preds = %4
%15 = and i64 %9, 4088
%16 = icmp sgt i32 %3, %2
br i1 %16, label %17, label %19
17: ; preds = %14
%18 = add nsw i64 %15, -8
br label %21
19: ; preds = %14
%20 = add nuw nsw i64 %15, 8
br label %21
21: ; preds = %17, %19, %4
%22 = phi i64 [ %18, %17 ], [ %20, %19 ], [ %11, %4 ]
%23 = icmp eq i32 %2, %3
%24 = select i1 %23, i64 0, i64 %10
%25 = select i1 %23, i64 0, i64 %22
%26 = tail call i64 @read_reg(%struct.uio_map* %0, i32 84)
%27 = icmp eq i32 %1, 0
br i1 %27, label %34, label %28
28: ; preds = %21
%29 = and i64 %26, 65535
%30 = shl i64 %24, 28
%31 = shl nsw i64 %25, 16
%32 = or i64 %31, %30
%33 = or i64 %32, %29
br label %39
34: ; preds = %21
%35 = and i64 %26, -65536
%36 = shl nuw i64 %24, 12
%37 = or i64 %25, %36
%38 = or i64 %37, %35
br label %39
39: ; preds = %34, %28
%40 = phi i64 [ -65536, %34 ], [ 65535, %28 ]
%41 = phi i64 [ %38, %34 ], [ %33, %28 ]
%42 = tail call i32 @write_reg(%struct.uio_map* %0, i64 %41, i32 84)
%43 = tail call i64 @read_reg(%struct.uio_map* %0, i32 88)
%44 = shl i32 %3, 16
%45 = select i1 %27, i32 %3, i32 %44
%46 = and i64 %43, %40
%47 = sext i32 %45 to i64
%48 = or i64 %46, %47
%49 = tail call i32 @write_reg(%struct.uio_map* %0, i64 %48, i32 88)
%50 = icmp slt i32 %3, %2
br i1 %50, label %51, label %61
51: ; preds = %39
%52 = and i64 %24, 4503599627370488
%53 = icmp eq i64 %52, 8
%54 = and i64 %24, 4503599627370492
%55 = icmp eq i64 %54, 4
%56 = select i1 %55, i64 524288, i64 262144
%57 = select i1 %53, i64 1048576, i64 %56
%58 = shl nuw i64 %24, 12
%59 = add i64 %25, %58
%60 = udiv i64 %57, %59
br label %61
61: ; preds = %39, %51
%62 = phi i64 [ %60, %51 ], [ 64, %39 ]
%63 = tail call i64 @read_reg(%struct.uio_map* %0, i32 200)
br i1 %27, label %68, label %64
64: ; preds = %61
%65 = and i64 %63, 65535
%66 = shl nuw nsw i64 %62, 16
%67 = or i64 %65, %66
br label %71
68: ; preds = %61
%69 = and i64 %63, -65536
%70 = or i64 %69, %62
br label %71
71: ; preds = %68, %64
%72 = phi i64 [ %67, %64 ], [ %70, %68 ]
%73 = tail call i32 @write_reg(%struct.uio_map* %0, i64 %72, i32 200)
ret void
}