#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 */
float log(double);
float adsr_envelope(int A_LENGTH, int D_LENGTH, int S_LENGTH, int R_LENGTH,
                    float S_LEVEL, int sample_number) {
  if (S_LEVEL < 0.0)
    S_LEVEL = 0.0;
  if (S_LEVEL > 1.0)
    S_LEVEL = 1.0;
  if (sample_number > A_LENGTH + D_LENGTH + S_LENGTH + R_LENGTH) {
    return 0.0;
  } else if (sample_number > A_LENGTH + D_LENGTH + S_LENGTH) {
    return S_LEVEL *
           (1.0 -
            (log(1 + (((float)(sample_number - A_LENGTH - D_LENGTH - S_LENGTH) /
                       R_LENGTH) *
                      (2.7182818284590452354 - 1)))));
  } else if (sample_number > A_LENGTH + D_LENGTH) {
    return S_LEVEL;
  } else if (sample_number > A_LENGTH) {
    return S_LEVEL -
           (S_LEVEL - 1.0 -
            ((S_LEVEL - 1.0) *
             log(1.0 + (((float)(sample_number - A_LENGTH) / D_LENGTH) *
                        (2.7182818284590452354 - 1)))));
  } else {
    return log(1.0 +
               ((float)sample_number / A_LENGTH * (2.7182818284590452354 - 1)));
  }
}


