PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
memcpy.c
1#define SYSCLIB_DISABLE_BUILTINS
2#include <sysclib.h>
3#include <stdint.h>
4
5void *memcpy(void *restrict dest, const void *restrict src, size_t n)
6{
7 unsigned char *d = dest;
8 const unsigned char *s = src;
9
10#ifdef __GNUC__
11
12#if __BYTE_ORDER == __LITTLE_ENDIAN
13#define LS >>
14#define RS <<
15#else
16#define LS <<
17#define RS >>
18#endif
19
20 typedef uint32_t __attribute__((__may_alias__)) u32;
21 // cppcheck-suppress variableScope
22 uint32_t w, x;
23
24 for (; (uintptr_t)s % 4 && n; n--) *d++ = *s++;
25
26 if ((uintptr_t)d % 4 == 0) {
27 for (; n>=16; s+=16, d+=16, n-=16) {
28 *(u32 *)(d+0) = *(u32 *)(s+0);
29 *(u32 *)(d+4) = *(u32 *)(s+4);
30 *(u32 *)(d+8) = *(u32 *)(s+8);
31 *(u32 *)(d+12) = *(u32 *)(s+12);
32 }
33 if (n&8) {
34 *(u32 *)(d+0) = *(u32 *)(s+0);
35 *(u32 *)(d+4) = *(u32 *)(s+4);
36 d += 8; s += 8;
37 }
38 if (n&4) {
39 *(u32 *)(d+0) = *(u32 *)(s+0);
40 d += 4; s += 4;
41 }
42 if (n&2) {
43 *d++ = *s++; *d++ = *s++;
44 }
45 if (n&1) {
46 *d = *s;
47 }
48 return dest;
49 }
50
51 if (n >= 32) switch ((uintptr_t)d % 4) {
52 case 1:
53 w = *(u32 *)s;
54 *d++ = *s++;
55 *d++ = *s++;
56 *d++ = *s++;
57 n -= 3;
58 for (; n>=17; s+=16, d+=16, n-=16) {
59 x = *(u32 *)(s+1);
60 *(u32 *)(d+0) = (w LS 24) | (x RS 8);
61 w = *(u32 *)(s+5);
62 *(u32 *)(d+4) = (x LS 24) | (w RS 8);
63 x = *(u32 *)(s+9);
64 *(u32 *)(d+8) = (w LS 24) | (x RS 8);
65 w = *(u32 *)(s+13);
66 *(u32 *)(d+12) = (x LS 24) | (w RS 8);
67 }
68 break;
69 case 2:
70 w = *(u32 *)s;
71 *d++ = *s++;
72 *d++ = *s++;
73 n -= 2;
74 for (; n>=18; s+=16, d+=16, n-=16) {
75 x = *(u32 *)(s+2);
76 *(u32 *)(d+0) = (w LS 16) | (x RS 16);
77 w = *(u32 *)(s+6);
78 *(u32 *)(d+4) = (x LS 16) | (w RS 16);
79 x = *(u32 *)(s+10);
80 *(u32 *)(d+8) = (w LS 16) | (x RS 16);
81 w = *(u32 *)(s+14);
82 *(u32 *)(d+12) = (x LS 16) | (w RS 16);
83 }
84 break;
85 case 3:
86 w = *(u32 *)s;
87 *d++ = *s++;
88 n -= 1;
89 for (; n>=19; s+=16, d+=16, n-=16) {
90 x = *(u32 *)(s+3);
91 *(u32 *)(d+0) = (w LS 8) | (x RS 24);
92 w = *(u32 *)(s+7);
93 *(u32 *)(d+4) = (x LS 8) | (w RS 24);
94 x = *(u32 *)(s+11);
95 *(u32 *)(d+8) = (w LS 8) | (x RS 24);
96 w = *(u32 *)(s+15);
97 *(u32 *)(d+12) = (x LS 8) | (w RS 24);
98 }
99 break;
100 }
101 if (n&16) {
102 *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
103 *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
104 *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
105 *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
106 }
107 if (n&8) {
108 *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
109 *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
110 }
111 if (n&4) {
112 *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
113 }
114 if (n&2) {
115 *d++ = *s++; *d++ = *s++;
116 }
117 if (n&1) {
118 *d = *s;
119 }
120 return dest;
121#endif
122
123 for (; n; n--) *d++ = *s++;
124 return dest;
125}