-
Notifications
You must be signed in to change notification settings - Fork 0
/
commonmacros
442 lines (376 loc) · 9 KB
/
commonmacros
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
/**
Macro INIT_PRIME_P
initializes the registers for prime p
*/
.macro INIT_PRIME_P
//load c of prime into ppc, load the least significant u64 of p, into pp0
adr pp1, prime_p_and_c
ldp pp0, ppc, [pp1]
mvn pp1, xzr //0xffffffffffffffff is now in pp1
.endm
/**
Macro INIT_ORDER_N
initializes the registers for prime n
*/
.macro INIT_ORDER_N
//load prime n into regs on0 - on3
adr on3, secp256k1_n
ldp on0, on1, [on3], #16
ldp on2, on3, [on3]
//load d of prime into ond0 and ond1
adr ond0, secp256k1_d
ldp ond1, ond0, [ond0]
.endm
/**
Macro LOAD_B_WITH_HALF_N
initializes the regs sb0...sb3 with the half of order n
*/
.macro LOAD_B_WITH_HALF_N
adr sb3, secp256k1_n_half
ldp sb0, sb1, [sb3], #16
ldp sb2, sb3, [sb3]
.endm
/**
Tests if Scalar A has zero values in all registers
Returns 0 in io0 if scalar is zero otherwise 1
*/
.macro IS_A_ZERO
mov io0, #1
cbnz sa0, end_test\@
cbnz sa1, end_test\@
cbnz sa2, end_test\@
cbnz sa3, end_test\@
mov io0, xzr
end_test\@:
.endm
/**
Tests if the lower part of Scalar R (lo, sr0...sr3) has zero values in
all registers.
Returns 0 in io0 R (lo) is zero otherwise 1
*/
.macro IS_R_LO_ZERO
mov io0, #1
cbnz sr0, end_test\@
cbnz sr1, end_test\@
cbnz sr2, end_test\@
cbnz sr3, end_test\@
mov io0, xzr
end_test\@:
.endm
.macro COPY_B_TO_A
mov sa0, sb0
mov sa1, sb1
mov sa2, sb2
mov sa3, sb3
.endm
.macro COPY_A_TO_R_LO
mov sr0, sa0
mov sr1, sa1
mov sr2, sa2
mov sr3, sa3
.endm
.macro COPY_B_TO_R_LO
mov sr0, sb0
mov sr1, sb1
mov sr2, sb2
mov sr3, sb3
.endm
.macro COPY_R_LO_TO_A
mov sa0, sr0
mov sa1, sr1
mov sa2, sr2
mov sa3, sr3
.endm
.macro COPY_R_LO_TO_B
mov sb0, sr0
mov sb1, sr1
mov sb2, sr2
mov sb3, sr3
.endm
/**
Macro LOAD_A_B
Loads scalar a from address in reg0 into sa0...sa3,
scalar b from address in reg1 into sb0...sb3
*/
.macro LOAD_A_B reg0=io0 reg1=io1
//load scalar a
mov sa3, \reg0
ldp sa0, sa1, [sa3], #16
ldp sa2, sa3, [sa3]
//load scalar b
mov sb3, \reg1
ldp sb0, sb1, [sb3], #16
ldp sb2, sb3, [sb3]
.endm
.macro LOAD_A reg0=io0
mov sa3, \reg0
ldp sa0, sa1, [sa3], #16
ldp sa2, sa3, [sa3]
.endm
.macro LOAD_B reg0=io1
mov sb3, \reg0
ldp sb0, sb1, [sb3], #16
ldp sb2, sb3, [sb3]
.endm
.macro CLEAR_A
mov sa0, xzr
mov sa1, xzr
mov sa2, xzr
mov sa3, xzr
.endm
.macro CLEAR_B
mov sb0, xzr
mov sb1, xzr
mov sb2, xzr
mov sb3, xzr
.endm
.macro CLEAR_R
mov sr0, xzr
mov sr1, xzr
mov sr2, xzr
mov sr3, xzr
mov sr4, xzr
mov sr5, xzr
mov sr6, xzr
mov sr7, xzr
.endm
.macro SET_A_TO_1
mov sa0, #1
mov sa1, xzr
mov sa2, xzr
mov sa3, xzr
.endm
.macro SET_A_TO_7
mov sa0, #7
mov sa1, xzr
mov sa2, xzr
mov sa3, xzr
.endm
.macro SET_B_TO_1
mov sb0, #1
mov sb1, xzr
mov sb2, xzr
mov sb3, xzr
.endm
.macro LOAD_K reg=io1
mov sk3, \reg
ldp sk0, sk1, [sk3], #16
ldp sk2, sk3, [sk3]
.endm
/**
Macro STORE_R_LO
Stores sr0...sr3 in memory at address in the given reg
*/
.macro STORE_R_LO reg
stp sr0, sr1, [\reg], #16
stp sr2, sr3, [\reg]
.endm
/**
Macro STORE_R_HI
Stores the higher part of R (R hi, sr4...sr7) in memory at address in reg
*/
.macro STORE_R_HI reg
stp sr4, sr5, [\reg], #16
stp sr6, sr7, [\reg]
.endm
/**
Macro STORE_R
stores sr0...sr7 into memory at address in reg
*/
.macro STORE_R reg
stp sr0, sr1, [\reg], #16
stp sr2, sr3, [\reg], #16
stp sr4, sr5, [\reg], #16
stp sr6, sr7, [\reg], #16
.endm
/**
Macro STORE_A
Stores a (sa0...sa3) in memory at address in the given reg
*/
.macro STORE_A reg
stp sa0, sa1, [\reg], #16
stp sa2, sa3, [\reg]
.endm
/**
Macro STORE_B
Stores b (sb0...sb3) in memory at address in the given reg
*/
.macro STORE_B reg
stp sb0, sb1, [\reg], #16
stp sb2, sb3, [\reg]
.endm
/**
Macro STORE_A_B
stores a and b in memory at address in reg
*/
.macro STORE_A_B
stp sa0, sa1, [\reg], #16
stp sa2, sa3, [\reg], #16
stp sb0, sb1, [\reg], #16
stp sb2, sb3, [\reg]
.endm
/**
Macro STORE_K
Stores k (regs sk0...sk3) in memory at address in the given reg
*/
.macro STORE_K reg
stp sk0, sk1, [\reg], #16
stp sk2, sk3, [\reg]
.endm
.macro COPY_INTO_K_FROM reg1 reg2 reg3 reg4
mov sk0, \reg1
mov sk1, \reg2
mov sk2, \reg3
mov sk3, \reg4
.endm
.macro COPY_K_INTO reg1 reg2 reg3 reg4
mov \reg1, sk0
mov \reg2, sk1
mov \reg3, sk2
mov \reg4, sk3
.endm
.macro COPY_P_INTO reg1 reg2 reg3 reg4
mov \reg1, pp0
mov \reg2, pp1
mov \reg3, pp1
mov \reg4, pp1
.endm
/*
Macros for saveing/restoring registers on the stack
*/
.macro PUSH reg1 reg2=xzr
stp \reg1, \reg2, [sp, #-16]!
.endm
.macro POP reg1 reg2=xzr
ldp \reg1, \reg2, [sp], #16
.endm
.macro PUSH_ALL
stp x0, x1, [sp, #-16]!
stp x2, x3, [sp, #-16]!
stp x4, x5, [sp, #-16]!
stp x6, x7, [sp, #-16]!
stp x8, x9, [sp, #-16]!
stp x10, x11, [sp, #-16]!
stp x12, x13, [sp, #-16]!
stp x14, x15, [sp, #-16]!
stp x16, x17, [sp, #-16]!
stp x18, x19, [sp, #-16]!
stp x20, x21, [sp, #-16]!
stp x22, x23, [sp, #-16]!
stp x24, x25, [sp, #-16]!
stp x26, x27, [sp, #-16]!
stp x28, x29, [sp, #-16]!
stp x30, xzr, [sp, #-16]!
.endm
.macro POP_ALL
ldp x30, xzr, [sp], #16
ldp x28, x29, [sp], #16
ldp x26, x27, [sp], #16
ldp x24, x25, [sp], #16
ldp x22, x23, [sp], #16
ldp x20, x21, [sp], #16
ldp x18, x19, [sp], #16
ldp x16, x17, [sp], #16
ldp x14, x15, [sp], #16
ldp x12, x13, [sp], #16
ldp x10, x11, [sp], #16
ldp x8, x9, [sp], #16
ldp x6, x7, [sp], #16
ldp x4, x5, [sp], #16
ldp x2, x3, [sp], #16
ldp x0, x1, [sp], #16
.endm
//Macros for the boilerplate of function declaration
//A global C-compatible function that preserves the callee saved registers
.macro BEGIN_C_FUNCTION function_name
.type \function_name, %function
.global \function_name
\function_name:
stp csr0, csr1, [sp, #-16]!
stp csr2, csr3, [sp, #-16]!
stp csr4, csr5, [sp, #-16]!
stp csr6, csr7, [sp, #-16]!
stp csr8, csr9, [sp, #-16]!
stp frmptr, prclrg, [sp, #-16]!
.endm
.macro END_C_FUNCTION function_name
ldp frmptr, prclrg, [sp], #16
ldp csr8, csr9, [sp], #16
ldp csr6, csr7, [sp], #16
ldp csr4, csr5, [sp], #16
ldp csr2, csr3, [sp], #16
ldp csr0, csr1, [sp], #16
ret
.size \function_name, (. - \function_name)
.endm
//A global function that preserves the frame pointer and procedure link register
//but not the other callee saved regs
.macro BEGIN_GLOBAL_FUNCTION function_name
.type \function_name, %function
.global \function_name
\function_name:
stp frmptr, prclrg, [sp, #-16]!
.endm
.macro END_GLOBAL_FUNCTION function_name
ldp frmptr, prclrg, [sp], #16
ret
.size \function_name, (. - \function_name)
.endm
//Macros for converting integers to ascii-strings
.macro INIT_MSKF1
mov mskf1, 0xf //000000000000000f
.endm
.macro CONVERT_NIBBLE_TO_ASCII input accum
and tmp2, \input, mskf1 //mskf1 must bi initialized with 0xF
cmp tmp2, 9
bhi is_above_9\@
add tmp2, tmp2, 48 //'0'...'9'
b is_converted\@
is_above_9\@:
add tmp2, tmp2, 87 //'a'...'f'
is_converted\@:
lsl \accum, \accum, #8
orr \accum, \accum, tmp2
lsr \input, \input, #4
.endm
.macro CONVERT_U32_TO_ASCII val accum
CONVERT_NIBBLE_TO_ASCII \val \accum
CONVERT_NIBBLE_TO_ASCII \val \accum
CONVERT_NIBBLE_TO_ASCII \val \accum
CONVERT_NIBBLE_TO_ASCII \val \accum
CONVERT_NIBBLE_TO_ASCII \val \accum
CONVERT_NIBBLE_TO_ASCII \val \accum
CONVERT_NIBBLE_TO_ASCII \val \accum
CONVERT_NIBBLE_TO_ASCII \val \accum
.endm
.macro CONVERT_U64_TO_ASCII input hi lo
CONVERT_U32_TO_ASCII \input \hi
CONVERT_U32_TO_ASCII \input \lo
.endm
/**
* The macro CONVERT_SCALAR_TO_ASCII
* converts a Scalar to an ASCII string with 64 chars.
* Input:
* Address of Scalar in register 'input'
* Output:
* Address of buffer for the resulting ASCII characters in register 'output'
*/
.macro CONVERT_SCALAR_TO_ASCII input output
CLEAR_R
INIT_MSKF1
LOAD_A \input
CONVERT_U64_TO_ASCII sa0 sr7 sr6
CONVERT_U64_TO_ASCII sa1 sr5 sr4
CONVERT_U64_TO_ASCII sa2 sr3 sr2
CONVERT_U64_TO_ASCII sa3 sr1 sr0
STORE_R \output
.endm
/**
Macro PRINTREG for debugging: prints the content of a register to stdout
*/
.macro PRINTREG reg=io0
PUSH_ALL
mov io0, \reg
bl printU64
POP_ALL
.endm