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

VxWorks

开发平台:

C/C++

  1. /* x_snan.s - Motorola 68040 FP signalling NAN exception handler (EXC) */
  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,10jan92,kdl  added modification history; general cleanup.
  13. 01a,15aug91,kdl  original version, from Motorola FPSP v2.0.
  14. */
  15. /*
  16. DESCRIPTION
  17. x_snansa 3.2 4/26/91
  18.  fpsp_snan --- FPSP handler for signalling NAN exception
  19.  SNAN for float -> integer conversions (integer conversion of
  20.  an SNAN) is a non-maskable run-time exception.
  21.  For trap disabled the 040 does the following:
  22.  If the dest data format is s, d, or x, then the SNAN bit in the NAN
  23.  is set to one and the resulting non-signaling NAN (truncated if
  24.  necessary) is transferred to the dest.  If the dest format is b, w,
  25.  or l, then garbage is written to the dest (actually the upper 32 bits
  26.  of the mantissa are sent to the integer unit).
  27.  For trap enabled the 040 does the following:
  28.  If the inst is move_out, then the results are the same as for trap
  29.  disabled with the exception posted.  If the instruction is not move_
  30.  out, the dest. is not modified, and the exception is posted.
  31. Copyright (C) Motorola, Inc. 1990
  32. All Rights Reserved
  33. THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
  34. The copyright notice above does not evidence any
  35. actual or intended publication of such source code.
  36. X_SNAN idnt    2,1 Motorola 040 Floating Point Software Package
  37. section 8
  38. NOMANUAL
  39. */
  40. #include "fpsp040E.h"
  41. | xref __x_get_fline
  42. | xref __x_mem_write
  43. | xref __x_real_snan
  44. | xref __x_real_inex
  45. | xref __x_fpsp_done
  46. | xref __x_reg_dest
  47. | xref __x_check_force
  48. .text
  49. .globl __x_fpsp_snan
  50. __x_fpsp_snan:
  51. link a6,#-LOCAL_SIZE
  52. fsave a7@-
  53. moveml d0-d1/a0-a1,a6@(USER_DA)
  54. fmovemx fp0-fp3,a6@(USER_FP0)
  55. fmoveml fpcr/fpsr/fpi,a6@(USER_FPCR)
  56. | At this point we need to look at the instructions and see if it is one of
  57. | the force-precision ones (fsadd,fdadd,fssub,fdsub,fsmul,fdmul,fsdiv,fddiv,
  58. | fssqrt,fdsqrt,fsmove,fdmove,fsabs,fdabs,fsneg,fdneg).  If it is then
  59. | correct the USER_FPCR to the instruction rounding precision (s or d).
  60. | Also, we need to check if the instruction is fsgldiv or fsglmul.  If it
  61. | is then the USER_FPCR is set to extended rounding precision.  Otherwise
  62. | leave the USER_FPCR alone.
  63. | bsrl __x_check_force
  64. |
  65. | Check if trap enabled
  66. |
  67. btst #__x_snan_bit,a6@(fpcr_ENABLE)
  68. jne  ena | If enabled, then branch
  69. bsrl move_out | else SNAN disabled
  70. |
  71. | It is possible to have an inex1 exception with the
  72. | snan.  If the inex enable bit is set in the fpcr, and either
  73. | inex2 or inex1 occured, we must clean up and branch to the
  74. | real inex handler.
  75. |
  76. ck_inex:
  77. moveb a6@(fpcr_ENABLE),d0
  78. andb a6@(FPSR_EXCEPT),d0
  79. andib #0x3,d0
  80. jeq  end_snan
  81. |
  82. | Inexact enabled and reported, and we must take an inexact exception.
  83. |
  84. take_inex:
  85. moveb #INEX_VEC,a6@(EXC_VEC+1)
  86. moveml a6@(USER_DA),d0-d1/a0-a1
  87. fmovemx a6@(USER_FP0),fp0-fp3
  88. fmoveml a6@(USER_FPCR),fpcr/fpsr/fpi
  89. frestore a7@+
  90. unlk a6
  91. jra  __x_real_inex
  92. |
  93. | SNAN is enabled.  Check if inst is move_out.
  94. | Make any corrections to the 040 output as necessary.
  95. |
  96. ena:
  97. btst #5,a6@(CMDREG1B) | if set, inst is move out
  98. jeq  not_out
  99. bsrl move_out
  100. report_snan:
  101. moveb a7@,a6@(VER_TMP)
  102. cmpib #VER_40,a7@ | test for orig unimp frame
  103. jne  ck_rev
  104. moveql #13,d0 | need to zero 14 lwords
  105. jra  rep_con
  106. ck_rev:
  107. moveql #11,d0 | need to zero 12 lwords
  108. rep_con:
  109. clrl a7@
  110. loop1:
  111. clrl a7@- | clear and dec a7
  112. dbra d0,loop1
  113. moveb a6@(VER_TMP),a7@ | format a busy frame
  114. moveb #BUSY_SIZE-4,a7@(1)
  115. movel a6@(USER_FPSR),a6@(FPSR_SHADOW)
  116. orl #sx_mask,a6@(E_BYTE)
  117. moveml a6@(USER_DA),d0-d1/a0-a1
  118. fmovemx a6@(USER_FP0),fp0-fp3
  119. fmoveml a6@(USER_FPCR),fpcr/fpsr/fpi
  120. frestore a7@+
  121. unlk a6
  122. jra  __x_real_snan
  123. |
  124. | Exit snan handler by expanding the unimp frame into a busy frame
  125. |
  126. end_snan:
  127. bclr #E1,a6@(E_BYTE)
  128. moveb a7@,a6@(VER_TMP)
  129. cmpib #VER_40,a7@ | test for orig unimp frame
  130. jne  ck_rev2
  131. moveql #13,d0 | need to zero 14 lwords
  132. jra  rep_con2
  133. ck_rev2:
  134. moveql #11,d0 | need to zero 12 lwords
  135. rep_con2:
  136. clrl a7@
  137. loop2:
  138. clrl a7@- | clear and dec a7
  139. dbra d0,loop2
  140. moveb a6@(VER_TMP),a7@ | format a busy frame
  141. moveb #BUSY_SIZE-4,a7@(1) | write busy size
  142. movel a6@(USER_FPSR),a6@(FPSR_SHADOW)
  143. orl #sx_mask,a6@(E_BYTE)
  144. moveml a6@(USER_DA),d0-d1/a0-a1
  145. fmovemx a6@(USER_FP0),fp0-fp3
  146. fmoveml a6@(USER_FPCR),fpcr/fpsr/fpi
  147. frestore a7@+
  148. unlk a6
  149. jra  __x_fpsp_done
  150. |
  151. | Move_out
  152. |
  153. move_out:
  154. movel a6@(EXC_EA),a0 | get <ea> from exc frame
  155. bfextu a6@(CMDREG1B){#3:#3},d0 | move rx field to d0{2:0}
  156. cmpil #0,d0 | check for long
  157. jeq  sto_long | branch if move_out long
  158. cmpil #4,d0 | check for word
  159. jeq  sto_word | branch if move_out word
  160. cmpil #6,d0 | check for byte
  161. jeq  sto_byte | branch if move_out byte
  162. |
  163. | Not byte, word or long
  164. |
  165. rts
  166. |
  167. | Get the 32 most significant bits of etemp mantissa
  168. |
  169. sto_long:
  170. movel a6@(ETEMP_HI),d1
  171. movel #4,d0 | load byte count
  172. |
  173. | Set signalling nan bit
  174. |
  175. bset #30,d1
  176. |
  177. | Store to the users destination address
  178. |
  179. tstl a0 | check if <ea> is 0
  180. jeq  wrt_dn | destination is a data register
  181. movel d1,a7@- | move the snan onto the stack
  182. movel a0,a1 | load dest addr into a1
  183. movel a7,a0 | load src addr of snan into a0
  184. bsrl __x_mem_write | write snan to user memory
  185. movel a7@+,d1 | clear off stack
  186. rts
  187. |
  188. | Get the 16 most significant bits of etemp mantissa
  189. |
  190. sto_word:
  191. movel a6@(ETEMP_HI),d1
  192. movel #2,d0 | load byte count
  193. |
  194. | Set signalling nan bit
  195. |
  196. bset #30,d1
  197. |
  198. | Store to the users destination address
  199. |
  200. tstl a0 | check if <ea> is 0
  201. jeq  wrt_dn | destination is a data register
  202. movel d1,a7@- | move the snan onto the stack
  203. movel a0,a1 | load dest addr into a1
  204. movel a7,a0 | point to low word
  205. bsrl __x_mem_write | write snan to user memory
  206. movel a7@+,d1 | clear off stack
  207. rts
  208. |
  209. | Get the 8 most significant bits of etemp mantissa
  210. |
  211. sto_byte:
  212. movel a6@(ETEMP_HI),d1
  213. movel #1,d0 | load byte count
  214. |
  215. | Set signalling nan bit
  216. |
  217. bset #30,d1
  218. |
  219. | Store to the users destination address
  220. |
  221. tstl a0 | check if <ea> is 0
  222. jeq  wrt_dn | destination is a data register
  223. movel d1,a7@- | move the snan onto the stack
  224. movel a0,a1 | load dest addr into a1
  225. movel a7,a0 | point to source byte
  226. bsrl __x_mem_write | write snan to user memory
  227. movel a7@+,d1 | clear off stack
  228. rts
  229. |
  230. | wrt_dn --- write to a data register
  231. |
  232. | We get here with D1 containing the data to write and D0 the
  233. | number of bytes to write: 1=byte,2=word,4=long.
  234. |
  235. wrt_dn:
  236. movel d1,a6@(L_SCR1) | data
  237. movel d0,a7@- | size
  238. bsrl __x_get_fline | returns fline word in d0
  239. movel d0,d1
  240. andil #0x7,d1 | d1 now holds register number
  241. movel a7@+,d0 | get original size
  242. cmpil #4,d0
  243. jeq  wrt_long
  244. cmpil #2,d0
  245. jne  wrt_byte
  246. wrt_word:
  247. orl #0x8,d1
  248. jra  __x_reg_dest
  249. wrt_long:
  250. orl #0x10,d1
  251. jra  __x_reg_dest
  252. wrt_byte:
  253. jra  __x_reg_dest
  254. |
  255. | Check if it is a src nan or dst nan
  256. |
  257. not_out:
  258. movel a6@(DTAG),d0
  259. bfextu d0{#0:#3},d0 | isolate dtag in lsbs
  260. cmpib #3,d0 | check for nan in destination
  261. jne  issrc | destination nan has priority
  262. __x_dst_nan:
  263. btst #6,a6@(FPTEMP_HI) | check if dest nan is an snan
  264. jne  issrc | no, so check source for snan
  265. movew a6@(FPTEMP_EX),d0
  266. jra  cont
  267. issrc:
  268. movew a6@(ETEMP_EX),d0
  269. cont:
  270. btst #15,d0 | test for sign of snan
  271. jeq  clr_neg
  272. bset #neg_bit,a6@(FPSR_CC)
  273. jra  report_snan
  274. clr_neg:
  275. bclr #neg_bit,a6@(FPSR_CC)
  276. jra  report_snan
  277. | end