github.com/consensys/gnark-crypto@v0.14.0/ecc/bw6-761/fr/element_mul_amd64.s (about) 1 // +build !purego 2 3 // Copyright 2020 ConsenSys Software Inc. 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 17 #include "textflag.h" 18 #include "funcdata.h" 19 20 // modulus q 21 DATA q<>+0(SB)/8, $0x8508c00000000001 22 DATA q<>+8(SB)/8, $0x170b5d4430000000 23 DATA q<>+16(SB)/8, $0x1ef3622fba094800 24 DATA q<>+24(SB)/8, $0x1a22d9f300f5138f 25 DATA q<>+32(SB)/8, $0xc63b05c06ca1493b 26 DATA q<>+40(SB)/8, $0x01ae3a4617c510ea 27 GLOBL q<>(SB), (RODATA+NOPTR), $48 28 29 // qInv0 q'[0] 30 DATA qInv0<>(SB)/8, $0x8508bfffffffffff 31 GLOBL qInv0<>(SB), (RODATA+NOPTR), $8 32 33 #define REDUCE(ra0, ra1, ra2, ra3, ra4, ra5, rb0, rb1, rb2, rb3, rb4, rb5) \ 34 MOVQ ra0, rb0; \ 35 SUBQ q<>(SB), ra0; \ 36 MOVQ ra1, rb1; \ 37 SBBQ q<>+8(SB), ra1; \ 38 MOVQ ra2, rb2; \ 39 SBBQ q<>+16(SB), ra2; \ 40 MOVQ ra3, rb3; \ 41 SBBQ q<>+24(SB), ra3; \ 42 MOVQ ra4, rb4; \ 43 SBBQ q<>+32(SB), ra4; \ 44 MOVQ ra5, rb5; \ 45 SBBQ q<>+40(SB), ra5; \ 46 CMOVQCS rb0, ra0; \ 47 CMOVQCS rb1, ra1; \ 48 CMOVQCS rb2, ra2; \ 49 CMOVQCS rb3, ra3; \ 50 CMOVQCS rb4, ra4; \ 51 CMOVQCS rb5, ra5; \ 52 53 // mul(res, x, y *Element) 54 TEXT ·mul(SB), $24-24 55 56 // the algorithm is described in the Element.Mul declaration (.go) 57 // however, to benefit from the ADCX and ADOX carry chains 58 // we split the inner loops in 2: 59 // for i=0 to N-1 60 // for j=0 to N-1 61 // (A,t[j]) := t[j] + x[j]*y[i] + A 62 // m := t[0]*q'[0] mod W 63 // C,_ := t[0] + m*q[0] 64 // for j=1 to N-1 65 // (C,t[j-1]) := t[j] + m*q[j] + C 66 // t[N-1] = C + A 67 68 NO_LOCAL_POINTERS 69 CMPB ·supportAdx(SB), $1 70 JNE l1 71 MOVQ x+8(FP), R8 72 73 // x[0] -> R10 74 // x[1] -> R11 75 // x[2] -> R12 76 MOVQ 0(R8), R10 77 MOVQ 8(R8), R11 78 MOVQ 16(R8), R12 79 MOVQ y+16(FP), R13 80 81 // A -> BP 82 // t[0] -> R14 83 // t[1] -> R15 84 // t[2] -> CX 85 // t[3] -> BX 86 // t[4] -> SI 87 // t[5] -> DI 88 // clear the flags 89 XORQ AX, AX 90 MOVQ 0(R13), DX 91 92 // (A,t[0]) := x[0]*y[0] + A 93 MULXQ R10, R14, R15 94 95 // (A,t[1]) := x[1]*y[0] + A 96 MULXQ R11, AX, CX 97 ADOXQ AX, R15 98 99 // (A,t[2]) := x[2]*y[0] + A 100 MULXQ R12, AX, BX 101 ADOXQ AX, CX 102 103 // (A,t[3]) := x[3]*y[0] + A 104 MULXQ 24(R8), AX, SI 105 ADOXQ AX, BX 106 107 // (A,t[4]) := x[4]*y[0] + A 108 MULXQ 32(R8), AX, DI 109 ADOXQ AX, SI 110 111 // (A,t[5]) := x[5]*y[0] + A 112 MULXQ 40(R8), AX, BP 113 ADOXQ AX, DI 114 115 // A += carries from ADCXQ and ADOXQ 116 MOVQ $0, AX 117 ADOXQ AX, BP 118 119 // m := t[0]*q'[0] mod W 120 MOVQ qInv0<>(SB), DX 121 IMULQ R14, DX 122 123 // clear the flags 124 XORQ AX, AX 125 126 // C,_ := t[0] + m*q[0] 127 MULXQ q<>+0(SB), AX, R9 128 ADCXQ R14, AX 129 MOVQ R9, R14 130 131 // (C,t[0]) := t[1] + m*q[1] + C 132 ADCXQ R15, R14 133 MULXQ q<>+8(SB), AX, R15 134 ADOXQ AX, R14 135 136 // (C,t[1]) := t[2] + m*q[2] + C 137 ADCXQ CX, R15 138 MULXQ q<>+16(SB), AX, CX 139 ADOXQ AX, R15 140 141 // (C,t[2]) := t[3] + m*q[3] + C 142 ADCXQ BX, CX 143 MULXQ q<>+24(SB), AX, BX 144 ADOXQ AX, CX 145 146 // (C,t[3]) := t[4] + m*q[4] + C 147 ADCXQ SI, BX 148 MULXQ q<>+32(SB), AX, SI 149 ADOXQ AX, BX 150 151 // (C,t[4]) := t[5] + m*q[5] + C 152 ADCXQ DI, SI 153 MULXQ q<>+40(SB), AX, DI 154 ADOXQ AX, SI 155 156 // t[5] = C + A 157 MOVQ $0, AX 158 ADCXQ AX, DI 159 ADOXQ BP, DI 160 161 // clear the flags 162 XORQ AX, AX 163 MOVQ 8(R13), DX 164 165 // (A,t[0]) := t[0] + x[0]*y[1] + A 166 MULXQ R10, AX, BP 167 ADOXQ AX, R14 168 169 // (A,t[1]) := t[1] + x[1]*y[1] + A 170 ADCXQ BP, R15 171 MULXQ R11, AX, BP 172 ADOXQ AX, R15 173 174 // (A,t[2]) := t[2] + x[2]*y[1] + A 175 ADCXQ BP, CX 176 MULXQ R12, AX, BP 177 ADOXQ AX, CX 178 179 // (A,t[3]) := t[3] + x[3]*y[1] + A 180 ADCXQ BP, BX 181 MULXQ 24(R8), AX, BP 182 ADOXQ AX, BX 183 184 // (A,t[4]) := t[4] + x[4]*y[1] + A 185 ADCXQ BP, SI 186 MULXQ 32(R8), AX, BP 187 ADOXQ AX, SI 188 189 // (A,t[5]) := t[5] + x[5]*y[1] + A 190 ADCXQ BP, DI 191 MULXQ 40(R8), AX, BP 192 ADOXQ AX, DI 193 194 // A += carries from ADCXQ and ADOXQ 195 MOVQ $0, AX 196 ADCXQ AX, BP 197 ADOXQ AX, BP 198 199 // m := t[0]*q'[0] mod W 200 MOVQ qInv0<>(SB), DX 201 IMULQ R14, DX 202 203 // clear the flags 204 XORQ AX, AX 205 206 // C,_ := t[0] + m*q[0] 207 MULXQ q<>+0(SB), AX, R9 208 ADCXQ R14, AX 209 MOVQ R9, R14 210 211 // (C,t[0]) := t[1] + m*q[1] + C 212 ADCXQ R15, R14 213 MULXQ q<>+8(SB), AX, R15 214 ADOXQ AX, R14 215 216 // (C,t[1]) := t[2] + m*q[2] + C 217 ADCXQ CX, R15 218 MULXQ q<>+16(SB), AX, CX 219 ADOXQ AX, R15 220 221 // (C,t[2]) := t[3] + m*q[3] + C 222 ADCXQ BX, CX 223 MULXQ q<>+24(SB), AX, BX 224 ADOXQ AX, CX 225 226 // (C,t[3]) := t[4] + m*q[4] + C 227 ADCXQ SI, BX 228 MULXQ q<>+32(SB), AX, SI 229 ADOXQ AX, BX 230 231 // (C,t[4]) := t[5] + m*q[5] + C 232 ADCXQ DI, SI 233 MULXQ q<>+40(SB), AX, DI 234 ADOXQ AX, SI 235 236 // t[5] = C + A 237 MOVQ $0, AX 238 ADCXQ AX, DI 239 ADOXQ BP, DI 240 241 // clear the flags 242 XORQ AX, AX 243 MOVQ 16(R13), DX 244 245 // (A,t[0]) := t[0] + x[0]*y[2] + A 246 MULXQ R10, AX, BP 247 ADOXQ AX, R14 248 249 // (A,t[1]) := t[1] + x[1]*y[2] + A 250 ADCXQ BP, R15 251 MULXQ R11, AX, BP 252 ADOXQ AX, R15 253 254 // (A,t[2]) := t[2] + x[2]*y[2] + A 255 ADCXQ BP, CX 256 MULXQ R12, AX, BP 257 ADOXQ AX, CX 258 259 // (A,t[3]) := t[3] + x[3]*y[2] + A 260 ADCXQ BP, BX 261 MULXQ 24(R8), AX, BP 262 ADOXQ AX, BX 263 264 // (A,t[4]) := t[4] + x[4]*y[2] + A 265 ADCXQ BP, SI 266 MULXQ 32(R8), AX, BP 267 ADOXQ AX, SI 268 269 // (A,t[5]) := t[5] + x[5]*y[2] + A 270 ADCXQ BP, DI 271 MULXQ 40(R8), AX, BP 272 ADOXQ AX, DI 273 274 // A += carries from ADCXQ and ADOXQ 275 MOVQ $0, AX 276 ADCXQ AX, BP 277 ADOXQ AX, BP 278 279 // m := t[0]*q'[0] mod W 280 MOVQ qInv0<>(SB), DX 281 IMULQ R14, DX 282 283 // clear the flags 284 XORQ AX, AX 285 286 // C,_ := t[0] + m*q[0] 287 MULXQ q<>+0(SB), AX, R9 288 ADCXQ R14, AX 289 MOVQ R9, R14 290 291 // (C,t[0]) := t[1] + m*q[1] + C 292 ADCXQ R15, R14 293 MULXQ q<>+8(SB), AX, R15 294 ADOXQ AX, R14 295 296 // (C,t[1]) := t[2] + m*q[2] + C 297 ADCXQ CX, R15 298 MULXQ q<>+16(SB), AX, CX 299 ADOXQ AX, R15 300 301 // (C,t[2]) := t[3] + m*q[3] + C 302 ADCXQ BX, CX 303 MULXQ q<>+24(SB), AX, BX 304 ADOXQ AX, CX 305 306 // (C,t[3]) := t[4] + m*q[4] + C 307 ADCXQ SI, BX 308 MULXQ q<>+32(SB), AX, SI 309 ADOXQ AX, BX 310 311 // (C,t[4]) := t[5] + m*q[5] + C 312 ADCXQ DI, SI 313 MULXQ q<>+40(SB), AX, DI 314 ADOXQ AX, SI 315 316 // t[5] = C + A 317 MOVQ $0, AX 318 ADCXQ AX, DI 319 ADOXQ BP, DI 320 321 // clear the flags 322 XORQ AX, AX 323 MOVQ 24(R13), DX 324 325 // (A,t[0]) := t[0] + x[0]*y[3] + A 326 MULXQ R10, AX, BP 327 ADOXQ AX, R14 328 329 // (A,t[1]) := t[1] + x[1]*y[3] + A 330 ADCXQ BP, R15 331 MULXQ R11, AX, BP 332 ADOXQ AX, R15 333 334 // (A,t[2]) := t[2] + x[2]*y[3] + A 335 ADCXQ BP, CX 336 MULXQ R12, AX, BP 337 ADOXQ AX, CX 338 339 // (A,t[3]) := t[3] + x[3]*y[3] + A 340 ADCXQ BP, BX 341 MULXQ 24(R8), AX, BP 342 ADOXQ AX, BX 343 344 // (A,t[4]) := t[4] + x[4]*y[3] + A 345 ADCXQ BP, SI 346 MULXQ 32(R8), AX, BP 347 ADOXQ AX, SI 348 349 // (A,t[5]) := t[5] + x[5]*y[3] + A 350 ADCXQ BP, DI 351 MULXQ 40(R8), AX, BP 352 ADOXQ AX, DI 353 354 // A += carries from ADCXQ and ADOXQ 355 MOVQ $0, AX 356 ADCXQ AX, BP 357 ADOXQ AX, BP 358 359 // m := t[0]*q'[0] mod W 360 MOVQ qInv0<>(SB), DX 361 IMULQ R14, DX 362 363 // clear the flags 364 XORQ AX, AX 365 366 // C,_ := t[0] + m*q[0] 367 MULXQ q<>+0(SB), AX, R9 368 ADCXQ R14, AX 369 MOVQ R9, R14 370 371 // (C,t[0]) := t[1] + m*q[1] + C 372 ADCXQ R15, R14 373 MULXQ q<>+8(SB), AX, R15 374 ADOXQ AX, R14 375 376 // (C,t[1]) := t[2] + m*q[2] + C 377 ADCXQ CX, R15 378 MULXQ q<>+16(SB), AX, CX 379 ADOXQ AX, R15 380 381 // (C,t[2]) := t[3] + m*q[3] + C 382 ADCXQ BX, CX 383 MULXQ q<>+24(SB), AX, BX 384 ADOXQ AX, CX 385 386 // (C,t[3]) := t[4] + m*q[4] + C 387 ADCXQ SI, BX 388 MULXQ q<>+32(SB), AX, SI 389 ADOXQ AX, BX 390 391 // (C,t[4]) := t[5] + m*q[5] + C 392 ADCXQ DI, SI 393 MULXQ q<>+40(SB), AX, DI 394 ADOXQ AX, SI 395 396 // t[5] = C + A 397 MOVQ $0, AX 398 ADCXQ AX, DI 399 ADOXQ BP, DI 400 401 // clear the flags 402 XORQ AX, AX 403 MOVQ 32(R13), DX 404 405 // (A,t[0]) := t[0] + x[0]*y[4] + A 406 MULXQ R10, AX, BP 407 ADOXQ AX, R14 408 409 // (A,t[1]) := t[1] + x[1]*y[4] + A 410 ADCXQ BP, R15 411 MULXQ R11, AX, BP 412 ADOXQ AX, R15 413 414 // (A,t[2]) := t[2] + x[2]*y[4] + A 415 ADCXQ BP, CX 416 MULXQ R12, AX, BP 417 ADOXQ AX, CX 418 419 // (A,t[3]) := t[3] + x[3]*y[4] + A 420 ADCXQ BP, BX 421 MULXQ 24(R8), AX, BP 422 ADOXQ AX, BX 423 424 // (A,t[4]) := t[4] + x[4]*y[4] + A 425 ADCXQ BP, SI 426 MULXQ 32(R8), AX, BP 427 ADOXQ AX, SI 428 429 // (A,t[5]) := t[5] + x[5]*y[4] + A 430 ADCXQ BP, DI 431 MULXQ 40(R8), AX, BP 432 ADOXQ AX, DI 433 434 // A += carries from ADCXQ and ADOXQ 435 MOVQ $0, AX 436 ADCXQ AX, BP 437 ADOXQ AX, BP 438 439 // m := t[0]*q'[0] mod W 440 MOVQ qInv0<>(SB), DX 441 IMULQ R14, DX 442 443 // clear the flags 444 XORQ AX, AX 445 446 // C,_ := t[0] + m*q[0] 447 MULXQ q<>+0(SB), AX, R9 448 ADCXQ R14, AX 449 MOVQ R9, R14 450 451 // (C,t[0]) := t[1] + m*q[1] + C 452 ADCXQ R15, R14 453 MULXQ q<>+8(SB), AX, R15 454 ADOXQ AX, R14 455 456 // (C,t[1]) := t[2] + m*q[2] + C 457 ADCXQ CX, R15 458 MULXQ q<>+16(SB), AX, CX 459 ADOXQ AX, R15 460 461 // (C,t[2]) := t[3] + m*q[3] + C 462 ADCXQ BX, CX 463 MULXQ q<>+24(SB), AX, BX 464 ADOXQ AX, CX 465 466 // (C,t[3]) := t[4] + m*q[4] + C 467 ADCXQ SI, BX 468 MULXQ q<>+32(SB), AX, SI 469 ADOXQ AX, BX 470 471 // (C,t[4]) := t[5] + m*q[5] + C 472 ADCXQ DI, SI 473 MULXQ q<>+40(SB), AX, DI 474 ADOXQ AX, SI 475 476 // t[5] = C + A 477 MOVQ $0, AX 478 ADCXQ AX, DI 479 ADOXQ BP, DI 480 481 // clear the flags 482 XORQ AX, AX 483 MOVQ 40(R13), DX 484 485 // (A,t[0]) := t[0] + x[0]*y[5] + A 486 MULXQ R10, AX, BP 487 ADOXQ AX, R14 488 489 // (A,t[1]) := t[1] + x[1]*y[5] + A 490 ADCXQ BP, R15 491 MULXQ R11, AX, BP 492 ADOXQ AX, R15 493 494 // (A,t[2]) := t[2] + x[2]*y[5] + A 495 ADCXQ BP, CX 496 MULXQ R12, AX, BP 497 ADOXQ AX, CX 498 499 // (A,t[3]) := t[3] + x[3]*y[5] + A 500 ADCXQ BP, BX 501 MULXQ 24(R8), AX, BP 502 ADOXQ AX, BX 503 504 // (A,t[4]) := t[4] + x[4]*y[5] + A 505 ADCXQ BP, SI 506 MULXQ 32(R8), AX, BP 507 ADOXQ AX, SI 508 509 // (A,t[5]) := t[5] + x[5]*y[5] + A 510 ADCXQ BP, DI 511 MULXQ 40(R8), AX, BP 512 ADOXQ AX, DI 513 514 // A += carries from ADCXQ and ADOXQ 515 MOVQ $0, AX 516 ADCXQ AX, BP 517 ADOXQ AX, BP 518 519 // m := t[0]*q'[0] mod W 520 MOVQ qInv0<>(SB), DX 521 IMULQ R14, DX 522 523 // clear the flags 524 XORQ AX, AX 525 526 // C,_ := t[0] + m*q[0] 527 MULXQ q<>+0(SB), AX, R9 528 ADCXQ R14, AX 529 MOVQ R9, R14 530 531 // (C,t[0]) := t[1] + m*q[1] + C 532 ADCXQ R15, R14 533 MULXQ q<>+8(SB), AX, R15 534 ADOXQ AX, R14 535 536 // (C,t[1]) := t[2] + m*q[2] + C 537 ADCXQ CX, R15 538 MULXQ q<>+16(SB), AX, CX 539 ADOXQ AX, R15 540 541 // (C,t[2]) := t[3] + m*q[3] + C 542 ADCXQ BX, CX 543 MULXQ q<>+24(SB), AX, BX 544 ADOXQ AX, CX 545 546 // (C,t[3]) := t[4] + m*q[4] + C 547 ADCXQ SI, BX 548 MULXQ q<>+32(SB), AX, SI 549 ADOXQ AX, BX 550 551 // (C,t[4]) := t[5] + m*q[5] + C 552 ADCXQ DI, SI 553 MULXQ q<>+40(SB), AX, DI 554 ADOXQ AX, SI 555 556 // t[5] = C + A 557 MOVQ $0, AX 558 ADCXQ AX, DI 559 ADOXQ BP, DI 560 561 // reduce element(R14,R15,CX,BX,SI,DI) using temp registers (R9,R8,R13,R10,R11,R12) 562 REDUCE(R14,R15,CX,BX,SI,DI,R9,R8,R13,R10,R11,R12) 563 564 MOVQ res+0(FP), AX 565 MOVQ R14, 0(AX) 566 MOVQ R15, 8(AX) 567 MOVQ CX, 16(AX) 568 MOVQ BX, 24(AX) 569 MOVQ SI, 32(AX) 570 MOVQ DI, 40(AX) 571 RET 572 573 l1: 574 MOVQ res+0(FP), AX 575 MOVQ AX, (SP) 576 MOVQ x+8(FP), AX 577 MOVQ AX, 8(SP) 578 MOVQ y+16(FP), AX 579 MOVQ AX, 16(SP) 580 CALL ·_mulGeneric(SB) 581 RET 582 583 TEXT ·fromMont(SB), $8-8 584 NO_LOCAL_POINTERS 585 586 // the algorithm is described here 587 // https://hackmd.io/@gnark/modular_multiplication 588 // when y = 1 we have: 589 // for i=0 to N-1 590 // t[i] = x[i] 591 // for i=0 to N-1 592 // m := t[0]*q'[0] mod W 593 // C,_ := t[0] + m*q[0] 594 // for j=1 to N-1 595 // (C,t[j-1]) := t[j] + m*q[j] + C 596 // t[N-1] = C 597 CMPB ·supportAdx(SB), $1 598 JNE l2 599 MOVQ res+0(FP), DX 600 MOVQ 0(DX), R14 601 MOVQ 8(DX), R15 602 MOVQ 16(DX), CX 603 MOVQ 24(DX), BX 604 MOVQ 32(DX), SI 605 MOVQ 40(DX), DI 606 XORQ DX, DX 607 608 // m := t[0]*q'[0] mod W 609 MOVQ qInv0<>(SB), DX 610 IMULQ R14, DX 611 XORQ AX, AX 612 613 // C,_ := t[0] + m*q[0] 614 MULXQ q<>+0(SB), AX, BP 615 ADCXQ R14, AX 616 MOVQ BP, R14 617 618 // (C,t[0]) := t[1] + m*q[1] + C 619 ADCXQ R15, R14 620 MULXQ q<>+8(SB), AX, R15 621 ADOXQ AX, R14 622 623 // (C,t[1]) := t[2] + m*q[2] + C 624 ADCXQ CX, R15 625 MULXQ q<>+16(SB), AX, CX 626 ADOXQ AX, R15 627 628 // (C,t[2]) := t[3] + m*q[3] + C 629 ADCXQ BX, CX 630 MULXQ q<>+24(SB), AX, BX 631 ADOXQ AX, CX 632 633 // (C,t[3]) := t[4] + m*q[4] + C 634 ADCXQ SI, BX 635 MULXQ q<>+32(SB), AX, SI 636 ADOXQ AX, BX 637 638 // (C,t[4]) := t[5] + m*q[5] + C 639 ADCXQ DI, SI 640 MULXQ q<>+40(SB), AX, DI 641 ADOXQ AX, SI 642 MOVQ $0, AX 643 ADCXQ AX, DI 644 ADOXQ AX, DI 645 XORQ DX, DX 646 647 // m := t[0]*q'[0] mod W 648 MOVQ qInv0<>(SB), DX 649 IMULQ R14, DX 650 XORQ AX, AX 651 652 // C,_ := t[0] + m*q[0] 653 MULXQ q<>+0(SB), AX, BP 654 ADCXQ R14, AX 655 MOVQ BP, R14 656 657 // (C,t[0]) := t[1] + m*q[1] + C 658 ADCXQ R15, R14 659 MULXQ q<>+8(SB), AX, R15 660 ADOXQ AX, R14 661 662 // (C,t[1]) := t[2] + m*q[2] + C 663 ADCXQ CX, R15 664 MULXQ q<>+16(SB), AX, CX 665 ADOXQ AX, R15 666 667 // (C,t[2]) := t[3] + m*q[3] + C 668 ADCXQ BX, CX 669 MULXQ q<>+24(SB), AX, BX 670 ADOXQ AX, CX 671 672 // (C,t[3]) := t[4] + m*q[4] + C 673 ADCXQ SI, BX 674 MULXQ q<>+32(SB), AX, SI 675 ADOXQ AX, BX 676 677 // (C,t[4]) := t[5] + m*q[5] + C 678 ADCXQ DI, SI 679 MULXQ q<>+40(SB), AX, DI 680 ADOXQ AX, SI 681 MOVQ $0, AX 682 ADCXQ AX, DI 683 ADOXQ AX, DI 684 XORQ DX, DX 685 686 // m := t[0]*q'[0] mod W 687 MOVQ qInv0<>(SB), DX 688 IMULQ R14, DX 689 XORQ AX, AX 690 691 // C,_ := t[0] + m*q[0] 692 MULXQ q<>+0(SB), AX, BP 693 ADCXQ R14, AX 694 MOVQ BP, R14 695 696 // (C,t[0]) := t[1] + m*q[1] + C 697 ADCXQ R15, R14 698 MULXQ q<>+8(SB), AX, R15 699 ADOXQ AX, R14 700 701 // (C,t[1]) := t[2] + m*q[2] + C 702 ADCXQ CX, R15 703 MULXQ q<>+16(SB), AX, CX 704 ADOXQ AX, R15 705 706 // (C,t[2]) := t[3] + m*q[3] + C 707 ADCXQ BX, CX 708 MULXQ q<>+24(SB), AX, BX 709 ADOXQ AX, CX 710 711 // (C,t[3]) := t[4] + m*q[4] + C 712 ADCXQ SI, BX 713 MULXQ q<>+32(SB), AX, SI 714 ADOXQ AX, BX 715 716 // (C,t[4]) := t[5] + m*q[5] + C 717 ADCXQ DI, SI 718 MULXQ q<>+40(SB), AX, DI 719 ADOXQ AX, SI 720 MOVQ $0, AX 721 ADCXQ AX, DI 722 ADOXQ AX, DI 723 XORQ DX, DX 724 725 // m := t[0]*q'[0] mod W 726 MOVQ qInv0<>(SB), DX 727 IMULQ R14, DX 728 XORQ AX, AX 729 730 // C,_ := t[0] + m*q[0] 731 MULXQ q<>+0(SB), AX, BP 732 ADCXQ R14, AX 733 MOVQ BP, R14 734 735 // (C,t[0]) := t[1] + m*q[1] + C 736 ADCXQ R15, R14 737 MULXQ q<>+8(SB), AX, R15 738 ADOXQ AX, R14 739 740 // (C,t[1]) := t[2] + m*q[2] + C 741 ADCXQ CX, R15 742 MULXQ q<>+16(SB), AX, CX 743 ADOXQ AX, R15 744 745 // (C,t[2]) := t[3] + m*q[3] + C 746 ADCXQ BX, CX 747 MULXQ q<>+24(SB), AX, BX 748 ADOXQ AX, CX 749 750 // (C,t[3]) := t[4] + m*q[4] + C 751 ADCXQ SI, BX 752 MULXQ q<>+32(SB), AX, SI 753 ADOXQ AX, BX 754 755 // (C,t[4]) := t[5] + m*q[5] + C 756 ADCXQ DI, SI 757 MULXQ q<>+40(SB), AX, DI 758 ADOXQ AX, SI 759 MOVQ $0, AX 760 ADCXQ AX, DI 761 ADOXQ AX, DI 762 XORQ DX, DX 763 764 // m := t[0]*q'[0] mod W 765 MOVQ qInv0<>(SB), DX 766 IMULQ R14, DX 767 XORQ AX, AX 768 769 // C,_ := t[0] + m*q[0] 770 MULXQ q<>+0(SB), AX, BP 771 ADCXQ R14, AX 772 MOVQ BP, R14 773 774 // (C,t[0]) := t[1] + m*q[1] + C 775 ADCXQ R15, R14 776 MULXQ q<>+8(SB), AX, R15 777 ADOXQ AX, R14 778 779 // (C,t[1]) := t[2] + m*q[2] + C 780 ADCXQ CX, R15 781 MULXQ q<>+16(SB), AX, CX 782 ADOXQ AX, R15 783 784 // (C,t[2]) := t[3] + m*q[3] + C 785 ADCXQ BX, CX 786 MULXQ q<>+24(SB), AX, BX 787 ADOXQ AX, CX 788 789 // (C,t[3]) := t[4] + m*q[4] + C 790 ADCXQ SI, BX 791 MULXQ q<>+32(SB), AX, SI 792 ADOXQ AX, BX 793 794 // (C,t[4]) := t[5] + m*q[5] + C 795 ADCXQ DI, SI 796 MULXQ q<>+40(SB), AX, DI 797 ADOXQ AX, SI 798 MOVQ $0, AX 799 ADCXQ AX, DI 800 ADOXQ AX, DI 801 XORQ DX, DX 802 803 // m := t[0]*q'[0] mod W 804 MOVQ qInv0<>(SB), DX 805 IMULQ R14, DX 806 XORQ AX, AX 807 808 // C,_ := t[0] + m*q[0] 809 MULXQ q<>+0(SB), AX, BP 810 ADCXQ R14, AX 811 MOVQ BP, R14 812 813 // (C,t[0]) := t[1] + m*q[1] + C 814 ADCXQ R15, R14 815 MULXQ q<>+8(SB), AX, R15 816 ADOXQ AX, R14 817 818 // (C,t[1]) := t[2] + m*q[2] + C 819 ADCXQ CX, R15 820 MULXQ q<>+16(SB), AX, CX 821 ADOXQ AX, R15 822 823 // (C,t[2]) := t[3] + m*q[3] + C 824 ADCXQ BX, CX 825 MULXQ q<>+24(SB), AX, BX 826 ADOXQ AX, CX 827 828 // (C,t[3]) := t[4] + m*q[4] + C 829 ADCXQ SI, BX 830 MULXQ q<>+32(SB), AX, SI 831 ADOXQ AX, BX 832 833 // (C,t[4]) := t[5] + m*q[5] + C 834 ADCXQ DI, SI 835 MULXQ q<>+40(SB), AX, DI 836 ADOXQ AX, SI 837 MOVQ $0, AX 838 ADCXQ AX, DI 839 ADOXQ AX, DI 840 841 // reduce element(R14,R15,CX,BX,SI,DI) using temp registers (R8,R9,R10,R11,R12,R13) 842 REDUCE(R14,R15,CX,BX,SI,DI,R8,R9,R10,R11,R12,R13) 843 844 MOVQ res+0(FP), AX 845 MOVQ R14, 0(AX) 846 MOVQ R15, 8(AX) 847 MOVQ CX, 16(AX) 848 MOVQ BX, 24(AX) 849 MOVQ SI, 32(AX) 850 MOVQ DI, 40(AX) 851 RET 852 853 l2: 854 MOVQ res+0(FP), AX 855 MOVQ AX, (SP) 856 CALL ·_fromMontGeneric(SB) 857 RET