| 449 | // B[N] --- multiplicant |
| 450 | |
| 451 | void RecursiveMultiply(word *R, word *T, const word *A, const word *B, unsigned int N) |
| 452 | { |
| 453 | assert(N>=2 && N%2==0); |
| 454 | |
| 455 | if (N==2) |
| 456 | AtomicMultiply(R, A[0], A[1], B[0], B[1]); |
| 457 | else if (N==4) |
| 458 | CombaMultiply(R, A, B); |
| 459 | else |
| 460 | { |
| 461 | const unsigned int N2 = N/2; |
| 462 | int carry; |
| 463 | |
| 464 | int aComp = Compare(A0, A1, N2); |
| 465 | int bComp = Compare(B0, B1, N2); |
| 466 | |
| 467 | switch (2*aComp + aComp + bComp) |
| 468 | { |
| 469 | case -4: |
| 470 | Subtract(R0, A1, A0, N2); |
| 471 | Subtract(R1, B0, B1, N2); |
| 472 | RecursiveMultiply(T0, T2, R0, R1, N2); |
| 473 | Subtract(T1, T1, R0, N2); |
| 474 | carry = -1; |
| 475 | break; |
| 476 | case -2: |
| 477 | Subtract(R0, A1, A0, N2); |
| 478 | Subtract(R1, B0, B1, N2); |
| 479 | RecursiveMultiply(T0, T2, R0, R1, N2); |
| 480 | carry = 0; |
| 481 | break; |
| 482 | case 2: |
| 483 | Subtract(R0, A0, A1, N2); |
| 484 | Subtract(R1, B1, B0, N2); |
| 485 | RecursiveMultiply(T0, T2, R0, R1, N2); |
| 486 | carry = 0; |
| 487 | break; |
| 488 | case 4: |
| 489 | Subtract(R0, A1, A0, N2); |
| 490 | Subtract(R1, B0, B1, N2); |
| 491 | RecursiveMultiply(T0, T2, R0, R1, N2); |
| 492 | Subtract(T1, T1, R1, N2); |
| 493 | carry = -1; |
| 494 | break; |
| 495 | default: |
| 496 | SetWords(T0, 0, N); |
| 497 | carry = 0; |
| 498 | } |
| 499 | |
| 500 | RecursiveMultiply(R0, T2, A0, B0, N2); |
| 501 | RecursiveMultiply(R2, T2, A1, B1, N2); |
| 502 | |
| 503 | // now T[01] holds (A1-A0)*(B0-B1), R[01] holds A0*B0, R[23] holds A1*B1 |
| 504 | |
| 505 | carry += Add(T0, T0, R0, N); |
| 506 | carry += Add(T0, T0, R2, N); |
| 507 | carry += Add(R1, R1, T0, N); |
| 508 |
no test coverage detected