sint.S 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. |
  2. | sint.sa 3.1 12/10/90
  3. |
  4. | The entry point sINT computes the rounded integer
  5. | equivalent of the input argument, sINTRZ computes
  6. | the integer rounded to zero of the input argument.
  7. |
  8. | Entry points sint and sintrz are called from do_func
  9. | to emulate the fint and fintrz unimplemented instructions,
  10. | respectively. Entry point sintdo is used by bindec.
  11. |
  12. | Input: (Entry points sint and sintrz) Double-extended
  13. | number X in the ETEMP space in the floating-point
  14. | save stack.
  15. | (Entry point sintdo) Double-extended number X in
  16. | location pointed to by the address register a0.
  17. | (Entry point sintd) Double-extended denormalized
  18. | number X in the ETEMP space in the floating-point
  19. | save stack.
  20. |
  21. | Output: The function returns int(X) or intrz(X) in fp0.
  22. |
  23. | Modifies: fp0.
  24. |
  25. | Algorithm: (sint and sintrz)
  26. |
  27. | 1. If exp(X) >= 63, return X.
  28. | If exp(X) < 0, return +/- 0 or +/- 1, according to
  29. | the rounding mode.
  30. |
  31. | 2. (X is in range) set rsc = 63 - exp(X). Unnormalize the
  32. | result to the exponent $403e.
  33. |
  34. | 3. Round the result in the mode given in USER_FPCR. For
  35. | sintrz, force round-to-zero mode.
  36. |
  37. | 4. Normalize the rounded result; store in fp0.
  38. |
  39. | For the denormalized cases, force the correct result
  40. | for the given sign and rounding mode.
  41. |
  42. | Sign(X)
  43. | RMODE + -
  44. | ----- --------
  45. | RN +0 -0
  46. | RZ +0 -0
  47. | RM +0 -1
  48. | RP +1 -0
  49. |
  50. |
  51. | Copyright (C) Motorola, Inc. 1990
  52. | All Rights Reserved
  53. |
  54. | For details on the license for this file, please see the
  55. | file, README, in this same directory.
  56. |SINT idnt 2,1 | Motorola 040 Floating Point Software Package
  57. |section 8
  58. #include "fpsp.h"
  59. |xref dnrm_lp
  60. |xref nrm_set
  61. |xref round
  62. |xref t_inx2
  63. |xref ld_pone
  64. |xref ld_mone
  65. |xref ld_pzero
  66. |xref ld_mzero
  67. |xref snzrinx
  68. |
  69. | FINT
  70. |
  71. .global sint
  72. sint:
  73. bfextu FPCR_MODE(%a6){#2:#2},%d1 |use user's mode for rounding
  74. | ;implicitly has extend precision
  75. | ;in upper word.
  76. movel %d1,L_SCR1(%a6) |save mode bits
  77. bras sintexc
  78. |
  79. | FINT with extended denorm inputs.
  80. |
  81. .global sintd
  82. sintd:
  83. btstb #5,FPCR_MODE(%a6)
  84. beq snzrinx |if round nearest or round zero, +/- 0
  85. btstb #4,FPCR_MODE(%a6)
  86. beqs rnd_mns
  87. rnd_pls:
  88. btstb #sign_bit,LOCAL_EX(%a0)
  89. bnes sintmz
  90. bsr ld_pone |if round plus inf and pos, answer is +1
  91. bra t_inx2
  92. rnd_mns:
  93. btstb #sign_bit,LOCAL_EX(%a0)
  94. beqs sintpz
  95. bsr ld_mone |if round mns inf and neg, answer is -1
  96. bra t_inx2
  97. sintpz:
  98. bsr ld_pzero
  99. bra t_inx2
  100. sintmz:
  101. bsr ld_mzero
  102. bra t_inx2
  103. |
  104. | FINTRZ
  105. |
  106. .global sintrz
  107. sintrz:
  108. movel #1,L_SCR1(%a6) |use rz mode for rounding
  109. | ;implicitly has extend precision
  110. | ;in upper word.
  111. bras sintexc
  112. |
  113. | SINTDO
  114. |
  115. | Input: a0 points to an IEEE extended format operand
  116. | Output: fp0 has the result
  117. |
  118. | Exceptions:
  119. |
  120. | If the subroutine results in an inexact operation, the inx2 and
  121. | ainx bits in the USER_FPSR are set.
  122. |
  123. |
  124. .global sintdo
  125. sintdo:
  126. bfextu FPCR_MODE(%a6){#2:#2},%d1 |use user's mode for rounding
  127. | ;implicitly has ext precision
  128. | ;in upper word.
  129. movel %d1,L_SCR1(%a6) |save mode bits
  130. |
  131. | Real work of sint is in sintexc
  132. |
  133. sintexc:
  134. bclrb #sign_bit,LOCAL_EX(%a0) |convert to internal extended
  135. | ;format
  136. sne LOCAL_SGN(%a0)
  137. cmpw #0x403e,LOCAL_EX(%a0) |check if (unbiased) exp > 63
  138. bgts out_rnge |branch if exp < 63
  139. cmpw #0x3ffd,LOCAL_EX(%a0) |check if (unbiased) exp < 0
  140. bgt in_rnge |if 63 >= exp > 0, do calc
  141. |
  142. | Input is less than zero. Restore sign, and check for directed
  143. | rounding modes. L_SCR1 contains the rmode in the lower byte.
  144. |
  145. un_rnge:
  146. btstb #1,L_SCR1+3(%a6) |check for rn and rz
  147. beqs un_rnrz
  148. tstb LOCAL_SGN(%a0) |check for sign
  149. bnes un_rmrp_neg
  150. |
  151. | Sign is +. If rp, load +1.0, if rm, load +0.0
  152. |
  153. cmpib #3,L_SCR1+3(%a6) |check for rp
  154. beqs un_ldpone |if rp, load +1.0
  155. bsr ld_pzero |if rm, load +0.0
  156. bra t_inx2
  157. un_ldpone:
  158. bsr ld_pone
  159. bra t_inx2
  160. |
  161. | Sign is -. If rm, load -1.0, if rp, load -0.0
  162. |
  163. un_rmrp_neg:
  164. cmpib #2,L_SCR1+3(%a6) |check for rm
  165. beqs un_ldmone |if rm, load -1.0
  166. bsr ld_mzero |if rp, load -0.0
  167. bra t_inx2
  168. un_ldmone:
  169. bsr ld_mone
  170. bra t_inx2
  171. |
  172. | Rmode is rn or rz; return signed zero
  173. |
  174. un_rnrz:
  175. tstb LOCAL_SGN(%a0) |check for sign
  176. bnes un_rnrz_neg
  177. bsr ld_pzero
  178. bra t_inx2
  179. un_rnrz_neg:
  180. bsr ld_mzero
  181. bra t_inx2
  182. |
  183. | Input is greater than 2^63. All bits are significant. Return
  184. | the input.
  185. |
  186. out_rnge:
  187. bfclr LOCAL_SGN(%a0){#0:#8} |change back to IEEE ext format
  188. beqs intps
  189. bsetb #sign_bit,LOCAL_EX(%a0)
  190. intps:
  191. fmovel %fpcr,-(%sp)
  192. fmovel #0,%fpcr
  193. fmovex LOCAL_EX(%a0),%fp0 |if exp > 63
  194. | ;then return X to the user
  195. | ;there are no fraction bits
  196. fmovel (%sp)+,%fpcr
  197. rts
  198. in_rnge:
  199. | ;shift off fraction bits
  200. clrl %d0 |clear d0 - initial g,r,s for
  201. | ;dnrm_lp
  202. movel #0x403e,%d1 |set threshold for dnrm_lp
  203. | ;assumes a0 points to operand
  204. bsr dnrm_lp
  205. | ;returns unnormalized number
  206. | ;pointed by a0
  207. | ;output d0 supplies g,r,s
  208. | ;used by round
  209. movel L_SCR1(%a6),%d1 |use selected rounding mode
  210. |
  211. |
  212. bsr round |round the unnorm based on users
  213. | ;input a0 ptr to ext X
  214. | ; d0 g,r,s bits
  215. | ; d1 PREC/MODE info
  216. | ;output a0 ptr to rounded result
  217. | ;inexact flag set in USER_FPSR
  218. | ;if initial grs set
  219. |
  220. | normalize the rounded result and store value in fp0
  221. |
  222. bsr nrm_set |normalize the unnorm
  223. | ;Input: a0 points to operand to
  224. | ;be normalized
  225. | ;Output: a0 points to normalized
  226. | ;result
  227. bfclr LOCAL_SGN(%a0){#0:#8}
  228. beqs nrmrndp
  229. bsetb #sign_bit,LOCAL_EX(%a0) |return to IEEE extended format
  230. nrmrndp:
  231. fmovel %fpcr,-(%sp)
  232. fmovel #0,%fpcr
  233. fmovex LOCAL_EX(%a0),%fp0 |move result to fp0
  234. fmovel (%sp)+,%fpcr
  235. rts
  236. |end