l_sint.s
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:6k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* l_sint.s - Motorola 68040 FP integer routines (LIB) */
  2. /* Copyright 1991-1993 Wind River Systems, Inc. */
  3. .data
  4. .globl _copyright_wind_river
  5. .long _copyright_wind_river
  6. /*
  7. modification history
  8. --------------------
  9. 01e,21jul93,kdl  added .text (SPR #2372).
  10. 01d,23aug92,jcf  changed bxxx to jxx.
  11. 01c,26may92,rrr  the tree shuffle
  12. 01b,09jan92,kdl  added modification history; general cleanup.
  13. 01a,15aug91,kdl  original version, from Motorola FPSP v2.0.
  14. */
  15. /*
  16. DESCRIPTION
  17. sintsa 3.1 12/10/90
  18. The entry point sINT computes the rounded integer
  19. equivalent of the input argument, sINTRZ computes
  20. the integer rounded to zero of the input argument.
  21. Entry points __l_sint and __l_sintrz are called from __l_do_func
  22. to emulate the fint and fintrz unimplemented instructions,
  23. respectively.  Entry point __l_sintdo is used by __l_bindec.
  24. Input: (Entry points __l_sint and __l_sintrz) Double-extended
  25. number X in the ETEMP space in the floating-point
  26. save stack.
  27.        (Entry point __l_sintdo) Double-extended number X in
  28. location pointed to by the address register a0.
  29.        (Entry point __l_sintd) Double-extended denormalized
  30. number X in the ETEMP space in the floating-point
  31. save stack.
  32. Output: The function returns int(X) or intrz(X) in fp0.
  33. Modifies: fp0.
  34. Algorithm: (sint and __l_sintrz)
  35. 1. If exp(X) >= 63, return X.
  36.    If exp(X) < 0, return +/- 0 or +/- 1, according to
  37.    the rounding mode.
  38. 2. (X is in range) set rsc = 63 - exp(X). Unnormalize the
  39.    result to the exponent 0x403e.
  40. 3. Round the result in the mode given in USER_FPCR. For
  41.    __l_sintrz, force round-to-zero mode.
  42. 4. Normalize the rounded result; store in fp0.
  43. For the denormalized cases, force the correct result
  44. for the given sign and rounding mode.
  45.         Sign(X)
  46. RMODE   +    -
  47. -----  --------
  48.  RN    +0   -0
  49.  RZ    +0   -0
  50.  RM    +0   -1
  51.  RP    +1   -0
  52. Copyright (C) Motorola, Inc. 1990
  53. All Rights Reserved
  54. THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
  55. The copyright notice above does not evidence any
  56. actual or intended publication of such source code.
  57. SINT    idnt    2,1 Motorola 040 Floating Point Software Package
  58. section 8
  59. NOMANUAL
  60. */
  61. #include "fpsp040L.h"
  62. | xref __l_dnrm_lp
  63. | xref __l_nrm_set
  64. | xref __l_round
  65. | xref __l_t_inx2
  66. | xref __l_ld_pone
  67. | xref __l_ld_mone
  68. | xref __l_ld_pzero
  69. | xref __l_ld_mzero
  70. | xref __l_snzrinx
  71. |
  72. | FINT
  73. |
  74. .text
  75. .globl __l_sint
  76. __l_sint:
  77. bfextu a6@(fpcr_MODE){#2:#2},d1  /* | use user's mode for rounding */
  78. | | implicity has extend precision
  79. | | in upper word.
  80. movel d1,a6@(L_SCR1) | save mode bits
  81. jra  __l_sintexc
  82. |
  83. | FINT with extended denorm inputs.
  84. |
  85. .globl __l_sintd
  86. __l_sintd:
  87. btst #5,a6@(fpcr_MODE)
  88. jeq  __l_snzrinx | if round nearest or round zero, +/- 0
  89. btst #4,a6@(fpcr_MODE)
  90. jeq  rnd_mns
  91. rnd_pls:
  92. btst #sign_bit,a0@(LOCAL_EX)
  93. jne  __l_sintmz
  94. bsrl __l_ld_pone | if round plus inf and pos, answer = +1
  95. jra  __l_t_inx2
  96. rnd_mns:
  97. btst #sign_bit,a0@(LOCAL_EX)
  98. jeq  __l_sintpz
  99. bsrl __l_ld_mone | if round mns inf and neg, answer is -1
  100. jra  __l_t_inx2
  101. __l_sintpz:
  102. bsrl __l_ld_pzero
  103. jra  __l_t_inx2
  104. __l_sintmz:
  105. bsrl __l_ld_mzero
  106. jra  __l_t_inx2
  107. |
  108. | FINTRZ
  109. |
  110. .globl __l_sintrz
  111. __l_sintrz:
  112. movel #1,a6@(L_SCR1) | use rz mode for rounding
  113. | | implicity has extend precision
  114. | | in upper word.
  115. jra  __l_sintexc
  116. |
  117. | SINTDO
  118. |
  119. | Input: a0 points to an IEEE extended format operand
  120. |  Output: fp0 has the result
  121. |
  122. | Exeptions:
  123. |
  124. | If the subroutine results in an inexact operation, the inx2 and
  125. | ainx bits in the USER_FPSR are set.
  126. |
  127. |
  128. .globl __l_sintdo
  129. __l_sintdo:
  130. bfextu a6@(fpcr_MODE){#2:#2},d1  /* | use user's mode for rounding */
  131. | | implicitly has ext precision
  132. | | in upper word.
  133. movel d1,a6@(L_SCR1) | save mode bits
  134. |
  135. | Real work of __l_sint is in __l_sintexc
  136. |
  137. __l_sintexc:
  138. bclr #sign_bit,a0@(LOCAL_EX) | convert to internal extended
  139. | | format
  140. sne a0@(LOCAL_SGN)
  141. cmpw #0x403e,a0@(LOCAL_EX) | check if (unbiased) exp > 63
  142. jgt  out_rnge | branch if exp < 63
  143. cmpw #0x3ffd,a0@(LOCAL_EX) | check if (unbiased) exp < 0
  144. jgt  in_rnge | if 63 >= exp > 0, do calc
  145. |
  146. | Input is less than zero.  Restore sign, and check for directed
  147. | rounding modes.  L_SCR1 contains the rmode in the lower byte.
  148. |
  149. un_rnge:
  150. btst #1,a6@(L_SCR1+3) | check for rn and rz
  151. jeq  un_rnrz
  152. tstb a0@(LOCAL_SGN) | check for sign
  153. jne  un_rmrp_neg
  154. |
  155. | Sign is +.  If rp, load +1.0, if rm, load +0.0
  156. |
  157. cmpib #3,a6@(L_SCR1+3) | check for rp
  158. jeq  un_ldpone | if rp, load +1.0
  159. bsrl __l_ld_pzero | if rm, load +0.0
  160. jra  __l_t_inx2
  161. un_ldpone:
  162. bsrl __l_ld_pone
  163. jra  __l_t_inx2
  164. |
  165. | Sign is -.  If rm, load -1.0, if rp, load -0.0
  166. |
  167. un_rmrp_neg:
  168. cmpib #2,a6@(L_SCR1+3) | check for rm
  169. jeq  un_ldmone | if rm, load -1.0
  170. bsrl __l_ld_mzero | if rp, load -0.0
  171. jra  __l_t_inx2
  172. un_ldmone:
  173. bsrl __l_ld_mone
  174. jra  __l_t_inx2
  175. |
  176. | Rmode is rn or rz|  return signed zero
  177. |
  178. un_rnrz:
  179. tstb a0@(LOCAL_SGN) | check for sign
  180. jne  un_rnrz_neg
  181. bsrl __l_ld_pzero
  182. jra  __l_t_inx2
  183. un_rnrz_neg:
  184. bsrl __l_ld_mzero
  185. jra  __l_t_inx2
  186. |
  187. | Input is greater than 2^63.  All bits are significant.  Return
  188. | the input.
  189. |
  190. out_rnge:
  191. bfclr a0@(LOCAL_SGN){#0:#8} | change back to IEEE ext format
  192. jeq  intps
  193. bset #sign_bit,a0@(LOCAL_EX)
  194. intps:
  195. fmovel fpcr,a7@-
  196. fmovel #0,fpcr
  197. fmovex a0@(LOCAL_EX),fp0 | if exp > 63
  198. | | then return X to the user
  199. | | there are no fraction bits
  200. fmovel a7@+,fpcr
  201. rts
  202. in_rnge:
  203. |  | shift off fraction bits
  204. clrl d0 | clear d0 - initial g,r,s for
  205. | | dnrm_lp
  206. movel #0x403e,d1 | set threshold for __l_dnrm_lp
  207. | | assumes a0 points to operand
  208. bsrl __l_dnrm_lp
  209. | | returns unnormalized number
  210. | | pointed by a0
  211. | | output d0 supplies g,r,s
  212. | | used by __l_round
  213. movel a6@(L_SCR1),d1 | use selected rounding mode
  214. |
  215. |
  216. bsrl __l_round | round the unnorm based on users
  217. | | input a0 ptr to ext X
  218. | |  d0 g,r,s bits
  219. | |  d1 PREC/MODE info
  220. | | output a0 ptr to rounded result
  221. | | inexact flag set in USER_FPSR
  222. | | if initial grs set
  223. |
  224. | normalize the rounded result and store value in fp0
  225. |
  226. bsrl __l_nrm_set | normalize the unnorm
  227. | | Input: a0 points to operand to
  228. | | be normalized
  229. | | Output: a0 points to normalized
  230. | | result
  231. bfclr a0@(LOCAL_SGN){#0:#8}
  232. jeq  nrmrndp
  233. bset #sign_bit,a0@(LOCAL_EX) | return to IEEE extended format
  234. nrmrndp:
  235. fmovel fpcr,a7@-
  236. fmovel #0,fpcr
  237. fmovex a0@(LOCAL_EX),fp0 | move result to fp0
  238. fmovel a7@+,fpcr
  239. rts
  240. | end