user: Converte this assembly snippet into its equivalent C code:

```asm
<calc_error>:
  endbr64
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x8,%rsp
  mov    %rdi,%rbp
  mov    %rsi,%rbx
  mov    %edx,%r13d
  mov    %ecx,%r12d
  mov    %ecx,%edi
  call   <is_double_rettype@plt>
  test   %rax,%rax
  je     L439
  mov    0x0(%rbp),%edx
  mov    %edx,%ecx
  and    $0x7ff00000,%ecx
  cmp    $0x7ff00000,%ecx
  je     L266
  mov    (%rbx),%eax
  and    $0x7ff00000,%eax
  cmp    $0x7ff00000,%eax
  je     L266
L24:
  mov    0x0(%rbp),%eax
  xor    (%rbx),%eax
  js     L231
  mov    %r12d,%edi
  call   <is_double_rettype@plt>
  test   %rax,%rax
  je     L86
  mov    0x8(%rbx),%edx
  neg    %edx
  sete   %sil
  mov    0x4(%rbp),%eax
  mov    %eax,%edi
  sub    0x4(%rbx),%edi
  movzbl %sil,%ecx
  lea    -0x1(%rdi,%rcx,1),%edi
  mov    $0x1,%ecx
  cmp    %edi,%eax
  ja     L449
  sete   %cl
  movzbl %cl,%ecx
  and    %esi,%ecx
L449:
  mov    0x0(%rbp),%eax
  sub    (%rbx),%eax
  lea    -0x1(%rcx,%rax,1),%esi
L277:
  test   %r13d,%r13d
  jle    L129
  mov    $0x0,%eax
  cmp    $0x60,%r13d
  jg     L390
  cmp    $0x1f,%r13d
  jle    L421
  mov    %r13d,%edx
  jmp    L247
L266:
  test   $0x800fffff,%edx
  jne    L144
  cmpl   $0x0,0x4(%rbp)
  je     L401
L144:
  mov    (%rbx),%eax
  test   $0x800fffff,%eax
  jne    L245
  cmpl   $0x0,0x4(%rbx)
  je     L262
L245:
  cmp    $0x7ff00000,%ecx
  je     L358
L262:
  test   $0xfffff,%edx
  jne    L198
  cmpl   $0x0,0x4(%rbp)
  jne    L198
L356:
  mov    (%rbx),%ecx
  test   $0xfffff,%ecx
  jne    L198
  cmpl   $0x0,0x4(%rbx)
  jne    L198
  mov    $0x0,%eax
  cmp    %ecx,%edx
  je     L390
L198:
  mov    D23(%rip),%rax
  mov    (%rax),%rax
L390:
  add    $0x8,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  ret
L358:
  and    $0x7ff00000,%eax
  mov    %eax,%ecx
  mov    $0x0,%eax
  cmp    $0x7ff00000,%ecx
  jne    L262
  jmp    L390
L439:
  mov    0x0(%rbp),%edx
  mov    %edx,%ecx
  and    $0x7f800000,%ecx
  cmp    $0x7f800000,%ecx
  je     L268
  mov    (%rbx),%ecx
  and    $0x7f800000,%ecx
  cmp    $0x7f800000,%ecx
  jne    L24
L17:
  test   $0x7fffff,%edx
  jne    L178
  mov    (%rbx),%ecx
  test   $0x7fffff,%ecx
  jne    L178
  cmp    %ecx,%edx
  je     L390
L178:
  mov    D23(%rip),%rax
  mov    (%rax),%rax
  jmp    L390
L268:
  test   $0x807fffff,%edx
  je     L17
  mov    (%rbx),%ecx
  test   $0x807fffff,%ecx
  je     L17
  and    $0x7f800000,%ecx
  cmp    $0x7f800000,%ecx
  jne    L17
  jmp    L390
L231:
  mov    D23(%rip),%rax
  mov    (%rax),%rax
  jmp    L390
L86:
  mov    0x4(%rbx),%edx
  neg    %edx
  sete   %cl
  mov    0x0(%rbp),%eax
  mov    %eax,%edi
  sub    (%rbx),%edi
  movzbl %cl,%esi
  lea    -0x1(%rdi,%rsi,1),%edi
  mov    $0x1,%esi
  cmp    %edi,%eax
  ja     L152
  sete   %sil
  movzbl %sil,%esi
  and    %ecx,%esi
L152:
  sub    $0x1,%esi
  jmp    L277
L415:
  mov    %esi,%edi
  mov    %eax,%esi
L247:
  mov    %esi,%eax
  sar    $0x1f,%eax
  mov    %eax,%r8d
  sub    $0x20,%edx
  cmp    $0x1f,%edx
  jg     L415
  and    $0x1f,%r13d
  jne    L443
  mov    %edi,%edx
  mov    %esi,%edi
  mov    %eax,%esi
  jmp    L129
L421:
  mov    %esi,%r8d
  mov    %edi,%esi
  mov    %edx,%edi
L443:
  mov    %r13d,%ecx
  shr    %cl,%edi
  mov    $0x20,%eax
  sub    %r13d,%eax
  mov    %esi,%edx
  mov    %eax,%ecx
  shl    %cl,%edx
  or     %edi,%edx
  mov    %r13d,%ecx
  shr    %cl,%esi
  mov    %r8d,%edi
  mov    %eax,%ecx
  shl    %cl,%edi
  or     %esi,%edi
  mov    %r8d,%esi
  mov    %r13d,%ecx
  shr    %cl,%esi
  sar    $0x1f,%r8d
  mov    %eax,%ecx
  shl    %cl,%r8d
  or     %r8d,%esi
L129:
  test   %esi,%esi
  js     L278
  cmp    $0x7ffff,%esi
  ja     L195
  shr    $0x14,%edx
  shl    $0xc,%edi
  or     %edi,%edx
  mov    %rsi,%rax
  shl    $0x2c,%rax
  or     %rdx,%rax
  jmp    L390
L278:
  xor    $0xffffffff,%edx
  mov    %edx,%ecx
  sete   %dl
  movzbl %dl,%edx
  mov    %edx,%eax
  sub    %edi,%eax
  sub    $0x1,%eax
  sub    %esi,%edx
  sub    $0x1,%edx
  cmp    $0x7ffff,%edx
  ja     L195
  shl    $0xc,%eax
  shr    $0x14,%ecx
  or     %eax,%ecx
  mov    %rdx,%rax
  shl    $0x2c,%rax
  or     %rcx,%rax
  neg    %rax
  jmp    L390
L195:
  mov    D23(%rip),%rax
  mov    (%rax),%rax
  jmp    L390
L401:
  test   $0xfffff,%edx
  je     L356
  jmp    L198
```

