user: 请显示与下面列出的汇编代码相匹配的C语言实现：

```asm
<calc_error>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x40,%rsp
  mov    %rdi,-0x28(%rbp)
  mov    %rsi,-0x30(%rbp)
  mov    %edx,-0x34(%rbp)
  mov    %ecx,-0x38(%rbp)
  mov    -0x38(%rbp),%eax
  mov    %eax,%edi
  call   <is_double_rettype@plt>
  test   %rax,%rax
  je     L0
  mov    -0x28(%rbp),%rax
  mov    (%rax),%eax
  and    $0x7ff00000,%eax
  cmp    $0x7ff00000,%eax
  je     L275
  mov    -0x30(%rbp),%rax
  mov    (%rax),%eax
  and    $0x7ff00000,%eax
  cmp    $0x7ff00000,%eax
  jne    L43
L275:
  mov    -0x28(%rbp),%rax
  mov    (%rax),%eax
  and    $0x800fffff,%eax
  test   %eax,%eax
  jne    L335
  mov    -0x28(%rbp),%rax
  add    $0x4,%rax
  mov    (%rax),%eax
  test   %eax,%eax
  je     L414
L335:
  mov    -0x30(%rbp),%rax
  mov    (%rax),%eax
  and    $0x800fffff,%eax
  test   %eax,%eax
  jne    L113
  mov    -0x30(%rbp),%rax
  add    $0x4,%rax
  mov    (%rax),%eax
  test   %eax,%eax
  je     L414
L113:
  mov    -0x28(%rbp),%rax
  mov    (%rax),%eax
  and    $0x7ff00000,%eax
  cmp    $0x7ff00000,%eax
  jne    L414
  mov    -0x30(%rbp),%rax
  mov    (%rax),%eax
  and    $0x7ff00000,%eax
  cmp    $0x7ff00000,%eax
  jne    L414
  mov    $0x0,%eax
  jmp    L116
L414:
  mov    -0x28(%rbp),%rax
  mov    (%rax),%eax
  and    $0xfffff,%eax
  test   %eax,%eax
  jne    L258
  mov    -0x28(%rbp),%rax
  add    $0x4,%rax
  mov    (%rax),%eax
  test   %eax,%eax
  jne    L258
  mov    -0x30(%rbp),%rax
  mov    (%rax),%eax
  and    $0xfffff,%eax
  test   %eax,%eax
  jne    L258
  mov    -0x30(%rbp),%rax
  add    $0x4,%rax
  mov    (%rax),%eax
  test   %eax,%eax
  jne    L258
  mov    -0x28(%rbp),%rax
  mov    (%rax),%edx
  mov    -0x30(%rbp),%rax
  mov    (%rax),%eax
  cmp    %eax,%edx
  jne    L258
  mov    $0x0,%eax
  jmp    L116
L258:
  mov    D24(%rip),%rax
  mov    (%rax),%rax
  jmp    L116
L0:
  mov    -0x28(%rbp),%rax
  mov    (%rax),%eax
  and    $0x7f800000,%eax
  cmp    $0x7f800000,%eax
  je     L83
  mov    -0x30(%rbp),%rax
  mov    (%rax),%eax
  and    $0x7f800000,%eax
  cmp    $0x7f800000,%eax
  jne    L43
L83:
  mov    -0x28(%rbp),%rax
  mov    (%rax),%eax
  and    $0x807fffff,%eax
  test   %eax,%eax
  je     L305
  mov    -0x30(%rbp),%rax
  mov    (%rax),%eax
  and    $0x807fffff,%eax
  test   %eax,%eax
  je     L305
  mov    -0x28(%rbp),%rax
  mov    (%rax),%eax
  and    $0x7f800000,%eax
  cmp    $0x7f800000,%eax
  jne    L305
  mov    -0x30(%rbp),%rax
  mov    (%rax),%eax
  and    $0x7f800000,%eax
  cmp    $0x7f800000,%eax
  jne    L305
  mov    $0x0,%eax
  jmp    L116
L305:
  mov    -0x28(%rbp),%rax
  mov    (%rax),%eax
  and    $0x7fffff,%eax
  test   %eax,%eax
  jne    L297
  mov    -0x30(%rbp),%rax
  mov    (%rax),%eax
  and    $0x7fffff,%eax
  test   %eax,%eax
  jne    L297
  mov    -0x28(%rbp),%rax
  mov    (%rax),%edx
  mov    -0x30(%rbp),%rax
  mov    (%rax),%eax
  cmp    %eax,%edx
  jne    L297
  mov    $0x0,%eax
  jmp    L116
L297:
  mov    D24(%rip),%rax
  mov    (%rax),%rax
  jmp    L116
L43:
  mov    -0x28(%rbp),%rax
  mov    (%rax),%edx
  mov    -0x30(%rbp),%rax
  mov    (%rax),%eax
  xor    %edx,%eax
  test   %eax,%eax
  jns    L206
  mov    D24(%rip),%rax
  mov    (%rax),%rax
  jmp    L116
L206:
  mov    -0x38(%rbp),%eax
  mov    %eax,%edi
  call   <is_double_rettype@plt>
  test   %rax,%rax
  je     L501
  mov    -0x30(%rbp),%rax
  add    $0x8,%rax
  mov    (%rax),%eax
  neg    %eax
  mov    %eax,-0x14(%rbp)
  cmpl   $0x0,-0x14(%rbp)
  sete   %al
  movzbl %al,%eax
  mov    %eax,-0xc(%rbp)
  mov    -0x28(%rbp),%rax
  add    $0x4,%rax
  mov    (%rax),%eax
  mov    -0x30(%rbp),%rdx
  add    $0x4,%rdx
  mov    (%rdx),%edx
  sub    %edx,%eax
  mov    %eax,%ecx
  mov    -0xc(%rbp),%eax
  add    %ecx,%eax
  sub    $0x1,%eax
  mov    %eax,-0x18(%rbp)
  mov    -0x28(%rbp),%rax
  add    $0x4,%rax
  mov    (%rax),%eax
  cmp    %eax,-0x18(%rbp)
  jb     L205
  cmpl   $0x0,-0xc(%rbp)
  je     L439
  mov    -0x28(%rbp),%rax
  add    $0x4,%rax
  mov    (%rax),%eax
  cmp    %eax,-0x18(%rbp)
  jne    L439
L205:
  mov    $0x1,%eax
  jmp    L159
L439:
  mov    $0x0,%eax
L159:
  mov    %eax,-0xc(%rbp)
  mov    -0x28(%rbp),%rax
  mov    (%rax),%edx
  mov    -0x30(%rbp),%rax
  mov    (%rax),%eax
  sub    %eax,%edx
  mov    -0xc(%rbp),%eax
  add    %edx,%eax
  sub    $0x1,%eax
  mov    %eax,-0x1c(%rbp)
  jmp    L410
L501:
  mov    -0x30(%rbp),%rax
  add    $0x4,%rax
  mov    (%rax),%eax
  neg    %eax
  mov    %eax,-0x14(%rbp)
  cmpl   $0x0,-0x14(%rbp)
  sete   %al
  movzbl %al,%eax
  mov    %eax,-0xc(%rbp)
  mov    -0x28(%rbp),%rax
  mov    (%rax),%edx
  mov    -0x30(%rbp),%rax
  mov    (%rax),%eax
  sub    %eax,%edx
  mov    -0xc(%rbp),%eax
  add    %edx,%eax
  sub    $0x1,%eax
  mov    %eax,-0x18(%rbp)
  mov    -0x28(%rbp),%rax
  mov    (%rax),%eax
  cmp    %eax,-0x18(%rbp)
  jb     L327
  cmpl   $0x0,-0xc(%rbp)
  je     L201
  mov    -0x28(%rbp),%rax
  mov    (%rax),%eax
  cmp    %eax,-0x18(%rbp)
  jne    L201
L327:
  mov    $0x1,%eax
  jmp    L288
L201:
  mov    $0x0,%eax
L288:
  mov    %eax,-0xc(%rbp)
  mov    -0xc(%rbp),%eax
  sub    $0x1,%eax
  mov    %eax,-0x1c(%rbp)
L410:
  cmpl   $0x0,-0x34(%rbp)
  jle    L310
  cmpl   $0x60,-0x34(%rbp)
  jle    L355
  mov    $0x0,%eax
  jmp    L116
L122:
  mov    -0x18(%rbp),%eax
  mov    %eax,-0x14(%rbp)
  mov    -0x1c(%rbp),%eax
  mov    %eax,-0x18(%rbp)
  mov    -0x1c(%rbp),%eax
  sar    $0x1f,%eax
  mov    %eax,-0x1c(%rbp)
  subl   $0x20,-0x34(%rbp)
L355:
  cmpl   $0x1f,-0x34(%rbp)
  jg     L122
  cmpl   $0x0,-0x34(%rbp)
  jle    L310
  mov    -0x34(%rbp),%eax
  mov    -0x14(%rbp),%edx
  mov    %edx,%esi
  mov    %eax,%ecx
  shr    %cl,%esi
  mov    $0x20,%eax
  sub    -0x34(%rbp),%eax
  mov    -0x18(%rbp),%edx
  mov    %eax,%ecx
  shl    %cl,%edx
  mov    %edx,%eax
  or     %esi,%eax
  mov    %eax,-0x14(%rbp)
  mov    -0x34(%rbp),%eax
  mov    -0x18(%rbp),%edx
  mov    %edx,%esi
  mov    %eax,%ecx
  shr    %cl,%esi
  mov    $0x20,%eax
  sub    -0x34(%rbp),%eax
  mov    -0x1c(%rbp),%edx
  mov    %eax,%ecx
  shl    %cl,%edx
  mov    %edx,%eax
  or     %esi,%eax
  mov    %eax,-0x18(%rbp)
  mov    -0x34(%rbp),%eax
  mov    -0x1c(%rbp),%edx
  mov    %eax,%ecx
  shr    %cl,%edx
  mov    -0x1c(%rbp),%eax
  sar    $0x1f,%eax
  mov    %eax,%esi
  mov    $0x20,%eax
  sub    -0x34(%rbp),%eax
  mov    %eax,%ecx
  shl    %cl,%esi
  mov    %esi,%eax
  or     %edx,%eax
  mov    %eax,-0x1c(%rbp)
L310:
  mov    -0x1c(%rbp),%eax
  test   %eax,%eax
  jns    L480
  movl   $0x1,-0x10(%rbp)
  notl   -0x14(%rbp)
  cmpl   $0x0,-0x14(%rbp)
  sete   %al
  movzbl %al,%eax
  mov    %eax,-0xc(%rbp)
  mov    -0xc(%rbp),%eax
  sub    -0x18(%rbp),%eax
  sub    $0x1,%eax
  mov    %eax,-0x18(%rbp)
  cmpl   $0x0,-0xc(%rbp)
  je     L124
  cmpl   $0x0,-0x14(%rbp)
  jne    L124
  mov    $0x1,%eax
  jmp    L313
L124:
  mov    $0x0,%eax
L313:
  mov    %eax,-0xc(%rbp)
  mov    -0xc(%rbp),%eax
  sub    -0x1c(%rbp),%eax
  sub    $0x1,%eax
  mov    %eax,-0x1c(%rbp)
  jmp    L447
L480:
  movl   $0x0,-0x10(%rbp)
L447:
  cmpl   $0x7ffff,-0x1c(%rbp)
  jbe    L411
  mov    D24(%rip),%rax
  mov    (%rax),%rax
  jmp    L116
L411:
  mov    -0x14(%rbp),%eax
  shr    $0x14,%eax
  mov    %eax,%eax
  mov    %rax,-0x8(%rbp)
  mov    -0x18(%rbp),%eax
  shl    $0xc,%eax
  mov    %eax,%eax
  or     %rax,-0x8(%rbp)
  mov    -0x1c(%rbp),%eax
  shl    $0x2c,%rax
  or     %rax,-0x8(%rbp)
  cmpl   $0x0,-0x10(%rbp)
  je     L495
  negq   -0x8(%rbp)
L495:
  mov    -0x8(%rbp),%rax
L116:
  leave
  ret
```

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;
}
```