12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- /*
- * Copyright (c) 2024, sakumisu
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- #ifndef USB_MEMCPY_H
- #define USB_MEMCPY_H
- #include <stdint.h>
- #include <stddef.h>
- #define ALIGN_UP_DWORD(x) ((uint32_t)(uintptr_t)(x) & (sizeof(uint32_t) - 1))
- static inline void dword2array(char *addr, uint32_t w)
- {
- addr[0] = w;
- addr[1] = w >> 8;
- addr[2] = w >> 16;
- addr[3] = w >> 24;
- }
- static inline void *usb_memcpy(void *s1, const void *s2, size_t n)
- {
- char *b1 = (char *)s1;
- const char *b2 = (const char *)s2;
- uint32_t *w1;
- const uint32_t *w2;
- if (ALIGN_UP_DWORD(b1) == ALIGN_UP_DWORD(b2)) {
- while (ALIGN_UP_DWORD(b1) != 0 && n > 0) {
- *b1++ = *b2++;
- --n;
- }
- w1 = (uint32_t *)b1;
- w2 = (const uint32_t *)b2;
- while (n >= 4 * sizeof(uint32_t)) {
- *w1++ = *w2++;
- *w1++ = *w2++;
- *w1++ = *w2++;
- *w1++ = *w2++;
- n -= 4 * sizeof(uint32_t);
- }
- while (n >= sizeof(uint32_t)) {
- *w1++ = *w2++;
- n -= sizeof(uint32_t);
- }
- b1 = (char *)w1;
- b2 = (const char *)w2;
- while (n--) {
- *b1++ = *b2++;
- }
- } else {
- while (n > 0 && ALIGN_UP_DWORD(b2) != 0) {
- *b1++ = *b2++;
- --n;
- }
- w2 = (const uint32_t *)b2;
- while (n >= 4 * sizeof(uint32_t)) {
- dword2array(b1, *w2++);
- b1 += sizeof(uint32_t);
- dword2array(b1, *w2++);
- b1 += sizeof(uint32_t);
- dword2array(b1, *w2++);
- b1 += sizeof(uint32_t);
- dword2array(b1, *w2++);
- b1 += sizeof(uint32_t);
- n -= 4 * sizeof(uint32_t);
- }
- while (n >= sizeof(uint32_t)) {
- dword2array(b1, *w2++);
- b1 += sizeof(uint32_t);
- n -= sizeof(uint32_t);
- }
- b2 = (const char *)w2;
- while (n--) {
- *b1++ = *b2++;
- }
- }
- return s1;
- }
- #endif
|