do a 3 word by 2 word divide, returns quotient and leaves remainder in A
| 819 | |
| 820 | // do a 3 word by 2 word divide, returns quotient and leaves remainder in A |
| 821 | static word SubatomicDivide(word *A, word B0, word B1) |
| 822 | { |
| 823 | // assert {A[2],A[1]} < {B1,B0}, so quotient can fit in a word |
| 824 | assert(A[2] < B1 || (A[2]==B1 && A[1] < B0)); |
| 825 | |
| 826 | dword_union p, u; |
| 827 | word Q; |
| 828 | |
| 829 | // estimate the quotient: do a 2 word by 1 word divide |
| 830 | if (B1+1 == 0) |
| 831 | Q = A[2]; |
| 832 | else |
| 833 | Q = word(MAKE_DWORD(A[1], A[2]) / (B1+1)); |
| 834 | |
| 835 | // now subtract Q*B from A |
| 836 | p.dw = (dword) B0*Q; |
| 837 | u.dw = (dword) A[0] - p.low; |
| 838 | A[0] = u.low; |
| 839 | u.dw = (dword) A[1] - p.high - (word)(0-u.high) - (dword)B1*Q; |
| 840 | A[1] = u.low; |
| 841 | A[2] += u.high; |
| 842 | |
| 843 | // Q <= actual quotient, so fix it |
| 844 | while (A[2] || A[1] > B1 || (A[1]==B1 && A[0]>=B0)) |
| 845 | { |
| 846 | u.dw = (dword) A[0] - B0; |
| 847 | A[0] = u.low; |
| 848 | u.dw = (dword) A[1] - B1 - (word)(0-u.high); |
| 849 | A[1] = u.low; |
| 850 | A[2] += u.high; |
| 851 | Q++; |
| 852 | assert(Q); // shouldn't overflow |
| 853 | } |
| 854 | |
| 855 | return Q; |
| 856 | } |
| 857 | |
| 858 | // do a 4 word by 2 word divide, returns 2 word quotient in Q0 and Q1 |
| 859 | static inline void AtomicDivide(word &Q0, word &Q1, const word *A, word B0, word B1) |