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

VxWorks

开发平台:

C/C++

  1. /* kernel_ex.s - Motorola 68040 FP exception routines (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. kernel_exsa 3.3 12/19/90
  18. This file contains routines to force exception status in the
  19. fpu for exceptional cases detected or reported within the
  20. transcendental functions.  Typically, the t_xx routine will
  21. set the appropriate bits in the USER_FPSR word on the stack.
  22. The bits are tested in __x_gen_exceptsa to determine if an exceptional
  23. situation needs to be created on return from the FPSP.
  24. Copyright (C) Motorola, Inc. 1990
  25. All Rights Reserved
  26. THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
  27. The copyright notice above does not evidence any
  28. actual or intended publication of such source code.
  29. KERNEL_EX    idnt    2,1 Motorola 040 Floating Point Software Package
  30. section    8
  31. NOMANUAL
  32. */
  33. #include "fpsp040E.h"
  34. mns_inf:  .long 0xffff0000,0x00000000,0x00000000
  35. pls_inf:  .long 0x7fff0000,0x00000000,0x00000000
  36. nan:      .long 0x7fff0000,0xffffffff,0xffffffff
  37. huge:     .long 0x7ffe0000,0xffffffff,0xffffffff
  38. | xref   __x_ovf_r_k
  39. | xref   __x_unf_sub
  40. | xref   __x_nrm_set
  41. .globl    __x_t_dz
  42. .globl    __x_t_dz2
  43. .globl    __x_t_operr
  44. .globl    __x_t_unfl
  45. .globl    __x_t_ovfl
  46. .globl    __x_t_ovfl2
  47. .globl    __x_t_inx2
  48. .globl   __x_t_frcinx
  49. .globl   __x_t_extdnrm
  50. .globl   __x_t_resdnrm
  51. .globl   __x_dst_nan
  52. .globl   __x_src_nan
  53. .text
  54. |
  55. | DZ exception
  56. |
  57. |
  58. | if dz trap disabled
  59. | store properly signed inf (use sign of etemp) into fp0
  60. | set FPSR exception status dz bit, condition code
  61. | inf bit, and accrued dz bit
  62. | return
  63. | frestore the frame into the machine (done by unimp_hd)
  64. |
  65. | else dz trap enabled
  66. | set exception status bit # accrued bits in FPSR
  67. | set flag to disable __x_sto_res from corrupting fp register
  68. | return
  69. | frestore the frame into the machine (done by unimp_hd)
  70. |
  71. | __x_t_dz2 is used by monadic functions such as flogn (from __x_do_func).
  72. | __x_t_dz is used by monadic functions such as __x_satanh (from the
  73. | transcendental function).
  74. |
  75. __x_t_dz2:
  76. bset #neg_bit,a6@(FPSR_CC) | set neg bit in FPSR
  77. fmovel #0,FPSR | clr status bits (Z set)
  78. btst #__x_dz_bit,a6@(fpcr_ENABLE) | test fpcr for dz exc enabled
  79. jne  __x_dz_ena_end
  80. jra  m_inf | flogx always returns -inf
  81. __x_t_dz:
  82. fmovel #0,FPSR | clr status bits (Z set)
  83. btst #__x_dz_bit,a6@(fpcr_ENABLE) | test fpcr for dz exc enabled
  84. jne  __x_dz_ena
  85. |
  86. | __x_dz disabled
  87. |
  88. btst #sign_bit,a6@(ETEMP_EX) | check sign for neg or pos
  89. jeq  p_inf | branch if pos sign
  90. m_inf:
  91. fmovemx mns_inf,fp0-fp0 | load -inf
  92. bset #neg_bit,a6@(FPSR_CC) | set neg bit in FPSR
  93. jra  set_fpsr
  94. p_inf:
  95. fmovemx pls_inf,fp0-fp0 | load +inf
  96. set_fpsr:
  97. orl #__x_dzinf_mask,a6@(USER_FPSR) | set I,DZ,ADZ
  98. rts
  99. |
  100. | __x_dz enabled
  101. |
  102. __x_dz_ena:
  103. btst #sign_bit,a6@(ETEMP_EX) | check sign for neg or pos
  104. jeq  __x_dz_ena_end
  105. bset #neg_bit,a6@(FPSR_CC) | set neg bit in FPSR
  106. __x_dz_ena_end:
  107. orl #__x_dzinf_mask,a6@(USER_FPSR) | set I,DZ,ADZ
  108. st a6@(STORE_FLG)
  109. rts
  110. |
  111. | OPERR exception
  112. |
  113. | if (operr trap disabled)
  114. | set FPSR exception status operr bit, condition code
  115. | nan bit|  Store default NAN into fp0
  116. | frestore the frame into the machine (done by unimp_hd)
  117. |
  118. | else (operr trap enabled)
  119. | set FPSR exception status operr bit, accrued operr bit
  120. | set flag to disable __x_sto_res from corrupting fp register
  121. | frestore the frame into the machine (done by unimp_hd)
  122. |
  123. __x_t_operr:
  124. orl #opnan_mask,a6@(USER_FPSR) | set NaN, OPERR, AIOP
  125. btst #__x_operr_bit,a6@(fpcr_ENABLE) | test fpcr for operr enabled
  126. jne  op_ena
  127. fmovemx nan,fp0-fp0 | load default nan
  128. rts
  129. op_ena:
  130. st a6@(STORE_FLG) | do not corrupt destination
  131. rts
  132. |
  133. | __x_t_unfl --- UNFL exception
  134. |
  135. | This entry point is used by all routines requiring unfl, inex2,
  136. | aunfl, and ainex to be set on exit.
  137. |
  138. | On entry, a0 points to the exceptional operand.  The final exceptional
  139. | operand is built in FP_SCR1 and only the sign from the original operand
  140. | is used.
  141. |
  142. __x_t_unfl:
  143. clrl a6@(FP_SCR1) | set exceptional operand to zero
  144. clrl a6@(FP_SCR1+4)
  145. clrl a6@(FP_SCR1+8)
  146. tstb a0@ /* | extract sign from caller's exop */
  147. jpl  __x_unfl_signok
  148. bset #sign_bit,a6@(FP_SCR1)
  149. __x_unfl_signok:
  150. lea a6@(FP_SCR1),a0
  151. orl #unfinx_mask,a6@(USER_FPSR)
  152. | | set UNFL, INEX2, AUNFL, AINEX
  153. __x_unfl_con:
  154. btst #__x_unfl_bit,a6@(fpcr_ENABLE)
  155. jeq  __x_unfl_dis
  156. __x_unfl_ena:
  157. bfclr a6@(STAG){#5:#3} | clear wbtm66,wbtm1,wbtm0
  158. bset #wbtemp15_bit,a6@(WB_BYTE) | set wbtemp15
  159. bset #sticky_bit,a6@(STICKY) | set sticky bit
  160. bclr #E1,a6@(E_BYTE)
  161. __x_unfl_dis:
  162. bfextu a6@(fpcr_MODE){#0:#2},d0 | get round precision
  163. bclr #sign_bit,a0@(LOCAL_EX)
  164. sne a0@(LOCAL_SGN) | convert to internal ext format
  165. bsrl __x_unf_sub | returns IEEE result at a0
  166. | | and sets FPSR_CC accordingly
  167. bfclr a0@(LOCAL_SGN){#0:#8} | convert back to IEEE ext format
  168. jeq  __x_unfl_fin
  169. bset #sign_bit,a0@(LOCAL_EX)
  170. bset #sign_bit,a6@(FP_SCR1) | set sign bit of exc operand
  171. __x_unfl_fin:
  172. fmovemx a0@,fp0-fp0 | store result in fp0
  173. rts
  174. |
  175. | __x_t_ovfl2 --- OVFL exception (without inex2 returned)
  176. |
  177. | This entry is used by scale to force catastrophic overflow.  The
  178. | ovfl, aovfl, and ainex bits are set, but not the inex2 bit.
  179. |
  180. __x_t_ovfl2:
  181. orl #__x_ovfl_inx_mask,a6@(USER_FPSR)
  182. movel a6@(ETEMP),a6@(FP_SCR1)
  183. movel a6@(ETEMP_HI),a6@(FP_SCR1+4)
  184. movel a6@(ETEMP_LO),a6@(FP_SCR1+8)
  185. |
  186. | Check for single or double round precision.  If single, check if
  187. | the lower 40 bits of ETEMP are zero|  if not, set inex2.  If double,
  188. | check if the lower 21 bits are zero|  if not, set inex2.
  189. |
  190. moveb a6@(fpcr_MODE),d0
  191. andib #0xc0,d0
  192. jeq  t_work | if extended, finish ovfl processing
  193. cmpib #0x40,d0 | test for single
  194. jne  t_dbl
  195. t_sgl:
  196. tstb a6@(ETEMP_LO)
  197. jne  t_setinx2
  198. movel a6@(ETEMP_HI),d0
  199. andil #0xff,d0 | look at only lower 8 bits
  200. jne  t_setinx2
  201. jra  t_work
  202. t_dbl:
  203. movel a6@(ETEMP_LO),d0
  204. andil #0x7ff,d0 | look at only lower 11 bits
  205. jeq  t_work
  206. t_setinx2:
  207. orl #__x_inex2_mask,a6@(USER_FPSR)
  208. jra  t_work
  209. |
  210. | __x_t_ovfl --- OVFL exception
  211. |
  212. |** Note: the exc operand is returned in ETEMP.
  213. |
  214. __x_t_ovfl:
  215. orl #ovfinx_mask,a6@(USER_FPSR)
  216. t_work:
  217. btst #__x_ovfl_bit,a6@(fpcr_ENABLE) | test fpcr for ovfl enabled
  218. jeq  ovf_dis
  219. ovf_ena:
  220. clrl a6@(FP_SCR1) | set exceptional operand
  221. clrl a6@(FP_SCR1+4)
  222. clrl a6@(FP_SCR1+8)
  223. bfclr a6@(STAG){#5:#3} | clear wbtm66,wbtm1,wbtm0
  224. bclr #wbtemp15_bit,a6@(WB_BYTE) | clear wbtemp15
  225. bset #sticky_bit,a6@(STICKY) | set sticky bit
  226. bclr #E1,a6@(E_BYTE)
  227. | | fall through to disabled case
  228. /* | For disabled overflow call 'ovf_r_k'.  This routine loads the */
  229. | correct result based on the rounding precision, destination
  230. | format, rounding mode and sign.
  231. |
  232. ovf_dis:
  233. bsrl __x_ovf_r_k | returns unsigned ETEMP_EX
  234. | | and sets FPSR_CC accordingly.
  235. bfclr a6@(ETEMP_SGN){#0:#8} | fix sign
  236. jeq  ovf_pos
  237. bset #sign_bit,a6@(ETEMP_EX)
  238. bset #sign_bit,a6@(FP_SCR1) | set exceptional operand sign
  239. ovf_pos:
  240. fmovemx a6@(ETEMP),fp0-fp0 | move the result to fp0
  241. rts
  242. |
  243. | INEX2 exception
  244. |
  245. | The inex2 and ainex bits are set.
  246. |
  247. __x_t_inx2:
  248. orl #inx2a_mask,a6@(USER_FPSR) | set INEX2, AINEX
  249. rts
  250. |
  251. | Force Inex2
  252. |
  253. | This routine is called by the transcendental routines to force
  254. | the inex2 exception bits set in the FPSR.  If the underflow bit
  255. | is set, but the underflow trap was not taken, the aunfl bit in
  256. | the FPSR must be set.
  257. |
  258. __x_t_frcinx:
  259. orl #inx2a_mask,a6@(USER_FPSR) | set INEX2, AINEX
  260. btst #__x_unfl_bit,a6@(FPSR_EXCEPT) | test for unfl bit set
  261. jeq  no_uacc1 | if clear, do not set aunfl
  262. bset #aunfl_bit,a6@(FPSR_AEXCEPT)
  263. no_uacc1:
  264. rts
  265. |
  266. | DST_NAN
  267. |
  268. | Determine if the destination nan is signalling or non-signalling,
  269. /* | and set the FPSR bits accordingly.  See the MC68040 User's Manual  */
  270. |* section 3.2.2.5 NOT-A-NUMBERS.
  271. |
  272. __x_dst_nan:
  273. btst #sign_bit,a6@(FPTEMP_EX) | test sign of nan
  274. jeq  dst_pos | if clr, it was positive
  275. bset #neg_bit,a6@(FPSR_CC) | set N bit
  276. dst_pos:
  277. btst #signan_bit,a6@(FPTEMP_HI) | check if signalling
  278. jeq  dst_snan | branch if signalling
  279. fmovel d1,fpcr /* | restore user's rmode/prec */
  280. fmovex a6@(FPTEMP),fp0 | return the non-signalling nan
  281. |
  282. | Check the source nan.  If it is signalling, snan will be reported.
  283. |
  284. moveb a6@(STAG),d0
  285. andib #0xe0,d0
  286. cmpib #0x60,d0
  287. jne  no_snan
  288. btst #signan_bit,a6@(ETEMP_HI) | check if signalling
  289. jne  no_snan
  290. orl #__x_snaniop_mask,a6@(USER_FPSR) | set NAN, SNAN, AIOP
  291. no_snan:
  292. rts
  293. dst_snan:
  294. btst #__x_snan_bit,a6@(fpcr_ENABLE) | check if trap enabled
  295. jeq  dst_dis | branch if disabled
  296. orb #nan_tag,a6@(DTAG) | set up dtag for nan
  297. st a6@(STORE_FLG) | do not store a result
  298. orl #__x_snaniop_mask,a6@(USER_FPSR) | set NAN, SNAN, AIOP
  299. rts
  300. dst_dis:
  301. bset #signan_bit,a6@(FPTEMP_HI) | set SNAN bit in sop
  302. fmovel d1,fpcr /* | restore user's rmode/prec */
  303. fmovex a6@(FPTEMP),fp0 | load non-sign. nan
  304. orl #__x_snaniop_mask,a6@(USER_FPSR) | set NAN, SNAN, AIOP
  305. rts
  306. |
  307. | SRC_NAN
  308. |
  309. | Determine if the source nan is signalling or non-signalling,
  310. /* | and set the FPSR bits accordingly.  See the MC68040 User's Manual  */
  311. |* section 3.2.2.5 NOT-A-NUMBERS.
  312. |
  313. __x_src_nan:
  314. btst #sign_bit,a6@(ETEMP_EX) | test sign of nan
  315. jeq  src_pos | if clr, it was positive
  316. bset #neg_bit,a6@(FPSR_CC) | set N bit
  317. src_pos:
  318. btst #signan_bit,a6@(ETEMP_HI) | check if signalling
  319. jeq  src_snan | branch if signalling
  320. fmovel d1,fpcr /* | restore user's rmode/prec */
  321. fmovex a6@(ETEMP),fp0 | return the non-signalling nan
  322. rts
  323. src_snan:
  324. btst #__x_snan_bit,a6@(fpcr_ENABLE) | check if trap enabled
  325. jeq  src_dis | branch if disabled
  326. bset #signan_bit,a6@(ETEMP_HI) | set SNAN bit in sop
  327. orb #__x_norm_tag,a6@(DTAG) | set up dtag for __x_norm
  328. orb #nan_tag,a6@(STAG) | set up stag for nan
  329. st a6@(STORE_FLG) | do not store a result
  330. orl #__x_snaniop_mask,a6@(USER_FPSR) | set NAN, SNAN, AIOP
  331. rts
  332. src_dis:
  333. bset #signan_bit,a6@(ETEMP_HI) | set SNAN bit in sop
  334. fmovel d1,fpcr /* | restore user's rmode/prec */
  335. fmovex a6@(ETEMP),fp0 | load non-sign. nan
  336. orl #__x_snaniop_mask,a6@(USER_FPSR) | set NAN, SNAN, AIOP
  337. rts
  338. |
  339. | For all functions that have a denormalized input and that f(x)=x,
  340. | this is the entry point
  341. |
  342. __x_t_extdnrm:
  343. orl #unfinx_mask,a6@(USER_FPSR)
  344. | | set UNFL, INEX2, AUNFL, AINEX
  345. jra  xdnrm_con
  346. |
  347. | Entry point for scale with extended denorm.  The function does
  348. | not set inex2, aunfl, or ainex.
  349. |
  350. __x_t_resdnrm:
  351. orl #__x_unfl_mask,a6@(USER_FPSR)
  352. xdnrm_con:
  353. btst #__x_unfl_bit,a6@(fpcr_ENABLE)
  354. jeq  xdnrm_dis
  355. |
  356. | If exceptions are enabled, the additional task of setting up WBTEMP
  357. | is needed so that when the underflow exception handler is entered,
  358. | the user perceives no difference between what the 040 provides vs.
  359. | what the FPSP provides.
  360. |
  361. xdnrm_ena:
  362. movel a0,a7@-
  363. movel a0@(LOCAL_EX),a6@(FP_SCR1)
  364. movel a0@(LOCAL_HI),a6@(FP_SCR1+4)
  365. movel a0@(LOCAL_LO),a6@(FP_SCR1+8)
  366. lea a6@(FP_SCR1),a0
  367. bclr #sign_bit,a0@(LOCAL_EX)
  368. sne a0@(LOCAL_SGN) | convert to internal ext format
  369. tstw a0@(LOCAL_EX) | check if input is denorm
  370. jeq  xdnrm_dn | if so, skip __x_nrm_set
  371. bsrl __x_nrm_set | normalize the result (exponent
  372. | | will be negative
  373. xdnrm_dn:
  374. bclr #sign_bit,a0@(LOCAL_EX) | take off false sign
  375. bfclr a0@(LOCAL_SGN){#0:#8} | change back to IEEE ext format
  376. jeq  xdep
  377. bset #sign_bit,a0@(LOCAL_EX)
  378. xdep:
  379. bfclr a6@(STAG){#5:#3} | clear wbtm66,wbtm1,wbtm0
  380. bset #wbtemp15_bit,a6@(WB_BYTE) | set wbtemp15
  381. bclr #sticky_bit,a6@(STICKY) | clear sticky bit
  382. bclr #E1,a6@(E_BYTE)
  383. movel a7@+,a0
  384. xdnrm_dis:
  385. bfextu a6@(fpcr_MODE){#0:#2},d0 | get round precision
  386. jne  not_ext | if not round extended, store
  387. | | IEEE defaults
  388. is_ext:
  389. btst #sign_bit,a0@(LOCAL_EX)
  390. jeq  xdnrm_store
  391. bset #neg_bit,a6@(FPSR_CC) | set N bit in FPSR_CC
  392. jra  xdnrm_store
  393. not_ext:
  394. bclr #sign_bit,a0@(LOCAL_EX)
  395. sne a0@(LOCAL_SGN) | convert to internal ext format
  396. bsrl __x_unf_sub | returns IEEE result pointed by
  397. | | a0|  sets FPSR_CC accordingly
  398. bfclr a0@(LOCAL_SGN){#0:#8} | convert back to IEEE ext format
  399. jeq  xdnrm_store
  400. bset #sign_bit,a0@(LOCAL_EX)
  401. xdnrm_store:
  402. fmovemx a0@,fp0-fp0 | store result in fp0
  403. rts
  404. |
  405. | This subroutine is used for dyadic operations that use an extended
  406. | denorm within the kernel. The approach used is to capture the frame,
  407. | fix/restore.
  408. |
  409. .globl __x_t_avoid_unsupp
  410. __x_t_avoid_unsupp:
  411. link a2,#-LOCAL_SIZE | so that a2 fpsp040E.h negative
  412. | | offsets may be used
  413. fsave a7@-
  414. tstb a7@(1) | check if idle, exit if so
  415. jeq  idle_end
  416. btst #E1,a2@(E_BYTE) | check for an E1 exception if
  417. | | enabled, there is an unsupp
  418. jeq  end_avun | else, exit
  419. btst #7,a2@(DTAG) | check for denorm destination
  420. jeq  src_den | else, must be a source denorm
  421. |
  422. | handle destination denorm
  423. |
  424. lea a2@(FPTEMP),a0
  425. btst #sign_bit,a0@(LOCAL_EX)
  426. sne a0@(LOCAL_SGN) | convert to internal ext format
  427. bclr #7,a2@(DTAG) | set DTAG to norm
  428. bsrl __x_nrm_set | normalize result, exponent
  429. | | will become negative
  430. bclr #sign_bit,a0@(LOCAL_EX) | get rid of fake sign
  431. bfclr a0@(LOCAL_SGN){#0:#8} | convert back to IEEE ext format
  432. jeq  ck_src_den | check if source is also denorm
  433. bset #sign_bit,a0@(LOCAL_EX)
  434. ck_src_den:
  435. btst #7,a2@(STAG)
  436. jeq  end_avun
  437. src_den:
  438. lea a2@(ETEMP),a0
  439. btst #sign_bit,a0@(LOCAL_EX)
  440. sne a0@(LOCAL_SGN) | convert to internal ext format
  441. bclr #7,a2@(STAG) | set STAG to norm
  442. bsrl __x_nrm_set | normalize result, exponent
  443. | | will become negative
  444. bclr #sign_bit,a0@(LOCAL_EX) | get rid of fake sign
  445. bfclr a0@(LOCAL_SGN){#0:#8} | convert back to IEEE ext format
  446. jeq  den_com
  447. bset #sign_bit,a0@(LOCAL_EX)
  448. den_com:
  449. moveb #0xfe,a2@(CU_SAVEPC) | set continue frame
  450. clrw a2@(NMNEXC) | clear NMNEXC
  451. bclr #E1,a2@(E_BYTE)
  452. | fmovel FPSR,a2@(FPSR_SHADOW)
  453. | bset #SFLAG,a2@(E_BYTE)
  454. | bset #XFLAG,a2@(T_BYTE)
  455. end_avun:
  456. frestore a7@+
  457. unlk a2
  458. rts
  459. idle_end:
  460. addl #4,a7
  461. unlk a2
  462. rts
  463. | end