x86 assembly (clang, -O0):
<adsr_envelope>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %edi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
mov    %ecx,-0x14(%rbp)
movss  %xmm0,-0x18(%rbp)
mov    %r8d,-0x1c(%rbp)
movss  -0x18(%rbp),%xmm0
cvtss2sd %xmm0,%xmm1
xorps  %xmm0,%xmm0
ucomisd %xmm1,%xmm0
jbe    114b <adsr_envelope+0x3b>
xorps  %xmm0,%xmm0
movss  %xmm0,-0x18(%rbp)
movss  -0x18(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xea4(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    1173 <adsr_envelope+0x63>
movss  0xea2(%rip),%xmm0
movss  %xmm0,-0x18(%rbp)
mov    -0x1c(%rbp),%eax
mov    -0x8(%rbp),%ecx
add    -0xc(%rbp),%ecx
add    -0x10(%rbp),%ecx
add    -0x14(%rbp),%ecx
cmp    %ecx,%eax
jle    1197 <adsr_envelope+0x87>
xorps  %xmm0,%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    133a <adsr_envelope+0x22a>
mov    -0x1c(%rbp),%eax
mov    -0x8(%rbp),%ecx
add    -0xc(%rbp),%ecx
add    -0x10(%rbp),%ecx
cmp    %ecx,%eax
jle    121d <adsr_envelope+0x10d>
movss  -0x18(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,-0x28(%rbp)
mov    -0x1c(%rbp),%eax
sub    -0x8(%rbp),%eax
sub    -0xc(%rbp),%eax
sub    -0x10(%rbp),%eax
cvtsi2ss %eax,%xmm0
cvtsi2ssl -0x14(%rbp),%xmm1
divss  %xmm1,%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xe2a(%rip),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xe16(%rip),%xmm1
addsd  %xmm1,%xmm0
call   1030 <log@plt>
movaps %xmm0,%xmm1
movsd  -0x28(%rbp),%xmm0
cvtss2sd %xmm1,%xmm2
movsd  0xdf9(%rip),%xmm1
subsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    133a <adsr_envelope+0x22a>
mov    -0x1c(%rbp),%eax
mov    -0x8(%rbp),%ecx
add    -0xc(%rbp),%ecx
cmp    %ecx,%eax
jle    123d <adsr_envelope+0x12d>
movss  -0x18(%rbp),%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    133a <adsr_envelope+0x22a>
mov    -0x1c(%rbp),%eax
cmp    -0x8(%rbp),%eax
jle    1306 <adsr_envelope+0x1f6>
movss  -0x18(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,-0x30(%rbp)
movss  -0x18(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xd98(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
movss  -0x18(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xd7e(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x1c(%rbp),%eax
sub    -0x8(%rbp),%eax
cvtsi2ss %eax,%xmm0
cvtsi2ssl -0xc(%rbp),%xmm1
divss  %xmm1,%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xd5e(%rip),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xd4a(%rip),%xmm1
addsd  %xmm1,%xmm0
call   1030 <log@plt>
movsd  -0x40(%rbp),%xmm1
movsd  -0x38(%rbp),%xmm2
movaps %xmm0,%xmm3
movsd  -0x30(%rbp),%xmm0
cvtss2sd %xmm3,%xmm3
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm3,%xmm1
addsd  %xmm2,%xmm1
subsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    133a <adsr_envelope+0x22a>
cvtsi2ssl -0x1c(%rbp),%xmm0
cvtsi2ssl -0x8(%rbp),%xmm1
divss  %xmm1,%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xce8(%rip),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xcd4(%rip),%xmm1
addsd  %xmm1,%xmm0
call   1030 <log@plt>
movss  %xmm0,-0x4(%rbp)
movss  -0x4(%rbp),%xmm0
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<adsr_envelope>:
sub    $0x18,%rsp
movaps %xmm0,%xmm1
xorps  %xmm0,%xmm0
lea    (%rsi,%rdi,1),%r9d
add    %r9d,%edx
lea    (%rdx,%rcx,1),%eax
cmp    %r8d,%eax
jl     121c <adsr_envelope+0x10c>
xorps  %xmm2,%xmm2
maxss  %xmm1,%xmm2
movss  0xec4(%rip),%xmm0
minss  %xmm2,%xmm0
cmp    %r8d,%edx
jge    11a3 <adsr_envelope+0x93>
sub    %edx,%r8d
xorps  %xmm1,%xmm1
cvtsi2ss %r8d,%xmm1
xorps  %xmm2,%xmm2
cvtsi2ss %ecx,%xmm2
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,0x8(%rsp)
divss  %xmm2,%xmm1
xorps  %xmm0,%xmm0
cvtss2sd %xmm1,%xmm0
mulsd  0xe94(%rip),%xmm0
addsd  0xe94(%rip),%xmm0
call   1030 <log@plt>
cvtss2sd %xmm0,%xmm0
movsd  0xe83(%rip),%xmm1
subsd  %xmm0,%xmm1
mulsd  0x8(%rsp),%xmm1
xorps  %xmm0,%xmm0
cvtsd2ss %xmm1,%xmm0
add    $0x18,%rsp
ret
cmp    %r8d,%r9d
jl     121c <adsr_envelope+0x10c>
mov    %r8d,%eax
sub    %edi,%eax
jle    1221 <adsr_envelope+0x111>
xorps  %xmm1,%xmm1
cvtsi2ss %eax,%xmm1
xorps  %xmm2,%xmm2
cvtss2sd %xmm0,%xmm2
movsd  %xmm2,0x8(%rsp)
xorps  %xmm0,%xmm0
cvtsi2ss %esi,%xmm0
movsd  0xe46(%rip),%xmm3
addsd  %xmm2,%xmm3
movsd  %xmm3,0x10(%rsp)
divss  %xmm0,%xmm1
xorps  %xmm0,%xmm0
cvtss2sd %xmm1,%xmm0
mulsd  0xe19(%rip),%xmm0
addsd  0xe19(%rip),%xmm0
call   1030 <log@plt>
cvtss2sd %xmm0,%xmm0
movsd  0x10(%rsp),%xmm1
mulsd  %xmm1,%xmm0
subsd  %xmm0,%xmm1
movsd  0x8(%rsp),%xmm0
subsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
add    $0x18,%rsp
ret
xorps  %xmm0,%xmm0
cvtsi2ss %r8d,%xmm0
xorps  %xmm1,%xmm1
cvtsi2ss %edi,%xmm1
divss  %xmm1,%xmm0
cvtss2sd %xmm0,%xmm0
mulsd  0xdc8(%rip),%xmm0
addsd  0xdc8(%rip),%xmm0
add    $0x18,%rsp
jmp    1030 <log@plt>

LLVM IR (-O0):
define float @adsr_envelope(i32 %0, i32 %1, i32 %2, i32 %3, float %4, i32 %5) {
%7 = alloca float
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
%11 = alloca i32
%12 = alloca float
%13 = alloca i32
store i32 %0, i32* %8
store i32 %1, i32* %9
store i32 %2, i32* %10
store i32 %3, i32* %11
store float %4, float* %12
store i32 %5, i32* %13
%14 = load float, float* %12
%15 = fpext float %14 to double
%16 = fcmp olt double %15, 0.000000e+00
br i1 %16, label %17, label %18
17: ; preds = %6
store float 0.000000e+00, float* %12
br label %18
18: ; preds = %17, %6
%19 = load float, float* %12
%20 = fpext float %19 to double
%21 = fcmp ogt double %20, 1.000000e+00
br i1 %21, label %22, label %23
22: ; preds = %18
store float 1.000000e+00, float* %12
br label %23
23: ; preds = %22, %18
%24 = load i32, i32* %13
%25 = load i32, i32* %8
%26 = load i32, i32* %9
%27 = add nsw i32 %25, %26
%28 = load i32, i32* %10
%29 = add nsw i32 %27, %28
%30 = load i32, i32* %11
%31 = add nsw i32 %29, %30
%32 = icmp sgt i32 %24, %31
br i1 %32, label %33, label %34
33: ; preds = %23
store float 0.000000e+00, float* %7
br label %108
34: ; preds = %23
%35 = load i32, i32* %13
%36 = load i32, i32* %8
%37 = load i32, i32* %9
%38 = add nsw i32 %36, %37
%39 = load i32, i32* %10
%40 = add nsw i32 %38, %39
%41 = icmp sgt i32 %35, %40
br i1 %41, label %42, label %63
42: ; preds = %34
%43 = load float, float* %12
%44 = fpext float %43 to double
%45 = load i32, i32* %13
%46 = load i32, i32* %8
%47 = sub nsw i32 %45, %46
%48 = load i32, i32* %9
%49 = sub nsw i32 %47, %48
%50 = load i32, i32* %10
%51 = sub nsw i32 %49, %50
%52 = sitofp i32 %51 to float
%53 = load i32, i32* %11
%54 = sitofp i32 %53 to float
%55 = fdiv float %52, %54
%56 = fpext float %55 to double
%57 = call double @llvm.fmuladd.f64(double %56, double 0x3FFB7E151628AED2, double 1.000000e+00)
%58 = call float @log(double %57)
%59 = fpext float %58 to double
%60 = fsub double 1.000000e+00, %59
%61 = fmul double %44, %60
%62 = fptrunc double %61 to float
store float %62, float* %7
br label %108
63: ; preds = %34
%64 = load i32, i32* %13
%65 = load i32, i32* %8
%66 = load i32, i32* %9
%67 = add nsw i32 %65, %66
%68 = icmp sgt i32 %64, %67
br i1 %68, label %69, label %71
69: ; preds = %63
%70 = load float, float* %12
store float %70, float* %7
br label %108
71: ; preds = %63
%72 = load i32, i32* %13
%73 = load i32, i32* %8
%74 = icmp sgt i32 %72, %73
br i1 %74, label %75, label %99
75: ; preds = %71
%76 = load float, float* %12
%77 = fpext float %76 to double
%78 = load float, float* %12
%79 = fpext float %78 to double
%80 = fsub double %79, 1.000000e+00
%81 = load float, float* %12
%82 = fpext float %81 to double
%83 = fsub double %82, 1.000000e+00
%84 = load i32, i32* %13
%85 = load i32, i32* %8
%86 = sub nsw i32 %84, %85
%87 = sitofp i32 %86 to float
%88 = load i32, i32* %9
%89 = sitofp i32 %88 to float
%90 = fdiv float %87, %89
%91 = fpext float %90 to double
%92 = call double @llvm.fmuladd.f64(double %91, double 0x3FFB7E151628AED2, double 1.000000e+00)
%93 = call float @log(double %92)
%94 = fpext float %93 to double
%95 = fneg double %83
%96 = call double @llvm.fmuladd.f64(double %95, double %94, double %80)
%97 = fsub double %77, %96
%98 = fptrunc double %97 to float
store float %98, float* %7
br label %108
99: ; preds = %71
%100 = load i32, i32* %13
%101 = sitofp i32 %100 to float
%102 = load i32, i32* %8
%103 = sitofp i32 %102 to float
%104 = fdiv float %101, %103
%105 = fpext float %104 to double
%106 = call double @llvm.fmuladd.f64(double %105, double 0x3FFB7E151628AED2, double 1.000000e+00)
%107 = call float @log(double %106)
store float %107, float* %7
br label %108
108: ; preds = %99, %75, %69, %42, %33
%109 = load float, float* %7
ret float %109
}

LLVM IR (-O2):
define float @adsr_envelope(i32 %0, i32 %1, i32 %2, i32 %3, float %4, i32 %5) {
%7 = fcmp olt float %4, 0.000000e+00
%8 = select i1 %7, float 0.000000e+00, float %4
%9 = fcmp ogt float %8, 1.000000e+00
%10 = select i1 %9, float 1.000000e+00, float %8
%11 = add i32 %1, %0
%12 = add i32 %11, %2
%13 = add nsw i32 %12, %3
%14 = icmp slt i32 %13, %5
br i1 %14, label %56, label %15
15: ; preds = %6
%16 = icmp slt i32 %12, %5
br i1 %16, label %17, label %30
17: ; preds = %15
%18 = fpext float %10 to double
%19 = sub i32 %5, %12
%20 = sitofp i32 %19 to float
%21 = sitofp i32 %3 to float
%22 = fdiv float %20, %21
%23 = fpext float %22 to double
%24 = tail call double @llvm.fmuladd.f64(double %23, double 0x3FFB7E151628AED2, double 1.000000e+00)
%25 = tail call float @log(double %24)
%26 = fpext float %25 to double
%27 = fsub double 1.000000e+00, %26
%28 = fmul double %27, %18
%29 = fptrunc double %28 to float
br label %56
30: ; preds = %15
%31 = icmp slt i32 %11, %5
br i1 %31, label %56, label %32
32: ; preds = %30
%33 = icmp sgt i32 %5, %0
br i1 %33, label %34, label %49
34: ; preds = %32
%35 = fpext float %10 to double
%36 = fadd double %35, -1.000000e+00
%37 = sub nsw i32 %5, %0
%38 = sitofp i32 %37 to float
%39 = sitofp i32 %1 to float
%40 = fdiv float %38, %39
%41 = fpext float %40 to double
%42 = tail call double @llvm.fmuladd.f64(double %41, double 0x3FFB7E151628AED2, double 1.000000e+00)
%43 = tail call float @log(double %42)
%44 = fpext float %43 to double
%45 = fneg double %36
%46 = tail call double @llvm.fmuladd.f64(double %45, double %44, double %36)
%47 = fsub double %35, %46
%48 = fptrunc double %47 to float
br label %56
49: ; preds = %32
%50 = sitofp i32 %5 to float
%51 = sitofp i32 %0 to float
%52 = fdiv float %50, %51
%53 = fpext float %52 to double
%54 = tail call double @llvm.fmuladd.f64(double %53, double 0x3FFB7E151628AED2, double 1.000000e+00)
%55 = tail call float @log(double %54)
br label %56
56: ; preds = %30, %6, %49, %34, %17
%57 = phi float [ %29, %17 ], [ %48, %34 ], [ %55, %49 ], [ 0.000000e+00, %6 ], [ %10, %30 ]
ret float %57
}