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

```asm
<read_float>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  mov    %rdx,%r12
  push   %rbp
  push   %rbx
  lea    (%rdi,%rsi,1),%rbx
  sub    $0x18,%rsp
  mov    %rcx,(%rsp)
  cmp    %rbx,%rdi
  jae    L104
  mov    %rdi,%rbp
  movsbl (%rdi),%edi
  movl   $0x0,0xc(%rsp)
  mov    %rbp,%r15
  cmp    $0x2d,%dil
  je     L132
L33:
  xor    %r14d,%r14d
  jmp    L180
  cs nopw 0x0(%rax,%rax,1)
L112:
  mov    D19(%rip),%rax
  movslq (%rax),%rax
  mov    %rax,%rcx
  imul   $0x66666667,%rax,%rax
  sar    $0x1f,%ecx
  sar    $0x22,%rax
  sub    %ecx,%eax
  cmp    %r14d,%eax
  jle    L109
  lea    (%r14,%r14,4),%eax
  add    $0x1,%r15
  lea    (%rdx,%rax,2),%r14d
  cmp    %r15,%rbx
  jbe    L159
  movsbl (%r15),%edi
L180:
  call   <digit_to_num@plt>
  mov    %eax,%edx
  test   %eax,%eax
  jns    L112
  xor    %r13d,%r13d
  cmp    %rbx,%r15
  jae    L158
  cmpb   $0x2e,(%r15)
  je     L28
L158:
  mov    0xc(%rsp),%eax
  mov    %r13d,(%r12)
  test   %eax,%eax
  je     L183
L172:
  neg    %r14d
L183:
  mov    %r15d,%eax
  sub    %ebp,%eax
  jmp    L71
  xchg   %ax,%ax
L104:
  movl   $0x0,(%rdx)
  xor    %eax,%eax
  xor    %r14d,%r14d
L71:
  mov    (%rsp),%rsi
  mov    %r14d,(%rsi)
  add    $0x18,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nopl   0x0(%rax)
L28:
  add    $0x1,%r15
  cmp    %r15,%rbx
  ja     L15
  jmp    L158
  nopl   0x0(%rax,%rax,1)
L72:
  lea    (%r14,%r14,4),%eax
  add    $0x1,%r15
  sub    $0x1,%r13d
  lea    (%rdx,%rax,2),%r14d
  cmp    %r15,%rbx
  je     L158
L15:
  movsbl (%r15),%edi
  call   <digit_to_num@plt>
  mov    %eax,%edx
  test   %eax,%eax
  js     L158
  mov    D19(%rip),%rax
  movslq (%rax),%rax
  mov    %rax,%rdi
  imul   $0x66666667,%rax,%rax
  sar    $0x1f,%edi
  sar    $0x22,%rax
  sub    %edi,%eax
  cmp    %r14d,%eax
  jg     L72
L109:
  mov    D21(%rip),%rax
  mov    (%rax),%eax
  add    $0x18,%rsp
  pop    %rbx
  pop    %rbp
  neg    %eax
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nopl   0x0(%rax,%rax,1)
L132:
  lea    0x1(%rbp),%r15
  cmp    %r15,%rbx
  jbe    L10
  movl   $0x1,0xc(%rsp)
  movsbl 0x1(%rbp),%edi
  jmp    L33
L10:
  movl   $0x0,(%rdx)
  xor    %r14d,%r14d
  jmp    L172
L159:
  xor    %r13d,%r13d
  jmp    L158
```

assistant: ```c
int read_float(char *buf, size_t size, int *exponent_out, int *mantissa_out) {
  int mantissa = 0;
  int exponent = 0;
  bool neg = false;
  char *cursor = buf;
  char *end = buf + size;
  if (cursor < end && *cursor == '-') {
    neg = true;
    cursor++;
  }
  while (cursor < end) {
    int digit = digit_to_num(*cursor);
    if (digit < 0)
      break;
    if (mantissa >= (INT_MAX / 10))
      return -EOVERFLOW;
    mantissa *= 10;
    mantissa += digit;
    cursor++;
  }
  if (cursor < end && *cursor == '.') {
    cursor++;
    while (cursor < end) {
      int digit = digit_to_num(*cursor);
      if (digit < 0)
        break;
      if (mantissa >= (INT_MAX / 10))
        return -EOVERFLOW;
      mantissa *= 10;
      mantissa += digit;
      cursor++;
      exponent--;
    }
  }
  *exponent_out = exponent;
  *mantissa_out = neg ? -mantissa : mantissa;
  return cursor - buf;
}
```