| 580 | // B[N] --- multiplicant |
| 581 | |
| 582 | void RecursiveMultiplyTop(word *R, word *T, const word *L, const word *A, const word *B, unsigned int N) |
| 583 | { |
| 584 | assert(N>=2 && N%2==0); |
| 585 | |
| 586 | if (N==2) |
| 587 | { |
| 588 | AtomicMultiply(T, A[0], A[1], B[0], B[1]); |
| 589 | R[0] = T[2]; |
| 590 | R[1] = T[3]; |
| 591 | } |
| 592 | else |
| 593 | { |
| 594 | const unsigned int N2 = N/2; |
| 595 | int carry; |
| 596 | |
| 597 | int aComp = Compare(A0, A1, N2); |
| 598 | int bComp = Compare(B0, B1, N2); |
| 599 | |
| 600 | switch (2*aComp + aComp + bComp) |
| 601 | { |
| 602 | case -4: |
| 603 | Subtract(R0, A1, A0, N2); |
| 604 | Subtract(R1, B0, B1, N2); |
| 605 | RecursiveMultiply(T0, T2, R0, R1, N2); |
| 606 | Subtract(T1, T1, R0, N2); |
| 607 | carry = -1; |
| 608 | break; |
| 609 | case -2: |
| 610 | Subtract(R0, A1, A0, N2); |
| 611 | Subtract(R1, B0, B1, N2); |
| 612 | RecursiveMultiply(T0, T2, R0, R1, N2); |
| 613 | carry = 0; |
| 614 | break; |
| 615 | case 2: |
| 616 | Subtract(R0, A0, A1, N2); |
| 617 | Subtract(R1, B1, B0, N2); |
| 618 | RecursiveMultiply(T0, T2, R0, R1, N2); |
| 619 | carry = 0; |
| 620 | break; |
| 621 | case 4: |
| 622 | Subtract(R0, A1, A0, N2); |
| 623 | Subtract(R1, B0, B1, N2); |
| 624 | RecursiveMultiply(T0, T2, R0, R1, N2); |
| 625 | Subtract(T1, T1, R1, N2); |
| 626 | carry = -1; |
| 627 | break; |
| 628 | default: |
| 629 | SetWords(T0, 0, N); |
| 630 | carry = 0; |
| 631 | } |
| 632 | |
| 633 | RecursiveMultiply(T2, R0, A1, B1, N2); |
| 634 | |
| 635 | // now T[01] holds (A1-A0)*(B0-B1), T[23] holds A1*B1 |
| 636 | |
| 637 | CopyWords(R0, L+N2, N2); |
| 638 | word c2 = Subtract(R0, R0, L, N2); |
| 639 | c2 += Subtract(R0, R0, T0, N2); |
no test coverage detected