| 357 | } |
| 358 | |
| 359 | static void CombaMultiply(word *R, const word *A, const word *B) |
| 360 | { |
| 361 | dword_union p; |
| 362 | word c=0, d=0, e=0; |
| 363 | |
| 364 | #define MulAcc(x, y) \ |
| 365 | p.dw = (dword)A[x] * B[y] + c; \ |
| 366 | c = p.low; \ |
| 367 | p.dw = (dword)d + p.high; \ |
| 368 | d = p.low; \ |
| 369 | e += p.high; |
| 370 | |
| 371 | #define SaveMulAcc(s, x, y) \ |
| 372 | R[s] = c; \ |
| 373 | p.dw = (dword)A[x] * B[y] + d; \ |
| 374 | c = p.low; \ |
| 375 | p.dw = (dword)e + p.high; \ |
| 376 | d = p.low; \ |
| 377 | e = p.high; |
| 378 | |
| 379 | p.dw = (dword)A[0] * B[0]; |
| 380 | R[0] = p.low; |
| 381 | c = p.high; |
| 382 | d = e = 0; |
| 383 | |
| 384 | MulAcc(0, 1); |
| 385 | MulAcc(1, 0); |
| 386 | |
| 387 | SaveMulAcc(1, 2, 0); |
| 388 | MulAcc(1, 1); |
| 389 | MulAcc(0, 2); |
| 390 | |
| 391 | SaveMulAcc(2, 0, 3); |
| 392 | MulAcc(1, 2); |
| 393 | MulAcc(2, 1); |
| 394 | MulAcc(3, 0); |
| 395 | |
| 396 | SaveMulAcc(3, 3, 1); |
| 397 | MulAcc(2, 2); |
| 398 | MulAcc(1, 3); |
| 399 | |
| 400 | SaveMulAcc(4, 2, 3); |
| 401 | MulAcc(3, 2); |
| 402 | |
| 403 | R[5] = c; |
| 404 | p.dw = (dword)A[3] * B[3] + d; |
| 405 | R[6] = p.low; |
| 406 | R[7] = e + p.high; |
| 407 | |
| 408 | #undef MulAcc |
| 409 | #undef SaveMulAcc |
| 410 | } |
| 411 | |
| 412 | static void AtomicInverseModPower2(word *C, word A0, word A1) |
| 413 | { |