long fp16_log(int x) {
  int t;
  int y = 0xa65af;
  if (x < 0x00008000)
    x <<= 16, y -= 0xb1721;
  if (x < 0x00800000)
    x <<= 8, y -= 0x58b91;
  if (x < 0x08000000)
    x <<= 4, y -= 0x2c5c8;
  if (x < 0x20000000)
    x <<= 2, y -= 0x162e4;
  if (x < 0x40000000)
    x <<= 1, y -= 0x0b172;
  t = x + (x >> 1);
  if ((t & 0x80000000) == 0)
    x = t, y -= 0x067cd;
  t = x + (x >> 2);
  if ((t & 0x80000000) == 0)
    x = t, y -= 0x03920;
  t = x + (x >> 3);
  if ((t & 0x80000000) == 0)
    x = t, y -= 0x01e27;
  t = x + (x >> 4);
  if ((t & 0x80000000) == 0)
    x = t, y -= 0x00f85;
  t = x + (x >> 5);
  if ((t & 0x80000000) == 0)
    x = t, y -= 0x007e1;
  t = x + (x >> 6);
  if ((t & 0x80000000) == 0)
    x = t, y -= 0x003f8;
  t = x + (x >> 7);
  if ((t & 0x80000000) == 0)
    x = t, y -= 0x001fe;
  x = 0x80000000 - x;
  y -= x >> 15;
  return y;
}


