user: Translate the below assembly code into C programming language:

```asm
<idct_perform32_fixed>:
  endbr64
  push   %r15
  xor    %r15d,%r15d
  push   %r14
  mov    %rdi,%r14
  push   %r13
  lea    0x80(%rdi),%r13
  push   %r12
  mov    %rdi,%r12
  push   %rbp
  mov    %rdi,%rbp
  push   %rbx
  mov    %rsi,%rbx
  sub    $0x18,%rsp
  nopl   0x0(%rax,%rax,1)
L26:
  mov    (%r12),%edi
  add    $0x4,%r12
  call   <abs@plt>
  add    %eax,%r15d
  cmp    %r13,%r12
  jne    L26
  xor    %r12d,%r12d
  cmp    $0x400000,%r15d
  setg   %r12b
  add    %r12d,%r12d
  cs nopw 0x0(%rax,%rax,1)
L1:
  mov    0x0(%rbp),%eax
  mov    %r12d,%ecx
  add    $0x4,%rbp
  add    %r12d,%eax
  sar    %cl,%eax
  mov    %eax,-0x4(%rbp)
  cmp    %r13,%rbp
  jne    L1
  lea    0x40(%rbx),%rbp
  mov    $0x10,%edx
  mov    %rbx,%rsi
  mov    %r14,%rdi
  call   <sum_a@plt>
  mov    $0x10,%edx
  mov    %rbp,%rsi
  mov    %r14,%rdi
  call   <sum_b@plt>
  mov    %rbx,%rdi
  lea    0x40(%r14),%r13
  lea    0x60(%r14),%r15
  mov    $0x20,%esi
  call   <clp_v@plt>
  mov    $0x8,%edx
  mov    %r14,%rsi
  mov    %rbx,%rdi
  call   <sum_a@plt>
  lea    0x20(%r14),%r8
  mov    $0x8,%edx
  mov    %rbx,%rdi
  mov    %r8,%rsi
  mov    %r8,0x8(%rsp)
  call   <sum_b@plt>
  mov    %rbp,%rdi
  mov    $0x8,%edx
  mov    %r13,%rsi
  call   <sum_c@plt>
  mov    $0x8,%edx
  mov    %rbp,%rdi
  mov    %r15,%rsi
  call   <sum_d@plt>
  mov    $0x20,%esi
  mov    %r14,%rdi
  call   <clp_v@plt>
  mov    %rbx,%rsi
  mov    %r14,%rdi
  call   <dct_a@plt>
  mov    0x8(%rsp),%rdi
  lea    0x20(%rbx),%rsi
  call   <dct_b@plt>
  mov    %rbp,%rsi
  mov    %r13,%rdi
  call   <dct_b@plt>
  lea    0x60(%rbx),%rsi
  mov    %r15,%rdi
  call   <dct_b@plt>
  mov    $0x20,%esi
  mov    %rbx,%rdi
  call   <clp_v@plt>
  mov    %r14,%rsi
  mov    %rbx,%rdi
  call   <mod_a@plt>
  mov    %rbp,%rdi
  mov    %r13,%rsi
  lea    0x80(%rbx),%rbp
  call   <mod_b@plt>
  mov    $0x20,%esi
  mov    %r14,%rdi
  call   <clp_v@plt>
  mov    %rbx,%rsi
  mov    %r14,%rdi
  call   <mod_c@plt>
  nopl   0x0(%rax,%rax,1)
L21:
  mov    (%rbx),%edi
  mov    %r12d,%ecx
  add    $0x4,%rbx
  shl    %cl,%edi
  call   <clip23@plt>
  mov    %eax,-0x4(%rbx)
  cmp    %rbx,%rbp
  jne    L21
  add    $0x18,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
```

assistant: ```c
void idct_perform32_fixed(int *restrict input, int *restrict output) {
  int mag = 0;
  for (int i = 0; i < 32; i++)
    mag += abs(input[i]);
  int shift = mag > 0x400000 ? 2 : 0;
  int round = shift > 0 ? 1 << (shift - 1) : 0;
  for (int i = 0; i < 32; i++)
    input[i] = (input[i] + round) >> shift;
  sum_a(input, output + 0, 16);
  sum_b(input, output + 16, 16);
  clp_v(output, 32);
  sum_a(output + 0, input + 0, 8);
  sum_b(output + 0, input + 8, 8);
  sum_c(output + 16, input + 16, 8);
  sum_d(output + 16, input + 24, 8);
  clp_v(input, 32);
  dct_a(input + 0, output + 0);
  dct_b(input + 8, output + 8);
  dct_b(input + 16, output + 16);
  dct_b(input + 24, output + 24);
  clp_v(output, 32);
  mod_a(output + 0, input + 0);
  mod_b(output + 16, input + 16);
  clp_v(input, 32);
  mod_c(input, output);
  for (int i = 0; i < 32; i++)
    output[i] = clip23(output[i] * (1 << shift));
}
```