#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 */

/* Variables and functions */
long mask_and_sign_extend_word(long, int);
int /*<<< orphan*/ sprintf(char *, char *, float);
const char *decode_short_float(long int number) {
  static char buffer[20];
  long int e;
  long int s;
  long int f;
  union {
    float f;
    unsigned long l;
  } converter;
  if (number & 0xffff0000UL) {
    return "";
  }
  e = (number & 0xf000U) >> 12;
  s = number & 0x0800U;
  f = number & 0x07ffU;
  e = mask_and_sign_extend_word(e, 0xf);
  if (s == 0 && e == -8 && f == 0) {
    return "0.0";
  }
  converter.l = (e << 24) | (s << (23 - 11)) | (f << (22 - 10));
  sprintf(buffer, "%f", converter.f);
  return buffer;
}


x86 assembly (clang, -O0):
<decode_short_float>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x10(%rbp)
movabs $0xffff0000,%rax
and    -0x10(%rbp),%rax
cmp    $0x0,%rax
je     1154 <decode_short_float+0x34>
lea    0xeb8(%rip),%rax
mov    %rax,-0x8(%rbp)
jmp    120a <decode_short_float+0xea>
mov    -0x10(%rbp),%rax
and    $0xf000,%rax
sar    $0xc,%rax
mov    %rax,-0x18(%rbp)
mov    -0x10(%rbp),%rax
and    $0x800,%rax
mov    %rax,-0x20(%rbp)
mov    -0x10(%rbp),%rax
and    $0x7ff,%rax
mov    %rax,-0x28(%rbp)
mov    -0x18(%rbp),%rdi
mov    $0xf,%esi
call   1030 <mask_and_sign_extend_word@plt>
mov    %rax,-0x18(%rbp)
cmpq   $0x0,-0x20(%rbp)
jne    11c5 <decode_short_float+0xa5>
cmpq   $0xfffffffffffffff8,-0x18(%rbp)
jne    11c5 <decode_short_float+0xa5>
cmpq   $0x0,-0x28(%rbp)
jne    11c5 <decode_short_float+0xa5>
lea    0xe44(%rip),%rax
mov    %rax,-0x8(%rbp)
jmp    120a <decode_short_float+0xea>
mov    -0x18(%rbp),%rax
shl    $0x18,%rax
mov    -0x20(%rbp),%rcx
shl    $0xc,%rcx
or     %rcx,%rax
mov    -0x28(%rbp),%rcx
shl    $0xc,%rcx
or     %rcx,%rax
mov    %rax,-0x30(%rbp)
movss  -0x30(%rbp),%xmm0
lea    0x2e4d(%rip),%rdi
lea    0xe0a(%rip),%rsi
call   1040 <sprintf@plt>
lea    0x2e3a(%rip),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<decode_short_float>:
push   %r14
push   %rbx
push   %rax
mov    %rdi,%rbx
test   $0xffff0000,%ebx
je     1138 <decode_short_float+0x18>
lea    0xecd(%rip),%rbx
jmp    119b <decode_short_float+0x7b>
mov    %ebx,%edi
shr    $0xc,%edi
and    $0xf,%edi
mov    %ebx,%r14d
and    $0x800,%r14d
mov    $0xf,%esi
call   1030 <mask_and_sign_extend_word@plt>
and    $0x7ff,%rbx
jne    1171 <decode_short_float+0x51>
test   %r14,%r14
jne    1171 <decode_short_float+0x51>
cmp    $0xfffffffffffffff8,%rax
jne    1171 <decode_short_float+0x51>
lea    0xe91(%rip),%rbx
jmp    119b <decode_short_float+0x7b>
shl    $0x18,%eax
shl    $0xc,%r14d
or     %eax,%r14d
shl    $0xc,%ebx
or     %r14d,%ebx
movd   %ebx,%xmm0
lea    0x2eb4(%rip),%rbx
lea    0xe71(%rip),%rsi
mov    %rbx,%rdi
call   1040 <sprintf@plt>
mov    %rbx,%rax
add    $0x8,%rsp
pop    %rbx
pop    %r14
ret