x86 assembly (clang, -O0):
<fp16_log>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
movl   $0xa65af,-0xc(%rbp)
cmpl   $0x8000,-0x4(%rbp)
jge    112f <fp16_log+0x2f>
mov    -0x4(%rbp),%eax
shl    $0x10,%eax
mov    %eax,-0x4(%rbp)
mov    -0xc(%rbp),%eax
sub    $0xb1721,%eax
mov    %eax,-0xc(%rbp)
cmpl   $0x800000,-0x4(%rbp)
jge    1150 <fp16_log+0x50>
mov    -0x4(%rbp),%eax
shl    $0x8,%eax
mov    %eax,-0x4(%rbp)
mov    -0xc(%rbp),%eax
sub    $0x58b91,%eax
mov    %eax,-0xc(%rbp)
cmpl   $0x8000000,-0x4(%rbp)
jge    1171 <fp16_log+0x71>
mov    -0x4(%rbp),%eax
shl    $0x4,%eax
mov    %eax,-0x4(%rbp)
mov    -0xc(%rbp),%eax
sub    $0x2c5c8,%eax
mov    %eax,-0xc(%rbp)
cmpl   $0x20000000,-0x4(%rbp)
jge    1192 <fp16_log+0x92>
mov    -0x4(%rbp),%eax
shl    $0x2,%eax
mov    %eax,-0x4(%rbp)
mov    -0xc(%rbp),%eax
sub    $0x162e4,%eax
mov    %eax,-0xc(%rbp)
cmpl   $0x40000000,-0x4(%rbp)
jge    11b3 <fp16_log+0xb3>
mov    -0x4(%rbp),%eax
shl    $0x1,%eax
mov    %eax,-0x4(%rbp)
mov    -0xc(%rbp),%eax
sub    $0xb172,%eax
mov    %eax,-0xc(%rbp)
mov    -0x4(%rbp),%eax
mov    -0x4(%rbp),%ecx
sar    $0x1,%ecx
add    %ecx,%eax
mov    %eax,-0x8(%rbp)
mov    -0x8(%rbp),%eax
and    $0x80000000,%eax
cmp    $0x0,%eax
jne    11e3 <fp16_log+0xe3>
mov    -0x8(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0xc(%rbp),%eax
sub    $0x67cd,%eax
mov    %eax,-0xc(%rbp)
mov    -0x4(%rbp),%eax
mov    -0x4(%rbp),%ecx
sar    $0x2,%ecx
add    %ecx,%eax
mov    %eax,-0x8(%rbp)
mov    -0x8(%rbp),%eax
and    $0x80000000,%eax
cmp    $0x0,%eax
jne    1213 <fp16_log+0x113>
mov    -0x8(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0xc(%rbp),%eax
sub    $0x3920,%eax
mov    %eax,-0xc(%rbp)
mov    -0x4(%rbp),%eax
mov    -0x4(%rbp),%ecx
sar    $0x3,%ecx
add    %ecx,%eax
mov    %eax,-0x8(%rbp)
mov    -0x8(%rbp),%eax
and    $0x80000000,%eax
cmp    $0x0,%eax
jne    1243 <fp16_log+0x143>
mov    -0x8(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0xc(%rbp),%eax
sub    $0x1e27,%eax
mov    %eax,-0xc(%rbp)
mov    -0x4(%rbp),%eax
mov    -0x4(%rbp),%ecx
sar    $0x4,%ecx
add    %ecx,%eax
mov    %eax,-0x8(%rbp)
mov    -0x8(%rbp),%eax
and    $0x80000000,%eax
cmp    $0x0,%eax
jne    1273 <fp16_log+0x173>
mov    -0x8(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0xc(%rbp),%eax
sub    $0xf85,%eax
mov    %eax,-0xc(%rbp)
mov    -0x4(%rbp),%eax
mov    -0x4(%rbp),%ecx
sar    $0x5,%ecx
add    %ecx,%eax
mov    %eax,-0x8(%rbp)
mov    -0x8(%rbp),%eax
and    $0x80000000,%eax
cmp    $0x0,%eax
jne    12a3 <fp16_log+0x1a3>
mov    -0x8(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0xc(%rbp),%eax
sub    $0x7e1,%eax
mov    %eax,-0xc(%rbp)
mov    -0x4(%rbp),%eax
mov    -0x4(%rbp),%ecx
sar    $0x6,%ecx
add    %ecx,%eax
mov    %eax,-0x8(%rbp)
mov    -0x8(%rbp),%eax
and    $0x80000000,%eax
cmp    $0x0,%eax
jne    12d3 <fp16_log+0x1d3>
mov    -0x8(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0xc(%rbp),%eax
sub    $0x3f8,%eax
mov    %eax,-0xc(%rbp)
mov    -0x4(%rbp),%eax
mov    -0x4(%rbp),%ecx
sar    $0x7,%ecx
add    %ecx,%eax
mov    %eax,-0x8(%rbp)
mov    -0x8(%rbp),%eax
and    $0x80000000,%eax
cmp    $0x0,%eax
jne    1303 <fp16_log+0x203>
mov    -0x8(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0xc(%rbp),%eax
sub    $0x1fe,%eax
mov    %eax,-0xc(%rbp)
mov    $0x80000000,%eax
sub    -0x4(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%ecx
sar    $0xf,%ecx
mov    -0xc(%rbp),%eax
sub    %ecx,%eax
mov    %eax,-0xc(%rbp)
movslq -0xc(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<fp16_log>:
mov    %edi,%eax
shl    $0x10,%eax
cmp    $0x8000,%edi
cmovge %edi,%eax
mov    $0xffff4e8e,%ecx
mov    $0xa65af,%edx
cmovl  %ecx,%edx
mov    %eax,%ecx
shl    $0x8,%ecx
lea    -0x58b91(%rdx),%esi
cmp    $0x800000,%eax
cmovge %eax,%ecx
cmovge %edx,%esi
mov    %ecx,%eax
shl    $0x4,%eax
lea    -0x2c5c8(%rsi),%edx
cmp    $0x8000000,%ecx
cmovge %ecx,%eax
cmovge %esi,%edx
lea    0x0(,%rax,4),%esi
cmp    $0x20000000,%eax
cmovge %eax,%esi
lea    -0x162e4(%rdx),%eax
cmovge %edx,%eax
lea    -0xb172(%rax),%edx
cmp    $0x40000000,%esi
setl   %cl
cmovge %eax,%edx
shl    %cl,%esi
mov    %esi,%eax
sar    %eax
add    %esi,%eax
test   %eax,%eax
cmovs  %esi,%eax
lea    -0x67cd(%rdx),%ecx
cmovs  %edx,%ecx
mov    %eax,%edx
sar    $0x2,%edx
add    %eax,%edx
test   %edx,%edx
cmovs  %eax,%edx
lea    -0x3920(%rcx),%eax
cmovs  %ecx,%eax
mov    %edx,%ecx
sar    $0x3,%ecx
add    %edx,%ecx
test   %ecx,%ecx
cmovs  %edx,%ecx
lea    -0x1e27(%rax),%edx
cmovs  %eax,%edx
mov    %ecx,%eax
sar    $0x4,%eax
add    %ecx,%eax
test   %eax,%eax
cmovs  %ecx,%eax
lea    -0xf85(%rdx),%ecx
cmovs  %edx,%ecx
mov    %eax,%edx
sar    $0x5,%edx
add    %eax,%edx
test   %edx,%edx
cmovs  %eax,%edx
lea    -0x7e1(%rcx),%eax
cmovs  %ecx,%eax
mov    %edx,%ecx
sar    $0x6,%ecx
add    %edx,%ecx
test   %ecx,%ecx
cmovs  %edx,%ecx
lea    -0x3f8(%rax),%edx
cmovs  %eax,%edx
mov    %ecx,%eax
sar    $0x7,%eax
add    %ecx,%eax
test   %eax,%eax
cmovs  %ecx,%eax
lea    -0x1fe(%rdx),%ecx
cmovs  %edx,%ecx
mov    $0x80000000,%edx
sub    %eax,%edx
sar    $0xf,%edx
sub    %edx,%ecx
movslq %ecx,%rax
ret

LLVM IR (-O0):
define i64 @fp16_log(i32 %0) {
%2 = alloca i32
%3 = alloca i32
%4 = alloca i32
store i32 %0, i32* %2
store i32 681391, i32* %4
%5 = load i32, i32* %2
%6 = icmp slt i32 %5, 32768
br i1 %6, label %7, label %12
7: ; preds = %1
%8 = load i32, i32* %2
%9 = shl i32 %8, 16
store i32 %9, i32* %2
%10 = load i32, i32* %4
%11 = sub nsw i32 %10, 726817
store i32 %11, i32* %4
br label %12
12: ; preds = %7, %1
%13 = load i32, i32* %2
%14 = icmp slt i32 %13, 8388608
br i1 %14, label %15, label %20
15: ; preds = %12
%16 = load i32, i32* %2
%17 = shl i32 %16, 8
store i32 %17, i32* %2
%18 = load i32, i32* %4
%19 = sub nsw i32 %18, 363409
store i32 %19, i32* %4
br label %20
20: ; preds = %15, %12
%21 = load i32, i32* %2
%22 = icmp slt i32 %21, 134217728
br i1 %22, label %23, label %28
23: ; preds = %20
%24 = load i32, i32* %2
%25 = shl i32 %24, 4
store i32 %25, i32* %2
%26 = load i32, i32* %4
%27 = sub nsw i32 %26, 181704
store i32 %27, i32* %4
br label %28
28: ; preds = %23, %20
%29 = load i32, i32* %2
%30 = icmp slt i32 %29, 536870912
br i1 %30, label %31, label %36
31: ; preds = %28
%32 = load i32, i32* %2
%33 = shl i32 %32, 2
store i32 %33, i32* %2
%34 = load i32, i32* %4
%35 = sub nsw i32 %34, 90852
store i32 %35, i32* %4
br label %36
36: ; preds = %31, %28
%37 = load i32, i32* %2
%38 = icmp slt i32 %37, 1073741824
br i1 %38, label %39, label %44
39: ; preds = %36
%40 = load i32, i32* %2
%41 = shl i32 %40, 1
store i32 %41, i32* %2
%42 = load i32, i32* %4
%43 = sub nsw i32 %42, 45426
store i32 %43, i32* %4
br label %44
44: ; preds = %39, %36
%45 = load i32, i32* %2
%46 = load i32, i32* %2
%47 = ashr i32 %46, 1
%48 = add nsw i32 %45, %47
store i32 %48, i32* %3
%49 = load i32, i32* %3
%50 = and i32 %49, -2147483648
%51 = icmp eq i32 %50, 0
br i1 %51, label %52, label %56
52: ; preds = %44
%53 = load i32, i32* %3
store i32 %53, i32* %2
%54 = load i32, i32* %4
%55 = sub nsw i32 %54, 26573
store i32 %55, i32* %4
br label %56
56: ; preds = %52, %44
%57 = load i32, i32* %2
%58 = load i32, i32* %2
%59 = ashr i32 %58, 2
%60 = add nsw i32 %57, %59
store i32 %60, i32* %3
%61 = load i32, i32* %3
%62 = and i32 %61, -2147483648
%63 = icmp eq i32 %62, 0
br i1 %63, label %64, label %68
64: ; preds = %56
%65 = load i32, i32* %3
store i32 %65, i32* %2
%66 = load i32, i32* %4
%67 = sub nsw i32 %66, 14624
store i32 %67, i32* %4
br label %68
68: ; preds = %64, %56
%69 = load i32, i32* %2
%70 = load i32, i32* %2
%71 = ashr i32 %70, 3
%72 = add nsw i32 %69, %71
store i32 %72, i32* %3
%73 = load i32, i32* %3
%74 = and i32 %73, -2147483648
%75 = icmp eq i32 %74, 0
br i1 %75, label %76, label %80
76: ; preds = %68
%77 = load i32, i32* %3
store i32 %77, i32* %2
%78 = load i32, i32* %4
%79 = sub nsw i32 %78, 7719
store i32 %79, i32* %4
br label %80
80: ; preds = %76, %68
%81 = load i32, i32* %2
%82 = load i32, i32* %2
%83 = ashr i32 %82, 4
%84 = add nsw i32 %81, %83
store i32 %84, i32* %3
%85 = load i32, i32* %3
%86 = and i32 %85, -2147483648
%87 = icmp eq i32 %86, 0
br i1 %87, label %88, label %92
88: ; preds = %80
%89 = load i32, i32* %3
store i32 %89, i32* %2
%90 = load i32, i32* %4
%91 = sub nsw i32 %90, 3973
store i32 %91, i32* %4
br label %92
92: ; preds = %88, %80
%93 = load i32, i32* %2
%94 = load i32, i32* %2
%95 = ashr i32 %94, 5
%96 = add nsw i32 %93, %95
store i32 %96, i32* %3
%97 = load i32, i32* %3
%98 = and i32 %97, -2147483648
%99 = icmp eq i32 %98, 0
br i1 %99, label %100, label %104
100: ; preds = %92
%101 = load i32, i32* %3
store i32 %101, i32* %2
%102 = load i32, i32* %4
%103 = sub nsw i32 %102, 2017
store i32 %103, i32* %4
br label %104
104: ; preds = %100, %92
%105 = load i32, i32* %2
%106 = load i32, i32* %2
%107 = ashr i32 %106, 6
%108 = add nsw i32 %105, %107
store i32 %108, i32* %3
%109 = load i32, i32* %3
%110 = and i32 %109, -2147483648
%111 = icmp eq i32 %110, 0
br i1 %111, label %112, label %116
112: ; preds = %104
%113 = load i32, i32* %3
store i32 %113, i32* %2
%114 = load i32, i32* %4
%115 = sub nsw i32 %114, 1016
store i32 %115, i32* %4
br label %116
116: ; preds = %112, %104
%117 = load i32, i32* %2
%118 = load i32, i32* %2
%119 = ashr i32 %118, 7
%120 = add nsw i32 %117, %119
store i32 %120, i32* %3
%121 = load i32, i32* %3
%122 = and i32 %121, -2147483648
%123 = icmp eq i32 %122, 0
br i1 %123, label %124, label %128
124: ; preds = %116
%125 = load i32, i32* %3
store i32 %125, i32* %2
%126 = load i32, i32* %4
%127 = sub nsw i32 %126, 510
store i32 %127, i32* %4
br label %128
128: ; preds = %124, %116
%129 = load i32, i32* %2
%130 = sub i32 -2147483648, %129
store i32 %130, i32* %2
%131 = load i32, i32* %2
%132 = ashr i32 %131, 15
%133 = load i32, i32* %4
%134 = sub nsw i32 %133, %132
store i32 %134, i32* %4
%135 = load i32, i32* %4
%136 = sext i32 %135 to i64
ret i64 %136
}

LLVM IR (-O2):
define i64 @fp16_log(i32 %0) {
%2 = icmp slt i32 %0, 32768
%3 = shl i32 %0, 16
%4 = select i1 %2, i32 %3, i32 %0
%5 = select i1 %2, i32 -45426, i32 681391
%6 = icmp slt i32 %4, 8388608
%7 = shl i32 %4, 8
%8 = add nsw i32 %5, -363409
%9 = select i1 %6, i32 %7, i32 %4
%10 = select i1 %6, i32 %8, i32 %5
%11 = icmp slt i32 %9, 134217728
%12 = shl i32 %9, 4
%13 = add nsw i32 %10, -181704
%14 = select i1 %11, i32 %12, i32 %9
%15 = select i1 %11, i32 %13, i32 %10
%16 = icmp slt i32 %14, 536870912
%17 = shl i32 %14, 2
%18 = add nsw i32 %15, -90852
%19 = select i1 %16, i32 %17, i32 %14
%20 = select i1 %16, i32 %18, i32 %15
%21 = icmp slt i32 %19, 1073741824
%22 = add nsw i32 %20, -45426
%23 = zext i1 %21 to i32
%24 = shl i32 %19, %23
%25 = select i1 %21, i32 %22, i32 %20
%26 = ashr i32 %24, 1
%27 = add nsw i32 %26, %24
%28 = icmp sgt i32 %27, -1
%29 = add nsw i32 %25, -26573
%30 = select i1 %28, i32 %27, i32 %24
%31 = select i1 %28, i32 %29, i32 %25
%32 = ashr i32 %30, 2
%33 = add nsw i32 %32, %30
%34 = icmp sgt i32 %33, -1
%35 = add nsw i32 %31, -14624
%36 = select i1 %34, i32 %33, i32 %30
%37 = select i1 %34, i32 %35, i32 %31
%38 = ashr i32 %36, 3
%39 = add nsw i32 %38, %36
%40 = icmp sgt i32 %39, -1
%41 = add nsw i32 %37, -7719
%42 = select i1 %40, i32 %39, i32 %36
%43 = select i1 %40, i32 %41, i32 %37
%44 = ashr i32 %42, 4
%45 = add nsw i32 %44, %42
%46 = icmp sgt i32 %45, -1
%47 = add nsw i32 %43, -3973
%48 = select i1 %46, i32 %45, i32 %42
%49 = select i1 %46, i32 %47, i32 %43
%50 = ashr i32 %48, 5
%51 = add nsw i32 %50, %48
%52 = icmp sgt i32 %51, -1
%53 = add nsw i32 %49, -2017
%54 = select i1 %52, i32 %51, i32 %48
%55 = select i1 %52, i32 %53, i32 %49
%56 = ashr i32 %54, 6
%57 = add nsw i32 %56, %54
%58 = icmp sgt i32 %57, -1
%59 = add nsw i32 %55, -1016
%60 = select i1 %58, i32 %57, i32 %54
%61 = select i1 %58, i32 %59, i32 %55
%62 = ashr i32 %60, 7
%63 = add nsw i32 %62, %60
%64 = icmp sgt i32 %63, -1
%65 = add nsw i32 %61, -510
%66 = select i1 %64, i32 %63, i32 %60
%67 = select i1 %64, i32 %65, i32 %61
%68 = sub i32 -2147483648, %66
%69 = ashr i32 %68, 15
%70 = sub nsw i32 %67, %69
%71 = sext i32 %70 to i64
ret i64 %71
}