4#include "./field_impl.hpp"
5#include "asm_macros.hpp"
8template <
class T> field<T> field<T>::asm_mul_with_coarse_reduction(
const field& a,
const field& b)
noexcept
11 constexpr uint64_t r_inv = T::r_inv;
12 constexpr uint64_t modulus_0 = modulus.data[0];
13 constexpr uint64_t modulus_1 = modulus.data[1];
14 constexpr uint64_t modulus_2 = modulus.data[2];
15 constexpr uint64_t modulus_3 = modulus.data[3];
16 constexpr uint64_t zero_ref = 0;
27 __asm__(MUL(
"0(%0)",
"8(%0)",
"16(%0)",
"24(%0)",
"%1")
28 STORE_FIELD_ELEMENT(
"%2",
"%%r12",
"%%r13",
"%%r14",
"%%r15")
33 [modulus_0]
"m"(modulus_0),
34 [modulus_1]
"m"(modulus_1),
35 [modulus_2]
"m"(modulus_2),
36 [modulus_3]
"m"(modulus_3),
38 [zero_reference]
"m"(zero_ref)
39 :
"%rdx",
"%rdi",
"%r8",
"%r9",
"%r10",
"%r11",
"%r12",
"%r13",
"%r14",
"%r15",
"cc",
"memory");
43template <
class T>
void field<T>::asm_self_mul_with_coarse_reduction(
const field& a,
const field& b)
noexcept
45 constexpr uint64_t r_inv = T::r_inv;
46 constexpr uint64_t modulus_0 = modulus.data[0];
47 constexpr uint64_t modulus_1 = modulus.data[1];
48 constexpr uint64_t modulus_2 = modulus.data[2];
49 constexpr uint64_t modulus_3 = modulus.data[3];
50 constexpr uint64_t zero_ref = 0;
60 __asm__(MUL(
"0(%0)",
"8(%0)",
"16(%0)",
"24(%0)",
"%1")
61 STORE_FIELD_ELEMENT(
"%0",
"%%r12",
"%%r13",
"%%r14",
"%%r15")
65 [modulus_0]
"m"(modulus_0),
66 [modulus_1]
"m"(modulus_1),
67 [modulus_2]
"m"(modulus_2),
68 [modulus_3]
"m"(modulus_3),
70 [zero_reference]
"m"(zero_ref)
71 :
"%rdx",
"%rdi",
"%r8",
"%r9",
"%r10",
"%r11",
"%r12",
"%r13",
"%r14",
"%r15",
"cc",
"memory");
74template <
class T> field<T> field<T>::asm_sqr_with_coarse_reduction(
const field& a)
noexcept
77 constexpr uint64_t r_inv = T::r_inv;
78 constexpr uint64_t modulus_0 = modulus.data[0];
79 constexpr uint64_t modulus_1 = modulus.data[1];
80 constexpr uint64_t modulus_2 = modulus.data[2];
81 constexpr uint64_t modulus_3 = modulus.data[3];
82 constexpr uint64_t zero_ref = 0;
87#if !defined(__ADX__) || defined(DISABLE_ADX)
97 __asm__(MUL(
"0(%0)",
"8(%0)",
"16(%0)",
"24(%0)",
"%1")
98 STORE_FIELD_ELEMENT(
"%2",
"%%r12",
"%%r13",
"%%r14",
"%%r15")
103 [modulus_0]
"m"(modulus_0),
104 [modulus_1]
"m"(modulus_1),
105 [modulus_2]
"m"(modulus_2),
106 [modulus_3]
"m"(modulus_3),
108 [zero_reference]
"m"(zero_ref)
109 :
"%rdx",
"%rdi",
"%r8",
"%r9",
"%r10",
"%r11",
"%r12",
"%r13",
"%r14",
"%r15",
"cc",
"memory");
123 STORE_FIELD_ELEMENT(
"%1",
"%%r12",
"%%r13",
"%%r14",
"%%r15")
127 [zero_reference]
"m"(zero_ref),
128 [modulus_0]
"m"(modulus_0),
129 [modulus_1]
"m"(modulus_1),
130 [modulus_2]
"m"(modulus_2),
131 [modulus_3]
"m"(modulus_3),
133 :
"%rcx",
"%rdx",
"%rdi",
"%r8",
"%r9",
"%r10",
"%r11",
"%r12",
"%r13",
"%r14",
"%r15",
"cc",
"memory");
138template <
class T>
void field<T>::asm_self_sqr_with_coarse_reduction(
const field& a)
noexcept
140 constexpr uint64_t r_inv = T::r_inv;
141 constexpr uint64_t modulus_0 = modulus.data[0];
142 constexpr uint64_t modulus_1 = modulus.data[1];
143 constexpr uint64_t modulus_2 = modulus.data[2];
144 constexpr uint64_t modulus_3 = modulus.data[3];
145 constexpr uint64_t zero_ref = 0;
150#if !defined(__ADX__) || defined(DISABLE_ADX)
160 __asm__(MUL(
"0(%0)",
"8(%0)",
"16(%0)",
"24(%0)",
"%1")
161 STORE_FIELD_ELEMENT(
"%0",
"%%r12",
"%%r13",
"%%r14",
"%%r15")
165 [modulus_0]
"m"(modulus_0),
166 [modulus_1]
"m"(modulus_1),
167 [modulus_2]
"m"(modulus_2),
168 [modulus_3]
"m"(modulus_3),
170 [zero_reference]
"m"(zero_ref)
171 :
"%rdx",
"%rdi",
"%r8",
"%r9",
"%r10",
"%r11",
"%r12",
"%r13",
"%r14",
"%r15",
"cc",
"memory");
184 STORE_FIELD_ELEMENT(
"%0",
"%%r12",
"%%r13",
"%%r14",
"%%r15")
187 [zero_reference]
"m"(zero_ref),
188 [modulus_0]
"m"(modulus_0),
189 [modulus_1]
"m"(modulus_1),
190 [modulus_2]
"m"(modulus_2),
191 [modulus_3]
"m"(modulus_3),
193 :
"%rcx",
"%rdx",
"%rdi",
"%r8",
"%r9",
"%r10",
"%r11",
"%r12",
"%r13",
"%r14",
"%r15",
"cc",
"memory");
197template <
class T> field<T> field<T>::asm_add_with_coarse_reduction(
const field& a,
const field& b)
noexcept
201 constexpr uint64_t twice_not_modulus_0 = twice_not_modulus.data[0];
202 constexpr uint64_t twice_not_modulus_1 = twice_not_modulus.data[1];
203 constexpr uint64_t twice_not_modulus_2 = twice_not_modulus.data[2];
204 constexpr uint64_t twice_not_modulus_3 = twice_not_modulus.data[3];
206 __asm__(CLEAR_FLAGS(
"%%r12") LOAD_FIELD_ELEMENT(
"%0",
"%%r12",
"%%r13",
"%%r14",
"%%r15")
208 "%[twice_not_modulus_0]",
209 "%[twice_not_modulus_1]",
210 "%[twice_not_modulus_2]",
211 "%[twice_not_modulus_3]") STORE_FIELD_ELEMENT(
"%2",
"%%r12",
"%%r13",
"%%r14",
"%%r15")
216 [twice_not_modulus_0]
"m"(twice_not_modulus_0),
217 [twice_not_modulus_1]
"m"(twice_not_modulus_1),
218 [twice_not_modulus_2]
"m"(twice_not_modulus_2),
219 [twice_not_modulus_3]
"m"(twice_not_modulus_3)
220 :
"%r8",
"%r9",
"%r10",
"%r11",
"%r12",
"%r13",
"%r14",
"%r15",
"cc",
"memory");
224template <
class T>
void field<T>::asm_self_add_with_coarse_reduction(
const field& a,
const field& b)
noexcept
226 constexpr uint64_t twice_not_modulus_0 = twice_not_modulus.data[0];
227 constexpr uint64_t twice_not_modulus_1 = twice_not_modulus.data[1];
228 constexpr uint64_t twice_not_modulus_2 = twice_not_modulus.data[2];
229 constexpr uint64_t twice_not_modulus_3 = twice_not_modulus.data[3];
231 __asm__(CLEAR_FLAGS(
"%%r12") LOAD_FIELD_ELEMENT(
"%0",
"%%r12",
"%%r13",
"%%r14",
"%%r15")
233 "%[twice_not_modulus_0]",
234 "%[twice_not_modulus_1]",
235 "%[twice_not_modulus_2]",
236 "%[twice_not_modulus_3]") STORE_FIELD_ELEMENT(
"%0",
"%%r12",
"%%r13",
"%%r14",
"%%r15")
240 [twice_not_modulus_0]
"m"(twice_not_modulus_0),
241 [twice_not_modulus_1]
"m"(twice_not_modulus_1),
242 [twice_not_modulus_2]
"m"(twice_not_modulus_2),
243 [twice_not_modulus_3]
"m"(twice_not_modulus_3)
244 :
"%r8",
"%r9",
"%r10",
"%r11",
"%r12",
"%r13",
"%r14",
"%r15",
"cc",
"memory");
247template <
class T> field<T> field<T>::asm_sub_with_coarse_reduction(
const field& a,
const field& b)
noexcept
251 constexpr uint64_t twice_modulus_0 = twice_modulus.data[0];
252 constexpr uint64_t twice_modulus_1 = twice_modulus.data[1];
253 constexpr uint64_t twice_modulus_2 = twice_modulus.data[2];
254 constexpr uint64_t twice_modulus_3 = twice_modulus.data[3];
257 CLEAR_FLAGS(
"%%r12") LOAD_FIELD_ELEMENT(
"%0",
"%%r12",
"%%r13",
"%%r14",
"%%r15") SUB(
"%1")
258 REDUCE_FIELD_ELEMENT(
"%[twice_modulus_0]",
"%[twice_modulus_1]",
"%[twice_modulus_2]",
"%[twice_modulus_3]")
259 STORE_FIELD_ELEMENT(
"%2",
"%%r12",
"%%r13",
"%%r14",
"%%r15")
264 [twice_modulus_0]
"m"(twice_modulus_0),
265 [twice_modulus_1]
"m"(twice_modulus_1),
266 [twice_modulus_2]
"m"(twice_modulus_2),
267 [twice_modulus_3]
"m"(twice_modulus_3)
268 :
"%r8",
"%r9",
"%r10",
"%r11",
"%r12",
"%r13",
"%r14",
"%r15",
"cc",
"memory");
272template <
class T>
void field<T>::asm_self_sub_with_coarse_reduction(
const field& a,
const field& b)
noexcept
274 constexpr uint64_t twice_modulus_0 = twice_modulus.data[0];
275 constexpr uint64_t twice_modulus_1 = twice_modulus.data[1];
276 constexpr uint64_t twice_modulus_2 = twice_modulus.data[2];
277 constexpr uint64_t twice_modulus_3 = twice_modulus.data[3];
280 CLEAR_FLAGS(
"%%r12") LOAD_FIELD_ELEMENT(
"%0",
"%%r12",
"%%r13",
"%%r14",
"%%r15") SUB(
"%1")
281 REDUCE_FIELD_ELEMENT(
"%[twice_modulus_0]",
"%[twice_modulus_1]",
"%[twice_modulus_2]",
"%[twice_modulus_3]")
282 STORE_FIELD_ELEMENT(
"%0",
"%%r12",
"%%r13",
"%%r14",
"%%r15")
286 [twice_modulus_0]
"m"(twice_modulus_0),
287 [twice_modulus_1]
"m"(twice_modulus_1),
288 [twice_modulus_2]
"m"(twice_modulus_2),
289 [twice_modulus_3]
"m"(twice_modulus_3)
290 :
"%r8",
"%r9",
"%r10",
"%r11",
"%r12",
"%r13",
"%r14",
"%r15",
"cc",
"memory");
293template <
class T>
void field<T>::asm_conditional_negate(field& r,
const uint64_t predicate)
noexcept
295 constexpr uint64_t twice_modulus_0 = twice_modulus.data[0];
296 constexpr uint64_t twice_modulus_1 = twice_modulus.data[1];
297 constexpr uint64_t twice_modulus_2 = twice_modulus.data[2];
298 constexpr uint64_t twice_modulus_3 = twice_modulus.data[3];
300 __asm__(CLEAR_FLAGS(
"%%r8") LOAD_FIELD_ELEMENT(
301 "%1",
"%%r8",
"%%r9",
"%%r10",
"%%r11")
"movq %[twice_modulus_0], %%r12 \n\t"
302 "movq %[twice_modulus_1], %%r13 \n\t"
303 "movq %[twice_modulus_2], %%r14 \n\t"
304 "movq %[twice_modulus_3], %%r15 \n\t"
305 "subq %%r8, %%r12 \n\t"
306 "sbbq %%r9, %%r13 \n\t"
307 "sbbq %%r10, %%r14 \n\t"
308 "sbbq %%r11, %%r15 \n\t"
310 "cmovnzq %%r12, %%r8 \n\t"
311 "cmovnzq %%r13, %%r9 \n\t"
312 "cmovnzq %%r14, %%r10 \n\t"
313 "cmovnzq %%r15, %%r11 \n\t" STORE_FIELD_ELEMENT(
314 "%1",
"%%r8",
"%%r9",
"%%r10",
"%%r11")
318 [twice_modulus_0]
"i"(twice_modulus_0),
319 [twice_modulus_1]
"i"(twice_modulus_1),
320 [twice_modulus_2]
"i"(twice_modulus_2),
321 [twice_modulus_3]
"i"(twice_modulus_3)
322 :
"%r8",
"%r9",
"%r10",
"%r11",
"%r12",
"%r13",
"%r14",
"%r15",
"cc",
"memory");
325template <
class T> field<T> field<T>::asm_reduce_once(
const field& a)
noexcept
329 constexpr uint64_t not_modulus_0 = not_modulus.data[0];
330 constexpr uint64_t not_modulus_1 = not_modulus.data[1];
331 constexpr uint64_t not_modulus_2 = not_modulus.data[2];
332 constexpr uint64_t not_modulus_3 = not_modulus.data[3];
334 __asm__(CLEAR_FLAGS(
"%%r12") LOAD_FIELD_ELEMENT(
"%0",
"%%r12",
"%%r13",
"%%r14",
"%%r15")
335 REDUCE_FIELD_ELEMENT(
"%[not_modulus_0]",
"%[not_modulus_1]",
"%[not_modulus_2]",
"%[not_modulus_3]")
336 STORE_FIELD_ELEMENT(
"%1",
"%%r12",
"%%r13",
"%%r14",
"%%r15")
340 [not_modulus_0]
"m"(not_modulus_0),
341 [not_modulus_1]
"m"(not_modulus_1),
342 [not_modulus_2]
"m"(not_modulus_2),
343 [not_modulus_3]
"m"(not_modulus_3)
344 :
"%r8",
"%r9",
"%r10",
"%r11",
"%r12",
"%r13",
"%r14",
"%r15",
"cc",
"memory");
348template <
class T>
void field<T>::asm_self_reduce_once(
const field& a)
noexcept
350 constexpr uint64_t not_modulus_0 = not_modulus.data[0];
351 constexpr uint64_t not_modulus_1 = not_modulus.data[1];
352 constexpr uint64_t not_modulus_2 = not_modulus.data[2];
353 constexpr uint64_t not_modulus_3 = not_modulus.data[3];
355 __asm__(CLEAR_FLAGS(
"%%r12") LOAD_FIELD_ELEMENT(
"%0",
"%%r12",
"%%r13",
"%%r14",
"%%r15")
356 REDUCE_FIELD_ELEMENT(
"%[not_modulus_0]",
"%[not_modulus_1]",
"%[not_modulus_2]",
"%[not_modulus_3]")
357 STORE_FIELD_ELEMENT(
"%0",
"%%r12",
"%%r13",
"%%r14",
"%%r15")
360 [not_modulus_0]
"m"(not_modulus_0),
361 [not_modulus_1]
"m"(not_modulus_1),
362 [not_modulus_2]
"m"(not_modulus_2),
363 [not_modulus_3]
"m"(not_modulus_3)
364 :
"%r8",
"%r9",
"%r10",
"%r11",
"%r12",
"%r13",
"%r14",
"%r15",
"cc",
"memory");
constexpr_utils defines some helper methods that perform some stl-equivalent operations but in a cons...
Definition: constexpr_utils.hpp:16