remU.S 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /* 32 and 64-bit millicode, original author Hewlett-Packard
  2. adapted for gcc by Paul Bame <bame@debian.org>
  3. and Alan Modra <alan@linuxcare.com.au>.
  4. Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
  5. This file is part of GCC and is released under the terms of
  6. of the GNU General Public License as published by the Free Software
  7. Foundation; either version 2, or (at your option) any later version.
  8. See the file COPYING in the top-level GCC source directory for a copy
  9. of the license. */
  10. #include "milli.h"
  11. #ifdef L_remU
  12. /* ROUTINE: $$remU
  13. . Single precision divide for remainder with unsigned binary integers.
  14. .
  15. . The remainder must be dividend-(dividend/divisor)*divisor.
  16. . Divide by zero is trapped.
  17. INPUT REGISTERS:
  18. . arg0 == dividend
  19. . arg1 == divisor
  20. . mrp == return pc
  21. . sr0 == return space when called externally
  22. OUTPUT REGISTERS:
  23. . arg0 = undefined
  24. . arg1 = undefined
  25. . ret1 = remainder
  26. OTHER REGISTERS AFFECTED:
  27. . r1 = undefined
  28. SIDE EFFECTS:
  29. . Causes a trap under the following conditions: DIVIDE BY ZERO
  30. . Changes memory at the following places: NONE
  31. PERMISSIBLE CONTEXT:
  32. . Unwindable.
  33. . Does not create a stack frame.
  34. . Suitable for internal or external millicode.
  35. . Assumes the special millicode register conventions.
  36. DISCUSSION:
  37. . Calls other millicode routines using mrp: NONE
  38. . Calls other millicode routines: NONE */
  39. RDEFINE(temp,r1)
  40. RDEFINE(rmndr,ret1) /* r29 */
  41. SUBSPA_MILLI
  42. ATTR_MILLI
  43. .export $$remU,millicode
  44. .proc
  45. .callinfo millicode
  46. .entry
  47. GSYM($$remU)
  48. ldo -1(arg1),temp /* is there at most one bit set ? */
  49. and,= arg1,temp,r0 /* if not, don't use power of 2 */
  50. b LREF(regular_seq)
  51. addit,= 0,arg1,r0 /* trap on div by zero */
  52. and arg0,temp,rmndr /* get the result for power of 2 */
  53. MILLIRETN
  54. LSYM(regular_seq)
  55. comib,>=,n 0,arg1,LREF(special_case)
  56. subi 0,arg1,rmndr /* clear carry, negate the divisor */
  57. ds r0,rmndr,r0 /* set V-bit to 1 */
  58. add arg0,arg0,temp /* shift msb bit into carry */
  59. ds r0,arg1,rmndr /* 1st divide step, if no carry */
  60. addc temp,temp,temp /* shift temp with/into carry */
  61. ds rmndr,arg1,rmndr /* 2nd divide step */
  62. addc temp,temp,temp /* shift temp with/into carry */
  63. ds rmndr,arg1,rmndr /* 3rd divide step */
  64. addc temp,temp,temp /* shift temp with/into carry */
  65. ds rmndr,arg1,rmndr /* 4th divide step */
  66. addc temp,temp,temp /* shift temp with/into carry */
  67. ds rmndr,arg1,rmndr /* 5th divide step */
  68. addc temp,temp,temp /* shift temp with/into carry */
  69. ds rmndr,arg1,rmndr /* 6th divide step */
  70. addc temp,temp,temp /* shift temp with/into carry */
  71. ds rmndr,arg1,rmndr /* 7th divide step */
  72. addc temp,temp,temp /* shift temp with/into carry */
  73. ds rmndr,arg1,rmndr /* 8th divide step */
  74. addc temp,temp,temp /* shift temp with/into carry */
  75. ds rmndr,arg1,rmndr /* 9th divide step */
  76. addc temp,temp,temp /* shift temp with/into carry */
  77. ds rmndr,arg1,rmndr /* 10th divide step */
  78. addc temp,temp,temp /* shift temp with/into carry */
  79. ds rmndr,arg1,rmndr /* 11th divide step */
  80. addc temp,temp,temp /* shift temp with/into carry */
  81. ds rmndr,arg1,rmndr /* 12th divide step */
  82. addc temp,temp,temp /* shift temp with/into carry */
  83. ds rmndr,arg1,rmndr /* 13th divide step */
  84. addc temp,temp,temp /* shift temp with/into carry */
  85. ds rmndr,arg1,rmndr /* 14th divide step */
  86. addc temp,temp,temp /* shift temp with/into carry */
  87. ds rmndr,arg1,rmndr /* 15th divide step */
  88. addc temp,temp,temp /* shift temp with/into carry */
  89. ds rmndr,arg1,rmndr /* 16th divide step */
  90. addc temp,temp,temp /* shift temp with/into carry */
  91. ds rmndr,arg1,rmndr /* 17th divide step */
  92. addc temp,temp,temp /* shift temp with/into carry */
  93. ds rmndr,arg1,rmndr /* 18th divide step */
  94. addc temp,temp,temp /* shift temp with/into carry */
  95. ds rmndr,arg1,rmndr /* 19th divide step */
  96. addc temp,temp,temp /* shift temp with/into carry */
  97. ds rmndr,arg1,rmndr /* 20th divide step */
  98. addc temp,temp,temp /* shift temp with/into carry */
  99. ds rmndr,arg1,rmndr /* 21st divide step */
  100. addc temp,temp,temp /* shift temp with/into carry */
  101. ds rmndr,arg1,rmndr /* 22nd divide step */
  102. addc temp,temp,temp /* shift temp with/into carry */
  103. ds rmndr,arg1,rmndr /* 23rd divide step */
  104. addc temp,temp,temp /* shift temp with/into carry */
  105. ds rmndr,arg1,rmndr /* 24th divide step */
  106. addc temp,temp,temp /* shift temp with/into carry */
  107. ds rmndr,arg1,rmndr /* 25th divide step */
  108. addc temp,temp,temp /* shift temp with/into carry */
  109. ds rmndr,arg1,rmndr /* 26th divide step */
  110. addc temp,temp,temp /* shift temp with/into carry */
  111. ds rmndr,arg1,rmndr /* 27th divide step */
  112. addc temp,temp,temp /* shift temp with/into carry */
  113. ds rmndr,arg1,rmndr /* 28th divide step */
  114. addc temp,temp,temp /* shift temp with/into carry */
  115. ds rmndr,arg1,rmndr /* 29th divide step */
  116. addc temp,temp,temp /* shift temp with/into carry */
  117. ds rmndr,arg1,rmndr /* 30th divide step */
  118. addc temp,temp,temp /* shift temp with/into carry */
  119. ds rmndr,arg1,rmndr /* 31st divide step */
  120. addc temp,temp,temp /* shift temp with/into carry */
  121. ds rmndr,arg1,rmndr /* 32nd divide step, */
  122. comiclr,<= 0,rmndr,r0
  123. add rmndr,arg1,rmndr /* correction */
  124. MILLIRETN
  125. nop
  126. /* Putting >= on the last DS and deleting COMICLR does not work! */
  127. LSYM(special_case)
  128. sub,>>= arg0,arg1,rmndr
  129. copy arg0,rmndr
  130. MILLIRETN
  131. nop
  132. .exit
  133. .procend
  134. .end
  135. #endif