user: Please show me the C implementation that matches the assembly code listed below:

```asm
<imcd_xor>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x28,%rsp
  mov    %rdi,-0x78(%rbp)
  mov    %rsi,-0x80(%rbp)
  mov    %rdx,-0x88(%rbp)
  mov    %rcx,-0x90(%rbp)
  mov    %r8,-0x98(%rbp)
  mov    %r9,-0xa0(%rbp)
  cmpq   $0x0,-0x90(%rbp)
  je     L258
  mov    -0x90(%rbp),%rax
  cmp    -0x78(%rbp),%rax
  jne    L105
L258:
  mov    $0x1,%eax
  jmp    L284
L105:
  mov    $0x0,%eax
L284:
  mov    %eax,-0x5c(%rbp)
  cmpl   $0x0,-0x5c(%rbp)
  jne    L177
  mov    -0x98(%rbp),%rdx
  mov    -0x80(%rbp),%rax
  cmp    %rax,%rdx
  cmovle %rdx,%rax
  jmp    L422
L177:
  mov    -0x80(%rbp),%rax
L422:
  mov    %rax,-0x30(%rbp)
  cmpl   $0x0,-0x5c(%rbp)
  je     L749
  mov    -0x88(%rbp),%rax
  jmp    L268
L749:
  mov    -0xa0(%rbp),%rax
L268:
  mov    %rax,-0x28(%rbp)
  mov    -0x78(%rbp),%rax
  mov    %rax,-0x48(%rbp)
  cmpl   $0x0,-0x5c(%rbp)
  je     L69
  mov    -0x78(%rbp),%rax
  jmp    L745
L69:
  mov    -0x90(%rbp),%rax
L745:
  mov    %rax,-0x40(%rbp)
  cmpq   $0x0,-0x80(%rbp)
  js     L154
  cmpq   $0x0,-0x98(%rbp)
  jns    L328
L154:
  mov    $0xfffffffffffffffb,%rax
  jmp    L234
L328:
  cmpq   $0x0,-0x30(%rbp)
  jg     L342
  mov    $0x0,%eax
  jmp    L234
L342:
  cmpq   $0x8,0x10(%rbp)
  je     L129
  cmpq   $0x8,0x10(%rbp)
  jg     L737
  cmpq   $0x4,0x10(%rbp)
  je     L536
  cmpq   $0x4,0x10(%rbp)
  jg     L737
  cmpq   $0x1,0x10(%rbp)
  je     L545
  cmpq   $0x2,0x10(%rbp)
  je     L632
  jmp    L737
L545:
  cmpl   $0x0,0x18(%rbp)
  je     L191
  cmpl   $0x0,-0x5c(%rbp)
  je     L697
  cmpq   $0x4,-0x28(%rbp)
  jne    L697
  cmpq   $0x4,-0x88(%rbp)
  jne    L697
  mov    -0x48(%rbp),%rax
  mov    %rax,-0x8(%rbp)
  mov    -0x8(%rbp),%rax
  mov    (%rax),%eax
  mov    %eax,-0x6c(%rbp)
  movq   $0x1,-0x38(%rbp)
  jmp    L245
L366:
  mov    -0x38(%rbp),%rax
  lea    0x0(,%rax,4),%rdx
  mov    -0x8(%rbp),%rax
  add    %rdx,%rax
  mov    (%rax),%edx
  mov    -0x38(%rbp),%rax
  lea    0x0(,%rax,4),%rcx
  mov    -0x8(%rbp),%rax
  add    %rcx,%rax
  xor    -0x6c(%rbp),%edx
  mov    %edx,(%rax)
  mov    (%rax),%eax
  mov    %eax,-0x6c(%rbp)
  addq   $0x1,-0x38(%rbp)
L245:
  mov    -0x38(%rbp),%rax
  cmp    -0x30(%rbp),%rax
  jl     L366
  jmp    L513
L697:
  mov    -0x48(%rbp),%rax
  mov    (%rax),%eax
  mov    %eax,-0x6c(%rbp)
  mov    -0x40(%rbp),%rax
  mov    -0x6c(%rbp),%edx
  mov    %edx,(%rax)
  movq   $0x1,-0x38(%rbp)
  jmp    L349
L136:
  mov    -0x28(%rbp),%rax
  add    %rax,-0x40(%rbp)
  mov    -0x88(%rbp),%rax
  add    %rax,-0x48(%rbp)
  mov    -0x48(%rbp),%rax
  mov    (%rax),%eax
  xor    %eax,-0x6c(%rbp)
  mov    -0x40(%rbp),%rax
  mov    -0x6c(%rbp),%edx
  mov    %edx,(%rax)
  addq   $0x1,-0x38(%rbp)
L349:
  mov    -0x38(%rbp),%rax
  cmp    -0x30(%rbp),%rax
  jl     L136
  jmp    L736
L191:
  mov    -0x48(%rbp),%rax
  mov    (%rax),%eax
  mov    %eax,-0x6c(%rbp)
  mov    -0x40(%rbp),%rax
  mov    -0x6c(%rbp),%edx
  mov    %edx,(%rax)
  movq   $0x1,-0x38(%rbp)
  jmp    L295
L733:
  mov    -0x28(%rbp),%rax
  add    %rax,-0x40(%rbp)
  mov    -0x88(%rbp),%rax
  add    %rax,-0x48(%rbp)
  mov    -0x48(%rbp),%rax
  mov    (%rax),%eax
  mov    %eax,-0x4c(%rbp)
  mov    -0x4c(%rbp),%eax
  xor    -0x6c(%rbp),%eax
  mov    %eax,%edx
  mov    -0x40(%rbp),%rax
  mov    %edx,(%rax)
  mov    -0x4c(%rbp),%eax
  mov    %eax,-0x6c(%rbp)
  addq   $0x1,-0x38(%rbp)
L295:
  mov    -0x38(%rbp),%rax
  cmp    -0x30(%rbp),%rax
  jl     L733
  jmp    L736
L513:
  jmp    L736
L632:
  cmpl   $0x0,0x18(%rbp)
  je     L703
  cmpl   $0x0,-0x5c(%rbp)
  je     L498
  cmpq   $0x4,-0x28(%rbp)
  jne    L498
  cmpq   $0x4,-0x88(%rbp)
  jne    L498
  mov    -0x48(%rbp),%rax
  mov    %rax,-0x10(%rbp)
  mov    -0x10(%rbp),%rax
  mov    (%rax),%eax
  mov    %eax,-0x68(%rbp)
  movq   $0x1,-0x38(%rbp)
  jmp    L35
L11:
  mov    -0x38(%rbp),%rax
  lea    0x0(,%rax,4),%rdx
  mov    -0x10(%rbp),%rax
  add    %rdx,%rax
  mov    (%rax),%edx
  mov    -0x38(%rbp),%rax
  lea    0x0(,%rax,4),%rcx
  mov    -0x10(%rbp),%rax
  add    %rcx,%rax
  xor    -0x68(%rbp),%edx
  mov    %edx,(%rax)
  mov    (%rax),%eax
  mov    %eax,-0x68(%rbp)
  addq   $0x1,-0x38(%rbp)
L35:
  mov    -0x38(%rbp),%rax
  cmp    -0x30(%rbp),%rax
  jl     L11
  jmp    L771
L498:
  mov    -0x48(%rbp),%rax
  mov    (%rax),%eax
  mov    %eax,-0x68(%rbp)
  mov    -0x40(%rbp),%rax
  mov    -0x68(%rbp),%edx
  mov    %edx,(%rax)
  movq   $0x1,-0x38(%rbp)
  jmp    L509
L0:
  mov    -0x28(%rbp),%rax
  add    %rax,-0x40(%rbp)
  mov    -0x88(%rbp),%rax
  add    %rax,-0x48(%rbp)
  mov    -0x48(%rbp),%rax
  mov    (%rax),%eax
  xor    %eax,-0x68(%rbp)
  mov    -0x40(%rbp),%rax
  mov    -0x68(%rbp),%edx
  mov    %edx,(%rax)
  addq   $0x1,-0x38(%rbp)
L509:
  mov    -0x38(%rbp),%rax
  cmp    -0x30(%rbp),%rax
  jl     L0
  jmp    L736
L703:
  mov    -0x48(%rbp),%rax
  mov    (%rax),%eax
  mov    %eax,-0x68(%rbp)
  mov    -0x40(%rbp),%rax
  mov    -0x68(%rbp),%edx
  mov    %edx,(%rax)
  movq   $0x1,-0x38(%rbp)
  jmp    L560
L42:
  mov    -0x28(%rbp),%rax
  add    %rax,-0x40(%rbp)
  mov    -0x88(%rbp),%rax
  add    %rax,-0x48(%rbp)
  mov    -0x48(%rbp),%rax
  mov    (%rax),%eax
  mov    %eax,-0x50(%rbp)
  mov    -0x50(%rbp),%eax
  xor    -0x68(%rbp),%eax
  mov    %eax,%edx
  mov    -0x40(%rbp),%rax
  mov    %edx,(%rax)
  mov    -0x50(%rbp),%eax
  mov    %eax,-0x68(%rbp)
  addq   $0x1,-0x38(%rbp)
L560:
  mov    -0x38(%rbp),%rax
  cmp    -0x30(%rbp),%rax
  jl     L42
  jmp    L736
L771:
  jmp    L736
L536:
  cmpl   $0x0,0x18(%rbp)
  je     L636
  cmpl   $0x0,-0x5c(%rbp)
  je     L111
  cmpq   $0x4,-0x28(%rbp)
  jne    L111
  cmpq   $0x4,-0x88(%rbp)
  jne    L111
  mov    -0x48(%rbp),%rax
  mov    %rax,-0x18(%rbp)
  mov    -0x18(%rbp),%rax
  mov    (%rax),%eax
  mov    %eax,-0x64(%rbp)
  movq   $0x1,-0x38(%rbp)
  jmp    L775
L227:
  mov    -0x38(%rbp),%rax
  lea    0x0(,%rax,4),%rdx
  mov    -0x18(%rbp),%rax
  add    %rdx,%rax
  mov    (%rax),%edx
  mov    -0x38(%rbp),%rax
  lea    0x0(,%rax,4),%rcx
  mov    -0x18(%rbp),%rax
  add    %rcx,%rax
  xor    -0x64(%rbp),%edx
  mov    %edx,(%rax)
  mov    (%rax),%eax
  mov    %eax,-0x64(%rbp)
  addq   $0x1,-0x38(%rbp)
L775:
  mov    -0x38(%rbp),%rax
  cmp    -0x30(%rbp),%rax
  jl     L227
  jmp    L25
L111:
  mov    -0x48(%rbp),%rax
  mov    (%rax),%eax
  mov    %eax,-0x64(%rbp)
  mov    -0x40(%rbp),%rax
  mov    -0x64(%rbp),%edx
  mov    %edx,(%rax)
  movq   $0x1,-0x38(%rbp)
  jmp    L79
L605:
  mov    -0x28(%rbp),%rax
  add    %rax,-0x40(%rbp)
  mov    -0x88(%rbp),%rax
  add    %rax,-0x48(%rbp)
  mov    -0x48(%rbp),%rax
  mov    (%rax),%eax
  xor    %eax,-0x64(%rbp)
  mov    -0x40(%rbp),%rax
  mov    -0x64(%rbp),%edx
  mov    %edx,(%rax)
  addq   $0x1,-0x38(%rbp)
L79:
  mov    -0x38(%rbp),%rax
  cmp    -0x30(%rbp),%rax
  jl     L605
  jmp    L736
L636:
  mov    -0x48(%rbp),%rax
  mov    (%rax),%eax
  mov    %eax,-0x64(%rbp)
  mov    -0x40(%rbp),%rax
  mov    -0x64(%rbp),%edx
  mov    %edx,(%rax)
  movq   $0x1,-0x38(%rbp)
  jmp    L276
L60:
  mov    -0x28(%rbp),%rax
  add    %rax,-0x40(%rbp)
  mov    -0x88(%rbp),%rax
  add    %rax,-0x48(%rbp)
  mov    -0x48(%rbp),%rax
  mov    (%rax),%eax
  mov    %eax,-0x54(%rbp)
  mov    -0x54(%rbp),%eax
  xor    -0x64(%rbp),%eax
  mov    %eax,%edx
  mov    -0x40(%rbp),%rax
  mov    %edx,(%rax)
  mov    -0x54(%rbp),%eax
  mov    %eax,-0x64(%rbp)
  addq   $0x1,-0x38(%rbp)
L276:
  mov    -0x38(%rbp),%rax
  cmp    -0x30(%rbp),%rax
  jl     L60
  jmp    L736
L25:
  jmp    L736
L129:
  cmpl   $0x0,0x18(%rbp)
  je     L722
  cmpl   $0x0,-0x5c(%rbp)
  je     L590
  cmpq   $0x4,-0x28(%rbp)
  jne    L590
  cmpq   $0x4,-0x88(%rbp)
  jne    L590
  mov    -0x48(%rbp),%rax
  mov    %rax,-0x20(%rbp)
  mov    -0x20(%rbp),%rax
  mov    (%rax),%eax
  mov    %eax,-0x60(%rbp)
  movq   $0x1,-0x38(%rbp)
  jmp    L321
L373:
  mov    -0x38(%rbp),%rax
  lea    0x0(,%rax,4),%rdx
  mov    -0x20(%rbp),%rax
  add    %rdx,%rax
  mov    (%rax),%edx
  mov    -0x38(%rbp),%rax
  lea    0x0(,%rax,4),%rcx
  mov    -0x20(%rbp),%rax
  add    %rcx,%rax
  xor    -0x60(%rbp),%edx
  mov    %edx,(%rax)
  mov    (%rax),%eax
  mov    %eax,-0x60(%rbp)
  addq   $0x1,-0x38(%rbp)
L321:
  mov    -0x38(%rbp),%rax
  cmp    -0x30(%rbp),%rax
  jl     L373
  jmp    L216
L590:
  mov    -0x48(%rbp),%rax
  mov    (%rax),%eax
  mov    %eax,-0x60(%rbp)
  mov    -0x40(%rbp),%rax
  mov    -0x60(%rbp),%edx
  mov    %edx,(%rax)
  movq   $0x1,-0x38(%rbp)
  jmp    L700
L208:
  mov    -0x28(%rbp),%rax
  add    %rax,-0x40(%rbp)
  mov    -0x88(%rbp),%rax
  add    %rax,-0x48(%rbp)
  mov    -0x48(%rbp),%rax
  mov    (%rax),%eax
  xor    %eax,-0x60(%rbp)
  mov    -0x40(%rbp),%rax
  mov    -0x60(%rbp),%edx
  mov    %edx,(%rax)
  addq   $0x1,-0x38(%rbp)
L700:
  mov    -0x38(%rbp),%rax
  cmp    -0x30(%rbp),%rax
  jl     L208
  jmp    L736
L722:
  mov    -0x48(%rbp),%rax
  mov    (%rax),%eax
  mov    %eax,-0x60(%rbp)
  mov    -0x40(%rbp),%rax
  mov    -0x60(%rbp),%edx
  mov    %edx,(%rax)
  movq   $0x1,-0x38(%rbp)
  jmp    L24
L233:
  mov    -0x28(%rbp),%rax
  add    %rax,-0x40(%rbp)
  mov    -0x88(%rbp),%rax
  add    %rax,-0x48(%rbp)
  mov    -0x48(%rbp),%rax
  mov    (%rax),%eax
  mov    %eax,-0x58(%rbp)
  mov    -0x58(%rbp),%eax
  xor    -0x60(%rbp),%eax
  mov    %eax,%edx
  mov    -0x40(%rbp),%rax
  mov    %edx,(%rax)
  mov    -0x58(%rbp),%eax
  mov    %eax,-0x60(%rbp)
  addq   $0x1,-0x38(%rbp)
L24:
  mov    -0x38(%rbp),%rax
  cmp    -0x30(%rbp),%rax
  jl     L233
  jmp    L736
L216:
  jmp    L736
L737:
  mov    $0xfffffffffffffffb,%rax
  jmp    L234
L736:
  mov    -0x30(%rbp),%rax
L234:
  leave
  ret
```

