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

VxWorks

开发平台:

C/C++

  1. /* l_do_func.s - Motorola 68040 FP routine jump table (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. 01g,31may96,ms   updated to mototorola version 2.3
  10. 01f,14jun95,tpr  changed fbxx to fbxxl.
  11. 01e,21jul93,kdl  added .text (SPR #2372).
  12. 01d,23aug92,jcf  changed bxxx to jxx.
  13. 01c,26may92,rrr  the tree shuffle
  14. 01b,09jan92,kdl  added modification history; general cleanup.
  15. 01a,15aug91,kdl  original version, from Motorola FPSP v2.0.
  16. /
  17. /*
  18. DESCRIPTION
  19. __l_do_funcsa 3.4 2/18/91
  20. Do_func performs the unimplemented operation.  The operation
  21. to be performed is determined from the lower 7 bits of the
  22. extension word (except in the case of fmovecr and fsincos).
  23. The opcode and tag bits form an index into a jump table in
  24. tbldosa.  Cases of zero, infinity and NaN are handled in
  25. __l_do_func by forcing the default result.  Normalized and
  26. denormalized (there are no unnormalized numbers at this
  27. point) are passed onto the emulation code.
  28. CMDREG1B and STAG are extracted from the fsave frame
  29. and combined to form the table index.  The function called
  30. will start with a0 pointing to the ETEMP operand.  Dyadic
  31. functions can find FPTEMP at a0@(-12).
  32. Called functions return their result in fp0.  Sincos returns
  33. sin(x) in fp0 and cos(x) in fp1.
  34. Copyright (C) Motorola, Inc. 1990
  35. All Rights Reserved
  36. THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
  37. The copyright notice above does not evidence any
  38. actual or intended publication of such source code.
  39. DO_FUNC idnt    2,1 Motorola 040 Floating Point Software Package
  40. section 8
  41. NOMANUAL
  42. */
  43. #include "fpsp040L.h"
  44. | xref __l_t_dz2
  45. | xref __l_t_operr
  46. | xref __l_t_inx2
  47. | xref  __l_t_resdnrm
  48. | xref __l_dst_nan
  49. | xref __l_src_nan
  50. | xref __l_nrm_set
  51. | xref __l_sto_cos
  52. | xref __l_slognp1,__l_slogn,__l_slog10,__l_slog2
  53. | xref __l_slognd,__l_slog10d,__l_slog2d
  54. | xref __l_smod,__l_srem
  55. | xref __l_sscale
  56. PONE: .long 0x3fff0000,0x80000000,0x00000000 | +1
  57. MONE: .long 0xbfff0000,0x80000000,0x00000000 | -1
  58. PZERO: .long 0x00000000,0x00000000,0x00000000 | +0
  59. MZERO: .long 0x80000000,0x00000000,0x00000000 | -0
  60. PINF: .long 0x7fff0000,0x00000000,0x00000000 | +inf
  61. MINF: .long 0xffff0000,0x00000000,0x00000000 | -inf
  62. QNAN: .long 0x7fff0000,0xffffffff,0xffffffff | non-signaling nan
  63. PPIBY2:  .long 0x3FFF0000,0xC90FDAA2,0x2168C235 | +PI/2
  64. MPIBY2:  .long 0xbFFF0000,0xC90FDAA2,0x2168C235 | -PI/2
  65. |
  66. | These routines load forced values into fp0.  They are called
  67. | by index into tbldo.
  68. |
  69. | Load a signed zero to fp0 and set inex2/ainex
  70. |
  71. .text
  72. .globl __l_snzrinx
  73. __l_snzrinx:
  74. btst #sign_bit,a0@(LOCAL_EX) | get sign of source operand
  75. jne  ld_mzinx | if negative, branch
  76. bsrl __l_ld_pzero | bsr so we can return and set inx
  77. jra  __l_t_inx2 | now, set the inx for the next inst
  78. ld_mzinx:
  79. bsrl __l_ld_mzero | if neg, load neg zero, return here
  80. jra  __l_t_inx2 | now, set the inx for the next inst
  81. |
  82. | Load a signed zero to fp0|  do not set inex2/ainex
  83. |
  84. .globl __l_szero
  85. __l_szero:
  86. btst #sign_bit,a0@(LOCAL_EX) | get sign of source operand
  87. jne  __l_ld_mzero | if neg, load neg zero
  88. jra  __l_ld_pzero | load positive zero
  89. |
  90. | Load a signed infinity to fp0|  do not set inex2/ainex
  91. |
  92. .globl __l_sinf
  93. __l_sinf:
  94. btst #sign_bit,a0@(LOCAL_EX) | get sign of source operand
  95. jne  __l_ld_minf | if negative branch
  96. jra  __l_ld_pinf
  97. |
  98. | Load a signed one to fp0|  do not set inex2/ainex
  99. |
  100. .globl __l_sone
  101. __l_sone:
  102. btst #sign_bit,a0@(LOCAL_EX) | check sign of source
  103. jne  __l_ld_mone
  104. jra  __l_ld_pone
  105. |
  106. | Load a signed pi/2 to fp0|  do not set inex2/ainex
  107. |
  108. .globl __l_spi_2
  109. __l_spi_2:
  110. btst #sign_bit,a0@(LOCAL_EX) | check sign of source
  111. jne  __l_ld_mpi2
  112. jra  __l_ld_ppi2
  113. |
  114. | Load either a +0 or +inf for plus/minus operand
  115. |
  116. .globl __l_szr_inf
  117. __l_szr_inf:
  118. btst #sign_bit,a0@(LOCAL_EX) | check sign of source
  119. jne  __l_ld_pzero
  120. jra  __l_ld_pinf
  121. |
  122. | Result is either an operr or +inf for plus/minus operand
  123. | [Used by __l_slogn, __l_slognp1, __l_slog10, and __l_slog2]
  124. |
  125. .globl __l_sopr_inf
  126. __l_sopr_inf:
  127. btst #sign_bit,a0@(LOCAL_EX) | check sign of source
  128. jne  __l_t_operr
  129. jra  __l_ld_pinf
  130. |
  131. | FLOGNP1
  132. |
  133. .globl __l_sslognp1
  134. __l_sslognp1:
  135. fmovemx a0@,fp0-fp0
  136. fcmpb #-1,fp0
  137. fbgtl __l_slognp1
  138. fbeql __l_t_dz2 | if = -1, divide by zero exception
  139. fmovel #0,FPSR | clr N flag
  140. jra  __l_t_operr | take care of operands < -1
  141. |
  142. | FETOXM1
  143. |
  144. .globl __l_setoxm1i
  145. __l_setoxm1i:
  146. btst #sign_bit,a0@(LOCAL_EX) | check sign of source
  147. jne  __l_ld_mone
  148. jra  __l_ld_pinf
  149. |
  150. | FLOGN
  151. |
  152. | Test for 1.0 as an input argument, returning +zero.  Also check
  153. | the sign and return operr if negative.
  154. |
  155. .globl __l_sslogn
  156. __l_sslogn:
  157. btst #sign_bit,a0@(LOCAL_EX)
  158. jne  __l_t_operr | take care of operands < 0
  159. cmpiw #0x3fff,a0@(LOCAL_EX)  | test for 1.0 input
  160. jne  __l_slogn
  161. cmpil #0x80000000,a0@(LOCAL_HI)
  162. jne  __l_slogn
  163. tstl a0@(LOCAL_LO)
  164. jne  __l_slogn
  165. fmovex PZERO,fp0
  166. rts
  167. .globl __l_sslognd
  168. __l_sslognd:
  169. btst #sign_bit,a0@(LOCAL_EX)
  170. jeq  __l_slognd
  171. jra  __l_t_operr | take care of operands < 0
  172. |
  173. | FLOG10
  174. |
  175. .globl __l_sslog10
  176. __l_sslog10:
  177. btst #sign_bit,a0@(LOCAL_EX)
  178. jne  __l_t_operr | take care of operands < 0
  179. cmpiw #0x3fff,a0@(LOCAL_EX)  | test for 1.0 input
  180. jne  __l_slog10
  181. cmpil #0x80000000,a0@(LOCAL_HI)
  182. jne  __l_slog10
  183. tstl a0@(LOCAL_LO)
  184. jne  __l_slog10
  185. fmovex PZERO,fp0
  186. rts
  187. .globl __l_sslog10d
  188. __l_sslog10d:
  189. btst #sign_bit,a0@(LOCAL_EX)
  190. jeq  __l_slog10d
  191. jra  __l_t_operr | take care of operands < 0
  192. |
  193. | FLOG2
  194. |
  195. .globl __l_sslog2
  196. __l_sslog2:
  197. btst #sign_bit,a0@(LOCAL_EX)
  198. jne  __l_t_operr | take care of operands < 0
  199. cmpiw #0x3fff,a0@(LOCAL_EX)  | test for 1.0 input
  200. jne  __l_slog2
  201. cmpil #0x80000000,a0@(LOCAL_HI)
  202. jne  __l_slog2
  203. tstl a0@(LOCAL_LO)
  204. jne  __l_slog2
  205. fmovex PZERO,fp0
  206. rts
  207. .globl __l_sslog2d
  208. __l_sslog2d:
  209. btst #sign_bit,a0@(LOCAL_EX)
  210. jeq  __l_slog2d
  211. jra  __l_t_operr | take care of operands < 0
  212. |
  213. | FMOD
  214. |
  215. __l_pmodt:
  216. | | 0x21 fmod
  217. | | dtag,stag
  218. .long __l_smod |   00,00  norm,norm = normal
  219. .long __l_smod_oper |   00,01  norm,zero = nan with operr
  220. .long __l_smod_fpn |   00,10  norm,inf  = fpn
  221. .long __l_smod_snan |   00,11  norm,nan  = nan
  222. .long __l_smod_zro |   01,00  zero,norm = +-zero
  223. .long __l_smod_oper |   01,01  zero,zero = nan with operr
  224. .long __l_smod_zro |   01,10  zero,inf  = +-zero
  225. .long __l_smod_snan |   01,11  zero,nan  = nan
  226. .long __l_smod_oper |   10,00  inf,norm  = nan with operr
  227. .long __l_smod_oper |   10,01  inf,zero  = nan with operr
  228. .long __l_smod_oper |   10,10  inf,inf   = nan with operr
  229. .long __l_smod_snan |   10,11  inf,nan   = nan
  230. .long __l_smod_dnan |   11,00  nan,norm  = nan
  231. .long __l_smod_dnan |   11,01  nan,zero  = nan
  232. .long __l_smod_dnan |   11,10  nan,inf   = nan
  233. .long __l_smod_dnan |   11,11  nan,nan   = nan
  234. .globl __l_pmod
  235. __l_pmod:
  236. clr.b FPSR_QBYTE(a6)      | clear quotient field
  237. bfextu a6@(STAG){#0:#3},d0 | stag = d0
  238. bfextu a6@(DTAG){#0:#3},d1 | dtag = d1
  239. |
  240. | Alias extended denorms to norms for the jump table.
  241. |
  242. bclr #2,d0
  243. bclr #2,d1
  244. lslb #2,d1
  245. orb d0,d1 | d1{3:2} = dtag, d1{1:0} = stag
  246. | | Tag values:
  247. | | 00 = norm or denorm
  248. | | 01 = zero
  249. | | 10 = inf
  250. | | 11 = nan
  251. lea __l_pmodt,a1
  252. movel a1@(d1:w:4),a1
  253. jmp a1@
  254. __l_smod_snan:
  255. jra  __l_src_nan
  256. __l_smod_dnan:
  257. jra  __l_dst_nan
  258. __l_smod_oper:
  259. jra  __l_t_operr
  260. __l_smod_zro:
  261. moveb a6@(ETEMP),d1 | get sign of src op
  262. moveb a6@(FPTEMP),d0 | get sign of dst op
  263. eorb d0,d1 | get exor of sign bits
  264. btst #7,d1 | test for sign
  265. jeq  __l_smod_zsn | if clr, do not set sign big
  266. bset #q_sn_bit,a6@(FPSR_QBYTE) | set q-byte sign bit
  267. __l_smod_zsn:
  268. btst #7,d0 | test if + or -
  269. jeq  __l_ld_pzero | if pos then load +0
  270. jra  __l_ld_mzero | else neg load -0
  271. __l_smod_fpn:
  272. moveb a6@(ETEMP),d1 | get sign of src op
  273. moveb a6@(FPTEMP),d0 | get sign of dst op
  274. eorb d0,d1 | get exor of sign bits
  275. btst #7,d1 | test for sign
  276. jeq  __l_smod_fsn | if clr, do not set sign big
  277. bset #q_sn_bit,a6@(FPSR_QBYTE) | set q-byte sign bit
  278. __l_smod_fsn:
  279. tstb a6@(DTAG) | filter out denormal destination case
  280. jpl  __l_smod_nrm |
  281. lea a6@(FPTEMP),a0 | a0<- addr(FPTEMP)
  282. jra  __l_t_resdnrm | force UNFL(but exact) result
  283. __l_smod_nrm:
  284. fmovel a6@(USER_FPCR),fpcr  /* | use user's rmode and precision */
  285. fmovex a6@(FPTEMP),fp0 | return dest to fp0
  286. rts
  287. |
  288. | FREM
  289. |
  290. __l_premt:
  291. | | 0x25 frem
  292. | | dtag,stag
  293. .long __l_srem |   00,00  norm,norm = normal
  294. .long __l_srem_oper |   00,01  norm,zero = nan with operr
  295. .long __l_srem_fpn |   00,10  norm,inf  = fpn
  296. .long __l_srem_snan |   00,11  norm,nan  = nan
  297. .long __l_srem_zro |   01,00  zero,norm = +-zero
  298. .long __l_srem_oper |   01,01  zero,zero = nan with operr
  299. .long __l_srem_zro |   01,10  zero,inf  = +-zero
  300. .long __l_srem_snan |   01,11  zero,nan  = nan
  301. .long __l_srem_oper |   10,00  inf,norm  = nan with operr
  302. .long __l_srem_oper |   10,01  inf,zero  = nan with operr
  303. .long __l_srem_oper |   10,10  inf,inf   = nan with operr
  304. .long __l_srem_snan |   10,11  inf,nan   = nan
  305. .long __l_srem_dnan |   11,00  nan,norm  = nan
  306. .long __l_srem_dnan |   11,01  nan,zero  = nan
  307. .long __l_srem_dnan |   11,10  nan,inf   = nan
  308. .long __l_srem_dnan |   11,11  nan,nan   = nan
  309. .globl __l_prem
  310. __l_prem:
  311. clr.b FPSR_QBYTE(a6)      | clear quotient field
  312. bfextu a6@(STAG){#0:#3},d0 | stag = d0
  313. bfextu a6@(DTAG){#0:#3},d1 | dtag = d1
  314. |
  315. | Alias extended denorms to norms for the jump table.
  316. |
  317. bclr #2,d0
  318. bclr #2,d1
  319. lslb #2,d1
  320. orb d0,d1 | d1{3:2} = dtag, d1{1:0} = stag
  321. | | Tag values:
  322. | | 00 = norm or denorm
  323. | | 01 = zero
  324. | | 10 = inf
  325. | | 11 = nan
  326. lea __l_premt,a1
  327. movel a1@(d1:w:4),a1
  328. jmp a1@
  329. __l_srem_snan:
  330. jra  __l_src_nan
  331. __l_srem_dnan:
  332. jra  __l_dst_nan
  333. __l_srem_oper:
  334. jra  __l_t_operr
  335. __l_srem_zro:
  336. moveb a6@(ETEMP),d1 | get sign of src op
  337. moveb a6@(FPTEMP),d0 | get sign of dst op
  338. eorb d0,d1 | get exor of sign bits
  339. btst #7,d1 | test for sign
  340. jeq  __l_srem_zsn | if clr, do not set sign big
  341. bset #q_sn_bit,a6@(FPSR_QBYTE) | set q-byte sign bit
  342. __l_srem_zsn:
  343. btst #7,d0 | test if + or -
  344. jeq  __l_ld_pzero | if pos then load +0
  345. jra  __l_ld_mzero | else neg load -0
  346. __l_srem_fpn:
  347. moveb a6@(ETEMP),d1 | get sign of src op
  348. moveb a6@(FPTEMP),d0 | get sign of dst op
  349. eorb d0,d1 | get exor of sign bits
  350. btst #7,d1 | test for sign
  351. jeq  __l_srem_fsn | if clr, do not set sign big
  352. bset #q_sn_bit,a6@(FPSR_QBYTE) | set q-byte sign bit
  353. __l_srem_fsn:
  354. tstb a6@(DTAG) | filter out denormal destination case
  355. jpl  __l_srem_nrm |
  356. lea a6@(FPTEMP),a0 | a0<- addr(FPTEMP)
  357. jra  __l_t_resdnrm | force UNFL(but exact) result
  358. __l_srem_nrm:
  359. fmovel a6@(USER_FPCR),fpcr  /* | use user's rmode and precision */
  360. fmovex a6@(FPTEMP),fp0 | return dest to fp0
  361. rts
  362. |
  363. | FSCALE
  364. |
  365. __l_pscalet:
  366. | | 0x26 fscale
  367. | | dtag,stag
  368. .long __l_sscale |   00,00  norm,norm = result
  369. .long __l_sscale |   00,01  norm,zero = fpn
  370. .long scl_opr |   00,10  norm,inf  = nan with operr
  371. .long scl_snan |   00,11  norm,nan  = nan
  372. .long scl_zro |   01,00  zero,norm = +-zero
  373. .long scl_zro |   01,01  zero,zero = +-zero
  374. .long scl_opr |   01,10  zero,inf  = nan with operr
  375. .long scl_snan |   01,11  zero,nan  = nan
  376. .long scl_inf |   10,00  inf,norm  = +-inf
  377. .long scl_inf |   10,01  inf,zero  = +-inf
  378. .long scl_opr |   10,10  inf,inf   = nan with operr
  379.   .long scl_snan |   10,11  inf,nan   = nan
  380.   .long scl_dnan |   11,00  nan,norm  = nan
  381.   .long scl_dnan |   11,01  nan,zero  = nan
  382.   .long scl_dnan |   11,10  nan,inf   = nan
  383. .long scl_dnan |   11,11  nan,nan   = nan
  384. .globl __l_pscale
  385. __l_pscale:
  386. bfextu a6@(STAG){#0:#3},d0 | stag in d0
  387. bfextu a6@(DTAG){#0:#3},d1 | dtag in d1
  388. bclr #2,d0 | alias  denorm into norm
  389. bclr #2,d1 | alias  denorm into norm
  390. lslb #2,d1
  391. orb d0,d1 | d1{4:2} = dtag, d1{1:0} = stag
  392. | | dtag values     stag values:
  393. | | 000 = norm      00 = norm
  394. | | 001 = zero  01 = zero
  395. | | 010 = inf  10 = inf
  396. | | 011 = nan  11 = nan
  397. | | 100 = dnrm
  398. |
  399. |
  400. lea __l_pscalet,a1 | load start of jump table
  401. movel a1@(d1:w:4),a1 | load a1 with label depending on tag
  402. jmp a1@ | go to the routine
  403. scl_opr:
  404. jra  __l_t_operr
  405. scl_dnan:
  406. jra  __l_dst_nan
  407. scl_zro:
  408. btst #sign_bit,a6@(FPTEMP_EX) | test if + or -
  409. jeq  __l_ld_pzero | if pos then load +0
  410. jra  __l_ld_mzero | if neg then load -0
  411. scl_inf:
  412. btst #sign_bit,a6@(FPTEMP_EX) | test if + or -
  413. jeq  __l_ld_pinf | if pos then load +inf
  414. jra  __l_ld_minf | else neg load -inf
  415. scl_snan:
  416. jra  __l_src_nan
  417. |
  418. | FSINCOS
  419. |
  420. .globl __l_ssincosz
  421. __l_ssincosz:
  422. btst #sign_bit,a6@(ETEMP) | get sign
  423. jeq  sincosp
  424. fmovex MZERO,fp0
  425. jra  sincoscom
  426. sincosp:
  427. fmovex PZERO,fp0
  428. sincoscom:
  429.    fmovemx PONE,fp1-fp1 | do not allow FPSR to be affected
  430. jra  __l_sto_cos | store cosine result
  431. .globl __l_ssincosi
  432. __l_ssincosi:
  433. fmovex QNAN,fp1 | load NAN
  434. bsrl __l_sto_cos | store cosine result
  435. fmovex QNAN,fp0 | load NAN
  436. jra  __l_t_operr
  437. .globl __l_ssincosnan
  438. __l_ssincosnan:
  439. movel a6@(ETEMP_EX),a6@(FP_SCR1)
  440. movel a6@(ETEMP_HI),a6@(FP_SCR1+4)
  441. movel a6@(ETEMP_LO),a6@(FP_SCR1+8)
  442. bset #signan_bit,a6@(FP_SCR1+4)
  443. fmovemx a6@(FP_SCR1),fp1-fp1
  444. bsrl __l_sto_cos
  445. jra  __l_src_nan
  446. |
  447. | This code forces default values for the zero, inf, and nan cases
  448. | in the transcendentals code.  The CC bits must be set in the
  449. | stacked FPSR to be correctly reported.
  450. |
  451. |**Returns +PI/2
  452. .globl __l_ld_ppi2
  453. __l_ld_ppi2:
  454. fmovex PPIBY2,fp0 | load +pi/2
  455. jra  __l_t_inx2 | set inex2 exc
  456. |**Returns -PI/2
  457. .globl __l_ld_mpi2
  458. __l_ld_mpi2:
  459. fmovex MPIBY2,fp0 | load -pi/2
  460. orl #neg_mask,a6@(USER_FPSR) | set N bit
  461. jra  __l_t_inx2 | set inex2 exc
  462. |**Returns +inf
  463. .globl __l_ld_pinf
  464. __l_ld_pinf:
  465. fmovex PINF,fp0 | load +inf
  466. orl #inf_mask,a6@(USER_FPSR) | set I bit
  467. rts
  468. |**Returns -inf
  469. .globl __l_ld_minf
  470. __l_ld_minf:
  471. fmovex MINF,fp0 | load -inf
  472. orl #neg_mask+inf_mask,a6@(USER_FPSR) | set N and I bits
  473. rts
  474. |**Returns +1
  475. .globl __l_ld_pone
  476. __l_ld_pone:
  477. fmovex PONE,fp0 | load +1
  478. rts
  479. |**Returns -1
  480. .globl __l_ld_mone
  481. __l_ld_mone:
  482. fmovex MONE,fp0 | load -1
  483. orl #neg_mask,a6@(USER_FPSR) | set N bit
  484. rts
  485. |**Returns +0
  486. .globl __l_ld_pzero
  487. __l_ld_pzero:
  488. fmovex PZERO,fp0 | load +0
  489. orl #z_mask,a6@(USER_FPSR) | set Z bit
  490. rts
  491. |**Returns -0
  492. .globl __l_ld_mzero
  493. __l_ld_mzero:
  494. fmovex MZERO,fp0 | load -0
  495. orl #neg_mask+z_mask,a6@(USER_FPSR) | set N and Z bits
  496. rts
  497. | end