| 411 | // do a 3 word by 2 word divide, returns quotient and leaves remainder in A |
| 412 | template <class S, class D> |
| 413 | S DivideThreeWordsByTwo(S *A, S B0, S B1, D *dummy=NULL) |
| 414 | { |
| 415 | CRYPTOPP_UNUSED(dummy); |
| 416 | |
| 417 | // Assert {A[2],A[1]} < {B1,B0}, so quotient can fit in a S |
| 418 | CRYPTOPP_ASSERT(A[2] < B1 || (A[2]==B1 && A[1] < B0)); |
| 419 | |
| 420 | // estimate the quotient: do a 2 S by 1 S divide. |
| 421 | // Profiling tells us the original second case was dominant, so it was promoted to the first If statement. |
| 422 | // The code change occurred at Commit dc99266599a0e72d. |
| 423 | |
| 424 | S Q; bool pre = (S(B1+1) == 0); |
| 425 | if (B1 > 0 && !pre) |
| 426 | Q = D(A[1], A[2]) / S(B1+1); |
| 427 | else if (pre) |
| 428 | Q = A[2]; |
| 429 | else |
| 430 | Q = D(A[0], A[1]) / B0; |
| 431 | |
| 432 | // now subtract Q*B from A |
| 433 | D p = D::Multiply(B0, Q); |
| 434 | D u = (D) A[0] - p.GetLowHalf(); |
| 435 | A[0] = u.GetLowHalf(); |
| 436 | u = (D) A[1] - p.GetHighHalf() - u.GetHighHalfAsBorrow() - D::Multiply(B1, Q); |
| 437 | A[1] = u.GetLowHalf(); |
| 438 | A[2] += u.GetHighHalf(); |
| 439 | |
| 440 | // Q <= actual quotient, so fix it |
| 441 | while (A[2] || A[1] > B1 || (A[1]==B1 && A[0]>=B0)) |
| 442 | { |
| 443 | u = (D) A[0] - B0; |
| 444 | A[0] = u.GetLowHalf(); |
| 445 | u = (D) A[1] - B1 - u.GetHighHalfAsBorrow(); |
| 446 | A[1] = u.GetLowHalf(); |
| 447 | A[2] += u.GetHighHalf(); |
| 448 | Q++; |
| 449 | CRYPTOPP_ASSERT(Q); // shouldn't overflow |
| 450 | } |
| 451 | |
| 452 | return Q; |
| 453 | } |
| 454 | |
| 455 | // do a 4 word by 2 word divide, returns 2 word quotient in Q0 and Q1 |
| 456 | template <class S, class D> |
nothing calls this directly
no test coverage detected