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

```asm
<spi_read>:
  endbr64
  mov    $0xd4035000,%eax
  push   %rbx
  movq   $0x10000f,(%rax)
  movq   $0x10008f,(%rax)
  test   %rsi,%rsi
  jle    L199
  mov    %rdi,%r9
  mov    %rdx,%rcx
  mov    %rsi,%r10
  mov    $0xd4035010,%edi
  mov    $0xd4035008,%edx
  nopl   0x0(%rax)
L55:
  mov    %r9,%rax
  or     $0x3000000,%rax
  mov    %rax,(%rdi)
  cmp    $0x3b,%r10
  jg     L191
  mov    %r10,%rax
  sar    $0x2,%rax
  movslq %eax,%rsi
  je     L25
  lea    0x0(,%rax,4),%r8d
  mov    $0xd4035010,%ebx
  movq   $0x0,(%rbx)
  movslq %r8d,%r8
  cmp    $0x1,%eax
  je     L178
  movq   $0x0,(%rbx)
  sub    $0x2,%eax
  je     L86
L229:
  mov    $0xd4035010,%ebx
  movq   $0x0,(%rbx)
  cmp    $0x1,%eax
  je     L86
  movq   $0x0,(%rbx)
  cmp    $0x2,%eax
  je     L86
  movq   $0x0,(%rbx)
  cmp    $0x3,%eax
  je     L86
  movq   $0x0,(%rbx)
  cmp    $0x4,%eax
  je     L86
  movq   $0x0,(%rbx)
  cmp    $0x5,%eax
  je     L86
  movq   $0x0,(%rbx)
  cmp    $0x6,%eax
  je     L86
  movq   $0x0,(%rbx)
  cmp    $0x7,%eax
  je     L86
  movq   $0x0,(%rbx)
  cmp    $0x8,%eax
  je     L86
  movq   $0x0,(%rbx)
  cmp    $0x9,%eax
  je     L86
  movq   $0x0,(%rbx)
  cmp    $0xa,%eax
  je     L86
  movq   $0x0,(%rbx)
  sub    $0xb,%eax
  je     L86
  movq   $0x0,(%rbx)
  cmp    $0x1,%eax
  je     L86
  movq   $0x0,(%rbx)
  nopw   0x0(%rax,%rax,1)
L86:
  sub    %r8,%r10
  add    %r8,%r9
  xchg   %ax,%ax
L222:
  mov    (%rdx),%rax
  test   $0x8,%al
  je     L222
  mov    (%rdi),%rax
  test   %esi,%esi
  je     L59
  lea    (%rcx,%rsi,4),%r8
  nopw   0x0(%rax,%rax,1)
L45:
  mov    (%rdx),%rax
  test   $0x8,%al
  je     L45
  mov    (%rdi),%rax
  add    $0x4,%rcx
  mov    %rax,%rsi
  mov    %ah,-0x2(%rcx)
  shr    $0x18,%rsi
  mov    %sil,-0x4(%rcx)
  mov    %rax,%rsi
  shr    $0x10,%rsi
  mov    %sil,-0x3(%rcx)
  mov    %al,-0x1(%rcx)
  cmp    %r8,%rcx
  jne    L45
L59:
  test   %r10,%r10
  jg     L55
L199:
  mov    $0xd4035000,%eax
  movq   $0x7,(%rax)
  movq   $0x87,(%rax)
  pop    %rbx
  ret
L191:
  mov    $0xd4035010,%eax
  mov    $0x3c,%r8d
  mov    $0xf,%esi
  movq   $0x0,(%rax)
  movq   $0x0,(%rax)
  mov    $0xd,%eax
  jmp    L229
L25:
  xor    %esi,%esi
  jmp    L222
L178:
  mov    $0x1,%esi
  jmp    L86
```

assistant: ```c
void spi_read(long offset, long len, long adr) {
  unsigned char *p = (unsigned char *)adr;
  int cansend, i;
  volatile unsigned long *fifo = (volatile unsigned long *)0xd4035010;
  volatile unsigned long *stat = (volatile unsigned long *)0xd4035008;
  unsigned long regval;
  *(volatile unsigned long *)0xd4035000 = 0x0010000f;
  *(volatile unsigned long *)0xd4035000 = 0x0010008f;
  while (len > 0) {
    *fifo = (0x03 << 24) | offset;
    cansend = (len < (15 * 4)) ? (len / 4) : 15;
    for (i = cansend; i; i--) {
      *fifo = 0;
    }
    while ((*stat & 8) == 0)
      ;
    regval = *fifo;
    for (i = cansend; i; i--) {
      while ((*stat & 8) == 0)
        ;
      regval = *fifo;
      *p++ = (regval >> 24) & 0xff;
      *p++ = (regval >> 16) & 0xff;
      *p++ = (regval >> 8) & 0xff;
      *p++ = regval & 0xff;
    }
    len -= (cansend * 4);
    offset += (cansend * 4);
  }
  *(volatile unsigned long *)0xd4035000 = 0x00000007;
  *(volatile unsigned long *)0xd4035000 = 0x00000087;
}
```