divl.s 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /*
  2. * ulong
  3. * _udiv(ulong num, ulong den)
  4. * {
  5. * int i;
  6. * ulong quo;
  7. *
  8. * if(den == 0)
  9. * *(ulong*)-1 = 0;
  10. * quo = num;
  11. * if(quo > 1<<(32-1))
  12. * quo = 1<<(32-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: 12(R30)
  32. * returns
  33. * quo: 8(R30)
  34. * rem: 12(R30)
  35. */
  36. TEXT _udivmodl(SB), NOPROF, $-8
  37. MOVQ $-1, R11
  38. SLLQ $31, R11 /* (1<<31) in canonical form */
  39. MOVL 8(R30), R23 /* numerator */
  40. MOVL 12(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. SLLL $1, R10
  53. ADDQ $1, R11
  54. JMP udm38
  55. udm54:
  56. MOVQ R31, R12
  57. udm58:
  58. BLT R11, udm8c
  59. SLLL $1, R12
  60. CMPUGE R23, R10, R24
  61. BEQ R24, udm7c
  62. SUBL R10, R23
  63. OR $1, R12
  64. udm7c:
  65. SRLL $1, R10
  66. SUBQ $1, R11
  67. JMP udm58
  68. udm8c:
  69. MOVL R12, 8(R30) /* quotient */
  70. MOVL R23, 12(R30) /* remainder */
  71. RET
  72. /*
  73. * save working registers
  74. * and bring in num/den parameters
  75. */
  76. TEXT _unsargl(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. MOVL R27, 8(R30)
  83. MOVL 72(R30), R27
  84. MOVL R27, 12(R30)
  85. RET
  86. /*
  87. * save working registers
  88. * and bring in absolute value
  89. * of num/den parameters
  90. */
  91. TEXT _absargl(SB), NOPROF, $-8
  92. MOVQ R10, 24(R30)
  93. MOVQ R11, 32(R30)
  94. MOVQ R12, 40(R30)
  95. MOVQ R23, 48(R30)
  96. MOVQ R24, 56(R30)
  97. MOVL R27, 64(R30)
  98. BGE R27, ab1
  99. SUBL R27, R31, R27
  100. ab1:
  101. MOVL R27, 8(R30) /* numerator */
  102. MOVL 72(R30), R27
  103. BGE R27, ab2
  104. SUBL R27, R31, R27
  105. ab2:
  106. MOVL R27, 12(R30) /* denominator */
  107. RET
  108. /*
  109. * restore registers and
  110. * return to original caller
  111. * answer is in R27
  112. */
  113. TEXT _retargl(SB), NOPROF, $-8
  114. MOVQ 24(R30), R10
  115. MOVQ 32(R30), R11
  116. MOVQ 40(R30), R12
  117. MOVQ 48(R30), R23
  118. MOVQ 56(R30), R24
  119. MOVL 0(R30), R26
  120. ADDQ $64, R30
  121. RET /* back to main sequence */
  122. TEXT _divl(SB), NOPROF, $-8
  123. SUBQ $64, R30 /* 5 reg save, 2 parameters, link */
  124. MOVL R26, 0(R30)
  125. JSR _absargl(SB)
  126. JSR _udivmodl(SB)
  127. MOVL 8(R30), R27
  128. MOVL 64(R30), R10 /* clean up the sign */
  129. MOVL 72(R30), R11
  130. XOR R11, R10
  131. BGE R10, div1
  132. SUBL R27, R31, R27
  133. div1:
  134. JSR _retargl(SB)
  135. RET /* not executed */
  136. TEXT _divlu(SB), NOPROF, $-8
  137. SUBQ $64, R30 /* 5 reg save, 2 parameters, link */
  138. MOVL R26, 0(R30)
  139. JSR _unsargl(SB)
  140. JSR _udivmodl(SB)
  141. MOVL 8(R30), R27
  142. JSR _retargl(SB)
  143. RET /* not executed */
  144. TEXT _modl(SB), NOPROF, $-8
  145. SUBQ $64, R30 /* 5 reg save, 2 parameters, link */
  146. MOVL R26, 0(R30)
  147. JSR _absargl(SB)
  148. JSR _udivmodl(SB)
  149. MOVL 12(R30), R27
  150. MOVL 64(R30), R10 /* clean up the sign */
  151. BGE R10, div2
  152. SUBL R27, R31, R27
  153. div2:
  154. JSR _retargl(SB)
  155. RET /* not executed */
  156. TEXT _modlu(SB), NOPROF, $-8
  157. SUBQ $64, R30 /* 5 reg save, 2 parameters, link */
  158. MOVL R26, 0(R30)
  159. JSR _unsargl(SB)
  160. JSR _udivmodl(SB)
  161. MOVL 12(R30), R27
  162. JSR _retargl(SB)
  163. RET /* not executed */