20 #include "pedigree/kernel/compiler.h" 21 #include "pedigree/kernel/processor/types.h" 22 #include "pedigree/kernel/utilities/assert.h" 23 #include "pedigree/kernel/utilities/utility.h" 28 #define SSE_THRESHOLD 1024 29 #define STOSB_THRESHOLD 64 35 #ifdef UTILITY_LINUX_COVERAGE 43 #define EXPORT EXPORTED_PUBLIC 46 extern void memzero_xmm_aligned(
void *,
size_t);
47 extern void memzero_xmm(
void *,
size_t);
49 EXPORT
int memcmp(
const void *p1,
const void *p2,
size_t len)
PURE;
50 EXPORT
void *memset(
void *buf,
int c,
size_t n);
51 void *WordSet(
void *buf,
int c,
size_t n);
52 void *DoubleWordSet(
void *buf,
unsigned int c,
size_t n);
53 void *QuadWordSet(
void *buf,
unsigned long long c,
size_t n);
55 EXPORT
void *memcpy(
void *restrict s1,
const void *restrict s2,
size_t n);
56 EXPORT
void *memmove(
void *s1,
const void *s2,
size_t n);
60 #if !HAS_ADDRESS_SANITIZER 62 EXPORT
int memcmp(
const void *p1,
const void *p2,
size_t len)
64 const char *a = (
const char *) p1;
65 const char *b = (
const char *) p2;
70 if ((r = a[i] - b[i]) != 0)
76 EXPORT
void *memset(
void *buf,
int c,
size_t n)
79 if (n >= STOSB_THRESHOLD)
82 __asm__ __volatile__(
"rep stosb" 84 :
"0"(buf),
"a"(c),
"1"(n)
89 unsigned char *tmp = (
unsigned char *) buf;
97 EXPORT
void *memcpy(
void *restrict s1,
const void *restrict s2,
size_t n)
100 if (n >= STOSB_THRESHOLD)
103 __asm__ __volatile__(
"rep movsb" 104 :
"=&c"(a),
"=&D"(b),
"=&S"(c)
105 :
"1"(s1),
"2"(s2),
"0"(n)
110 const unsigned char *restrict sp = (
const unsigned char *restrict) s2;
111 unsigned char *restrict dp = (
unsigned char *restrict) s1;
118 static inline void *memmove_x86(
void *s1,
const void *s2,
size_t n)
121 const unsigned char *sp = (
const unsigned char *) s2 + (n - 1);
122 unsigned char *dp = (
unsigned char *) s1 + (n - 1);
125 __asm__ __volatile__(
"std; rep movsb; cld" 126 :
"=&c"(a),
"=&D"(b),
"=&S"(c)
127 :
"1"(dp),
"2"(sp),
"0"(n)
133 EXPORT
void *memmove(
void *s1,
const void *s2,
size_t n)
138 const size_t orig_n = n;
139 if (
LIKELY((s1 < s2) || !overlaps(s1, s2, n)))
147 if (n >= STOSB_THRESHOLD)
149 memmove_x86(s1, s2, n);
155 const unsigned char *sp = (
const unsigned char *) s2 + (n - 1);
156 unsigned char *dp = (
unsigned char *) s1 + (n - 1);
164 #ifdef EXCESSIVE_ADDITIONAL_CHECKS 166 if (
LIKELY(!overlaps(s1, s2, orig_n)))
168 assert(!memcmp(s1, s2, orig_n));
175 #endif // HAS_ADDRESS_SANITIZER 177 #endif // UTILITY_LINUX_COVERAGE 179 int overlaps(
const void *s1,
const void *s2,
size_t n)
181 uintptr_t a = (uintptr_t) s1;
182 uintptr_t a_end = (uintptr_t) s1 + n;
183 uintptr_t b = (uintptr_t) s2;
184 uintptr_t b_end = (uintptr_t) s2 + n;
186 return (a <= b_end) && (b <= a_end) ? 1 : 0;
189 void *WordSet(
void *buf,
int c,
size_t n)
192 if (n >= STOSB_THRESHOLD)
195 __asm__ __volatile__(
"rep stosw" 197 :
"0"(buf),
"a"(c),
"1"(n)
202 unsigned short *tmp = (
unsigned short *) buf;
210 void *DoubleWordSet(
void *buf,
unsigned int c,
size_t n)
213 if (n >= STOSB_THRESHOLD)
216 __asm__ __volatile__(
"rep stosl" 218 :
"0"(buf),
"a"(c),
"1"(n)
223 unsigned int *tmp = (
unsigned int *) buf;
231 void *QuadWordSet(
void *buf,
unsigned long long c,
size_t n)
234 if (n >= STOSB_THRESHOLD)
237 __asm__ __volatile__(
"rep stosq" 239 :
"0"(buf),
"a"(c),
"1"(n)
244 unsigned long long *p = (
unsigned long long *) buf;
253 void *ForwardMemoryCopy(
void *a,
const void *b,
size_t c)
255 return memcpy(a, b, c);
258 void *MemoryCopy(
void *a,
const void *b,
size_t c)
260 return memmove(a, b, c);
263 void *ByteSet(
void *a,
int b,
size_t c)
265 return memset(a, b, c);
268 int MemoryCompare(
const void *a,
const void *b,
size_t c)
270 return memcmp(a, b, c);