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

VxWorks

开发平台:

C/C++

  1. /* l_support.s - Motorola 68040 FP support 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,10jan92,kdl  added modification history; general cleanup.
  13. 01a,15aug91,kdl  original version, from Motorola FPSP v2.0;
  14.  added missing comment symbols.
  15. */
  16. /*
  17. DESCRIPTION
  18. supportsa 1.2 5/1/91
  19. Copyright (C) Motorola, Inc. 1991
  20. All Rights Reserved
  21. THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
  22. The copyright notice above does not evidence any
  23. actual or intended publication of such source code.
  24. L_SUPPORT    idnt    2,1 Motorola 040 Floating Point Software Package
  25. section    8
  26. NOMANUAL
  27. */
  28. mns_one:  .long 0xbfff0000,0x80000000,0x00000000
  29. pls_one:  .long 0x3fff0000,0x80000000,0x00000000
  30. pls_inf:  .long 0x7fff0000,0x00000000,0x00000000
  31. pls_huge: .long 0x7ffe0000,0xffffffff,0xffffffff
  32. mns_huge: .long 0xfffe0000,0xffffffff,0xffffffff
  33. pls_tiny: .long 0x00000000,0x80000000,0x00000000
  34. mns_tiny: .long 0x80000000,0x80000000,0x00000000
  35. small:    .long 0x20000000,0x80000000,0x00000000
  36. pls_zero: .long 0x00000000,0x00000000,0x00000000
  37. #include "fpsp040L.h"
  38. |
  39. |  __l_tag --- determine the type of an extended precision operand
  40. |
  41. | The tag values returned match the way the 68040 would have
  42. | tagged them.
  43. |
  44. | Input: a0 points to operand
  45. |
  46. | Output d0b = 0x00 norm
  47. |   0x20 zero
  48. |   0x40 inf
  49. |   0x60 nan
  50. |   0x80 denorm
  51. | All other registers are unchanged
  52. |
  53. .text
  54. .globl __l_tag
  55. __l_tag:
  56. movew a0@(LOCAL_EX),d0
  57. andiw #0x7fff,d0
  58. jeq  chk_zro
  59. cmpiw #0x7fff,d0
  60. jeq  chk_inf
  61. __l_tag_nrm:
  62. clrb d0
  63. rts
  64. __l_tag_nan:
  65. moveb #0x60,d0
  66. rts
  67. __l_tag_dnrm:
  68. moveb #0x80,d0
  69. rts
  70. chk_zro:
  71. btst #7,a0@(LOCAL_HI) | # check if J-bit is set
  72. jne  __l_tag_nrm
  73. tstl a0@(LOCAL_HI)
  74. jne  __l_tag_dnrm
  75. tstl a0@(LOCAL_LO)
  76. jne  __l_tag_dnrm
  77. __l_tag_zero:
  78. moveb #0x20,d0
  79. rts
  80. chk_inf:
  81. tstl a0@(LOCAL_HI)
  82. jne  __l_tag_nan
  83. tstl a0@(LOCAL_LO)
  84. jne  __l_tag_nan
  85. __l_tag_inf:
  86. moveb #0x40,d0
  87. rts
  88. |
  89. | __l_t_dz, __l_t_dz2 --- divide by zero exception
  90. |
  91. | __l_t_dz2 is used by monadic functions such as flogn (from __l_do_func).
  92. | __l_t_dz is used by monadic functions such as __l_satanh (from the
  93. | transcendental function).
  94. |
  95. .globl    __l_t_dz2
  96. __l_t_dz2:
  97. fmovemx mns_one,fp0-fp0
  98. fmovel d1,fpcr
  99. fdivx pls_zero,fp0
  100. rts
  101. .globl __l_t_dz
  102. __l_t_dz:
  103. btst #sign_bit,a6@(ETEMP_EX) | check sign for neg or pos
  104. jeq  p_inf | branch if pos sign
  105. m_inf:
  106. fmovemx mns_one,fp0-fp0
  107. fmovel d1,fpcr
  108. fdivx pls_zero,fp0
  109. rts
  110. p_inf:
  111. fmovemx pls_one,fp0-fp0
  112. fmovel d1,fpcr
  113. fdivx pls_zero,fp0
  114. rts
  115. |
  116. | __l_t_operr --- Operand Error exception
  117. |
  118. .globl    __l_t_operr
  119. __l_t_operr:
  120. fmovemx pls_inf,fp0-fp0
  121. fmovel d1,fpcr
  122. fmulx pls_zero,fp0
  123. rts
  124. |
  125. | __l_t_unfl --- UNFL exception
  126. |
  127. .globl    __l_t_unfl
  128. __l_t_unfl:
  129. btst #sign_bit,a6@(ETEMP)
  130. jeq  unf_pos
  131. unf_neg:
  132. fmovemx mns_tiny,fp0-fp0
  133. fmovel d1,fpcr
  134. fmulx pls_tiny,fp0
  135. rts
  136. unf_pos:
  137. fmovemx pls_tiny,fp0-fp0
  138. fmovel d1,fpcr
  139. fmulx fp0,fp0
  140. rts
  141. |
  142. | __l_t_ovfl --- OVFL exception
  143. |
  144. | __l_t_ovfl is called as an exit for monadic functions.  __l_t_ovfl2
  145. | is for dyadic exits.
  146. |
  147. .globl    __l_t_ovfl
  148. __l_t_ovfl:
  149. .globl    __l_t_ovfl2
  150. movel d1,a6@(USER_FPCR) /* |  user's control register */
  151. movel #ovfinx_mask,d0
  152. jra  t_work
  153. __l_t_ovfl2:
  154. movel #__l_ovfl_inx_mask,d0
  155. t_work:
  156. btst #sign_bit,a6@(ETEMP)
  157. jeq  ovf_pos
  158. ovf_neg:
  159. fmovemx mns_huge,fp0-fp0
  160. fmovel a6@(USER_FPCR),fpcr
  161. fmulx pls_huge,fp0
  162. fmovel fpsr,d1
  163. orl d1,d0
  164. fmovel d0,fpsr
  165. rts
  166. ovf_pos:
  167. fmovemx pls_huge,fp0-fp0
  168. fmovel a6@(USER_FPCR),fpcr
  169. fmulx pls_huge,fp0
  170. fmovel fpsr,d1
  171. orl d1,d0
  172. fmovel d0,fpsr
  173. rts
  174. |
  175. | __l_t_inx2 --- INEX2 exception (correct fpcr is in a6@(USER_FPCR))
  176. |
  177. .globl    __l_t_inx2
  178. __l_t_inx2:
  179. fmovel fpsr,a6@(USER_FPSR) |  capture incoming fpsr
  180. fmovel a6@(USER_FPCR),fpcr
  181. |
  182. | create an inex2 exception by adding two numbers with very different exponents
  183. | do the add in fp1 so as to not disturb the result sitting in fp0
  184. |
  185. fmovex pls_one,fp1
  186. faddx small,fp1
  187. |
  188. orl #inx2a_mask,a6@(USER_FPSR) | set INEX2, AINEX
  189. fmovel a6@(USER_FPSR),fpsr
  190. rts
  191. |
  192. | __l_t_frcinx --- Force Inex2 (for monadic functions)
  193. |
  194. .globl __l_t_frcinx
  195. __l_t_frcinx:
  196. fmovel fpsr,a6@(USER_FPSR) |  capture incoming fpsr
  197. fmovel d1,fpcr
  198. |
  199. | create an inex2 exception by adding two numbers with very different exponents
  200. | do the add in fp1 so as to not disturb the result sitting in fp0
  201. |
  202. fmovex pls_one,fp1
  203. faddx small,fp1
  204. |
  205. orl #inx2a_mask,a6@(USER_FPSR) | set INEX2, AINEX
  206. btst #__l_unfl_bit,a6@(FPSR_EXCEPT) | test for unfl bit set
  207. jeq  no_uacc1 | if clear, do not set aunfl
  208. bset #aunfl_bit,a6@(FPSR_AEXCEPT)
  209. no_uacc1:
  210. fmovel a6@(USER_FPSR),fpsr
  211. rts
  212. |
  213. | __l_dst_nan --- force result when destination is a NaN
  214. |
  215. .globl __l_dst_nan
  216. __l_dst_nan:
  217. fmovel a6@(USER_FPCR),fpcr
  218. fmovex a6@(FPTEMP),fp0
  219. rts
  220. |
  221. | __l_src_nan --- force result when source is a NaN
  222. |
  223. .globl __l_src_nan
  224. __l_src_nan:
  225. fmovel a6@(USER_FPCR),fpcr
  226. fmovex a6@(ETEMP),fp0
  227. rts
  228. |
  229. | __l_mon_nan --- force result when source is a NaN (monadic version)
  230. |
  231. /* | This is the same as __l_src_nan except that the user's fpcr comes */
  232. | in via d1, not a6@(USER_FPCR).
  233. |
  234. .globl __l_mon_nan
  235. __l_mon_nan:
  236. fmovel d1,fpcr
  237. fmovex a6@(ETEMP),fp0
  238. rts
  239. |
  240. | __l_t_extdnrm, __l_t_resdnrm --- generate results for denorm inputs
  241. |
  242. | For all functions that have a denormalized input and that f(x)=x,
  243. | this is the entry point.
  244. |
  245. .globl __l_t_extdnrm
  246. __l_t_extdnrm:
  247. fmovel d1,fpcr
  248. fmovex a0@(LOCAL_EX),fp0
  249. fmovel fpsr,d0
  250. orl #unfinx_mask,d0
  251. fmovel d0,fpsr
  252. rts
  253. .globl __l_t_resdnrm
  254. __l_t_resdnrm:
  255. fmovel a6@(USER_FPCR),fpcr
  256. fmovex a0@(LOCAL_EX),fp0
  257. fmovel fpsr,d0
  258. orl #__l_unfl_mask,d0
  259. fmovel d0,fpsr
  260. rts
  261. |
  262. |
  263. |
  264. .globl __l_t_avoid_unsupp
  265. __l_t_avoid_unsupp:
  266. fmovex fp0,fp0
  267. rts
  268. .globl __l_sto_cos
  269. __l_sto_cos:
  270. fmovemx a0@(LOCAL_EX),fp1-fp1
  271. rts
  272. |
  273. | Native instruction support
  274. |
  275. | Some systems may need entry points even for 68040 native
  276. | instructions.  These routines are provided for
  277. | convenience.
  278. |
  279. .globl __l_sadd
  280. __l_sadd:
  281. fmovemx a6@(FPTEMP),fp0-fp0
  282. fmovel a6@(USER_FPCR),fpcr
  283. faddx a6@(ETEMP),fp0
  284. rts
  285. .globl __l_ssub
  286. __l_ssub:
  287. fmovemx a6@(FPTEMP),fp0-fp0
  288. fmovel a6@(USER_FPCR),fpcr
  289. fsubx a6@(ETEMP),fp0
  290. rts
  291. .globl __l_smul
  292. __l_smul:
  293. fmovemx a6@(FPTEMP),fp0-fp0
  294. fmovel a6@(USER_FPCR),fpcr
  295. fmulx a6@(ETEMP),fp0
  296. rts
  297. .globl __l_sdiv
  298. __l_sdiv:
  299. fmovemx a6@(FPTEMP),fp0-fp0
  300. fmovel a6@(USER_FPCR),fpcr
  301. fdivx a6@(ETEMP),fp0
  302. rts
  303. .globl __l_sabs
  304. __l_sabs:
  305. fmovemx a6@(ETEMP),fp0-fp0
  306. fmovel d1,fpcr
  307. fabsx fp0
  308. rts
  309. .globl __l_sneg
  310. __l_sneg:
  311. fmovemx a6@(ETEMP),fp0-fp0
  312. fmovel d1,fpcr
  313. fnegx fp0
  314. rts
  315. .globl __l_ssqrt
  316. __l_ssqrt:
  317. fmovemx a6@(ETEMP),fp0-fp0
  318. fmovel d1,fpcr
  319. fsqrtx fp0
  320. rts
  321. |
  322. | __l_l_sint,__l_l_sintrz,__l_l_sintd --- wrapper for fint and fintrz
  323. |
  324. /*  On entry, move the user's fpcr to USER_FPCR. */
  325. |
  326. | On return from, we need to pickup the INEX2/AINEX bits
  327. | that are in USER_FPSR.
  328. |
  329. | xref __l_sint
  330. | xref __l_sintrz
  331. | xref __l_sintd
  332. .globl __l_l_sint
  333. __l_l_sint:
  334. movel d1,a6@(USER_FPCR)
  335. jsr __l_sint
  336. fmovel fpsr,d0
  337. orl a6@(USER_FPSR),d0
  338. fmovel d0,fpsr
  339. rts
  340. .globl __l_l_sintrz
  341. __l_l_sintrz:
  342. movel d1,a6@(USER_FPCR)
  343. jsr __l_sintrz
  344. fmovel fpsr,d0
  345. orl a6@(USER_FPSR),d0
  346. fmovel d0,fpsr
  347. rts
  348. .globl __l_l_sintd
  349. __l_l_sintd:
  350. movel d1,a6@(USER_FPCR)
  351. jsr __l_sintd
  352. fmovel fpsr,d0
  353. orl a6@(USER_FPSR),d0
  354. fmovel d0,fpsr
  355. rts
  356. | end