memory.h - libzahl - big integer library | |
git clone git://git.suckless.org/libzahl | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
memory.h (3488B) | |
--- | |
1 /* See LICENSE file for copyright and license details. */ | |
2 | |
3 #define LIBZAHL_MEM_CASES \ | |
4 LIBZAHL_X(20); \ | |
5 LIBZAHL_X(19); \ | |
6 LIBZAHL_X(18); \ | |
7 LIBZAHL_X(17); \ | |
8 LIBZAHL_X(16); \ | |
9 LIBZAHL_X(15); \ | |
10 LIBZAHL_X(14); \ | |
11 LIBZAHL_X(13); \ | |
12 LIBZAHL_X(12); \ | |
13 LIBZAHL_X(11); \ | |
14 LIBZAHL_X(10); \ | |
15 LIBZAHL_X( 9); \ | |
16 LIBZAHL_X( 8); \ | |
17 LIBZAHL_X( 7); \ | |
18 LIBZAHL_X( 6); \ | |
19 LIBZAHL_X( 5); \ | |
20 LIBZAHL_X( 4); \ | |
21 LIBZAHL_X( 3); \ | |
22 LIBZAHL_X( 2); \ | |
23 LIBZAHL_X( 1); \ | |
24 case 0: break; | |
25 | |
26 | |
27 #if defined(ZAHL_ISA_MISSING_INDIRECT_JUMP) | |
28 # define LIBZAHL_SMALL_INPUT_BEGIN(n) | |
29 # define LIBZAHL_SMALL_INPUT_END | |
30 #else | |
31 # define LIBZAHL_SMALL_INPUT_BEGIN(n) switch (n) { LIBZAHL_MEM_CASES de… | |
32 # define LIBZAHL_SMALL_INPUT_END break; } | |
33 #endif | |
34 | |
35 | |
36 ZAHL_INLINE void | |
37 libzahl_memcpy(register zahl_char_t *restrict d, register const zahl_cha… | |
38 { | |
39 #define LIBZAHL_X(I) case I: d[I - 1] = s[I - 1]; | |
40 LIBZAHL_SMALL_INPUT_BEGIN(n); | |
41 { | |
42 #if defined(__x86_64__) && !defined(ZAHL_NO_ASM) | |
43 /* This crap is needed for clang. */ | |
44 register zahl_char_t t; | |
45 __asm__ __volatile__ ( | |
46 # if defined(ZAHL_ISA_MISSING_INDIRECT_JUMP) | |
47 "\n testq %[e], %[e]" | |
48 "\n jz 2f" | |
49 # endif | |
50 "\n shlq $3, %[e]" | |
51 "\n addq %[d], %[e]" | |
52 "\n 1:" | |
53 "\n movq 0(%[s]), %[t]" | |
54 "\n movq %[t], 0(%[d])" | |
55 "\n movq 8(%[s]), %[t]" | |
56 "\n movq %[t], 8(%[d])" | |
57 "\n movq 16(%[s]), %[t]" | |
58 "\n movq %[t], 16(%[d])" | |
59 "\n movq 24(%[s]), %[t]" | |
60 "\n movq %[t], 24(%[d])" | |
61 "\n addq $32, %[s]" | |
62 "\n addq $32, %[d]" | |
63 "\n cmpq %[e], %[d]" | |
64 "\n jl 1b" | |
65 # if defined(ZAHL_ISA_MISSING_INDIRECT_JUMP) | |
66 "\n 2:" | |
67 # endif | |
68 : [t]"=r"(t), [d]"+r"(d), [s]"+r"(s), [e]"+r"(n)… | |
69 #else | |
70 size_t i; | |
71 for (i = 0; i < n; i += 4) { | |
72 d[i + 0] = s[i + 0]; | |
73 d[i + 1] = s[i + 1]; | |
74 d[i + 2] = s[i + 2]; | |
75 d[i + 3] = s[i + 3]; | |
76 } | |
77 #endif | |
78 } | |
79 LIBZAHL_SMALL_INPUT_END; | |
80 #undef LIBZAHL_X | |
81 } | |
82 | |
83 | |
84 ZAHL_INLINE void | |
85 libzahl_memset(register zahl_char_t *a, register zahl_char_t v, size_t n) | |
86 { | |
87 size_t i; | |
88 for (i = 0; i < n; i += 4) { | |
89 a[i + 0] = v; | |
90 a[i + 1] = v; | |
91 a[i + 2] = v; | |
92 a[i + 3] = v; | |
93 } | |
94 } | |
95 | |
96 ZAHL_INLINE void | |
97 libzahl_memset_precise(register zahl_char_t *a, register zahl_char_t v, … | |
98 { | |
99 size_t i; | |
100 if (n <= 4) { | |
101 if (n >= 1) | |
102 a[0] = v; | |
103 if (n >= 2) | |
104 a[1] = v; | |
105 if (n >= 3) | |
106 a[2] = v; | |
107 if (n >= 4) | |
108 a[3] = v; | |
109 } else { | |
110 for (i = 0; (i += 4) <= n;) { | |
111 a[i - 1] = v; | |
112 a[i - 2] = v; | |
113 a[i - 3] = v; | |
114 a[i - 4] = v; | |
115 } | |
116 if (i > n) | |
117 for (i -= 4; i < n; i++) | |
118 a[i] = v; | |
119 } | |
120 } | |
121 | |
122 | |
123 ZAHL_INLINE void | |
124 libzahl_memmovef(register zahl_char_t *d, register const zahl_char_t *s,… | |
125 { | |
126 if (n && n < 4) { | |
127 d[0] = s[0]; | |
128 d[1] = s[1]; | |
129 d[2] = s[2]; | |
130 } else { | |
131 size_t i; | |
132 for (i = 0; i < n; i += 4) { | |
133 d[i + 0] = s[i + 0]; | |
134 d[i + 1] = s[i + 1]; | |
135 d[i + 2] = s[i + 2]; | |
136 d[i + 3] = s[i + 3]; | |
137 } | |
138 } | |
139 } | |
140 | |
141 ZAHL_INLINE void | |
142 libzahl_memmoveb(register zahl_char_t *d, register const zahl_char_t *s,… | |
143 { | |
144 ssize_t i; | |
145 #define LIBZAHL_X(I) case I: d[I - 1] = s[I - 1]; | |
146 LIBZAHL_SMALL_INPUT_BEGIN(n); | |
147 for (i = ((ssize_t)n + 3) & ~3; (i -= 4) >= 0;) { | |
148 d[i + 3] = s[i + 3]; | |
149 d[i + 2] = s[i + 2]; | |
150 d[i + 1] = s[i + 1]; | |
151 d[i + 0] = s[i + 0]; | |
152 } | |
153 LIBZAHL_SMALL_INPUT_END; | |
154 #undef LIBZAHL_X | |
155 } | |
156 | |
157 ZAHL_INLINE void | |
158 libzahl_memmove(register zahl_char_t *d, register const zahl_char_t *s, … | |
159 { | |
160 if (d < s) | |
161 libzahl_memmovef(d, s, n); | |
162 else | |
163 libzahl_memmoveb(d, s, n); | |
164 } |