assistant: ```c
ssize_t imcd_xor(void *src, const ssize_t srcsize, const ssize_t srcstride, void *dst, const ssize_t dstsize, const ssize_t dststride, const ssize_t itemsize, const int decode) {
  const int inplace = (dst == NULL) || (dst == src);
  const ssize_t size = inplace ? srcsize : (((srcsize) < (dstsize)) ? (srcsize) : (dstsize));
  const ssize_t stride = inplace ? srcstride : dststride;
  char *srcptr = (char *)src;
  char *dstptr = inplace ? (char *)src : (char *)dst;
  ssize_t i;
  if ((srcsize < 0) || (dstsize < 0)) {
    return -5;
  }
  if (size <= 0) {
    return 0;
  }
  switch (itemsize) {
  case 1: {
    uint8_t prev, t;
    if (decode) {
      if (inplace && (stride == sizeof(uint8_t)) && (srcstride == sizeof(uint8_t))) {
        uint8_t *psrc = (uint8_t *)srcptr;
        prev = psrc[0];
        for (i = 1; i < size; i++) {
          prev = psrc[i] ^= prev;
        }
      } else {
        *(uint8_t *)dstptr = prev = (*(uint8_t *)srcptr);
        for (i = 1; i < size; i++) {
          dstptr += stride;
          srcptr += srcstride;
          *(uint8_t *)dstptr = prev = (*(uint8_t *)srcptr) ^ prev;
        }
      }
    } else {
      *(uint8_t *)dstptr = prev = (*(uint8_t *)srcptr);
      for (i = 1; i < size; i++) {
        dstptr += stride;
        srcptr += srcstride;
        t = (*(uint8_t *)srcptr);
        *(uint8_t *)dstptr = t ^ prev;
        prev = t;
      }
    }
  }; break;
  case 2: {
    uint16_t prev, t;
    if (decode) {
      if (inplace && (stride == sizeof(uint16_t)) && (srcstride == sizeof(uint16_t))) {
        uint16_t *psrc = (uint16_t *)srcptr;
        prev = psrc[0];
        for (i = 1; i < size; i++) {
          prev = psrc[i] ^= prev;
        }
      } else {
        *(uint16_t *)dstptr = prev = (*(uint16_t *)srcptr);
        for (i = 1; i < size; i++) {
          dstptr += stride;
          srcptr += srcstride;
          *(uint16_t *)dstptr = prev = (*(uint16_t *)srcptr) ^ prev;
        }
      }
    } else {
      *(uint16_t *)dstptr = prev = (*(uint16_t *)srcptr);
      for (i = 1; i < size; i++) {
        dstptr += stride;
        srcptr += srcstride;
        t = (*(uint16_t *)srcptr);
        *(uint16_t *)dstptr = t ^ prev;
        prev = t;
      }
    }
  }; break;
  case 4: {
    uint32_t prev, t;
    if (decode) {
      if (inplace && (stride == sizeof(uint32_t)) && (srcstride == sizeof(uint32_t))) {
        uint32_t *psrc = (uint32_t *)srcptr;
        prev = psrc[0];
        for (i = 1; i < size; i++) {
          prev = psrc[i] ^= prev;
        }
      } else {
        *(uint32_t *)dstptr = prev = (*(uint32_t *)srcptr);
        for (i = 1; i < size; i++) {
          dstptr += stride;
          srcptr += srcstride;
          *(uint32_t *)dstptr = prev = (*(uint32_t *)srcptr) ^ prev;
        }
      }
    } else {
      *(uint32_t *)dstptr = prev = (*(uint32_t *)srcptr);
      for (i = 1; i < size; i++) {
        dstptr += stride;
        srcptr += srcstride;
        t = (*(uint32_t *)srcptr);
        *(uint32_t *)dstptr = t ^ prev;
        prev = t;
      }
    }
  }; break;
  case 8: {
    uint64_t prev, t;
    if (decode) {
      if (inplace && (stride == sizeof(uint64_t)) && (srcstride == sizeof(uint64_t))) {
        uint64_t *psrc = (uint64_t *)srcptr;
        prev = psrc[0];
        for (i = 1; i < size; i++) {
          prev = psrc[i] ^= prev;
        }
      } else {
        *(uint64_t *)dstptr = prev = (*(uint64_t *)srcptr);
        for (i = 1; i < size; i++) {
          dstptr += stride;
          srcptr += srcstride;
          *(uint64_t *)dstptr = prev = (*(uint64_t *)srcptr) ^ prev;
        }
      }
    } else {
      *(uint64_t *)dstptr = prev = (*(uint64_t *)srcptr);
      for (i = 1; i < size; i++) {
        dstptr += stride;
        srcptr += srcstride;
        t = (*(uint64_t *)srcptr);
        *(uint64_t *)dstptr = t ^ prev;
        prev = t;
      }
    }
  }; break;
  default:
    return -5;
  }
  return size;
}
```