void SsAdpcm_pack(double *d_samples, short *four_bit, int predict_nr,
                  int shift_factor) {
  static double f[5][2] = {{0.0, 0.0},
                           {-60.0 / 64.0, 0.0},
                           {-115.0 / 64.0, 52.0 / 64.0},
                           {-98.0 / 64.0, 55.0 / 64.0},
                           {-122.0 / 64.0, 60.0 / 64.0}};
  double ds;
  int di;
  double s_0;
  static double s_1 = 0.0;
  static double s_2 = 0.0;
  int i;
  for (i = 0; i < 28; i++) {
    s_0 = d_samples[i] + s_1 * f[predict_nr][0] + s_2 * f[predict_nr][1];
    ds = s_0 * (double)(1 << shift_factor);
    di = ((int)ds + 0x800) & 0xfffff000;
    if (di > 32767)
      di = 32767;
    if (di < -32768)
      di = -32768;
    four_bit[i] = (short)di;
    di = di >> shift_factor;
    s_2 = s_1;
    s_1 = (double)di - s_0;
  }
}


x86 assembly (clang, -O0):
<SsAdpcm_pack>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    %ecx,-0x18(%rbp)
movl   $0x0,-0x34(%rbp)
cmpl   $0x1c,-0x34(%rbp)
jge    1225 <SsAdpcm_pack+0x125>
mov    -0x8(%rbp),%rax
movslq -0x34(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  0x2f50(%rip),%xmm1
movslq -0x14(%rbp),%rcx
lea    0x2eed(%rip),%rax
shl    $0x4,%rcx
add    %rcx,%rax
movsd  (%rax),%xmm2
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
movsd  0x2f32(%rip),%xmm0
movslq -0x14(%rbp),%rcx
lea    0x2ec7(%rip),%rax
shl    $0x4,%rcx
add    %rcx,%rax
movsd  0x8(%rax),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x30(%rbp),%xmm0
mov    -0x18(%rbp),%ecx
mov    $0x1,%eax
shl    %cl,%eax
cvtsi2sd %eax,%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
cvttsd2si -0x20(%rbp),%eax
add    $0x800,%eax
and    $0xfffff000,%eax
mov    %eax,-0x24(%rbp)
cmpl   $0x7fff,-0x24(%rbp)
jle    11c4 <SsAdpcm_pack+0xc4>
movl   $0x7fff,-0x24(%rbp)
cmpl   $0xffff8000,-0x24(%rbp)
jge    11d8 <SsAdpcm_pack+0xd8>
movl   $0xffff8000,-0x24(%rbp)
mov    -0x24(%rbp),%eax
mov    %ax,%dx
mov    -0x10(%rbp),%rax
movslq -0x34(%rbp),%rcx
mov    %dx,(%rax,%rcx,2)
mov    -0x24(%rbp),%eax
mov    -0x18(%rbp),%ecx
sar    %cl,%eax
mov    %eax,-0x24(%rbp)
movsd  0x2e8b(%rip),%xmm0
movsd  %xmm0,0x2e8b(%rip)
cvtsi2sdl -0x24(%rbp),%xmm0
subsd  -0x30(%rbp),%xmm0
movsd  %xmm0,0x2e71(%rip)
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    1119 <SsAdpcm_pack+0x19>
pop    %rbp
ret

x86 assembly (clang, -O2):
<SsAdpcm_pack>:
movslq %edx,%rax
shl    $0x4,%rax
lea    0xef2(%rip),%r8
movsd  (%rax,%r8,1),%xmm0
mov    $0x1,%edx
shl    %cl,%edx
movsd  0x8(%rax,%r8,1),%xmm1
cvtsi2sd %edx,%xmm2
movsd  0x2efa(%rip),%xmm4
movsd  0x2efa(%rip),%xmm3
xor    %eax,%eax
mov    $0x7fff,%r8d
mov    $0xffff8000,%r9d
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movapd %xmm3,%xmm5
movapd %xmm4,%xmm3
mulsd  %xmm1,%xmm5
movapd %xmm4,%xmm6
mulsd  %xmm0,%xmm6
addsd  (%rdi,%rax,8),%xmm6
addsd  %xmm5,%xmm6
movapd %xmm6,%xmm4
mulsd  %xmm2,%xmm4
cvttsd2si %xmm4,%edx
add    $0x800,%edx
and    $0xfffff000,%edx
cmp    $0x7fff,%edx
cmovge %r8d,%edx
cmp    $0xffff8001,%edx
cmovl  %r9d,%edx
mov    %dx,(%rsi,%rax,2)
sar    %cl,%edx
xorps  %xmm4,%xmm4
cvtsi2sd %edx,%xmm4
subsd  %xmm6,%xmm4
add    $0x1,%rax
cmp    $0x1c,%rax
jne    1150 <SsAdpcm_pack+0x50>
movsd  %xmm4,0x2e6c(%rip)
movsd  %xmm3,0x2e6c(%rip)
ret

LLVM IR (-O0):
@SsAdpcm_pack.f = internal global [5 x [2 x double]] [[2 x double] zeroinitializer, [2 x double] [double -9.375000e-01, double 0.000000e+00], [2 x double] [double 0xBFFCC00000000000, double 8.125000e-01], [2 x double] [double -1.531250e+00, double 8.593750e-01], [2 x double] [double -1.906250e+00, double 9.375000e-01]]
@SsAdpcm_pack.s_1 = internal global double 0.000000e+00
@SsAdpcm_pack.s_2 = internal global double 0.000000e+00
define void @SsAdpcm_pack(double* %0, i16* %1, i32 %2, i32 %3) {
%5 = alloca double*
%6 = alloca i16*
%7 = alloca i32
%8 = alloca i32
%9 = alloca double
%10 = alloca i32
%11 = alloca double
%12 = alloca i32
store double* %0, double** %5
store i16* %1, i16** %6
store i32 %2, i32* %7
store i32 %3, i32* %8
store i32 0, i32* %12
br label %13
13: ; preds = %67, %4
%14 = load i32, i32* %12
%15 = icmp slt i32 %14, 28
br i1 %15, label %16, label %70
16: ; preds = %13
%17 = load double*, double** %5
%18 = load i32, i32* %12
%19 = sext i32 %18 to i64
%20 = getelementptr inbounds double, double* %17, i64 %19
%21 = load double, double* %20
%22 = load double, double* @SsAdpcm_pack.s_1
%23 = load i32, i32* %7
%24 = sext i32 %23 to i64
%25 = getelementptr inbounds [5 x [2 x double]], [5 x [2 x double]]* @SsAdpcm_pack.f, i64 0, i64 %24
%26 = getelementptr inbounds [2 x double], [2 x double]* %25, i64 0, i64 0
%27 = load double, double* %26
%28 = call double @llvm.fmuladd.f64(double %22, double %27, double %21)
%29 = load double, double* @SsAdpcm_pack.s_2
%30 = load i32, i32* %7
%31 = sext i32 %30 to i64
%32 = getelementptr inbounds [5 x [2 x double]], [5 x [2 x double]]* @SsAdpcm_pack.f, i64 0, i64 %31
%33 = getelementptr inbounds [2 x double], [2 x double]* %32, i64 0, i64 1
%34 = load double, double* %33
%35 = call double @llvm.fmuladd.f64(double %29, double %34, double %28)
store double %35, double* %11
%36 = load double, double* %11
%37 = load i32, i32* %8
%38 = shl i32 1, %37
%39 = sitofp i32 %38 to double
%40 = fmul double %36, %39
store double %40, double* %9
%41 = load double, double* %9
%42 = fptosi double %41 to i32
%43 = add nsw i32 %42, 2048
%44 = and i32 %43, -4096
store i32 %44, i32* %10
%45 = load i32, i32* %10
%46 = icmp sgt i32 %45, 32767
br i1 %46, label %47, label %48
47: ; preds = %16
store i32 32767, i32* %10
br label %48
48: ; preds = %47, %16
%49 = load i32, i32* %10
%50 = icmp slt i32 %49, -32768
br i1 %50, label %51, label %52
51: ; preds = %48
store i32 -32768, i32* %10
br label %52
52: ; preds = %51, %48
%53 = load i32, i32* %10
%54 = trunc i32 %53 to i16
%55 = load i16*, i16** %6
%56 = load i32, i32* %12
%57 = sext i32 %56 to i64
%58 = getelementptr inbounds i16, i16* %55, i64 %57
store i16 %54, i16* %58
%59 = load i32, i32* %10
%60 = load i32, i32* %8
%61 = ashr i32 %59, %60
store i32 %61, i32* %10
%62 = load double, double* @SsAdpcm_pack.s_1
store double %62, double* @SsAdpcm_pack.s_2
%63 = load i32, i32* %10
%64 = sitofp i32 %63 to double
%65 = load double, double* %11
%66 = fsub double %64, %65
store double %66, double* @SsAdpcm_pack.s_1
br label %67
67: ; preds = %52
%68 = load i32, i32* %12
%69 = add nsw i32 %68, 1
store i32 %69, i32* %12
br label %13
70: ; preds = %13
ret void
}

LLVM IR (-O2):
@SsAdpcm_pack.f = internal unnamed_addr constant [5 x [2 x double]] [[2 x double] zeroinitializer, [2 x double] [double -9.375000e-01, double 0.000000e+00], [2 x double] [double 0xBFFCC00000000000, double 8.125000e-01], [2 x double] [double -1.531250e+00, double 8.593750e-01], [2 x double] [double -1.906250e+00, double 9.375000e-01]]
@SsAdpcm_pack.s_1 = internal unnamed_addr global double 0.000000e+00
@SsAdpcm_pack.s_2 = internal unnamed_addr global double 0.000000e+00
define void @SsAdpcm_pack(double* nocapture %0, i16* nocapture writeonly %1, i32 %2, i32 %3) {
%5 = sext i32 %2 to i64
%6 = getelementptr inbounds [5 x [2 x double]], [5 x [2 x double]]* @SsAdpcm_pack.f, i64 0, i64 %5, i64 0
%7 = load double, double* %6
%8 = getelementptr inbounds [5 x [2 x double]], [5 x [2 x double]]* @SsAdpcm_pack.f, i64 0, i64 %5, i64 1
%9 = load double, double* %8
%10 = shl nuw i32 1, %3
%11 = sitofp i32 %10 to double
%12 = load double, double* @SsAdpcm_pack.s_1
%13 = load double, double* @SsAdpcm_pack.s_2
br label %14
14: ; preds = %4, %14
%15 = phi i64 [ 0, %4 ], [ %35, %14 ]
%16 = phi double [ %12, %4 ], [ %34, %14 ]
%17 = phi double [ %13, %4 ], [ %16, %14 ]
%18 = getelementptr inbounds double, double* %0, i64 %15
%19 = load double, double* %18
%20 = tail call double @llvm.fmuladd.f64(double %16, double %7, double %19)
%21 = tail call double @llvm.fmuladd.f64(double %17, double %9, double %20)
%22 = fmul double %21, %11
%23 = fptosi double %22 to i32
%24 = add nsw i32 %23, 2048
%25 = and i32 %24, -4096
%26 = icmp slt i32 %25, 32767
%27 = select i1 %26, i32 %25, i32 32767
%28 = icmp sgt i32 %27, -32768
%29 = select i1 %28, i32 %27, i32 -32768
%30 = trunc i32 %29 to i16
%31 = getelementptr inbounds i16, i16* %1, i64 %15
store i16 %30, i16* %31
%32 = ashr i32 %29, %3
%33 = sitofp i32 %32 to double
%34 = fsub double %33, %21
%35 = add nuw nsw i64 %15, 1
%36 = icmp eq i64 %35, 28
br i1 %36, label %37, label %14
37: ; preds = %14
store double %34, double* @SsAdpcm_pack.s_1
store double %16, double* @SsAdpcm_pack.s_2
ret void
}