#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 */
double NAN;
double fmin(int, double);
scalar_t__ isnan(double);
double pwm_map(double value, double rev_max, double rev_min, double center,
               double fwd_min, double fwd_max) {
  if (value < 0) {
    return fmin(1, -value) * (rev_max - rev_min) + rev_min;
  } else if (value > 0) {
    return fmin(1, -value) * (rev_max - rev_min) + rev_min;
  } else if (isnan(value)) {
    return NAN;
  } else {
    return center;
  }
}


x86 assembly (clang, -O0):
<pwm_map>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
movsd  %xmm0,-0x10(%rbp)
movsd  %xmm1,-0x18(%rbp)
movsd  %xmm2,-0x20(%rbp)
movsd  %xmm3,-0x28(%rbp)
movsd  %xmm4,-0x30(%rbp)
movsd  %xmm5,-0x38(%rbp)
xorps  %xmm0,%xmm0
ucomisd -0x10(%rbp),%xmm0
jbe    119b <pwm_map+0x7b>
movsd  -0x10(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mov    $0x1,%edi
call   1030 <fmin@plt>
movsd  -0x18(%rbp),%xmm2
subsd  -0x20(%rbp),%xmm2
movsd  -0x20(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1227 <pwm_map+0x107>
movsd  -0x10(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jbe    11f4 <pwm_map+0xd4>
movsd  -0x10(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mov    $0x1,%edi
call   1030 <fmin@plt>
movsd  -0x18(%rbp),%xmm2
subsd  -0x20(%rbp),%xmm2
movsd  -0x20(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1227 <pwm_map+0x107>
movsd  -0x10(%rbp),%xmm0
call   1040 <isnan@plt>
cmp    $0x0,%rax
je     121d <pwm_map+0xfd>
mov    0x2de9(%rip),%rax
movsd  (%rax),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1227 <pwm_map+0x107>
movsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<pwm_map>:
sub    $0x18,%rsp
xorpd  %xmm4,%xmm4
ucomisd %xmm0,%xmm4
ja     1134 <pwm_map+0x14>
ucomisd %xmm4,%xmm0
jbe    116f <pwm_map+0x4f>
xorpd  0xec4(%rip),%xmm0
mov    $0x1,%edi
movsd  %xmm2,0x8(%rsp)
movsd  %xmm1,0x10(%rsp)
call   1030 <fmin@plt>
movsd  0x8(%rsp),%xmm1
movsd  0x10(%rsp),%xmm2
subsd  %xmm1,%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
add    $0x18,%rsp
ret
movsd  %xmm3,0x8(%rsp)
call   1040 <isnan@plt>
movsd  0x8(%rsp),%xmm0
test   %rax,%rax
je     1190 <pwm_map+0x70>
mov    0x2e6c(%rip),%rax
movsd  (%rax),%xmm0
add    $0x18,%rsp
ret

LLVM IR (-O0):
@NAN = global double 0.000000e+00
define double @pwm_map(double %0, double %1, double %2, double %3, double %4, double %5) {
%7 = alloca double
%8 = alloca double
%9 = alloca double
%10 = alloca double
%11 = alloca double
%12 = alloca double
%13 = alloca double
store double %0, double* %8
store double %1, double* %9
store double %2, double* %10
store double %3, double* %11
store double %4, double* %12
store double %5, double* %13
%14 = load double, double* %8
%15 = fcmp olt double %14, 0.000000e+00
br i1 %15, label %16, label %25
16: ; preds = %6
%17 = load double, double* %8
%18 = fneg double %17
%19 = call double @fmin(i32 1, double %18)
%20 = load double, double* %9
%21 = load double, double* %10
%22 = fsub double %20, %21
%23 = load double, double* %10
%24 = call double @llvm.fmuladd.f64(double %19, double %22, double %23)
store double %24, double* %7
br label %45
25: ; preds = %6
%26 = load double, double* %8
%27 = fcmp ogt double %26, 0.000000e+00
br i1 %27, label %28, label %37
28: ; preds = %25
%29 = load double, double* %8
%30 = fneg double %29
%31 = call double @fmin(i32 1, double %30)
%32 = load double, double* %9
%33 = load double, double* %10
%34 = fsub double %32, %33
%35 = load double, double* %10
%36 = call double @llvm.fmuladd.f64(double %31, double %34, double %35)
store double %36, double* %7
br label %45
37: ; preds = %25
%38 = load double, double* %8
%39 = call i64 @isnan(double %38)
%40 = icmp ne i64 %39, 0
br i1 %40, label %41, label %43
41: ; preds = %37
%42 = load double, double* @NAN
store double %42, double* %7
br label %45
43: ; preds = %37
%44 = load double, double* %11
store double %44, double* %7
br label %45
45: ; preds = %43, %41, %28, %16
%46 = load double, double* %7
ret double %46
}

LLVM IR (-O2):
@NAN = global double 0.000000e+00
define double @pwm_map(double %0, double %1, double %2, double %3, double %4, double %5) {
%7 = fcmp olt double %0, 0.000000e+00
br i1 %7, label %8, label %13
8: ; preds = %6
%9 = fneg double %0
%10 = tail call double @fmin(i32 1, double %9)
%11 = fsub double %1, %2
%12 = tail call double @llvm.fmuladd.f64(double %10, double %11, double %2)
br label %25
13: ; preds = %6
%14 = fcmp ogt double %0, 0.000000e+00
br i1 %14, label %15, label %20
15: ; preds = %13
%16 = fneg double %0
%17 = tail call double @fmin(i32 1, double %16)
%18 = fsub double %1, %2
%19 = tail call double @llvm.fmuladd.f64(double %17, double %18, double %2)
br label %25
20: ; preds = %13
%21 = tail call i64 @isnan(double %0)
%22 = icmp eq i64 %21, 0
%23 = load double, double* @NAN
%24 = select i1 %22, double %3, double %23
br label %25
25: ; preds = %20, %15, %8
%26 = phi double [ %12, %8 ], [ %19, %15 ], [ %24, %20 ]
ret double %26
}