divq.s 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /*
  2. * uvlong
  3. * _udiv(uvlong num, uvlong den)
  4. * {
  5. * int i;
  6. * uvlong quo;
  7. *
  8. * if(den == 0)
  9. * *(ulong*)-1 = 0;
  10. * quo = num;
  11. * if(quo > 1<<(64-1))
  12. * quo = 1<<(64-1);
  13. * for(i=0; den<quo; i++)
  14. * den <<= 1;
  15. * quo = 0;
  16. * for(; i>=0; i--) {
  17. * quo <<= 1;
  18. * if(num >= den) {
  19. * num -= den;
  20. * quo |= 1;
  21. * }
  22. * den >>= 1;
  23. * }
  24. * return quo::num;
  25. * }
  26. */
  27. #define NOPROF 1
  28. /*
  29. * calling sequence:
  30. * num: 8(R30)
  31. * den: 16(R30)
  32. * returns
  33. * quo: 8(R30)
  34. * rem: 16(R30)
  35. */
  36. TEXT _udivmodq(SB), NOPROF, $-8
  37. MOVQ $1, R11
  38. SLLQ $63, R11
  39. MOVQ 8(R30), R23 /* numerator */
  40. MOVQ 16(R30), R10 /* denominator */
  41. BNE R10, udm20
  42. MOVQ R31, -1(R31) /* fault -- divide by zero; todo: use gentrap? */
  43. udm20:
  44. MOVQ R23, R12
  45. BGE R12, udm34
  46. MOVQ R11, R12
  47. udm34:
  48. MOVQ R31, R11
  49. udm38:
  50. CMPUGE R10, R12, R24
  51. BNE R24, udm54
  52. SLLQ $1, R10
  53. ADDQ $1, R11
  54. JMP udm38
  55. udm54:
  56. MOVQ R31, R12
  57. udm58:
  58. BLT R11, udm8c
  59. SLLQ $1, R12
  60. CMPUGE R23, R10, R24
  61. BEQ R24, udm7c
  62. SUBQ R10, R23
  63. OR $1, R12
  64. udm7c:
  65. SRLQ $1, R10
  66. SUBQ $1, R11
  67. JMP udm58
  68. udm8c:
  69. MOVQ R12, 8(R30) /* quotient */
  70. MOVQ R23, 16(R30) /* remainder */
  71. RET
  72. /*
  73. * save working registers
  74. * and bring in num/den parameters
  75. */
  76. TEXT _unsargq(SB), NOPROF, $-8
  77. MOVQ R10, 24(R30)
  78. MOVQ R11, 32(R30)
  79. MOVQ R12, 40(R30)
  80. MOVQ R23, 48(R30)
  81. MOVQ R24, 56(R30)
  82. MOVQ R27, 8(R30)
  83. MOVQ 72(R30), R27
  84. MOVQ R27, 16(R30)
  85. MOVQ (R30), R10 /* debug */
  86. RET
  87. /*
  88. * save working registers
  89. * and bring in absolute value
  90. * of num/den parameters
  91. */
  92. TEXT _absargq(SB), NOPROF, $-8
  93. MOVQ R10, 24(R30)
  94. MOVQ R11, 32(R30)
  95. MOVQ R12, 40(R30)
  96. MOVQ R23, 48(R30)
  97. MOVQ R24, 56(R30)
  98. MOVQ R27, 64(R30)
  99. BGE R27, ab1
  100. SUBQ R27, R31, R27
  101. ab1:
  102. MOVQ R27, 8(R30) /* numerator */
  103. MOVQ 72(R30), R27
  104. BGE R27, ab2
  105. SUBQ R27, R31, R27
  106. ab2:
  107. MOVQ R27, 16(R30) /* denominator */
  108. MOVQ (R30), R10 /* debug */
  109. RET
  110. /*
  111. * restore registers and
  112. * return to original caller
  113. * answer is in R27
  114. */
  115. TEXT _retargq(SB), NOPROF, $-8
  116. MOVQ 24(R30), R10
  117. MOVQ 32(R30), R11
  118. MOVQ 40(R30), R12
  119. MOVQ 48(R30), R23
  120. MOVQ 56(R30), R24
  121. MOVL 0(R30), R26
  122. ADDQ $64, R30
  123. RET /* back to main sequence */
  124. TEXT _divq(SB), NOPROF, $-8
  125. SUBQ $64, R30 /* 5 reg save, 2 parameters, link */
  126. MOVQ R26, 0(R30)
  127. JSR _absargq(SB)
  128. JSR _udivmodq(SB)
  129. MOVQ 8(R30), R27
  130. MOVQ 64(R30), R10 /* clean up the sign */
  131. MOVQ 72(R30), R11
  132. XOR R11, R10
  133. BGE R10, div1
  134. SUBQ R27, R31, R27
  135. div1:
  136. JSR _retargq(SB)
  137. RET /* not executed */
  138. TEXT _divqu(SB), NOPROF, $-8
  139. SUBQ $64, R30 /* 5 reg save, 2 parameters, link */
  140. MOVQ R26, 0(R30)
  141. JSR _unsargq(SB)
  142. JSR _udivmodq(SB)
  143. MOVQ 8(R30), R27
  144. JSR _retargq(SB)
  145. RET /* not executed */
  146. TEXT _modq(SB), NOPROF, $-8
  147. SUBQ $64, R30 /* 5 reg save, 2 parameters, link */
  148. MOVQ R26, 0(R30)
  149. JSR _absargq(SB)
  150. JSR _udivmodq(SB)
  151. MOVQ 16(R30), R27
  152. MOVQ 64(R30), R10 /* clean up the sign */
  153. BGE R10, div2
  154. SUBQ R27, R31, R27
  155. div2:
  156. JSR _retargq(SB)
  157. RET /* not executed */
  158. TEXT _modqu(SB), NOPROF, $-8
  159. SUBQ $64, R30 /* 5 reg save, 2 parameters, link */
  160. MOVQ R26, 0(R30)
  161. JSR _unsargq(SB)
  162. JSR _udivmodq(SB)
  163. MOVQ 16(R30), R27
  164. JSR _retargq(SB)
  165. RET /* not executed */