void dsp_protocol_Q152linear(const unsigned short int scale,
                             const unsigned short int power2,
                             unsigned short int *output) {
  float result = scale * 1.0 / 0x8000 * (1 << power2) * 100.0;
  do {
  } while (0);
  *output = (short int)(result);
  if ((result - *output) > 0.5)
    (*output)++;
  do {
  } while (0);
  do {
  } while (0);
}


x86 assembly (clang, -O0):
<dsp_protocol_Q152linear>:
push   %rbp
mov    %rsp,%rbp
mov    %si,%ax
mov    %di,%cx
mov    %cx,-0x2(%rbp)
mov    %ax,-0x4(%rbp)
mov    %rdx,-0x10(%rbp)
movzwl -0x2(%rbp),%eax
cvtsi2sd %eax,%xmm0
movsd  0xeea(%rip),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xed6(%rip),%xmm1
divsd  %xmm1,%xmm0
movzwl -0x4(%rbp),%ecx
mov    $0x1,%eax
shl    %cl,%eax
cvtsi2sd %eax,%xmm1
mulsd  %xmm1,%xmm0
movsd  0xeaf(%rip),%xmm1
mulsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x14(%rbp)
jmp    1163 <dsp_protocol_Q152linear+0x63>
movss  -0x14(%rbp),%xmm0
cvttss2si %xmm0,%eax
mov    %ax,%cx
mov    -0x10(%rbp),%rax
mov    %cx,(%rax)
movss  -0x14(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movzwl (%rax),%eax
cvtsi2ss %eax,%xmm1
subss  %xmm1,%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xe82(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    11ae <dsp_protocol_Q152linear+0xae>
mov    -0x10(%rbp),%rax
mov    (%rax),%cx
add    $0x1,%cx
mov    %cx,(%rax)
jmp    11b3 <dsp_protocol_Q152linear+0xb3>
jmp    11b8 <dsp_protocol_Q152linear+0xb8>
jmp    11bd <dsp_protocol_Q152linear+0xbd>
jmp    11c2 <dsp_protocol_Q152linear+0xc2>
pop    %rbp
ret

x86 assembly (clang, -O2):
<dsp_protocol_Q152linear>:
mov    %esi,%ecx
mov    $0x1,%eax
shl    %cl,%eax
cvtsi2sd %edi,%xmm0
mulsd  0xeeb(%rip),%xmm0
cvtsi2sd %eax,%xmm1
mulsd  %xmm0,%xmm1
mulsd  0xee3(%rip),%xmm1
xorps  %xmm0,%xmm0
cvtsd2ss %xmm1,%xmm0
cvttss2si %xmm0,%eax
movzwl %ax,%ecx
xorps  %xmm1,%xmm1
cvtsi2ss %ecx,%xmm1
subss  %xmm1,%xmm0
xor    %ecx,%ecx
ucomiss 0xec9(%rip),%xmm0
seta   %cl
add    %eax,%ecx
mov    %cx,(%rdx)
ret

LLVM IR (-O0):
define void @dsp_protocol_Q152linear(i16 zeroext %0, i16 zeroext %1, i16* %2) {
%4 = alloca i16
%5 = alloca i16
%6 = alloca i16*
%7 = alloca float
store i16 %0, i16* %4
store i16 %1, i16* %5
store i16* %2, i16** %6
%8 = load i16, i16* %4
%9 = zext i16 %8 to i32
%10 = sitofp i32 %9 to double
%11 = fmul double %10, 1.000000e+00
%12 = fdiv double %11, 3.276800e+04
%13 = load i16, i16* %5
%14 = zext i16 %13 to i32
%15 = shl i32 1, %14
%16 = sitofp i32 %15 to double
%17 = fmul double %12, %16
%18 = fmul double %17, 1.000000e+02
%19 = fptrunc double %18 to float
store float %19, float* %7
br label %20
20: ; preds = %3
br label %21
21: ; preds = %20
%22 = load float, float* %7
%23 = fptosi float %22 to i16
%24 = load i16*, i16** %6
store i16 %23, i16* %24
%25 = load float, float* %7
%26 = load i16*, i16** %6
%27 = load i16, i16* %26
%28 = zext i16 %27 to i32
%29 = sitofp i32 %28 to float
%30 = fsub float %25, %29
%31 = fpext float %30 to double
%32 = fcmp ogt double %31, 5.000000e-01
br i1 %32, label %33, label %37
33: ; preds = %21
%34 = load i16*, i16** %6
%35 = load i16, i16* %34
%36 = add i16 %35, 1
store i16 %36, i16* %34
br label %37
37: ; preds = %33, %21
br label %38
38: ; preds = %37
br label %39
39: ; preds = %38
br label %40
40: ; preds = %39
br label %41
41: ; preds = %40
ret void
}

LLVM IR (-O2):
define void @dsp_protocol_Q152linear(i16 zeroext %0, i16 zeroext %1, i16* nocapture writeonly %2) {
%4 = uitofp i16 %0 to double
%5 = fmul double %4, 0x3F00000000000000
%6 = zext i16 %1 to i32
%7 = shl nuw i32 1, %6
%8 = sitofp i32 %7 to double
%9 = fmul double %5, %8
%10 = fmul double %9, 1.000000e+02
%11 = fptrunc double %10 to float
%12 = fptosi float %11 to i16
%13 = uitofp i16 %12 to float
%14 = fsub float %11, %13
%15 = fcmp ogt float %14, 5.000000e-01
%16 = zext i1 %15 to i16
%17 = add i16 %16, %12
store i16 %17, i16* %2
ret void
}