user: 请从给定的汇编指令推导出C源代码:

```asm
<decode_8_half>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x28,%rsp
  mov    %rdi,%r14
  mov    %rsi,%r12
  mov    %edx,%r13d
  mov    %rcx,%rbx
  mov    %r8,%rbp
  mov    %fs:0x28,%rax
  mov    %rax,0x18(%rsp)
  xor    %eax,%eax
  mov    $0x10,%edx
  mov    $0x0,%esi
  mov    %r12,%rdi
  call   <memset@plt>
  lea    0x2(%r13),%r15d
  movzbl (%r14),%esi
  shr    $0x6,%sil
  movzbl %sil,%esi
  mov    %r13d,%ecx
  shl    %cl,%esi
  movswl %si,%esi
  mov    %r15d,%edi
  call   <sfx_sign_extend@plt>
  mov    %ax,(%rsp)
  movzbl (%r14),%esi
  sar    $0x4,%esi
  and    $0x3,%esi
  mov    %r13d,%ecx
  shl    %cl,%esi
  movswl %si,%esi
  mov    %r15d,%edi
  call   <sfx_sign_extend@plt>
  mov    %ax,0x2(%rsp)
  movzbl (%r14),%esi
  sar    $0x2,%esi
  and    $0x3,%esi
  mov    %r13d,%ecx
  shl    %cl,%esi
  movswl %si,%esi
  mov    %r15d,%edi
  call   <sfx_sign_extend@plt>
  mov    %ax,0x4(%rsp)
  movzbl (%r14),%esi
  and    $0x3,%esi
  mov    %r13d,%ecx
  shl    %cl,%esi
  movswl %si,%esi
  mov    %r15d,%edi
  call   <sfx_sign_extend@plt>
  mov    %ax,0x6(%rsp)
  movzbl 0x1(%r14),%esi
  shr    $0x6,%sil
  movzbl %sil,%esi
  mov    %r13d,%ecx
  shl    %cl,%esi
  movswl %si,%esi
  mov    %r15d,%edi
  call   <sfx_sign_extend@plt>
  mov    %ax,0x8(%rsp)
  movzbl 0x1(%r14),%esi
  sar    $0x4,%esi
  and    $0x3,%esi
  mov    %r13d,%ecx
  shl    %cl,%esi
  movswl %si,%esi
  mov    %r15d,%edi
  call   <sfx_sign_extend@plt>
  mov    %ax,0xa(%rsp)
  movzbl 0x1(%r14),%esi
  sar    $0x2,%esi
  and    $0x3,%esi
  mov    %r13d,%ecx
  shl    %cl,%esi
  movswl %si,%esi
  mov    %r15d,%edi
  call   <sfx_sign_extend@plt>
  mov    %ax,0xc(%rsp)
  movzbl 0x1(%r14),%esi
  and    $0x3,%esi
  mov    %r13d,%ecx
  shl    %cl,%esi
  movswl %si,%esi
  mov    %r15d,%edi
  call   <sfx_sign_extend@plt>
  mov    %ax,0xe(%rsp)
  mov    $0xffffffffffffffff,%r8
  mov    %rsp,%r10
  mov    $0x7fff,%r9d
  movss  D14(%rip),%xmm1
  mov    $0xffff8000,%r11d
  jmp    L31
L78:
  mov    %ax,0x2(%r12,%r8,2)
  add    $0x1,%r8
  cmp    $0x7,%r8
  je     L54
L31:
  movswl 0x2(%rbx,%r8,2),%eax
  movswl 0xc(%rbp),%edx
  imul   %edx,%eax
  cltq
  movswl 0x12(%rbx,%r8,2),%ecx
  movswl 0xe(%rbp),%edx
  imul   %edx,%ecx
  movslq %ecx,%rcx
  add    %rax,%rcx
  lea    0x1(%r8),%eax
  test   %eax,%eax
  jle    L56
  mov    %rsp,%rsi
  mov    %r8,%rdx
L43:
  movswl (%rsi),%eax
  movswl 0x10(%rbx,%rdx,2),%edi
  imul   %edi,%eax
  cltq
  add    %rax,%rcx
  sub    $0x1,%rdx
  add    $0x2,%rsi
  test   %edx,%edx
  jns    L43
L56:
  movswl 0x2(%r10,%r8,2),%eax
  shl    $0xb,%eax
  cltq
  add    %rcx,%rax
  sar    $0xb,%rax
  pxor   %xmm0,%xmm0
  cvtsi2ss %rax,%xmm0
  mov    %r9d,%eax
  comiss D12(%rip),%xmm0
  ja     L78
  mov    %r11d,%eax
  comiss %xmm0,%xmm1
  ja     L78
  cvttss2si %xmm0,%eax
  jmp    L78
L54:
  mov    $0x10,%edx
  mov    %r12,%rsi
  mov    %rbp,%rdi
  call   <memcpy@plt>
  mov    0x18(%rsp),%rax
  sub    %fs:0x28,%rax
  jne    L27
  add    $0x28,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L27:
  call   <__stack_chk_fail@plt>
```

tool_calls: name: read_data
arguments: data_tag: D14
data_type: byte[4]
name: read_data
arguments: data_tag: D12
data_type: byte[4]

tool: {"D14": [0x00,0x00,0x00,0xc7]}

tool: {"D12": [0x00,0xfe,0xff,0x46]}

assistant: ```c
void decode_8_half(unsigned char *in, signed short *out, int index, signed short *pred1, signed short lastsmp[8]) {
  int i;
  signed short tmp[8];
  signed long total = 0;
  signed short sample = 0;
  memset(out, 0, sizeof(signed short) * 8);
  signed short *pred2 = (pred1 + 8);
  tmp[0] = (((((*in) & 0xC0) >> 6) & 0x3)) << (index);
  tmp[0] = sfx_sign_extend(index + 2, tmp[0]);
  tmp[1] = (((((*in) & 0x30) >> 4) & 0x3)) << (index);
  tmp[1] = sfx_sign_extend(index + 2, tmp[1]);
  tmp[2] = (((((*in) & 0x0C) >> 2) & 0x3)) << (index);
  tmp[2] = sfx_sign_extend(index + 2, tmp[2]);
  tmp[3] = ((((*in++) & 0x03) & 0x3)) << (index);
  tmp[3] = sfx_sign_extend(index + 2, tmp[3]);
  tmp[4] = (((((*in) & 0xC0) >> 6) & 0x3)) << (index);
  tmp[4] = sfx_sign_extend(index + 2, tmp[4]);
  tmp[5] = (((((*in) & 0x30) >> 4) & 0x3)) << (index);
  tmp[5] = sfx_sign_extend(index + 2, tmp[5]);
  tmp[6] = (((((*in) & 0x0C) >> 2) & 0x3)) << (index);
  tmp[6] = sfx_sign_extend(index + 2, tmp[6]);
  tmp[7] = ((((*in++) & 0x03) & 0x3)) << (index);
  tmp[7] = sfx_sign_extend(index + 2, tmp[7]);
  for (i = 0; i < 8; i++) {
    total = (pred1[i] * lastsmp[6]);
    total += (pred2[i] * lastsmp[7]);
    if (i > 0) {
      for (int x = i - 1; x > -1; x--) {
        total += (tmp[((i - 1) - x)] * pred2[x]);
      }
    }
    float result = ((tmp[i] << 0xb) + total) >> 0xb;
    if (result > 32767)
      sample = 32767;
    else if (result < -32768)
      sample = -32768;
    else
      sample = (signed short)result;
    out[i] = sample;
  }
  memcpy(lastsmp, out, sizeof(signed short) * 8);
}
```