LLVM IR (-O0):
%union.anon = type { i64 }
@decode_short_float.buffer = internal global [20 x i8] zeroinitializer
@.str = [1 x i8] zeroinitializer
@.str.1 = [4 x i8] c"0.0\00"
@.str.2 = [3 x i8] c"%f\00"
define i8* @decode_short_float(i64 %0) {
%2 = alloca i8*
%3 = alloca i64
%4 = alloca i64
%5 = alloca i64
%6 = alloca i64
%7 = alloca %union.anon
store i64 %0, i64* %3
%8 = load i64, i64* %3
%9 = and i64 %8, 4294901760
%10 = icmp ne i64 %9, 0
br i1 %10, label %11, label %12
11: ; preds = %1
store i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i64 0, i64 0), i8** %2
br label %44
12: ; preds = %1
%13 = load i64, i64* %3
%14 = and i64 %13, 61440
%15 = ashr i64 %14, 12
store i64 %15, i64* %4
%16 = load i64, i64* %3
%17 = and i64 %16, 2048
store i64 %17, i64* %5
%18 = load i64, i64* %3
%19 = and i64 %18, 2047
store i64 %19, i64* %6
%20 = load i64, i64* %4
%21 = call i64 @mask_and_sign_extend_word(i64 %20, i32 15)
store i64 %21, i64* %4
%22 = load i64, i64* %5
%23 = icmp eq i64 %22, 0
br i1 %23, label %24, label %31
24: ; preds = %12
%25 = load i64, i64* %4
%26 = icmp eq i64 %25, -8
br i1 %26, label %27, label %31
27: ; preds = %24
%28 = load i64, i64* %6
%29 = icmp eq i64 %28, 0
br i1 %29, label %30, label %31
30: ; preds = %27
store i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.1, i64 0, i64 0), i8** %2
br label %44
31: ; preds = %27, %24, %12
%32 = load i64, i64* %4
%33 = shl i64 %32, 24
%34 = load i64, i64* %5
%35 = shl i64 %34, 12
%36 = or i64 %33, %35
%37 = load i64, i64* %6
%38 = shl i64 %37, 12
%39 = or i64 %36, %38
%40 = bitcast %union.anon* %7 to i64*
store i64 %39, i64* %40
%41 = bitcast %union.anon* %7 to float*
%42 = load float, float* %41
%43 = call i32 @sprintf(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @decode_short_float.buffer, i64 0, i64 0), i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.2, i64 0, i64 0), float %42)
store i8* getelementptr inbounds ([20 x i8], [20 x i8]* @decode_short_float.buffer, i64 0, i64 0), i8** %2
br label %44
44: ; preds = %31, %30, %11
%45 = load i8*, i8** %2
ret i8* %45
}

LLVM IR (-O2):
@decode_short_float.buffer = internal global [20 x i8] zeroinitializer
@.str = [1 x i8] zeroinitializer
@.str.1 = [4 x i8] c"0.0\00"
@.str.2 = [3 x i8] c"%f\00"
define i8* @decode_short_float(i64 %0) {
%2 = and i64 %0, 4294901760
%3 = icmp eq i64 %2, 0
br i1 %3, label %4, label %24
4: ; preds = %1
%5 = lshr i64 %0, 12
%6 = and i64 %5, 15
%7 = and i64 %0, 2048
%8 = and i64 %0, 2047
%9 = tail call i64 @mask_and_sign_extend_word(i64 %6, i32 15)
%10 = icmp eq i64 %7, 0
%11 = icmp eq i64 %9, -8
%12 = select i1 %10, i1 %11, i1 false
%13 = icmp eq i64 %8, 0
%14 = and i1 %13, %12
br i1 %14, label %24, label %15
15: ; preds = %4
%16 = shl i64 %9, 24
%17 = shl nuw nsw i64 %7, 12
%18 = or i64 %16, %17
%19 = shl nuw nsw i64 %8, 12
%20 = or i64 %18, %19
%21 = trunc i64 %20 to i32
%22 = bitcast i32 %21 to float
%23 = tail call i32 @sprintf(i8* dereferenceable(1) getelementptr inbounds ([20 x i8], [20 x i8]* @decode_short_float.buffer, i64 0, i64 0), i8* dereferenceable(1) getelementptr inbounds ([3 x i8], [3 x i8]* @.str.2, i64 0, i64 0), float %22)
br label %24
24: ; preds = %4, %1, %15
%25 = phi i8* [ getelementptr inbounds ([20 x i8], [20 x i8]* @decode_short_float.buffer, i64 0, i64 0), %15 ], [ getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i64 0, i64 0), %1 ], [ getelementptr inbounds ([4 x i8], [4 x i8]* @.str.1, i64 0, i64 0), %4 ]
ret i8* %25
}