assistant: ```c
long long calc_error(unsigned a[2], unsigned b[3], int shift, int rettype) {
  unsigned r0, r1, r2;
  int sign, carry;
  long long result;
  if (is_double_rettype(rettype)) {
    if ((a[0] & 0x7FF00000) == 0x7FF00000 || (b[0] & 0x7FF00000) == 0x7FF00000) {
      if (((a[0] & 0x800FFFFF) || a[1]) && ((b[0] & 0x800FFFFF) || b[1]) && (a[0] & 0x7FF00000) == 0x7FF00000 && (b[0] & 0x7FF00000) == 0x7FF00000)
        return 0;
      if (!((a[0] & 0xFFFFF) || a[1]) && !((b[0] & 0xFFFFF) || b[1]) && a[0] == b[0])
        return 0;
      return LLONG_MAX;
    }
  } else {
    if ((a[0] & 0x7F800000) == 0x7F800000 || (b[0] & 0x7F800000) == 0x7F800000) {
      if ((a[0] & 0x807FFFFF) && (b[0] & 0x807FFFFF) && (a[0] & 0x7F800000) == 0x7F800000 && (b[0] & 0x7F800000) == 0x7F800000)
        return 0;
      if (!(a[0] & 0x7FFFFF) && !(b[0] & 0x7FFFFF) && a[0] == b[0])
        return 0;
      return LLONG_MAX;
    }
  }
  if ((a[0] ^ b[0]) & 0x80000000)
    return LLONG_MAX;
  if (is_double_rettype(rettype)) {
    r2 = -b[2];
    carry = (r2 == 0);
    r1 = a[1] + ~b[1] + carry;
    carry = (r1 < a[1] || (carry && r1 == a[1]));
    r0 = a[0] + ~b[0] + carry;
  } else {
    r2 = -b[1];
    carry = (r2 == 0);
    r1 = a[0] + ~b[0] + carry;
    carry = (r1 < a[0] || (carry && r1 == a[0]));
    r0 = ~0 + carry;
  }
  if (shift > 0) {
    if (shift > 32 * 3)
      return 0;
    while (shift >= 32) {
      r2 = r1;
      r1 = r0;
      r0 = -(r0 >> 31);
      shift -= 32;
    }
    if (shift > 0) {
      r2 = (r2 >> shift) | (r1 << (32 - shift));
      r1 = (r1 >> shift) | (r0 << (32 - shift));
      r0 = (r0 >> shift) | ((-(r0 >> 31)) << (32 - shift));
    }
  }
  if (r0 & 0x80000000) {
    sign = 1;
    r2 = ~r2;
    carry = (r2 == 0);
    r1 = 0 + ~r1 + carry;
    carry = (carry && (r2 == 0));
    r0 = 0 + ~r0 + carry;
  } else {
    sign = 0;
  }
  if (r0 >= (1LL << (31 - (12))))
    return LLONG_MAX;
  result = (r2 >> (32 - (12))) & ((1 << (12)) - 1);
  result |= r1 << (12);
  result |= (long long)r0 << (32 + (12));
  if (sign)
    result = -result;
  return result;
}
```