memory.h - libzahl - big integer library
(HTM) git clone git://git.suckless.org/libzahl
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) 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 default:
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_char_t *restrict s, register size_t n)
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, size_t n)
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, size_t n)
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, size_t n)
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, size_t n)
159 {
160 if (d < s)
161 libzahl_memmovef(d, s, n);
162 else
163 libzahl_memmoveb(d, s, n);
164 }