#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 int uint32_t;
typedef int uint16_t;

/* Variables and functions */
float uf10_to_f32(uint16_t val) {
  union {
    float f;
    uint32_t ui;
  } f32;
  int exponent = (val & 0x03e0) >> 5;
  int mantissa = (val & 0x001f);
  f32.f = 0.0;
  if (exponent == 0) {
    if (mantissa != 0) {
      const float scale = 1.0 / (1 << 19);
      f32.f = scale * mantissa;
    }
  } else if (exponent == 31) {
    f32.ui = 0x7f800000 | mantissa;
  } else {
    float scale, decimal;
    exponent -= 15;
    if (exponent < 0) {
      scale = 1.0f / (1 << -exponent);
    } else {
      scale = (float)(1 << exponent);
    }
    decimal = 1.0f + (float)mantissa / 32;
    f32.f = scale * decimal;
  }
  return f32.f;
}


x86 assembly (clang, -O0):
<uf10_to_f32>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    -0x4(%rbp),%eax
and    $0x3e0,%eax
sar    $0x5,%eax
mov    %eax,-0xc(%rbp)
mov    -0x4(%rbp),%eax
and    $0x1f,%eax
mov    %eax,-0x10(%rbp)
xorps  %xmm0,%xmm0
movss  %xmm0,-0x8(%rbp)
cmpl   $0x0,-0xc(%rbp)
jne    1162 <uf10_to_f32+0x62>
cmpl   $0x0,-0x10(%rbp)
je     115d <uf10_to_f32+0x5d>
movss  0xec6(%rip),%xmm0
movss  %xmm0,-0x14(%rbp)
cvtsi2ssl -0x10(%rbp),%xmm1
movss  0xeb4(%rip),%xmm0
mulss  %xmm1,%xmm0
movss  %xmm0,-0x8(%rbp)
jmp    11fe <uf10_to_f32+0xfe>
cmpl   $0x1f,-0xc(%rbp)
jne    117c <uf10_to_f32+0x7c>
mov    -0x10(%rbp),%eax
or     $0x7f800000,%eax
mov    %eax,-0x8(%rbp)
jmp    11f9 <uf10_to_f32+0xf9>
mov    -0xc(%rbp),%eax
sub    $0xf,%eax
mov    %eax,-0xc(%rbp)
cmpl   $0x0,-0xc(%rbp)
jge    11b5 <uf10_to_f32+0xb5>
xor    %ecx,%ecx
sub    -0xc(%rbp),%ecx
mov    $0x1,%eax
shl    %cl,%eax
cvtsi2ss %eax,%xmm1
movss  0xe59(%rip),%xmm0
divss  %xmm1,%xmm0
movss  %xmm0,-0x18(%rbp)
jmp    11c8 <uf10_to_f32+0xc8>
mov    -0xc(%rbp),%ecx
mov    $0x1,%eax
shl    %cl,%eax
cvtsi2ss %eax,%xmm0
movss  %xmm0,-0x18(%rbp)
cvtsi2ssl -0x10(%rbp),%xmm1
movss  0xe2f(%rip),%xmm0
divss  %xmm0,%xmm1
movss  0xe1f(%rip),%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x1c(%rbp)
movss  -0x18(%rbp),%xmm0
mulss  -0x1c(%rbp),%xmm0
movss  %xmm0,-0x8(%rbp)
jmp    11fe <uf10_to_f32+0xfe>
movss  -0x8(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<uf10_to_f32>:
mov    %edi,%ecx
shr    $0x5,%ecx
and    $0x1f,%ecx
and    $0x1f,%edi
cmp    $0x1f,%ecx
je     1125 <uf10_to_f32+0x25>
test   %ecx,%ecx
jne    1130 <uf10_to_f32+0x30>
test   %edi,%edi
je     117e <uf10_to_f32+0x7e>
cvtsi2ss %edi,%xmm0
mulss  0xedc(%rip),%xmm0
ret
or     $0x7f800000,%edi
movd   %edi,%xmm0
ret
cmp    $0xe,%ecx
ja     1154 <uf10_to_f32+0x54>
mov    $0xf,%al
sub    %cl,%al
mov    $0x1,%edx
mov    %eax,%ecx
shl    %cl,%edx
cvtsi2ss %edx,%xmm0
movss  0xeb6(%rip),%xmm1
divss  %xmm0,%xmm1
jmp    1162 <uf10_to_f32+0x62>
add    $0xf1,%cl
mov    $0x1,%eax
shl    %cl,%eax
cvtsi2ss %eax,%xmm1
xorps  %xmm0,%xmm0
cvtsi2ss %edi,%xmm0
mulss  0xe97(%rip),%xmm0
addss  0xe8b(%rip),%xmm0
mulss  %xmm1,%xmm0
ret
xorps  %xmm0,%xmm0
ret

LLVM IR (-O0):
%union.anon = type { float }
define float @uf10_to_f32(i32 %0) {
%2 = alloca i32
%3 = alloca %union.anon
%4 = alloca i32
%5 = alloca i32
%6 = alloca float
%7 = alloca float
%8 = alloca float
store i32 %0, i32* %2
%9 = load i32, i32* %2
%10 = and i32 %9, 992
%11 = ashr i32 %10, 5
store i32 %11, i32* %4
%12 = load i32, i32* %2
%13 = and i32 %12, 31
store i32 %13, i32* %5
%14 = bitcast %union.anon* %3 to float*
store float 0.000000e+00, float* %14
%15 = load i32, i32* %4
%16 = icmp eq i32 %15, 0
br i1 %16, label %17, label %26
17: ; preds = %1
%18 = load i32, i32* %5
%19 = icmp ne i32 %18, 0
br i1 %19, label %20, label %25
20: ; preds = %17
store float 0x3EC0000000000000, float* %6
%21 = load i32, i32* %5
%22 = sitofp i32 %21 to float
%23 = fmul float 0x3EC0000000000000, %22
%24 = bitcast %union.anon* %3 to float*
store float %23, float* %24
br label %25
25: ; preds = %20, %17
br label %58
26: ; preds = %1
%27 = load i32, i32* %4
%28 = icmp eq i32 %27, 31
br i1 %28, label %29, label %33
29: ; preds = %26
%30 = load i32, i32* %5
%31 = or i32 2139095040, %30
%32 = bitcast %union.anon* %3 to i32*
store i32 %31, i32* %32
br label %57
33: ; preds = %26
%34 = load i32, i32* %4
%35 = sub nsw i32 %34, 15
store i32 %35, i32* %4
%36 = load i32, i32* %4
%37 = icmp slt i32 %36, 0
br i1 %37, label %38, label %44
38: ; preds = %33
%39 = load i32, i32* %4
%40 = sub nsw i32 0, %39
%41 = shl i32 1, %40
%42 = sitofp i32 %41 to float
%43 = fdiv float 1.000000e+00, %42
store float %43, float* %7
br label %48
44: ; preds = %33
%45 = load i32, i32* %4
%46 = shl i32 1, %45
%47 = sitofp i32 %46 to float
store float %47, float* %7
br label %48
48: ; preds = %44, %38
%49 = load i32, i32* %5
%50 = sitofp i32 %49 to float
%51 = fdiv float %50, 3.200000e+01
%52 = fadd float 1.000000e+00, %51
store float %52, float* %8
%53 = load float, float* %7
%54 = load float, float* %8
%55 = fmul float %53, %54
%56 = bitcast %union.anon* %3 to float*
store float %55, float* %56
br label %57
57: ; preds = %48, %29
br label %58
58: ; preds = %57, %25
%59 = bitcast %union.anon* %3 to float*
%60 = load float, float* %59
ret float %60
}

LLVM IR (-O2):
define float @uf10_to_f32(i32 %0) {
%2 = lshr i32 %0, 5
%3 = and i32 %2, 31
%4 = and i32 %0, 31
switch i32 %3, label %13 [
i32 0, label %5
i32 31, label %10
]
5: ; preds = %1
%6 = icmp eq i32 %4, 0
br i1 %6, label %30, label %7
7: ; preds = %5
%8 = sitofp i32 %4 to float
%9 = fmul float %8, 0x3EC0000000000000
br label %30
10: ; preds = %1
%11 = or i32 %4, 2139095040
%12 = bitcast i32 %11 to float
br label %30
13: ; preds = %1
%14 = icmp ult i32 %3, 15
br i1 %14, label %15, label %20
15: ; preds = %13
%16 = sub nuw nsw i32 15, %3
%17 = shl nuw nsw i32 1, %16
%18 = sitofp i32 %17 to float
%19 = fdiv float 1.000000e+00, %18
br label %24
20: ; preds = %13
%21 = add nsw i32 %3, -15
%22 = shl nuw nsw i32 1, %21
%23 = sitofp i32 %22 to float
br label %24
24: ; preds = %20, %15
%25 = phi float [ %19, %15 ], [ %23, %20 ]
%26 = sitofp i32 %4 to float
%27 = fmul float %26, 3.125000e-02
%28 = fadd float %27, 1.000000e+00
%29 = fmul float %28, %25
br label %30
30: ; preds = %10, %24, %5, %7
%31 = phi float [ %9, %7 ], [ 0.000000e+00, %5 ], [ %12, %10 ], [ %29, %24 ]
ret float %31
}