1
2
3
4
5
6
7
8
9
10
11
12 package main
13
14 import (
15 "os"
16 "strings"
17
18 . "github.com/mmcloughlin/avo/build"
19 "github.com/mmcloughlin/avo/ir"
20 . "github.com/mmcloughlin/avo/operand"
21 . "github.com/mmcloughlin/avo/reg"
22 )
23
24
25
26 var (
27 res_ptr GPPhysical = RDI
28 x_ptr = RSI
29 y_ptr = RCX
30 )
31
32
33
34 var (
35 acc0_v1 GPPhysical = R8
36 acc1_v1 = R9
37 acc2_v1 = R10
38 acc3_v1 = R11
39 acc4_v1 = R12
40 acc5_v1 = R13
41 t0_v1 = R14
42 t1_v1 = R15
43 )
44
45 func main() {
46 Package("crypto/internal/fips140/nistec")
47 ConstraintExpr("!purego")
48 p256MovCond()
49 p256NegCond()
50 p256Sqr()
51 p256Mul()
52 p256FromMont()
53 p256Select()
54 p256SelectAffine()
55 p256SubInternal()
56 p256MulInternal()
57 p256SqrInternal()
58 p256PointAddAffineAsm()
59 p256IsZero()
60 p256PointAddAsm()
61 p256PointDoubleAsm()
62 Generate()
63
64 internalFunctions := []string{
65 "·p256SubInternal",
66 "·p256MulInternal",
67 "·p256SqrInternal",
68 "·p256IsZero",
69 }
70 removePeskyUnicodeDot(internalFunctions, "../p256_asm_amd64.s")
71 }
72
73
74
75
76 func p256MovCond() {
77 Implement("p256MovCond")
78 Attributes(NOSPLIT)
79
80 Load(Param("res"), res_ptr)
81 Load(Param("a"), x_ptr)
82 Load(Param("b"), y_ptr)
83 Load(Param("cond"), X12)
84
85 PXOR(X13, X13)
86 PSHUFD(Imm(0), X12, X12)
87 PCMPEQL(X13, X12)
88
89 MOVOU(X12, X0)
90 MOVOU(Mem{Base: x_ptr}.Offset(16*0), X6)
91 PANDN(X6, X0)
92 MOVOU(X12, X1)
93 MOVOU(Mem{Base: x_ptr}.Offset(16*1), X7)
94 PANDN(X7, X1)
95 MOVOU(X12, X2)
96 MOVOU(Mem{Base: x_ptr}.Offset(16*2), X8)
97 PANDN(X8, X2)
98 MOVOU(X12, X3)
99 MOVOU(Mem{Base: x_ptr}.Offset(16*3), X9)
100 PANDN(X9, X3)
101 MOVOU(X12, X4)
102 MOVOU(Mem{Base: x_ptr}.Offset(16*4), X10)
103 PANDN(X10, X4)
104 MOVOU(X12, X5)
105 MOVOU(Mem{Base: x_ptr}.Offset(16*5), X11)
106 PANDN(X11, X5)
107
108 MOVOU(Mem{Base: y_ptr}.Offset(16*0), X6)
109 MOVOU(Mem{Base: y_ptr}.Offset(16*1), X7)
110 MOVOU(Mem{Base: y_ptr}.Offset(16*2), X8)
111 MOVOU(Mem{Base: y_ptr}.Offset(16*3), X9)
112 MOVOU(Mem{Base: y_ptr}.Offset(16*4), X10)
113 MOVOU(Mem{Base: y_ptr}.Offset(16*5), X11)
114
115 PAND(X12, X6)
116 PAND(X12, X7)
117 PAND(X12, X8)
118 PAND(X12, X9)
119 PAND(X12, X10)
120 PAND(X12, X11)
121
122 PXOR(X6, X0)
123 PXOR(X7, X1)
124 PXOR(X8, X2)
125 PXOR(X9, X3)
126 PXOR(X10, X4)
127 PXOR(X11, X5)
128
129 MOVOU(X0, Mem{Base: res_ptr}.Offset(16*0))
130 MOVOU(X1, Mem{Base: res_ptr}.Offset(16*1))
131 MOVOU(X2, Mem{Base: res_ptr}.Offset(16*2))
132 MOVOU(X3, Mem{Base: res_ptr}.Offset(16*3))
133 MOVOU(X4, Mem{Base: res_ptr}.Offset(16*4))
134 MOVOU(X5, Mem{Base: res_ptr}.Offset(16*5))
135
136 RET()
137 }
138
139
140
141
142 func p256NegCond() {
143 Implement("p256NegCond")
144 Attributes(NOSPLIT)
145
146 Load(Param("val"), res_ptr)
147 Load(Param("cond"), t0_v1)
148
149 Comment("acc = poly")
150 MOVQ(I32(-1), acc0_v1)
151 p256const0 := p256const0_DATA()
152 MOVQ(p256const0, acc1_v1)
153 MOVQ(I32(0), acc2_v1)
154 p256const1 := p256const1_DATA()
155 MOVQ(p256const1, acc3_v1)
156
157 Comment("Load the original value")
158 MOVQ(Mem{Base: res_ptr}.Offset(8*0), acc5_v1)
159 MOVQ(Mem{Base: res_ptr}.Offset(8*1), x_ptr)
160 MOVQ(Mem{Base: res_ptr}.Offset(8*2), y_ptr)
161 MOVQ(Mem{Base: res_ptr}.Offset(8*3), t1_v1)
162
163 Comment("Speculatively subtract")
164 SUBQ(acc5_v1, acc0_v1)
165 SBBQ(x_ptr, acc1_v1)
166 SBBQ(y_ptr, acc2_v1)
167 SBBQ(t1_v1, acc3_v1)
168
169 Comment("If condition is 0, keep original value")
170 TESTQ(t0_v1, t0_v1)
171 CMOVQEQ(acc5_v1, acc0_v1)
172 CMOVQEQ(x_ptr, acc1_v1)
173 CMOVQEQ(y_ptr, acc2_v1)
174 CMOVQEQ(t1_v1, acc3_v1)
175
176 Comment("Store result")
177 MOVQ(acc0_v1, Mem{Base: res_ptr}.Offset(8*0))
178 MOVQ(acc1_v1, Mem{Base: res_ptr}.Offset(8*1))
179 MOVQ(acc2_v1, Mem{Base: res_ptr}.Offset(8*2))
180 MOVQ(acc3_v1, Mem{Base: res_ptr}.Offset(8*3))
181
182 RET()
183 }
184
185
186
187
188 func p256Sqr() {
189 Implement("p256Sqr")
190 Attributes(NOSPLIT)
191
192 Load(Param("res"), res_ptr)
193 Load(Param("in"), x_ptr)
194 Load(Param("n"), RBX)
195
196 Label("sqrLoop")
197
198 Comment("y[1:] * y[0]")
199 MOVQ(Mem{Base: x_ptr}.Offset(8*0), t0_v1)
200
201 MOVQ(Mem{Base: x_ptr}.Offset(8*1), RAX)
202 MULQ(t0_v1)
203 MOVQ(RAX, acc1_v1)
204 MOVQ(RDX, acc2_v1)
205
206 MOVQ(Mem{Base: x_ptr}.Offset(8*2), RAX)
207 MULQ(t0_v1)
208 ADDQ(RAX, acc2_v1)
209 ADCQ(Imm(0), RDX)
210 MOVQ(RDX, acc3_v1)
211
212 MOVQ(Mem{Base: x_ptr}.Offset(8*3), RAX)
213 MULQ(t0_v1)
214 ADDQ(RAX, acc3_v1)
215 ADCQ(Imm(0), RDX)
216 MOVQ(RDX, acc4_v1)
217
218 Comment("y[2:] * y[1]")
219 MOVQ(Mem{Base: x_ptr}.Offset(8*1), t0_v1)
220
221 MOVQ(Mem{Base: x_ptr}.Offset(8*2), RAX)
222 MULQ(t0_v1)
223 ADDQ(RAX, acc3_v1)
224 ADCQ(Imm(0), RDX)
225 MOVQ(RDX, t1_v1)
226
227 MOVQ(Mem{Base: x_ptr}.Offset(8*3), RAX)
228 MULQ(t0_v1)
229 ADDQ(t1_v1, acc4_v1)
230 ADCQ(Imm(0), RDX)
231 ADDQ(RAX, acc4_v1)
232 ADCQ(Imm(0), RDX)
233 MOVQ(RDX, acc5_v1)
234
235 Comment("y[3] * y[2]")
236 MOVQ(Mem{Base: x_ptr}.Offset(8*2), t0_v1)
237
238 MOVQ(Mem{Base: x_ptr}.Offset(8*3), RAX)
239 MULQ(t0_v1)
240 ADDQ(RAX, acc5_v1)
241 ADCQ(Imm(0), RDX)
242 MOVQ(RDX, y_ptr)
243 XORQ(t1_v1, t1_v1)
244
245 Comment("*2")
246 ADDQ(acc1_v1, acc1_v1)
247 ADCQ(acc2_v1, acc2_v1)
248 ADCQ(acc3_v1, acc3_v1)
249 ADCQ(acc4_v1, acc4_v1)
250 ADCQ(acc5_v1, acc5_v1)
251 ADCQ(y_ptr, y_ptr)
252 ADCQ(Imm(0), t1_v1)
253
254 Comment("Missing products")
255 MOVQ(Mem{Base: x_ptr}.Offset(8*0), RAX)
256 MULQ(RAX)
257 MOVQ(RAX, acc0_v1)
258 MOVQ(RDX, t0_v1)
259
260 MOVQ(Mem{Base: x_ptr}.Offset(8*1), RAX)
261 MULQ(RAX)
262 ADDQ(t0_v1, acc1_v1)
263 ADCQ(RAX, acc2_v1)
264 ADCQ(Imm(0), RDX)
265 MOVQ(RDX, t0_v1)
266
267 MOVQ(Mem{Base: x_ptr}.Offset(8*2), RAX)
268 MULQ(RAX)
269 ADDQ(t0_v1, acc3_v1)
270 ADCQ(RAX, acc4_v1)
271 ADCQ(Imm(0), RDX)
272 MOVQ(RDX, t0_v1)
273
274 MOVQ(Mem{Base: x_ptr}.Offset(8*3), RAX)
275 MULQ(RAX)
276 ADDQ(t0_v1, acc5_v1)
277 ADCQ(RAX, y_ptr)
278 ADCQ(RDX, t1_v1)
279 MOVQ(t1_v1, x_ptr)
280
281 Comment("First reduction step")
282 MOVQ(acc0_v1, RAX)
283 MOVQ(acc0_v1, t1_v1)
284 SHLQ(Imm(32), acc0_v1)
285
286 p256const1 := p256const1_DATA()
287 MULQ(p256const1)
288
289 SHRQ(Imm(32), t1_v1)
290 ADDQ(acc0_v1, acc1_v1)
291 ADCQ(t1_v1, acc2_v1)
292 ADCQ(RAX, acc3_v1)
293 ADCQ(Imm(0), RDX)
294 MOVQ(RDX, acc0_v1)
295
296 Comment("Second reduction step")
297 MOVQ(acc1_v1, RAX)
298 MOVQ(acc1_v1, t1_v1)
299 SHLQ(Imm(32), acc1_v1)
300 MULQ(p256const1)
301 SHRQ(Imm(32), t1_v1)
302 ADDQ(acc1_v1, acc2_v1)
303 ADCQ(t1_v1, acc3_v1)
304 ADCQ(RAX, acc0_v1)
305 ADCQ(Imm(0), RDX)
306 MOVQ(RDX, acc1_v1)
307
308 Comment("Third reduction step")
309 MOVQ(acc2_v1, RAX)
310 MOVQ(acc2_v1, t1_v1)
311 SHLQ(Imm(32), acc2_v1)
312 MULQ(p256const1)
313 SHRQ(Imm(32), t1_v1)
314 ADDQ(acc2_v1, acc3_v1)
315 ADCQ(t1_v1, acc0_v1)
316 ADCQ(RAX, acc1_v1)
317 ADCQ(Imm(0), RDX)
318 MOVQ(RDX, acc2_v1)
319
320 Comment("Last reduction step")
321 XORQ(t0_v1, t0_v1)
322 MOVQ(acc3_v1, RAX)
323 MOVQ(acc3_v1, t1_v1)
324 SHLQ(Imm(32), acc3_v1)
325 MULQ(p256const1)
326 SHRQ(Imm(32), t1_v1)
327 ADDQ(acc3_v1, acc0_v1)
328 ADCQ(t1_v1, acc1_v1)
329 ADCQ(RAX, acc2_v1)
330 ADCQ(Imm(0), RDX)
331 MOVQ(RDX, acc3_v1)
332
333 Comment("Add bits [511:256] of the sqr result")
334 ADCQ(acc4_v1, acc0_v1)
335 ADCQ(acc5_v1, acc1_v1)
336 ADCQ(y_ptr, acc2_v1)
337 ADCQ(x_ptr, acc3_v1)
338 ADCQ(Imm(0), t0_v1)
339
340 MOVQ(acc0_v1, acc4_v1)
341 MOVQ(acc1_v1, acc5_v1)
342 MOVQ(acc2_v1, y_ptr)
343 MOVQ(acc3_v1, t1_v1)
344
345 Comment("Subtract p256")
346 SUBQ(I8(-1), acc0_v1)
347
348 p256const0 := p256const0_DATA()
349 SBBQ(p256const0, acc1_v1)
350 SBBQ(Imm(0), acc2_v1)
351 SBBQ(p256const1, acc3_v1)
352 SBBQ(Imm(0), t0_v1)
353
354 CMOVQCS(acc4_v1, acc0_v1)
355 CMOVQCS(acc5_v1, acc1_v1)
356 CMOVQCS(y_ptr, acc2_v1)
357 CMOVQCS(t1_v1, acc3_v1)
358
359 MOVQ(acc0_v1, Mem{Base: res_ptr}.Offset(8*0))
360 MOVQ(acc1_v1, Mem{Base: res_ptr}.Offset(8*1))
361 MOVQ(acc2_v1, Mem{Base: res_ptr}.Offset(8*2))
362 MOVQ(acc3_v1, Mem{Base: res_ptr}.Offset(8*3))
363 MOVQ(res_ptr, x_ptr)
364 DECQ(RBX)
365 JNE(LabelRef("sqrLoop"))
366
367 RET()
368 }
369
370
371
372
373 func p256Mul() {
374 Implement("p256Mul")
375 Attributes(NOSPLIT)
376
377 Load(Param("res"), res_ptr)
378 Load(Param("in1"), x_ptr)
379 Load(Param("in2"), y_ptr)
380
381 Comment("x * y[0]")
382 MOVQ(Mem{Base: y_ptr}.Offset(8*0), t0_v1)
383
384 MOVQ(Mem{Base: x_ptr}.Offset(8*0), RAX)
385 MULQ(t0_v1)
386 MOVQ(RAX, acc0_v1)
387 MOVQ(RDX, acc1_v1)
388
389 MOVQ(Mem{Base: x_ptr}.Offset(8*1), RAX)
390 MULQ(t0_v1)
391 ADDQ(RAX, acc1_v1)
392 ADCQ(Imm(0), RDX)
393 MOVQ(RDX, acc2_v1)
394
395 MOVQ(Mem{Base: x_ptr}.Offset(8*2), RAX)
396 MULQ(t0_v1)
397 ADDQ(RAX, acc2_v1)
398 ADCQ(Imm(0), RDX)
399 MOVQ(RDX, acc3_v1)
400
401 MOVQ(Mem{Base: x_ptr}.Offset(8*3), RAX)
402 MULQ(t0_v1)
403 ADDQ(RAX, acc3_v1)
404 ADCQ(Imm(0), RDX)
405 MOVQ(RDX, acc4_v1)
406 XORQ(acc5_v1, acc5_v1)
407
408 Comment("First reduction step")
409 MOVQ(acc0_v1, RAX)
410 MOVQ(acc0_v1, t1_v1)
411 SHLQ(Imm(32), acc0_v1)
412 p256const1 := p256const1_DATA()
413 MULQ(p256const1)
414 SHRQ(Imm(32), t1_v1)
415 ADDQ(acc0_v1, acc1_v1)
416 ADCQ(t1_v1, acc2_v1)
417 ADCQ(RAX, acc3_v1)
418 ADCQ(RDX, acc4_v1)
419 ADCQ(Imm(0), acc5_v1)
420 XORQ(acc0_v1, acc0_v1)
421
422 Comment("x * y[1]")
423 MOVQ(Mem{Base: y_ptr}.Offset(8*1), t0_v1)
424
425 MOVQ(Mem{Base: x_ptr}.Offset(8*0), RAX)
426 MULQ(t0_v1)
427 ADDQ(RAX, acc1_v1)
428 ADCQ(Imm(0), RDX)
429 MOVQ(RDX, t1_v1)
430
431 MOVQ(Mem{Base: x_ptr}.Offset(8*1), RAX)
432 MULQ(t0_v1)
433 ADDQ(t1_v1, acc2_v1)
434 ADCQ(Imm(0), RDX)
435 ADDQ(RAX, acc2_v1)
436 ADCQ(Imm(0), RDX)
437 MOVQ(RDX, t1_v1)
438
439 MOVQ(Mem{Base: x_ptr}.Offset(8*2), RAX)
440 MULQ(t0_v1)
441 ADDQ(t1_v1, acc3_v1)
442 ADCQ(Imm(0), RDX)
443 ADDQ(RAX, acc3_v1)
444 ADCQ(Imm(0), RDX)
445 MOVQ(RDX, t1_v1)
446
447 MOVQ(Mem{Base: x_ptr}.Offset(8*3), RAX)
448 MULQ(t0_v1)
449 ADDQ(t1_v1, acc4_v1)
450 ADCQ(Imm(0), RDX)
451 ADDQ(RAX, acc4_v1)
452 ADCQ(RDX, acc5_v1)
453 ADCQ(Imm(0), acc0_v1)
454
455 Comment("Second reduction step")
456 MOVQ(acc1_v1, RAX)
457 MOVQ(acc1_v1, t1_v1)
458 SHLQ(Imm(32), acc1_v1)
459 MULQ(p256const1)
460 SHRQ(Imm(32), t1_v1)
461 ADDQ(acc1_v1, acc2_v1)
462 ADCQ(t1_v1, acc3_v1)
463 ADCQ(RAX, acc4_v1)
464 ADCQ(RDX, acc5_v1)
465 ADCQ(Imm(0), acc0_v1)
466 XORQ(acc1_v1, acc1_v1)
467
468 Comment("x * y[2]")
469 MOVQ(Mem{Base: y_ptr}.Offset(8*2), t0_v1)
470
471 MOVQ(Mem{Base: x_ptr}.Offset(8*0), RAX)
472 MULQ(t0_v1)
473 ADDQ(RAX, acc2_v1)
474 ADCQ(Imm(0), RDX)
475 MOVQ(RDX, t1_v1)
476
477 MOVQ(Mem{Base: x_ptr}.Offset(8*1), RAX)
478 MULQ(t0_v1)
479 ADDQ(t1_v1, acc3_v1)
480 ADCQ(Imm(0), RDX)
481 ADDQ(RAX, acc3_v1)
482 ADCQ(Imm(0), RDX)
483 MOVQ(RDX, t1_v1)
484
485 MOVQ(Mem{Base: x_ptr}.Offset(8*2), RAX)
486 MULQ(t0_v1)
487 ADDQ(t1_v1, acc4_v1)
488 ADCQ(Imm(0), RDX)
489 ADDQ(RAX, acc4_v1)
490 ADCQ(Imm(0), RDX)
491 MOVQ(RDX, t1_v1)
492
493 MOVQ(Mem{Base: x_ptr}.Offset(8*3), RAX)
494 MULQ(t0_v1)
495 ADDQ(t1_v1, acc5_v1)
496 ADCQ(Imm(0), RDX)
497 ADDQ(RAX, acc5_v1)
498 ADCQ(RDX, acc0_v1)
499 ADCQ(Imm(0), acc1_v1)
500
501 Comment("Third reduction step")
502 MOVQ(acc2_v1, RAX)
503 MOVQ(acc2_v1, t1_v1)
504 SHLQ(Imm(32), acc2_v1)
505 MULQ(p256const1)
506 SHRQ(Imm(32), t1_v1)
507 ADDQ(acc2_v1, acc3_v1)
508 ADCQ(t1_v1, acc4_v1)
509 ADCQ(RAX, acc5_v1)
510 ADCQ(RDX, acc0_v1)
511 ADCQ(Imm(0), acc1_v1)
512 XORQ(acc2_v1, acc2_v1)
513 Comment("x * y[3]")
514
515 MOVQ(Mem{Base: y_ptr}.Offset(8*3), t0_v1)
516
517 MOVQ(Mem{Base: x_ptr}.Offset(8*0), RAX)
518 MULQ(t0_v1)
519 ADDQ(RAX, acc3_v1)
520 ADCQ(Imm(0), RDX)
521 MOVQ(RDX, t1_v1)
522
523 MOVQ(Mem{Base: x_ptr}.Offset(8*1), RAX)
524 MULQ(t0_v1)
525 ADDQ(t1_v1, acc4_v1)
526 ADCQ(Imm(0), RDX)
527 ADDQ(RAX, acc4_v1)
528 ADCQ(Imm(0), RDX)
529 MOVQ(RDX, t1_v1)
530
531 MOVQ(Mem{Base: x_ptr}.Offset(8*2), RAX)
532 MULQ(t0_v1)
533 ADDQ(t1_v1, acc5_v1)
534 ADCQ(Imm(0), RDX)
535 ADDQ(RAX, acc5_v1)
536 ADCQ(Imm(0), RDX)
537 MOVQ(RDX, t1_v1)
538
539 MOVQ(Mem{Base: x_ptr}.Offset(8*3), RAX)
540 MULQ(t0_v1)
541 ADDQ(t1_v1, acc0_v1)
542 ADCQ(Imm(0), RDX)
543 ADDQ(RAX, acc0_v1)
544 ADCQ(RDX, acc1_v1)
545 ADCQ(Imm(0), acc2_v1)
546
547 Comment("Last reduction step")
548 MOVQ(acc3_v1, RAX)
549 MOVQ(acc3_v1, t1_v1)
550 SHLQ(Imm(32), acc3_v1)
551 MULQ(p256const1)
552 SHRQ(Imm(32), t1_v1)
553 ADDQ(acc3_v1, acc4_v1)
554 ADCQ(t1_v1, acc5_v1)
555 ADCQ(RAX, acc0_v1)
556 ADCQ(RDX, acc1_v1)
557 ADCQ(Imm(0), acc2_v1)
558
559 Comment("Copy result [255:0]")
560 MOVQ(acc4_v1, x_ptr)
561 MOVQ(acc5_v1, acc3_v1)
562 MOVQ(acc0_v1, t0_v1)
563 MOVQ(acc1_v1, t1_v1)
564
565 Comment("Subtract p256")
566 SUBQ(I8(-1), acc4_v1)
567 p256const0 := p256const0_DATA()
568 SBBQ(p256const0, acc5_v1)
569 SBBQ(Imm(0), acc0_v1)
570
571 SBBQ(p256const1, acc1_v1)
572 SBBQ(Imm(0), acc2_v1)
573
574 CMOVQCS(x_ptr, acc4_v1)
575 CMOVQCS(acc3_v1, acc5_v1)
576 CMOVQCS(t0_v1, acc0_v1)
577 CMOVQCS(t1_v1, acc1_v1)
578
579 MOVQ(acc4_v1, Mem{Base: res_ptr}.Offset(8*0))
580 MOVQ(acc5_v1, Mem{Base: res_ptr}.Offset(8*1))
581 MOVQ(acc0_v1, Mem{Base: res_ptr}.Offset(8*2))
582 MOVQ(acc1_v1, Mem{Base: res_ptr}.Offset(8*3))
583
584 RET()
585 }
586
587
588
589
590 func p256FromMont() {
591 Implement("p256FromMont")
592 Attributes(NOSPLIT)
593
594 Load(Param("res"), res_ptr)
595 Load(Param("in"), x_ptr)
596
597 MOVQ(Mem{Base: x_ptr}.Offset(8*0), acc0_v1)
598 MOVQ(Mem{Base: x_ptr}.Offset(8*1), acc1_v1)
599 MOVQ(Mem{Base: x_ptr}.Offset(8*2), acc2_v1)
600 MOVQ(Mem{Base: x_ptr}.Offset(8*3), acc3_v1)
601 XORQ(acc4_v1, acc4_v1)
602
603 Comment("Only reduce, no multiplications are needed")
604 Comment("First stage")
605 MOVQ(acc0_v1, RAX)
606 MOVQ(acc0_v1, t1_v1)
607 SHLQ(Imm(32), acc0_v1)
608 p256const1 := p256const1_DATA()
609 MULQ(p256const1)
610 SHRQ(Imm(32), t1_v1)
611 ADDQ(acc0_v1, acc1_v1)
612 ADCQ(t1_v1, acc2_v1)
613 ADCQ(RAX, acc3_v1)
614 ADCQ(RDX, acc4_v1)
615 XORQ(acc5_v1, acc5_v1)
616
617 Comment("Second stage")
618 MOVQ(acc1_v1, RAX)
619 MOVQ(acc1_v1, t1_v1)
620 SHLQ(Imm(32), acc1_v1)
621 MULQ(p256const1)
622 SHRQ(Imm(32), t1_v1)
623 ADDQ(acc1_v1, acc2_v1)
624 ADCQ(t1_v1, acc3_v1)
625 ADCQ(RAX, acc4_v1)
626 ADCQ(RDX, acc5_v1)
627 XORQ(acc0_v1, acc0_v1)
628
629 Comment("Third stage")
630 MOVQ(acc2_v1, RAX)
631 MOVQ(acc2_v1, t1_v1)
632 SHLQ(Imm(32), acc2_v1)
633 MULQ(p256const1)
634 SHRQ(Imm(32), t1_v1)
635 ADDQ(acc2_v1, acc3_v1)
636 ADCQ(t1_v1, acc4_v1)
637 ADCQ(RAX, acc5_v1)
638 ADCQ(RDX, acc0_v1)
639 XORQ(acc1_v1, acc1_v1)
640
641 Comment("Last stage")
642 MOVQ(acc3_v1, RAX)
643 MOVQ(acc3_v1, t1_v1)
644 SHLQ(Imm(32), acc3_v1)
645 MULQ(p256const1)
646 SHRQ(Imm(32), t1_v1)
647 ADDQ(acc3_v1, acc4_v1)
648 ADCQ(t1_v1, acc5_v1)
649 ADCQ(RAX, acc0_v1)
650 ADCQ(RDX, acc1_v1)
651
652 MOVQ(acc4_v1, x_ptr)
653 MOVQ(acc5_v1, acc3_v1)
654 MOVQ(acc0_v1, t0_v1)
655 MOVQ(acc1_v1, t1_v1)
656
657 SUBQ(I8(-1), acc4_v1)
658 p256const0 := p256const0_DATA()
659 SBBQ(p256const0, acc5_v1)
660 SBBQ(Imm(0), acc0_v1)
661 SBBQ(p256const1, acc1_v1)
662
663 CMOVQCS(x_ptr, acc4_v1)
664 CMOVQCS(acc3_v1, acc5_v1)
665 CMOVQCS(t0_v1, acc0_v1)
666 CMOVQCS(t1_v1, acc1_v1)
667
668 MOVQ(acc4_v1, Mem{Base: res_ptr}.Offset(8*0))
669 MOVQ(acc5_v1, Mem{Base: res_ptr}.Offset(8*1))
670 MOVQ(acc0_v1, Mem{Base: res_ptr}.Offset(8*2))
671 MOVQ(acc1_v1, Mem{Base: res_ptr}.Offset(8*3))
672
673 RET()
674 }
675
676
677
678
679 func p256Select() {
680 Implement("p256Select")
681 Attributes(NOSPLIT)
682
683 Load(Param("idx"), RAX)
684 Load(Param("table"), RDI)
685 Load(Param("res"), RDX)
686
687 PXOR(X15, X15)
688 PCMPEQL(X14, X14)
689 PSUBL(X14, X15)
690
691
692 Instruction(&ir.Instruction{
693 Opcode: "MOVL",
694 Operands: []Op{
695 EAX, X14,
696 },
697 })
698 PSHUFD(Imm(0), X14, X14)
699
700 PXOR(X0, X0)
701 PXOR(X1, X1)
702 PXOR(X2, X2)
703 PXOR(X3, X3)
704 PXOR(X4, X4)
705 PXOR(X5, X5)
706 MOVQ(U32(16), RAX)
707
708 MOVOU(X15, X13)
709
710 Label("loop_select")
711
712 MOVOU(X13, X12)
713 PADDL(X15, X13)
714 PCMPEQL(X14, X12)
715
716 MOVOU(Mem{Base: DI}.Offset(16*0), X6)
717 MOVOU(Mem{Base: DI}.Offset(16*1), X7)
718 MOVOU(Mem{Base: DI}.Offset(16*2), X8)
719 MOVOU(Mem{Base: DI}.Offset(16*3), X9)
720 MOVOU(Mem{Base: DI}.Offset(16*4), X10)
721 MOVOU(Mem{Base: DI}.Offset(16*5), X11)
722 ADDQ(U8(16*6), RDI)
723
724 PAND(X12, X6)
725 PAND(X12, X7)
726 PAND(X12, X8)
727 PAND(X12, X9)
728 PAND(X12, X10)
729 PAND(X12, X11)
730
731 PXOR(X6, X0)
732 PXOR(X7, X1)
733 PXOR(X8, X2)
734 PXOR(X9, X3)
735 PXOR(X10, X4)
736 PXOR(X11, X5)
737
738 DECQ(RAX)
739 JNE(LabelRef("loop_select"))
740
741 MOVOU(X0, Mem{Base: DX}.Offset(16*0))
742 MOVOU(X1, Mem{Base: DX}.Offset(16*1))
743 MOVOU(X2, Mem{Base: DX}.Offset(16*2))
744 MOVOU(X3, Mem{Base: DX}.Offset(16*3))
745 MOVOU(X4, Mem{Base: DX}.Offset(16*4))
746 MOVOU(X5, Mem{Base: DX}.Offset(16*5))
747
748 RET()
749 }
750
751
752
753
754 func p256SelectAffine() {
755 Implement("p256SelectAffine")
756 Attributes(NOSPLIT)
757
758 Load(Param("idx"), RAX)
759 Load(Param("table"), RDI)
760 Load(Param("res"), RDX)
761
762 PXOR(X15, X15)
763 PCMPEQL(X14, X14)
764 PSUBL(X14, X15)
765
766
767
768 Instruction(&ir.Instruction{Opcode: "MOVL", Operands: []Op{RAX, X14}})
769
770 PSHUFD(Imm(0), X14, X14)
771
772 PXOR(X0, X0)
773 PXOR(X1, X1)
774 PXOR(X2, X2)
775 PXOR(X3, X3)
776 MOVQ(U32(16), RAX)
777
778 MOVOU(X15, X13)
779
780 Label("loop_select_base")
781
782 MOVOU(X13, X12)
783 PADDL(X15, X13)
784 PCMPEQL(X14, X12)
785
786 MOVOU(Mem{Base: DI}.Offset(16*0), X4)
787 MOVOU(Mem{Base: DI}.Offset(16*1), X5)
788 MOVOU(Mem{Base: DI}.Offset(16*2), X6)
789 MOVOU(Mem{Base: DI}.Offset(16*3), X7)
790
791 MOVOU(Mem{Base: DI}.Offset(16*4), X8)
792 MOVOU(Mem{Base: DI}.Offset(16*5), X9)
793 MOVOU(Mem{Base: DI}.Offset(16*6), X10)
794 MOVOU(Mem{Base: DI}.Offset(16*7), X11)
795
796 ADDQ(Imm(16*8), RDI)
797
798 PAND(X12, X4)
799 PAND(X12, X5)
800 PAND(X12, X6)
801 PAND(X12, X7)
802
803 MOVOU(X13, X12)
804 PADDL(X15, X13)
805 PCMPEQL(X14, X12)
806
807 PAND(X12, X8)
808 PAND(X12, X9)
809 PAND(X12, X10)
810 PAND(X12, X11)
811
812 PXOR(X4, X0)
813 PXOR(X5, X1)
814 PXOR(X6, X2)
815 PXOR(X7, X3)
816
817 PXOR(X8, X0)
818 PXOR(X9, X1)
819 PXOR(X10, X2)
820 PXOR(X11, X3)
821
822 DECQ(RAX)
823 JNE(LabelRef("loop_select_base"))
824
825 MOVOU(X0, Mem{Base: DX}.Offset(16*0))
826 MOVOU(X1, Mem{Base: DX}.Offset(16*1))
827 MOVOU(X2, Mem{Base: DX}.Offset(16*2))
828 MOVOU(X3, Mem{Base: DX}.Offset(16*3))
829
830 RET()
831 }
832
833
834
835 var (
836 mul0_v2 = RAX
837 mul1_v2 = RDX
838 acc0_v2 = RBX
839 acc1_v2 = RCX
840 acc2_v2 = R8
841 acc3_v2 = R9
842 acc4_v2 = R10
843 acc5_v2 = R11
844 acc6_v2 = R12
845 acc7_v2 = R13
846 t0_v2 = R14
847 t1_v2 = R15
848 t2_v2 = RDI
849 t3_v2 = RSI
850 hlp_v2 = RBP
851 )
852
853 func p256SubInternal() {
854 Function("p256SubInternal")
855 Attributes(NOSPLIT)
856
857 XORQ(mul0_v2, mul0_v2)
858 SUBQ(t0_v2, acc4_v2)
859 SBBQ(t1_v2, acc5_v2)
860 SBBQ(t2_v2, acc6_v2)
861 SBBQ(t3_v2, acc7_v2)
862 SBBQ(Imm(0), mul0_v2)
863
864 MOVQ(acc4_v2, acc0_v2)
865 MOVQ(acc5_v2, acc1_v2)
866 MOVQ(acc6_v2, acc2_v2)
867 MOVQ(acc7_v2, acc3_v2)
868
869 ADDQ(I8(-1), acc4_v2)
870 p256const0 := p256const0_DATA()
871 ADCQ(p256const0, acc5_v2)
872 ADCQ(Imm(0), acc6_v2)
873 p256const1 := p256const1_DATA()
874 ADCQ(p256const1, acc7_v2)
875 ANDQ(Imm(1), mul0_v2)
876
877 CMOVQEQ(acc0_v2, acc4_v2)
878 CMOVQEQ(acc1_v2, acc5_v2)
879 CMOVQEQ(acc2_v2, acc6_v2)
880 CMOVQEQ(acc3_v2, acc7_v2)
881
882 RET()
883 }
884
885 func p256MulInternal() {
886 Function("p256MulInternal")
887 Attributes(NOSPLIT)
888
889 MOVQ(acc4_v2, mul0_v2)
890 MULQ(t0_v2)
891 MOVQ(mul0_v2, acc0_v2)
892 MOVQ(mul1_v2, acc1_v2)
893
894 MOVQ(acc4_v2, mul0_v2)
895 MULQ(t1_v2)
896 ADDQ(mul0_v2, acc1_v2)
897 ADCQ(Imm(0), mul1_v2)
898 MOVQ(mul1_v2, acc2_v2)
899
900 MOVQ(acc4_v2, mul0_v2)
901 MULQ(t2_v2)
902 ADDQ(mul0_v2, acc2_v2)
903 ADCQ(Imm(0), mul1_v2)
904 MOVQ(mul1_v2, acc3_v2)
905
906 MOVQ(acc4_v2, mul0_v2)
907 MULQ(t3_v2)
908 ADDQ(mul0_v2, acc3_v2)
909 ADCQ(Imm(0), mul1_v2)
910 MOVQ(mul1_v2, acc4_v2)
911
912 MOVQ(acc5_v2, mul0_v2)
913 MULQ(t0_v2)
914 ADDQ(mul0_v2, acc1_v2)
915 ADCQ(Imm(0), mul1_v2)
916 MOVQ(mul1_v2, hlp_v2)
917
918 MOVQ(acc5_v2, mul0_v2)
919 MULQ(t1_v2)
920 ADDQ(hlp_v2, acc2_v2)
921 ADCQ(Imm(0), mul1_v2)
922 ADDQ(mul0_v2, acc2_v2)
923 ADCQ(Imm(0), mul1_v2)
924 MOVQ(mul1_v2, hlp_v2)
925
926 MOVQ(acc5_v2, mul0_v2)
927 MULQ(t2_v2)
928 ADDQ(hlp_v2, acc3_v2)
929 ADCQ(Imm(0), mul1_v2)
930 ADDQ(mul0_v2, acc3_v2)
931 ADCQ(Imm(0), mul1_v2)
932 MOVQ(mul1_v2, hlp_v2)
933
934 MOVQ(acc5_v2, mul0_v2)
935 MULQ(t3_v2)
936 ADDQ(hlp_v2, acc4_v2)
937 ADCQ(Imm(0), mul1_v2)
938 ADDQ(mul0_v2, acc4_v2)
939 ADCQ(Imm(0), mul1_v2)
940 MOVQ(mul1_v2, acc5_v2)
941
942 MOVQ(acc6_v2, mul0_v2)
943 MULQ(t0_v2)
944 ADDQ(mul0_v2, acc2_v2)
945 ADCQ(Imm(0), mul1_v2)
946 MOVQ(mul1_v2, hlp_v2)
947
948 MOVQ(acc6_v2, mul0_v2)
949 MULQ(t1_v2)
950 ADDQ(hlp_v2, acc3_v2)
951 ADCQ(Imm(0), mul1_v2)
952 ADDQ(mul0_v2, acc3_v2)
953 ADCQ(Imm(0), mul1_v2)
954 MOVQ(mul1_v2, hlp_v2)
955
956 MOVQ(acc6_v2, mul0_v2)
957 MULQ(t2_v2)
958 ADDQ(hlp_v2, acc4_v2)
959 ADCQ(Imm(0), mul1_v2)
960 ADDQ(mul0_v2, acc4_v2)
961 ADCQ(Imm(0), mul1_v2)
962 MOVQ(mul1_v2, hlp_v2)
963
964 MOVQ(acc6_v2, mul0_v2)
965 MULQ(t3_v2)
966 ADDQ(hlp_v2, acc5_v2)
967 ADCQ(Imm(0), mul1_v2)
968 ADDQ(mul0_v2, acc5_v2)
969 ADCQ(Imm(0), mul1_v2)
970 MOVQ(mul1_v2, acc6_v2)
971
972 MOVQ(acc7_v2, mul0_v2)
973 MULQ(t0_v2)
974 ADDQ(mul0_v2, acc3_v2)
975 ADCQ(Imm(0), mul1_v2)
976 MOVQ(mul1_v2, hlp_v2)
977
978 MOVQ(acc7_v2, mul0_v2)
979 MULQ(t1_v2)
980 ADDQ(hlp_v2, acc4_v2)
981 ADCQ(Imm(0), mul1_v2)
982 ADDQ(mul0_v2, acc4_v2)
983 ADCQ(Imm(0), mul1_v2)
984 MOVQ(mul1_v2, hlp_v2)
985
986 MOVQ(acc7_v2, mul0_v2)
987 MULQ(t2_v2)
988 ADDQ(hlp_v2, acc5_v2)
989 ADCQ(Imm(0), mul1_v2)
990 ADDQ(mul0_v2, acc5_v2)
991 ADCQ(Imm(0), mul1_v2)
992 MOVQ(mul1_v2, hlp_v2)
993
994 MOVQ(acc7_v2, mul0_v2)
995 MULQ(t3_v2)
996 ADDQ(hlp_v2, acc6_v2)
997 ADCQ(Imm(0), mul1_v2)
998 ADDQ(mul0_v2, acc6_v2)
999 ADCQ(Imm(0), mul1_v2)
1000 MOVQ(mul1_v2, acc7_v2)
1001
1002 Comment("First reduction step")
1003 MOVQ(acc0_v2, mul0_v2)
1004 MOVQ(acc0_v2, hlp_v2)
1005 SHLQ(Imm(32), acc0_v2)
1006 p256const1 := p256const1_DATA()
1007 MULQ(p256const1)
1008 SHRQ(Imm(32), hlp_v2)
1009 ADDQ(acc0_v2, acc1_v2)
1010 ADCQ(hlp_v2, acc2_v2)
1011 ADCQ(mul0_v2, acc3_v2)
1012 ADCQ(Imm(0), mul1_v2)
1013 MOVQ(mul1_v2, acc0_v2)
1014
1015 Comment("Second reduction step")
1016 MOVQ(acc1_v2, mul0_v2)
1017 MOVQ(acc1_v2, hlp_v2)
1018 SHLQ(Imm(32), acc1_v2)
1019 MULQ(p256const1)
1020 SHRQ(Imm(32), hlp_v2)
1021 ADDQ(acc1_v2, acc2_v2)
1022 ADCQ(hlp_v2, acc3_v2)
1023 ADCQ(mul0_v2, acc0_v2)
1024 ADCQ(Imm(0), mul1_v2)
1025 MOVQ(mul1_v2, acc1_v2)
1026
1027 Comment("Third reduction step")
1028 MOVQ(acc2_v2, mul0_v2)
1029 MOVQ(acc2_v2, hlp_v2)
1030 SHLQ(Imm(32), acc2_v2)
1031 MULQ(p256const1)
1032 SHRQ(Imm(32), hlp_v2)
1033 ADDQ(acc2_v2, acc3_v2)
1034 ADCQ(hlp_v2, acc0_v2)
1035 ADCQ(mul0_v2, acc1_v2)
1036 ADCQ(Imm(0), mul1_v2)
1037 MOVQ(mul1_v2, acc2_v2)
1038
1039 Comment("Last reduction step")
1040 MOVQ(acc3_v2, mul0_v2)
1041 MOVQ(acc3_v2, hlp_v2)
1042 SHLQ(Imm(32), acc3_v2)
1043 MULQ(p256const1)
1044 SHRQ(Imm(32), hlp_v2)
1045 ADDQ(acc3_v2, acc0_v2)
1046 ADCQ(hlp_v2, acc1_v2)
1047 ADCQ(mul0_v2, acc2_v2)
1048 ADCQ(Imm(0), mul1_v2)
1049 MOVQ(mul1_v2, acc3_v2)
1050 MOVQ(U32(0), RBP)
1051
1052 Comment("Add bits [511:256] of the result")
1053 ADCQ(acc0_v2, acc4_v2)
1054 ADCQ(acc1_v2, acc5_v2)
1055 ADCQ(acc2_v2, acc6_v2)
1056 ADCQ(acc3_v2, acc7_v2)
1057 ADCQ(Imm(0), hlp_v2)
1058
1059 Comment("Copy result")
1060 MOVQ(acc4_v2, acc0_v2)
1061 MOVQ(acc5_v2, acc1_v2)
1062 MOVQ(acc6_v2, acc2_v2)
1063 MOVQ(acc7_v2, acc3_v2)
1064
1065 Comment("Subtract p256")
1066 SUBQ(I8(-1), acc4_v2)
1067 p256const0 := p256const0_DATA()
1068 SBBQ(p256const0, acc5_v2)
1069 SBBQ(Imm(0), acc6_v2)
1070 SBBQ(p256const1, acc7_v2)
1071 SBBQ(Imm(0), hlp_v2)
1072
1073 Comment("If the result of the subtraction is negative, restore the previous result")
1074 CMOVQCS(acc0_v2, acc4_v2)
1075 CMOVQCS(acc1_v2, acc5_v2)
1076 CMOVQCS(acc2_v2, acc6_v2)
1077 CMOVQCS(acc3_v2, acc7_v2)
1078
1079 RET()
1080 }
1081
1082 func p256SqrInternal() {
1083 Function("p256SqrInternal")
1084 Attributes(NOSPLIT)
1085
1086 MOVQ(acc4_v2, mul0_v2)
1087 MULQ(acc5_v2)
1088 MOVQ(mul0_v2, acc1_v2)
1089 MOVQ(mul1_v2, acc2_v2)
1090
1091 MOVQ(acc4_v2, mul0_v2)
1092 MULQ(acc6_v2)
1093 ADDQ(mul0_v2, acc2_v2)
1094 ADCQ(Imm(0), mul1_v2)
1095 MOVQ(mul1_v2, acc3_v2)
1096
1097 MOVQ(acc4_v2, mul0_v2)
1098 MULQ(acc7_v2)
1099 ADDQ(mul0_v2, acc3_v2)
1100 ADCQ(Imm(0), mul1_v2)
1101 MOVQ(mul1_v2, t0_v2)
1102
1103 MOVQ(acc5_v2, mul0_v2)
1104 MULQ(acc6_v2)
1105 ADDQ(mul0_v2, acc3_v2)
1106 ADCQ(Imm(0), mul1_v2)
1107 MOVQ(mul1_v2, hlp_v2)
1108
1109 MOVQ(acc5_v2, mul0_v2)
1110 MULQ(acc7_v2)
1111 ADDQ(hlp_v2, t0_v2)
1112 ADCQ(Imm(0), mul1_v2)
1113 ADDQ(mul0_v2, t0_v2)
1114 ADCQ(Imm(0), mul1_v2)
1115 MOVQ(mul1_v2, t1_v2)
1116
1117 MOVQ(acc6_v2, mul0_v2)
1118 MULQ(acc7_v2)
1119 ADDQ(mul0_v2, t1_v2)
1120 ADCQ(Imm(0), mul1_v2)
1121 MOVQ(mul1_v2, t2_v2)
1122 XORQ(t3_v2, t3_v2)
1123
1124 Comment("*2")
1125 ADDQ(acc1_v2, acc1_v2)
1126 ADCQ(acc2_v2, acc2_v2)
1127 ADCQ(acc3_v2, acc3_v2)
1128 ADCQ(t0_v2, t0_v2)
1129 ADCQ(t1_v2, t1_v2)
1130 ADCQ(t2_v2, t2_v2)
1131 ADCQ(Imm(0), t3_v2)
1132
1133 Comment("Missing products")
1134 MOVQ(acc4_v2, mul0_v2)
1135 MULQ(mul0_v2)
1136 MOVQ(mul0_v2, acc0_v2)
1137 MOVQ(RDX, acc4_v2)
1138
1139 MOVQ(acc5_v2, mul0_v2)
1140 MULQ(mul0_v2)
1141 ADDQ(acc4_v2, acc1_v2)
1142 ADCQ(mul0_v2, acc2_v2)
1143 ADCQ(Imm(0), RDX)
1144 MOVQ(RDX, acc4_v2)
1145
1146 MOVQ(acc6_v2, mul0_v2)
1147 MULQ(mul0_v2)
1148 ADDQ(acc4_v2, acc3_v2)
1149 ADCQ(mul0_v2, t0_v2)
1150 ADCQ(Imm(0), RDX)
1151 MOVQ(RDX, acc4_v2)
1152
1153 MOVQ(acc7_v2, mul0_v2)
1154 MULQ(mul0_v2)
1155 ADDQ(acc4_v2, t1_v2)
1156 ADCQ(mul0_v2, t2_v2)
1157 ADCQ(RDX, t3_v2)
1158
1159 Comment("First reduction step")
1160 MOVQ(acc0_v2, mul0_v2)
1161 MOVQ(acc0_v2, hlp_v2)
1162 SHLQ(Imm(32), acc0_v2)
1163 p256const1 := p256const1_DATA()
1164 MULQ(p256const1)
1165 SHRQ(Imm(32), hlp_v2)
1166 ADDQ(acc0_v2, acc1_v2)
1167 ADCQ(hlp_v2, acc2_v2)
1168 ADCQ(mul0_v2, acc3_v2)
1169 ADCQ(Imm(0), mul1_v2)
1170 MOVQ(mul1_v2, acc0_v2)
1171
1172 Comment("Second reduction step")
1173 MOVQ(acc1_v2, mul0_v2)
1174 MOVQ(acc1_v2, hlp_v2)
1175 SHLQ(Imm(32), acc1_v2)
1176 MULQ(p256const1)
1177 SHRQ(Imm(32), hlp_v2)
1178 ADDQ(acc1_v2, acc2_v2)
1179 ADCQ(hlp_v2, acc3_v2)
1180 ADCQ(mul0_v2, acc0_v2)
1181 ADCQ(Imm(0), mul1_v2)
1182 MOVQ(mul1_v2, acc1_v2)
1183
1184 Comment("Third reduction step")
1185 MOVQ(acc2_v2, mul0_v2)
1186 MOVQ(acc2_v2, hlp_v2)
1187 SHLQ(Imm(32), acc2_v2)
1188 MULQ(p256const1)
1189 SHRQ(Imm(32), hlp_v2)
1190 ADDQ(acc2_v2, acc3_v2)
1191 ADCQ(hlp_v2, acc0_v2)
1192 ADCQ(mul0_v2, acc1_v2)
1193 ADCQ(Imm(0), mul1_v2)
1194 MOVQ(mul1_v2, acc2_v2)
1195
1196 Comment("Last reduction step")
1197 MOVQ(acc3_v2, mul0_v2)
1198 MOVQ(acc3_v2, hlp_v2)
1199 SHLQ(Imm(32), acc3_v2)
1200 MULQ(p256const1)
1201 SHRQ(Imm(32), hlp_v2)
1202 ADDQ(acc3_v2, acc0_v2)
1203 ADCQ(hlp_v2, acc1_v2)
1204 ADCQ(mul0_v2, acc2_v2)
1205 ADCQ(Imm(0), mul1_v2)
1206 MOVQ(mul1_v2, acc3_v2)
1207 MOVQ(U32(0), RBP)
1208
1209 Comment("Add bits [511:256] of the result")
1210 ADCQ(acc0_v2, t0_v2)
1211 ADCQ(acc1_v2, t1_v2)
1212 ADCQ(acc2_v2, t2_v2)
1213 ADCQ(acc3_v2, t3_v2)
1214 ADCQ(Imm(0), hlp_v2)
1215
1216 Comment("Copy result")
1217 MOVQ(t0_v2, acc4_v2)
1218 MOVQ(t1_v2, acc5_v2)
1219 MOVQ(t2_v2, acc6_v2)
1220 MOVQ(t3_v2, acc7_v2)
1221
1222 Comment("Subtract p256")
1223 SUBQ(I8(-1), acc4_v2)
1224 p256const0 := p256const0_DATA()
1225 SBBQ(p256const0, acc5_v2)
1226 SBBQ(Imm(0), acc6_v2)
1227 SBBQ(p256const1, acc7_v2)
1228 SBBQ(Imm(0), hlp_v2)
1229
1230 Comment("If the result of the subtraction is negative, restore the previous result")
1231 CMOVQCS(t0_v2, acc4_v2)
1232 CMOVQCS(t1_v2, acc5_v2)
1233 CMOVQCS(t2_v2, acc6_v2)
1234 CMOVQCS(t3_v2, acc7_v2)
1235
1236 RET()
1237 }
1238
1239 func p256MulBy2Inline() {
1240 XORQ(mul0_v2, mul0_v2)
1241 ADDQ(acc4_v2, acc4_v2)
1242 ADCQ(acc5_v2, acc5_v2)
1243 ADCQ(acc6_v2, acc6_v2)
1244 ADCQ(acc7_v2, acc7_v2)
1245 ADCQ(I8(0), mul0_v2)
1246 MOVQ(acc4_v2, t0_v2)
1247 MOVQ(acc5_v2, t1_v2)
1248 MOVQ(acc6_v2, t2_v2)
1249 MOVQ(acc7_v2, t3_v2)
1250 SUBQ(I8(-1), t0_v2)
1251 p256const0 := p256const0_DATA()
1252 SBBQ(p256const0, t1_v2)
1253 SBBQ(I8(0), t2_v2)
1254 p256const1 := p256const1_DATA()
1255 SBBQ(p256const1, t3_v2)
1256 SBBQ(I8(0), mul0_v2)
1257 CMOVQCS(acc4_v2, t0_v2)
1258 CMOVQCS(acc5_v2, t1_v2)
1259 CMOVQCS(acc6_v2, t2_v2)
1260 CMOVQCS(acc7_v2, t3_v2)
1261 }
1262
1263 func p256AddInline() {
1264 XORQ(mul0_v2, mul0_v2)
1265 ADDQ(t0_v2, acc4_v2)
1266 ADCQ(t1_v2, acc5_v2)
1267 ADCQ(t2_v2, acc6_v2)
1268 ADCQ(t3_v2, acc7_v2)
1269 ADCQ(I8(0), mul0_v2)
1270 MOVQ(acc4_v2, t0_v2)
1271 MOVQ(acc5_v2, t1_v2)
1272 MOVQ(acc6_v2, t2_v2)
1273 MOVQ(acc7_v2, t3_v2)
1274 SUBQ(I8(-1), t0_v2)
1275 p256const0 := p256const0_DATA()
1276 SBBQ(p256const0, t1_v2)
1277 SBBQ(I8(0), t2_v2)
1278 p256const1 := p256const1_DATA()
1279 SBBQ(p256const1, t3_v2)
1280 SBBQ(I8(0), mul0_v2)
1281 CMOVQCS(acc4_v2, t0_v2)
1282 CMOVQCS(acc5_v2, t1_v2)
1283 CMOVQCS(acc6_v2, t2_v2)
1284 CMOVQCS(acc7_v2, t3_v2)
1285 }
1286
1287
1288
1289 type MemFunc func(off int) Mem
1290
1291 func LDacc(src MemFunc) {
1292 MOVQ(src(8*0), acc4_v2)
1293 MOVQ(src(8*1), acc5_v2)
1294 MOVQ(src(8*2), acc6_v2)
1295 MOVQ(src(8*3), acc7_v2)
1296 }
1297
1298 func LDt(src MemFunc) {
1299 MOVQ(src(8*0), t0_v2)
1300 MOVQ(src(8*1), t1_v2)
1301 MOVQ(src(8*2), t2_v2)
1302 MOVQ(src(8*3), t3_v2)
1303 }
1304
1305 func ST(dst MemFunc) {
1306 MOVQ(acc4_v2, dst(8*0))
1307 MOVQ(acc5_v2, dst(8*1))
1308 MOVQ(acc6_v2, dst(8*2))
1309 MOVQ(acc7_v2, dst(8*3))
1310 }
1311
1312 func STt(dst MemFunc) {
1313 MOVQ(t0_v2, dst(8*0))
1314 MOVQ(t1_v2, dst(8*1))
1315 MOVQ(t2_v2, dst(8*2))
1316 MOVQ(t3_v2, dst(8*3))
1317 }
1318
1319 func acc2t() {
1320 MOVQ(acc4_v2, t0_v2)
1321 MOVQ(acc5_v2, t1_v2)
1322 MOVQ(acc6_v2, t2_v2)
1323 MOVQ(acc7_v2, t3_v2)
1324 }
1325
1326 func t2acc() {
1327 MOVQ(t0_v2, acc4_v2)
1328 MOVQ(t1_v2, acc5_v2)
1329 MOVQ(t2_v2, acc6_v2)
1330 MOVQ(t3_v2, acc7_v2)
1331 }
1332
1333
1334
1335
1336
1337
1338
1339
1340 func x1in_v1(off int) Mem { return Mem{Base: SP}.Offset(32*0 + off) }
1341 func y1in_v1(off int) Mem { return Mem{Base: SP}.Offset(32*1 + off) }
1342 func z1in_v1(off int) Mem { return Mem{Base: SP}.Offset(32*2 + off) }
1343 func x2in_v1(off int) Mem { return Mem{Base: SP}.Offset(32*3 + off) }
1344 func y2in_v1(off int) Mem { return Mem{Base: SP}.Offset(32*4 + off) }
1345 func xout_v1(off int) Mem { return Mem{Base: SP}.Offset(32*5 + off) }
1346 func yout_v1(off int) Mem { return Mem{Base: SP}.Offset(32*6 + off) }
1347 func zout_v1(off int) Mem { return Mem{Base: SP}.Offset(32*7 + off) }
1348 func s2_v1(off int) Mem { return Mem{Base: SP}.Offset(32*8 + off) }
1349 func z1sqr_v1(off int) Mem { return Mem{Base: SP}.Offset(32*9 + off) }
1350 func h_v1(off int) Mem { return Mem{Base: SP}.Offset(32*10 + off) }
1351 func r_v1(off int) Mem { return Mem{Base: SP}.Offset(32*11 + off) }
1352 func hsqr_v1(off int) Mem { return Mem{Base: SP}.Offset(32*12 + off) }
1353 func rsqr_v1(off int) Mem { return Mem{Base: SP}.Offset(32*13 + off) }
1354 func hcub_v1(off int) Mem { return Mem{Base: SP}.Offset(32*14 + off) }
1355
1356 var (
1357 rptr_v1 Mem = Mem{Base: SP}.Offset(32*15 + 0)
1358 sel_save_v1 = Mem{Base: SP}.Offset(32*15 + 8)
1359 zero_save_v1 = Mem{Base: SP}.Offset(32*15 + 8 + 4)
1360 )
1361
1362
1363
1364
1365 func p256PointAddAffineAsm() {
1366 Implement("p256PointAddAffineAsm")
1367 AllocLocal(512)
1368
1369 Load(Param("res"), RAX)
1370 Load(Param("in1"), RBX)
1371 Load(Param("in2"), RCX)
1372 Load(Param("sign"), RDX)
1373 Load(Param("sel"), t1_v2)
1374 Load(Param("zero"), t2_v2)
1375
1376 MOVOU(Mem{Base: BX}.Offset(16*0), X0)
1377 MOVOU(Mem{Base: BX}.Offset(16*1), X1)
1378 MOVOU(Mem{Base: BX}.Offset(16*2), X2)
1379 MOVOU(Mem{Base: BX}.Offset(16*3), X3)
1380 MOVOU(Mem{Base: BX}.Offset(16*4), X4)
1381 MOVOU(Mem{Base: BX}.Offset(16*5), X5)
1382
1383 MOVOU(X0, x1in_v1(16*0))
1384 MOVOU(X1, x1in_v1(16*1))
1385 MOVOU(X2, y1in_v1(16*0))
1386 MOVOU(X3, y1in_v1(16*1))
1387 MOVOU(X4, z1in_v1(16*0))
1388 MOVOU(X5, z1in_v1(16*1))
1389
1390 MOVOU(Mem{Base: CX}.Offset(16*0), X0)
1391 MOVOU(Mem{Base: CX}.Offset(16*1), X1)
1392
1393 MOVOU(X0, x2in_v1(16*0))
1394 MOVOU(X1, x2in_v1(16*1))
1395
1396 Comment("Store pointer to result")
1397 MOVQ(mul0_v2, rptr_v1)
1398
1399
1400
1401 Instruction(&ir.Instruction{
1402 Opcode: "MOVL",
1403 Operands: []Op{t1_v2, sel_save_v1},
1404 })
1405
1406
1407
1408 Instruction(&ir.Instruction{
1409 Opcode: "MOVL",
1410 Operands: []Op{t2_v2, zero_save_v1},
1411 })
1412
1413 Comment("Negate y2in based on sign")
1414 MOVQ(Mem{Base: CX}.Offset(16*2+8*0), acc4_v2)
1415 MOVQ(Mem{Base: CX}.Offset(16*2+8*1), acc5_v2)
1416 MOVQ(Mem{Base: CX}.Offset(16*2+8*2), acc6_v2)
1417 MOVQ(Mem{Base: CX}.Offset(16*2+8*3), acc7_v2)
1418 MOVQ(I32(-1), acc0_v2)
1419 p256const0 := p256const0_DATA()
1420 MOVQ(p256const0, acc1_v2)
1421 MOVQ(U32(0), acc2_v2)
1422 p256const1 := p256const1_DATA()
1423 MOVQ(p256const1, acc3_v2)
1424 XORQ(mul0_v2, mul0_v2)
1425
1426 Comment("Speculatively subtract")
1427 SUBQ(acc4_v2, acc0_v2)
1428 SBBQ(acc5_v2, acc1_v2)
1429 SBBQ(acc6_v2, acc2_v2)
1430 SBBQ(acc7_v2, acc3_v2)
1431 SBBQ(Imm(0), mul0_v2)
1432 MOVQ(acc0_v2, t0_v2)
1433 MOVQ(acc1_v2, t1_v2)
1434 MOVQ(acc2_v2, t2_v2)
1435 MOVQ(acc3_v2, t3_v2)
1436
1437 Comment("Add in case the operand was > p256")
1438 ADDQ(I8(-1), acc0_v2)
1439 ADCQ(p256const0, acc1_v2)
1440 ADCQ(Imm(0), acc2_v2)
1441 ADCQ(p256const1, acc3_v2)
1442 ADCQ(Imm(0), mul0_v2)
1443 CMOVQNE(t0_v2, acc0_v2)
1444 CMOVQNE(t1_v2, acc1_v2)
1445 CMOVQNE(t2_v2, acc2_v2)
1446 CMOVQNE(t3_v2, acc3_v2)
1447
1448 Comment("If condition is 0, keep original value")
1449 TESTQ(RDX, RDX)
1450 CMOVQEQ(acc4_v2, acc0_v2)
1451 CMOVQEQ(acc5_v2, acc1_v2)
1452 CMOVQEQ(acc6_v2, acc2_v2)
1453 CMOVQEQ(acc7_v2, acc3_v2)
1454
1455 Comment("Store result")
1456 MOVQ(acc0_v2, y2in_v1(8*0))
1457 MOVQ(acc1_v2, y2in_v1(8*1))
1458 MOVQ(acc2_v2, y2in_v1(8*2))
1459 MOVQ(acc3_v2, y2in_v1(8*3))
1460
1461 Comment("Begin point add")
1462 LDacc(z1in_v1)
1463 CALL(LabelRef("p256SqrInternal(SB)"))
1464 ST(z1sqr_v1)
1465
1466 LDt(x2in_v1)
1467 CALL(LabelRef("p256MulInternal(SB)"))
1468
1469 LDt(x1in_v1)
1470 CALL(LabelRef("p256SubInternal(SB)"))
1471 ST(h_v1)
1472
1473 LDt(z1in_v1)
1474 CALL(LabelRef("p256MulInternal(SB)"))
1475 ST(zout_v1)
1476
1477 LDacc(z1sqr_v1)
1478 CALL(LabelRef("p256MulInternal(SB)"))
1479
1480 LDt(y2in_v1)
1481 CALL(LabelRef("p256MulInternal(SB)"))
1482 ST(s2_v1)
1483
1484 LDt(y1in_v1)
1485 CALL(LabelRef("p256SubInternal(SB)"))
1486 ST(r_v1)
1487
1488 CALL(LabelRef("p256SqrInternal(SB)"))
1489 ST(rsqr_v1)
1490
1491 LDacc(h_v1)
1492 CALL(LabelRef("p256SqrInternal(SB)"))
1493 ST(hsqr_v1)
1494
1495 LDt(h_v1)
1496 CALL(LabelRef("p256MulInternal(SB)"))
1497 ST(hcub_v1)
1498
1499 LDt(y1in_v1)
1500 CALL(LabelRef("p256MulInternal(SB)"))
1501 ST(s2_v1)
1502
1503 LDacc(x1in_v1)
1504 LDt(hsqr_v1)
1505 CALL(LabelRef("p256MulInternal(SB)"))
1506 ST(h_v1)
1507
1508 p256MulBy2Inline()
1509 LDacc(rsqr_v1)
1510 CALL(LabelRef("p256SubInternal(SB)"))
1511
1512 LDt(hcub_v1)
1513 CALL(LabelRef("p256SubInternal(SB)"))
1514 ST(xout_v1)
1515
1516 MOVQ(acc4_v2, t0_v2)
1517 MOVQ(acc5_v2, t1_v2)
1518 MOVQ(acc6_v2, t2_v2)
1519 MOVQ(acc7_v2, t3_v2)
1520 LDacc(h_v1)
1521 CALL(LabelRef("p256SubInternal(SB)"))
1522
1523 LDt(r_v1)
1524 CALL(LabelRef("p256MulInternal(SB)"))
1525
1526 LDt(s2_v1)
1527 CALL(LabelRef("p256SubInternal(SB)"))
1528 ST(yout_v1)
1529
1530 Comment("Load stored values from stack")
1531 MOVQ(rptr_v1, RAX)
1532 MOVL(sel_save_v1, EBX)
1533 MOVL(zero_save_v1, ECX)
1534
1535 Comment("The result is not valid if (sel == 0), conditional choose")
1536 MOVOU(xout_v1(16*0), X0)
1537 MOVOU(xout_v1(16*1), X1)
1538 MOVOU(yout_v1(16*0), X2)
1539 MOVOU(yout_v1(16*1), X3)
1540 MOVOU(zout_v1(16*0), X4)
1541 MOVOU(zout_v1(16*1), X5)
1542
1543
1544
1545 Instruction(&ir.Instruction{
1546 Opcode: "MOVL",
1547 Operands: []Op{EBX, X6},
1548 })
1549
1550
1551
1552 Instruction(&ir.Instruction{
1553 Opcode: "MOVL",
1554 Operands: []Op{ECX, X7},
1555 })
1556
1557 PXOR(X8, X8)
1558 PCMPEQL(X9, X9)
1559
1560 PSHUFD(Imm(0), X6, X6)
1561 PSHUFD(Imm(0), X7, X7)
1562
1563 PCMPEQL(X8, X6)
1564 PCMPEQL(X8, X7)
1565
1566 MOVOU(X6, X15)
1567 PANDN(X9, X15)
1568
1569 MOVOU(x1in_v1(16*0), X9)
1570 MOVOU(x1in_v1(16*1), X10)
1571 MOVOU(y1in_v1(16*0), X11)
1572 MOVOU(y1in_v1(16*1), X12)
1573 MOVOU(z1in_v1(16*0), X13)
1574 MOVOU(z1in_v1(16*1), X14)
1575
1576 PAND(X15, X0)
1577 PAND(X15, X1)
1578 PAND(X15, X2)
1579 PAND(X15, X3)
1580 PAND(X15, X4)
1581 PAND(X15, X5)
1582
1583 PAND(X6, X9)
1584 PAND(X6, X10)
1585 PAND(X6, X11)
1586 PAND(X6, X12)
1587 PAND(X6, X13)
1588 PAND(X6, X14)
1589
1590 PXOR(X9, X0)
1591 PXOR(X10, X1)
1592 PXOR(X11, X2)
1593 PXOR(X12, X3)
1594 PXOR(X13, X4)
1595 PXOR(X14, X5)
1596
1597 Comment("Similarly if zero == 0")
1598 PCMPEQL(X9, X9)
1599 MOVOU(X7, X15)
1600 PANDN(X9, X15)
1601
1602 MOVOU(x2in_v1(16*0), X9)
1603 MOVOU(x2in_v1(16*1), X10)
1604 MOVOU(y2in_v1(16*0), X11)
1605 MOVOU(y2in_v1(16*1), X12)
1606 p256one := p256one_DATA()
1607 MOVOU(p256one.Offset(0x00), X13)
1608 MOVOU(p256one.Offset(0x10), X14)
1609
1610 PAND(X15, X0)
1611 PAND(X15, X1)
1612 PAND(X15, X2)
1613 PAND(X15, X3)
1614 PAND(X15, X4)
1615 PAND(X15, X5)
1616
1617 PAND(X7, X9)
1618 PAND(X7, X10)
1619 PAND(X7, X11)
1620 PAND(X7, X12)
1621 PAND(X7, X13)
1622 PAND(X7, X14)
1623
1624 PXOR(X9, X0)
1625 PXOR(X10, X1)
1626 PXOR(X11, X2)
1627 PXOR(X12, X3)
1628 PXOR(X13, X4)
1629 PXOR(X14, X5)
1630
1631 Comment("Finally output the result")
1632 MOVOU(X0, Mem{Base: AX}.Offset(16*0))
1633 MOVOU(X1, Mem{Base: AX}.Offset(16*1))
1634 MOVOU(X2, Mem{Base: AX}.Offset(16*2))
1635 MOVOU(X3, Mem{Base: AX}.Offset(16*3))
1636 MOVOU(X4, Mem{Base: AX}.Offset(16*4))
1637 MOVOU(X5, Mem{Base: AX}.Offset(16*5))
1638 MOVQ(U32(0), rptr_v1)
1639
1640 RET()
1641 }
1642
1643
1644
1645 func p256IsZero() {
1646 Function("p256IsZero")
1647 Attributes(NOSPLIT)
1648
1649 Comment("AX contains a flag that is set if the input is zero.")
1650 XORQ(RAX, RAX)
1651 MOVQ(U32(1), t1_v2)
1652
1653 Comment("Check whether [acc4..acc7] are all zero.")
1654 MOVQ(acc4_v2, t0_v2)
1655 ORQ(acc5_v2, t0_v2)
1656 ORQ(acc6_v2, t0_v2)
1657 ORQ(acc7_v2, t0_v2)
1658
1659 Comment("Set the zero flag if so. (CMOV of a constant to a register doesn't")
1660 Comment("appear to be supported in Go. Thus t1 = 1.)")
1661 CMOVQEQ(t1_v2, RAX)
1662
1663 Comment("XOR [acc4..acc7] with P and compare with zero again.")
1664 XORQ(I8(-1), acc4_v2)
1665 p256const0 := p256const0_DATA()
1666 XORQ(p256const0, acc5_v2)
1667 p256const1 := p256const1_DATA()
1668 XORQ(p256const1, acc7_v2)
1669 ORQ(acc5_v2, acc4_v2)
1670 ORQ(acc6_v2, acc4_v2)
1671 ORQ(acc7_v2, acc4_v2)
1672
1673 Comment("Set the zero flag if so.")
1674 CMOVQEQ(t1_v2, RAX)
1675 RET()
1676 }
1677
1678 func x1in_v2(off int) Mem { return Mem{Base: SP}.Offset(32*0 + off) }
1679 func y1in_v2(off int) Mem { return Mem{Base: SP}.Offset(32*1 + off) }
1680 func z1in_v2(off int) Mem { return Mem{Base: SP}.Offset(32*2 + off) }
1681 func x2in_v2(off int) Mem { return Mem{Base: SP}.Offset(32*3 + off) }
1682 func y2in_v2(off int) Mem { return Mem{Base: SP}.Offset(32*4 + off) }
1683 func z2in_v2(off int) Mem { return Mem{Base: SP}.Offset(32*5 + off) }
1684
1685 func xout_v2(off int) Mem { return Mem{Base: SP}.Offset(32*6 + off) }
1686 func yout_v2(off int) Mem { return Mem{Base: SP}.Offset(32*7 + off) }
1687 func zout_v2(off int) Mem { return Mem{Base: SP}.Offset(32*8 + off) }
1688
1689 func u1_v2(off int) Mem { return Mem{Base: SP}.Offset(32*9 + off) }
1690 func u2_v2(off int) Mem { return Mem{Base: SP}.Offset(32*10 + off) }
1691 func s1_v2(off int) Mem { return Mem{Base: SP}.Offset(32*11 + off) }
1692 func s2_v2(off int) Mem { return Mem{Base: SP}.Offset(32*12 + off) }
1693 func z1sqr_v2(off int) Mem { return Mem{Base: SP}.Offset(32*13 + off) }
1694 func z2sqr_v2(off int) Mem { return Mem{Base: SP}.Offset(32*14 + off) }
1695 func h_v2(off int) Mem { return Mem{Base: SP}.Offset(32*15 + off) }
1696 func r_v2(off int) Mem { return Mem{Base: SP}.Offset(32*16 + off) }
1697 func hsqr_v2(off int) Mem { return Mem{Base: SP}.Offset(32*17 + off) }
1698 func rsqr_v2(off int) Mem { return Mem{Base: SP}.Offset(32*18 + off) }
1699 func hcub_v2(off int) Mem { return Mem{Base: SP}.Offset(32*19 + off) }
1700
1701 var (
1702 rptr_v2 Mem = Mem{Base: SP}.Offset(32 * 20)
1703 points_eq_v2 = Mem{Base: SP}.Offset(32*20 + 8)
1704 )
1705
1706
1707
1708
1709
1710
1711 func p256PointAddAsm() {
1712 Implement("p256PointAddAsm")
1713 AllocLocal(680)
1714
1715 Comment("Move input to stack in order to free registers")
1716 Load(Param("res"), RAX)
1717 Load(Param("in1"), RBX)
1718 Load(Param("in2"), RCX)
1719
1720 MOVOU(Mem{Base: BX}.Offset(16*0), X0)
1721 MOVOU(Mem{Base: BX}.Offset(16*1), X1)
1722 MOVOU(Mem{Base: BX}.Offset(16*2), X2)
1723 MOVOU(Mem{Base: BX}.Offset(16*3), X3)
1724 MOVOU(Mem{Base: BX}.Offset(16*4), X4)
1725 MOVOU(Mem{Base: BX}.Offset(16*5), X5)
1726
1727 MOVOU(X0, x1in_v2(16*0))
1728 MOVOU(X1, x1in_v2(16*1))
1729 MOVOU(X2, y1in_v2(16*0))
1730 MOVOU(X3, y1in_v2(16*1))
1731 MOVOU(X4, z1in_v2(16*0))
1732 MOVOU(X5, z1in_v2(16*1))
1733
1734 MOVOU(Mem{Base: CX}.Offset(16*0), X0)
1735 MOVOU(Mem{Base: CX}.Offset(16*1), X1)
1736 MOVOU(Mem{Base: CX}.Offset(16*2), X2)
1737 MOVOU(Mem{Base: CX}.Offset(16*3), X3)
1738 MOVOU(Mem{Base: CX}.Offset(16*4), X4)
1739 MOVOU(Mem{Base: CX}.Offset(16*5), X5)
1740
1741 MOVOU(X0, x2in_v2(16*0))
1742 MOVOU(X1, x2in_v2(16*1))
1743 MOVOU(X2, y2in_v2(16*0))
1744 MOVOU(X3, y2in_v2(16*1))
1745 MOVOU(X4, z2in_v2(16*0))
1746 MOVOU(X5, z2in_v2(16*1))
1747
1748 Comment("Store pointer to result")
1749 MOVQ(RAX, rptr_v2)
1750
1751 Comment("Begin point add")
1752 LDacc(z2in_v2)
1753 CALL(LabelRef("p256SqrInternal(SB)"))
1754 ST(z2sqr_v2)
1755 LDt(z2in_v2)
1756 CALL(LabelRef("p256MulInternal(SB)"))
1757 LDt(y1in_v2)
1758 CALL(LabelRef("p256MulInternal(SB)"))
1759 ST(s1_v2)
1760
1761 LDacc(z1in_v2)
1762 CALL(LabelRef("p256SqrInternal(SB)"))
1763 ST(z1sqr_v2)
1764 LDt(z1in_v2)
1765 CALL(LabelRef("p256MulInternal(SB)"))
1766 LDt(y2in_v2)
1767 CALL(LabelRef("p256MulInternal(SB)"))
1768 ST(s2_v2)
1769
1770 LDt(s1_v2)
1771 CALL(LabelRef("p256SubInternal(SB)"))
1772 ST(r_v2)
1773 CALL(LabelRef("p256IsZero(SB)"))
1774 MOVQ(RAX, points_eq_v2)
1775
1776 LDacc(z2sqr_v2)
1777 LDt(x1in_v2)
1778 CALL(LabelRef("p256MulInternal(SB)"))
1779 ST(u1_v2)
1780 LDacc(z1sqr_v2)
1781 LDt(x2in_v2)
1782 CALL(LabelRef("p256MulInternal(SB)"))
1783 ST(u2_v2)
1784
1785 LDt(u1_v2)
1786 CALL(LabelRef("p256SubInternal(SB)"))
1787 ST(h_v2)
1788 CALL(LabelRef("p256IsZero(SB)"))
1789 ANDQ(points_eq_v2, RAX)
1790 MOVQ(RAX, points_eq_v2)
1791
1792 LDacc(r_v2)
1793 CALL(LabelRef("p256SqrInternal(SB)"))
1794 ST(rsqr_v2)
1795
1796 LDacc(h_v2)
1797 CALL(LabelRef("p256SqrInternal(SB)"))
1798 ST(hsqr_v2)
1799
1800 LDt(h_v2)
1801 CALL(LabelRef("p256MulInternal(SB)"))
1802 ST(hcub_v2)
1803
1804 LDt(s1_v2)
1805 CALL(LabelRef("p256MulInternal(SB)"))
1806 ST(s2_v2)
1807
1808 LDacc(z1in_v2)
1809 LDt(z2in_v2)
1810 CALL(LabelRef("p256MulInternal(SB)"))
1811 LDt(h_v2)
1812 CALL(LabelRef("p256MulInternal(SB)"))
1813 ST(zout_v2)
1814
1815 LDacc(hsqr_v2)
1816 LDt(u1_v2)
1817 CALL(LabelRef("p256MulInternal(SB)"))
1818 ST(u2_v2)
1819
1820 p256MulBy2Inline()
1821 LDacc(rsqr_v2)
1822 CALL(LabelRef("p256SubInternal(SB)"))
1823
1824 LDt(hcub_v2)
1825 CALL(LabelRef("p256SubInternal(SB)"))
1826 ST(xout_v2)
1827
1828 MOVQ(acc4_v2, t0_v2)
1829 MOVQ(acc5_v2, t1_v2)
1830 MOVQ(acc6_v2, t2_v2)
1831 MOVQ(acc7_v2, t3_v2)
1832 LDacc(u2_v2)
1833 CALL(LabelRef("p256SubInternal(SB)"))
1834
1835 LDt(r_v2)
1836 CALL(LabelRef("p256MulInternal(SB)"))
1837
1838 LDt(s2_v2)
1839 CALL(LabelRef("p256SubInternal(SB)"))
1840 ST(yout_v2)
1841
1842 MOVOU(xout_v2(16*0), X0)
1843 MOVOU(xout_v2(16*1), X1)
1844 MOVOU(yout_v2(16*0), X2)
1845 MOVOU(yout_v2(16*1), X3)
1846 MOVOU(zout_v2(16*0), X4)
1847 MOVOU(zout_v2(16*1), X5)
1848
1849 Comment("Finally output the result")
1850 MOVQ(rptr_v2, RAX)
1851 MOVQ(U32(0), rptr_v2)
1852 MOVOU(X0, Mem{Base: AX}.Offset(16*0))
1853 MOVOU(X1, Mem{Base: AX}.Offset(16*1))
1854 MOVOU(X2, Mem{Base: AX}.Offset(16*2))
1855 MOVOU(X3, Mem{Base: AX}.Offset(16*3))
1856 MOVOU(X4, Mem{Base: AX}.Offset(16*4))
1857 MOVOU(X5, Mem{Base: AX}.Offset(16*5))
1858
1859 MOVQ(points_eq_v2, RAX)
1860 ret := NewParamAddr("ret", 24)
1861 MOVQ(RAX, ret)
1862
1863 RET()
1864 }
1865
1866 func x(off int) Mem { return Mem{Base: SP}.Offset(32*0 + off) }
1867 func y(off int) Mem { return Mem{Base: SP}.Offset(32*1 + off) }
1868 func z(off int) Mem { return Mem{Base: SP}.Offset(32*2 + off) }
1869
1870 func s(off int) Mem { return Mem{Base: SP}.Offset(32*3 + off) }
1871 func m(off int) Mem { return Mem{Base: SP}.Offset(32*4 + off) }
1872 func zsqr(off int) Mem { return Mem{Base: SP}.Offset(32*5 + off) }
1873 func tmp(off int) Mem { return Mem{Base: SP}.Offset(32*6 + off) }
1874
1875 var rptr_v3 = Mem{Base: SP}.Offset(32 * 7)
1876
1877
1878
1879
1880 func p256PointDoubleAsm() {
1881 Implement("p256PointDoubleAsm")
1882 Attributes(NOSPLIT)
1883 AllocLocal(256)
1884
1885 Load(Param("res"), RAX)
1886 Load(Param("in"), RBX)
1887
1888 MOVOU(Mem{Base: BX}.Offset(16*0), X0)
1889 MOVOU(Mem{Base: BX}.Offset(16*1), X1)
1890 MOVOU(Mem{Base: BX}.Offset(16*2), X2)
1891 MOVOU(Mem{Base: BX}.Offset(16*3), X3)
1892 MOVOU(Mem{Base: BX}.Offset(16*4), X4)
1893 MOVOU(Mem{Base: BX}.Offset(16*5), X5)
1894
1895 MOVOU(X0, x(16*0))
1896 MOVOU(X1, x(16*1))
1897 MOVOU(X2, y(16*0))
1898 MOVOU(X3, y(16*1))
1899 MOVOU(X4, z(16*0))
1900 MOVOU(X5, z(16*1))
1901
1902 Comment("Store pointer to result")
1903 MOVQ(RAX, rptr_v3)
1904
1905 Comment("Begin point double")
1906 LDacc(z)
1907 CALL(LabelRef("p256SqrInternal(SB)"))
1908 ST(zsqr)
1909
1910 LDt(x)
1911 p256AddInline()
1912 STt(m)
1913
1914 LDacc(z)
1915 LDt(y)
1916 CALL(LabelRef("p256MulInternal(SB)"))
1917 p256MulBy2Inline()
1918 MOVQ(rptr_v3, RAX)
1919
1920 Comment("Store z")
1921 MOVQ(t0_v2, Mem{Base: AX}.Offset(16*4+8*0))
1922 MOVQ(t1_v2, Mem{Base: AX}.Offset(16*4+8*1))
1923 MOVQ(t2_v2, Mem{Base: AX}.Offset(16*4+8*2))
1924 MOVQ(t3_v2, Mem{Base: AX}.Offset(16*4+8*3))
1925
1926 LDacc(x)
1927 LDt(zsqr)
1928 CALL(LabelRef("p256SubInternal(SB)"))
1929 LDt(m)
1930 CALL(LabelRef("p256MulInternal(SB)"))
1931 ST(m)
1932
1933 Comment("Multiply by 3")
1934 p256MulBy2Inline()
1935 LDacc(m)
1936 p256AddInline()
1937 STt(m)
1938 Comment("////////////////////////")
1939 LDacc(y)
1940 p256MulBy2Inline()
1941 t2acc()
1942 CALL(LabelRef("p256SqrInternal(SB)"))
1943 ST(s)
1944 CALL(LabelRef("p256SqrInternal(SB)"))
1945
1946 Comment("Divide by 2")
1947 XORQ(mul0_v2, mul0_v2)
1948 MOVQ(acc4_v2, t0_v2)
1949 MOVQ(acc5_v2, t1_v2)
1950 MOVQ(acc6_v2, t2_v2)
1951 MOVQ(acc7_v2, t3_v2)
1952
1953 ADDQ(I8(-1), acc4_v2)
1954 p256const0 := p256const0_DATA()
1955 ADCQ(p256const0, acc5_v2)
1956 ADCQ(Imm(0), acc6_v2)
1957 p256const1 := p256const1_DATA()
1958 ADCQ(p256const1, acc7_v2)
1959 ADCQ(Imm(0), mul0_v2)
1960 TESTQ(U32(1), t0_v2)
1961
1962 CMOVQEQ(t0_v2, acc4_v2)
1963 CMOVQEQ(t1_v2, acc5_v2)
1964 CMOVQEQ(t2_v2, acc6_v2)
1965 CMOVQEQ(t3_v2, acc7_v2)
1966 ANDQ(t0_v2, mul0_v2)
1967
1968 SHRQ(Imm(1), acc5_v2, acc4_v2)
1969 SHRQ(Imm(1), acc6_v2, acc5_v2)
1970 SHRQ(Imm(1), acc7_v2, acc6_v2)
1971 SHRQ(Imm(1), mul0_v2, acc7_v2)
1972 ST(y)
1973 Comment("/////////////////////////")
1974 LDacc(x)
1975 LDt(s)
1976 CALL(LabelRef("p256MulInternal(SB)"))
1977 ST(s)
1978 p256MulBy2Inline()
1979 STt(tmp)
1980
1981 LDacc(m)
1982 CALL(LabelRef("p256SqrInternal(SB)"))
1983 LDt(tmp)
1984 CALL(LabelRef("p256SubInternal(SB)"))
1985
1986 MOVQ(rptr_v3, RAX)
1987
1988 Comment("Store x")
1989 MOVQ(acc4_v2, Mem{Base: AX}.Offset(16*0+8*0))
1990 MOVQ(acc5_v2, Mem{Base: AX}.Offset(16*0+8*1))
1991 MOVQ(acc6_v2, Mem{Base: AX}.Offset(16*0+8*2))
1992 MOVQ(acc7_v2, Mem{Base: AX}.Offset(16*0+8*3))
1993
1994 acc2t()
1995 LDacc(s)
1996 CALL(LabelRef("p256SubInternal(SB)"))
1997
1998 LDt(m)
1999 CALL(LabelRef("p256MulInternal(SB)"))
2000
2001 LDt(y)
2002 CALL(LabelRef("p256SubInternal(SB)"))
2003 MOVQ(rptr_v3, RAX)
2004
2005 Comment("Store y")
2006 MOVQ(acc4_v2, Mem{Base: AX}.Offset(16*2+8*0))
2007 MOVQ(acc5_v2, Mem{Base: AX}.Offset(16*2+8*1))
2008 MOVQ(acc6_v2, Mem{Base: AX}.Offset(16*2+8*2))
2009 MOVQ(acc7_v2, Mem{Base: AX}.Offset(16*2+8*3))
2010 Comment("///////////////////////")
2011 MOVQ(U32(0), rptr_v3)
2012
2013 RET()
2014 }
2015
2016
2017
2018
2019 var p256const0_ptr, p256const1_ptr, p256one_ptr *Mem
2020
2021 func p256const0_DATA() Mem {
2022 if p256const0_ptr != nil {
2023 return *p256const0_ptr
2024 }
2025
2026 p256const0 := GLOBL("p256const0", 8)
2027 p256const0_ptr = &p256const0
2028 DATA(0, U64(0x00000000ffffffff))
2029 return p256const0
2030 }
2031
2032 func p256const1_DATA() Mem {
2033 if p256const1_ptr != nil {
2034 return *p256const1_ptr
2035 }
2036
2037 p256const1 := GLOBL("p256const1", 8)
2038 p256const1_ptr = &p256const1
2039 DATA(0, U64(0xffffffff00000001))
2040 return p256const1
2041 }
2042
2043 var p256oneConstants = [4]uint64{
2044 0x0000000000000001,
2045 0xffffffff00000000,
2046 0xffffffffffffffff,
2047 0x00000000fffffffe,
2048 }
2049
2050 func p256one_DATA() Mem {
2051 if p256one_ptr != nil {
2052 return *p256one_ptr
2053 }
2054
2055 p256one := GLOBL("p256one", 8)
2056 p256one_ptr = &p256one
2057
2058 for i, k := range p256oneConstants {
2059 DATA(i*8, U64(k))
2060 }
2061
2062 return p256one
2063 }
2064
2065 const ThatPeskyUnicodeDot = "\u00b7"
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079 func removePeskyUnicodeDot(internalFunctions []string, target string) {
2080 bytes, err := os.ReadFile(target)
2081 if err != nil {
2082 panic(err)
2083 }
2084
2085 content := string(bytes)
2086
2087 for _, from := range internalFunctions {
2088 to := strings.ReplaceAll(from, ThatPeskyUnicodeDot, "")
2089 content = strings.ReplaceAll(content, from, to)
2090 }
2091
2092 err = os.WriteFile(target, []byte(content), 0644)
2093 if err != nil {
2094 panic(err)
2095 }
2096 }
2097
View as plain text