PatchworkOS  c9fea19
A non-POSIX operating system.
Loading...
Searching...
No Matches
memcpy.c
Go to the documentation of this file.
1#include <stdint.h>
2#include <string.h>
3#include <sys/cpuid.h>
4
5static void* memcpy_no_simd(void* _RESTRICT s1, const void* _RESTRICT s2, size_t n)
6{
7 uint8_t* d = s1;
8 const uint8_t* s = s2;
9
10 while (((uintptr_t)d & 7) && n)
11 {
12 *d++ = *s++;
13 n--;
14 }
15
16 while (n >= 64)
17 {
18 *(uint64_t*)(d + 0) = *(const uint64_t*)(s + 0);
19 *(uint64_t*)(d + 8) = *(const uint64_t*)(s + 8);
20 *(uint64_t*)(d + 16) = *(const uint64_t*)(s + 16);
21 *(uint64_t*)(d + 24) = *(const uint64_t*)(s + 24);
22 *(uint64_t*)(d + 32) = *(const uint64_t*)(s + 32);
23 *(uint64_t*)(d + 40) = *(const uint64_t*)(s + 40);
24 *(uint64_t*)(d + 48) = *(const uint64_t*)(s + 48);
25 *(uint64_t*)(d + 56) = *(const uint64_t*)(s + 56);
26 d += 64;
27 s += 64;
28 n -= 64;
29 }
30
31 while (n >= 8)
32 {
33 *(uint64_t*)d = *(const uint64_t*)s;
34 d += 8;
35 s += 8;
36 n -= 8;
37 }
38
39 while (n--)
40 {
41 *d++ = *s++;
42 }
43
44 return s1;
45}
46
47#ifdef _KERNEL_
48
49void* memcpy(void* _RESTRICT s1, const void* _RESTRICT s2, size_t n)
50{
51 return memcpy_no_simd(s1, s2, n);
52}
53
54#else
55
56// Check memcpy.s
57extern void* memcpy_sse2(void* _RESTRICT s1, const void* _RESTRICT s2, size_t n);
58
59static void* (*memcpy_impl)(void* _RESTRICT, const void* _RESTRICT, size_t) = NULL;
60
61void* memcpy(void* _RESTRICT s1, const void* _RESTRICT s2, size_t n)
62{
63 if (memcpy_impl == NULL)
64 {
66
68 {
70 }
71 else
72 {
74 }
75 }
76
77 return memcpy_impl(s1, s2, n);
78}
79
80#endif // _KERNEL_
static cpuid_instruction_sets_t cpuid_detect_instruction_sets(void)
Helper to detect supported instruction sets.
Definition cpuid.h:258
cpuid_instruction_sets_t
Supported CPU instruction sets.
Definition cpuid.h:240
@ CPUID_INSTRUCTION_SET_SSE2
Definition cpuid.h:243
#define NULL
Pointer error value.
Definition NULL.h:23
#define _RESTRICT
Definition config.h:17
static void * memcpy_no_simd(void *_RESTRICT s1, const void *_RESTRICT s2, size_t n)
Definition memcpy.c:5
void * memcpy_sse2(void *_RESTRICT s1, const void *_RESTRICT s2, size_t n)
void * memcpy(void *_RESTRICT s1, const void *_RESTRICT s2, size_t n)
Definition memcpy.c:61
static void *(* memcpy_impl)(void *_RESTRICT, const void *_RESTRICT, size_t)
Definition memcpy.c:59
__SIZE_TYPE__ size_t
Definition size_t.h:4
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
__UINT8_TYPE__ uint8_t
Definition stdint.h:11
__UINTPTR_TYPE__ uintptr_t
Definition stdint.h:43