| 589 | } |
| 590 | |
| 591 | void Portable::Multiply2(word *C, const word *A, const word *B) |
| 592 | { |
| 593 | /* |
| 594 | word s; |
| 595 | dword d; |
| 596 | |
| 597 | if (A1 >= A0) |
| 598 | if (B0 >= B1) |
| 599 | { |
| 600 | s = 0; |
| 601 | d = (dword)(A1-A0)*(B0-B1); |
| 602 | } |
| 603 | else |
| 604 | { |
| 605 | s = (A1-A0); |
| 606 | d = (dword)s*(word)(B0-B1); |
| 607 | } |
| 608 | else |
| 609 | if (B0 > B1) |
| 610 | { |
| 611 | s = (B0-B1); |
| 612 | d = (word)(A1-A0)*(dword)s; |
| 613 | } |
| 614 | else |
| 615 | { |
| 616 | s = 0; |
| 617 | d = (dword)(A0-A1)*(B1-B0); |
| 618 | } |
| 619 | */ |
| 620 | // this segment is the branchless equivalent of above |
| 621 | word D[4] = {A[1]-A[0], A[0]-A[1], B[0]-B[1], B[1]-B[0]}; |
| 622 | unsigned int ai = A[1] < A[0]; |
| 623 | unsigned int bi = B[0] < B[1]; |
| 624 | unsigned int di = ai & bi; |
| 625 | DWord d = DWord::Multiply(D[di], D[di+2]); |
| 626 | D[1] = D[3] = 0; |
| 627 | unsigned int si = ai + !bi; |
| 628 | word s = D[si]; |
| 629 | |
| 630 | DWord A0B0 = DWord::Multiply(A[0], B[0]); |
| 631 | C[0] = A0B0.GetLowHalf(); |
| 632 | |
| 633 | DWord A1B1 = DWord::Multiply(A[1], B[1]); |
| 634 | DWord t = (DWord) A0B0.GetHighHalf() + A0B0.GetLowHalf() + d.GetLowHalf() |
| 635 | + A1B1.GetLowHalf(); |
| 636 | C[1] = t.GetLowHalf(); |
| 637 | |
| 638 | t = A1B1 + t.GetHighHalf() + A0B0.GetHighHalf() + d.GetHighHalf() |
| 639 | + A1B1.GetHighHalf() - s; |
| 640 | C[2] = t.GetLowHalf(); |
| 641 | C[3] = t.GetHighHalf(); |
| 642 | } |
| 643 | |
| 644 | void Portable::Multiply2Bottom(word *C, const word *A, const word *B) |
| 645 | { |
nothing calls this directly
no test coverage detected