udivmodti4.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /* This has so very few changes over libgcc2's __udivmoddi4 it isn't funny. */
  2. #include <math-emu/soft-fp.h>
  3. #undef count_leading_zeros
  4. #define count_leading_zeros __FP_CLZ
  5. void
  6. _fp_udivmodti4(_FP_W_TYPE q[2], _FP_W_TYPE r[2],
  7. _FP_W_TYPE n1, _FP_W_TYPE n0,
  8. _FP_W_TYPE d1, _FP_W_TYPE d0)
  9. {
  10. _FP_W_TYPE q0, q1, r0, r1;
  11. _FP_I_TYPE b, bm;
  12. if (d1 == 0)
  13. {
  14. #if !UDIV_NEEDS_NORMALIZATION
  15. if (d0 > n1)
  16. {
  17. /* 0q = nn / 0D */
  18. udiv_qrnnd (q0, n0, n1, n0, d0);
  19. q1 = 0;
  20. /* Remainder in n0. */
  21. }
  22. else
  23. {
  24. /* qq = NN / 0d */
  25. if (d0 == 0)
  26. d0 = 1 / d0; /* Divide intentionally by zero. */
  27. udiv_qrnnd (q1, n1, 0, n1, d0);
  28. udiv_qrnnd (q0, n0, n1, n0, d0);
  29. /* Remainder in n0. */
  30. }
  31. r0 = n0;
  32. r1 = 0;
  33. #else /* UDIV_NEEDS_NORMALIZATION */
  34. if (d0 > n1)
  35. {
  36. /* 0q = nn / 0D */
  37. count_leading_zeros (bm, d0);
  38. if (bm != 0)
  39. {
  40. /* Normalize, i.e. make the most significant bit of the
  41. denominator set. */
  42. d0 = d0 << bm;
  43. n1 = (n1 << bm) | (n0 >> (_FP_W_TYPE_SIZE - bm));
  44. n0 = n0 << bm;
  45. }
  46. udiv_qrnnd (q0, n0, n1, n0, d0);
  47. q1 = 0;
  48. /* Remainder in n0 >> bm. */
  49. }
  50. else
  51. {
  52. /* qq = NN / 0d */
  53. if (d0 == 0)
  54. d0 = 1 / d0; /* Divide intentionally by zero. */
  55. count_leading_zeros (bm, d0);
  56. if (bm == 0)
  57. {
  58. /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
  59. conclude (the most significant bit of n1 is set) /\ (the
  60. leading quotient digit q1 = 1).
  61. This special case is necessary, not an optimization.
  62. (Shifts counts of SI_TYPE_SIZE are undefined.) */
  63. n1 -= d0;
  64. q1 = 1;
  65. }
  66. else
  67. {
  68. _FP_W_TYPE n2;
  69. /* Normalize. */
  70. b = _FP_W_TYPE_SIZE - bm;
  71. d0 = d0 << bm;
  72. n2 = n1 >> b;
  73. n1 = (n1 << bm) | (n0 >> b);
  74. n0 = n0 << bm;
  75. udiv_qrnnd (q1, n1, n2, n1, d0);
  76. }
  77. /* n1 != d0... */
  78. udiv_qrnnd (q0, n0, n1, n0, d0);
  79. /* Remainder in n0 >> bm. */
  80. }
  81. r0 = n0 >> bm;
  82. r1 = 0;
  83. #endif /* UDIV_NEEDS_NORMALIZATION */
  84. }
  85. else
  86. {
  87. if (d1 > n1)
  88. {
  89. /* 00 = nn / DD */
  90. q0 = 0;
  91. q1 = 0;
  92. /* Remainder in n1n0. */
  93. r0 = n0;
  94. r1 = n1;
  95. }
  96. else
  97. {
  98. /* 0q = NN / dd */
  99. count_leading_zeros (bm, d1);
  100. if (bm == 0)
  101. {
  102. /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
  103. conclude (the most significant bit of n1 is set) /\ (the
  104. quotient digit q0 = 0 or 1).
  105. This special case is necessary, not an optimization. */
  106. /* The condition on the next line takes advantage of that
  107. n1 >= d1 (true due to program flow). */
  108. if (n1 > d1 || n0 >= d0)
  109. {
  110. q0 = 1;
  111. sub_ddmmss (n1, n0, n1, n0, d1, d0);
  112. }
  113. else
  114. q0 = 0;
  115. q1 = 0;
  116. r0 = n0;
  117. r1 = n1;
  118. }
  119. else
  120. {
  121. _FP_W_TYPE m1, m0, n2;
  122. /* Normalize. */
  123. b = _FP_W_TYPE_SIZE - bm;
  124. d1 = (d1 << bm) | (d0 >> b);
  125. d0 = d0 << bm;
  126. n2 = n1 >> b;
  127. n1 = (n1 << bm) | (n0 >> b);
  128. n0 = n0 << bm;
  129. udiv_qrnnd (q0, n1, n2, n1, d1);
  130. umul_ppmm (m1, m0, q0, d0);
  131. if (m1 > n1 || (m1 == n1 && m0 > n0))
  132. {
  133. q0--;
  134. sub_ddmmss (m1, m0, m1, m0, d1, d0);
  135. }
  136. q1 = 0;
  137. /* Remainder in (n1n0 - m1m0) >> bm. */
  138. sub_ddmmss (n1, n0, n1, n0, m1, m0);
  139. r0 = (n1 << b) | (n0 >> bm);
  140. r1 = n1 >> bm;
  141. }
  142. }
  143. }
  144. q[0] = q0; q[1] = q1;
  145. r[0] = r0, r[1] = r1;
  146. }