unsigned int __gnu_h2f_internal(unsigned short a, int ieee) {
  unsigned int sign = (unsigned int)(a & 0x8000) << 16;
  int aexp = (a >> 10) & 0x1f;
  unsigned int mantissa = a & 0x3ff;
  if (aexp == 0x1f && ieee)
    return sign | 0x7f800000 | (mantissa << 13);
  if (aexp == 0) {
    int shift;
    if (mantissa == 0)
      return sign;
    shift = __builtin_clz(mantissa) - 21;
    mantissa <<= shift;
    aexp = -shift;
  }
  return sign | (((aexp + 0x70) << 23) + (mantissa << 13));
}


x86 assembly (clang, -O0):
<__gnu_h2f_internal>:
push   %rbp
mov    %rsp,%rbp
mov    %di,%ax
mov    %ax,-0x6(%rbp)
mov    %esi,-0xc(%rbp)
movzwl -0x6(%rbp),%eax
and    $0x8000,%eax
shl    $0x10,%eax
mov    %eax,-0x10(%rbp)
movzwl -0x6(%rbp),%eax
sar    $0xa,%eax
and    $0x1f,%eax
mov    %eax,-0x14(%rbp)
movzwl -0x6(%rbp),%eax
and    $0x3ff,%eax
mov    %eax,-0x18(%rbp)
cmpl   $0x1f,-0x14(%rbp)
jne    1162 <__gnu_h2f_internal+0x62>
cmpl   $0x0,-0xc(%rbp)
je     1162 <__gnu_h2f_internal+0x62>
mov    -0x10(%rbp),%eax
or     $0x7f800000,%eax
mov    -0x18(%rbp),%ecx
shl    $0xd,%ecx
or     %ecx,%eax
mov    %eax,-0x4(%rbp)
jmp    11bc <__gnu_h2f_internal+0xbc>
cmpl   $0x0,-0x14(%rbp)
jne    11a3 <__gnu_h2f_internal+0xa3>
cmpl   $0x0,-0x18(%rbp)
jne    1181 <__gnu_h2f_internal+0x81>
mov    -0x10(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    11bc <__gnu_h2f_internal+0xbc>
mov    -0x18(%rbp),%eax
bsr    %eax,%eax
xor    $0x1f,%eax
sub    $0x15,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x1c(%rbp),%ecx
mov    -0x18(%rbp),%eax
shl    %cl,%eax
mov    %eax,-0x18(%rbp)
xor    %eax,%eax
sub    -0x1c(%rbp),%eax
mov    %eax,-0x14(%rbp)
mov    -0x10(%rbp),%eax
mov    -0x14(%rbp),%ecx
add    $0x70,%ecx
shl    $0x17,%ecx
mov    -0x18(%rbp),%edx
shl    $0xd,%edx
add    %edx,%ecx
or     %ecx,%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<__gnu_h2f_internal>:
mov    %edi,%eax
shl    $0x10,%eax
and    $0x80000000,%eax
mov    %edi,%ecx
shr    $0xa,%ecx
and    $0x1f,%ecx
test   %esi,%esi
je     1126 <__gnu_h2f_internal+0x26>
cmp    $0x1f,%ecx
jne    1126 <__gnu_h2f_internal+0x26>
shl    $0xd,%edi
or     %edi,%eax
or     $0x7f800000,%eax
ret
and    $0x3ff,%edi
test   %ecx,%ecx
jne    1146 <__gnu_h2f_internal+0x46>
test   %edi,%edi
je     1156 <__gnu_h2f_internal+0x56>
bsr    %edi,%edx
xor    $0x1f,%edx
lea    -0x15(%rdx),%ecx
shl    %cl,%edi
mov    $0x15,%ecx
sub    %edx,%ecx
shl    $0x17,%ecx
shl    $0xd,%edi
add    %edi,%ecx
add    $0x38000000,%ecx
or     %ecx,%eax
ret

LLVM IR (-O0):
define i32 @__gnu_h2f_internal(i16 zeroext %0, i32 %1) {
%3 = alloca i32
%4 = alloca i16
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
store i16 %0, i16* %4
store i32 %1, i32* %5
%10 = load i16, i16* %4
%11 = zext i16 %10 to i32
%12 = and i32 %11, 32768
%13 = shl i32 %12, 16
store i32 %13, i32* %6
%14 = load i16, i16* %4
%15 = zext i16 %14 to i32
%16 = ashr i32 %15, 10
%17 = and i32 %16, 31
store i32 %17, i32* %7
%18 = load i16, i16* %4
%19 = zext i16 %18 to i32
%20 = and i32 %19, 1023
store i32 %20, i32* %8
%21 = load i32, i32* %7
%22 = icmp eq i32 %21, 31
br i1 %22, label %23, label %32
23: ; preds = %2
%24 = load i32, i32* %5
%25 = icmp ne i32 %24, 0
br i1 %25, label %26, label %32
26: ; preds = %23
%27 = load i32, i32* %6
%28 = or i32 %27, 2139095040
%29 = load i32, i32* %8
%30 = shl i32 %29, 13
%31 = or i32 %28, %30
store i32 %31, i32* %3
br label %58
32: ; preds = %23, %2
%33 = load i32, i32* %7
%34 = icmp eq i32 %33, 0
br i1 %34, label %35, label %49
35: ; preds = %32
%36 = load i32, i32* %8
%37 = icmp eq i32 %36, 0
br i1 %37, label %38, label %40
38: ; preds = %35
%39 = load i32, i32* %6
store i32 %39, i32* %3
br label %58
40: ; preds = %35
%41 = load i32, i32* %8
%42 = call i32 @llvm.ctlz.i32(i32 %41, i1 true)
%43 = sub nsw i32 %42, 21
store i32 %43, i32* %9
%44 = load i32, i32* %9
%45 = load i32, i32* %8
%46 = shl i32 %45, %44
store i32 %46, i32* %8
%47 = load i32, i32* %9
%48 = sub nsw i32 0, %47
store i32 %48, i32* %7
br label %49
49: ; preds = %40, %32
%50 = load i32, i32* %6
%51 = load i32, i32* %7
%52 = add nsw i32 %51, 112
%53 = shl i32 %52, 23
%54 = load i32, i32* %8
%55 = shl i32 %54, 13
%56 = add i32 %53, %55
%57 = or i32 %50, %56
store i32 %57, i32* %3
br label %58
58: ; preds = %49, %38, %26
%59 = load i32, i32* %3
ret i32 %59
}

LLVM IR (-O2):
define i32 @__gnu_h2f_internal(i16 zeroext %0, i32 %1) {
%3 = zext i16 %0 to i32
%4 = sext i16 %0 to i32
%5 = and i32 %4, -2147483648
%6 = lshr i32 %3, 10
%7 = and i32 %6, 31
%8 = and i32 %3, 1023
%9 = icmp eq i32 %7, 31
%10 = icmp ne i32 %1, 0
%11 = and i1 %10, %9
br i1 %11, label %12, label %16
12: ; preds = %2
%13 = shl nuw nsw i32 %3, 13
%14 = or i32 %5, %13
%15 = or i32 %14, 2139095040
br label %33
16: ; preds = %2
%17 = icmp eq i32 %7, 0
br i1 %17, label %18, label %25
18: ; preds = %16
%19 = icmp eq i32 %8, 0
br i1 %19, label %33, label %20
20: ; preds = %18
%21 = tail call i32 @llvm.ctlz.i32(i32 %8, i1 true)
%22 = add nsw i32 %21, -21
%23 = shl nuw nsw i32 %8, %22
%24 = sub nsw i32 21, %21
br label %25
25: ; preds = %20, %16
%26 = phi i32 [ %24, %20 ], [ %7, %16 ]
%27 = phi i32 [ %23, %20 ], [ %8, %16 ]
%28 = shl nsw i32 %26, 23
%29 = add nsw i32 %28, 939524096
%30 = shl i32 %27, 13
%31 = add i32 %29, %30
%32 = or i32 %31, %5
br label %33
33: ; preds = %18, %25, %12
%34 = phi i32 [ %15, %12 ], [ %32, %25 ], [ %5, %18 ]
ret i32 %34
}