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

VxWorks

开发平台:

C/C++

  1. /* Copyright 1991-2001 Wind River Systems, Inc. */
  2. /*
  3. modification history
  4. --------------------
  5. 01c,14jul99,tdl  added FUNC / FUNC_LABEL
  6. 01b,24oct96,yp   stuck in a # in USSC mailing addr so cpp will work
  7. 01a,24jan95,hdn  original US Software version.
  8. */
  9. #* * * * * * * * * *
  10. #       Filename:   EMUSUB.ASM
  11. #
  12. #       Copyright (C) 1990,1991 By
  13. #       # United States Software Corporation
  14. #       # 14215 N.W. Science Park Drive
  15. #       # Portland, Oregon 97229
  16. #
  17. #       This software is furnished under a license and may be used
  18. #       and copied only in accordance with the terms of such license
  19. #       and with the inclusion of the above copyright notice.
  20. #       This software or any other copies thereof may not be provided
  21. #       or otherwise made available to any other person.  No title to
  22. #       and ownership of the software is hereby transferred.
  23. #
  24. #       The information in this software is subject to change without
  25. #       notice and should not be construed as a commitment by United
  26. #       States Software Corporation.
  27. #
  28. #       Version:        V3.09  01/19/95 GOFAST  WRS GNU version of GF-PROT
  29. #       Released:       1 March 1991
  30. #
  31. #* * * * * * * * * *
  32. #define _ASMLANGUAGE
  33. #include "vxWorks.h"
  34. #include "asm.h"
  35. .data
  36. .globl  FUNC(copyright_wind_river)
  37. .long   FUNC(copyright_wind_river)
  38. .include "emuIncALib.s"
  39. .text
  40. #        extrn   exret:near
  41. #DGROUP  GROUP   hwseg
  42. #CGROUP  GROUP   emuseg
  43. #hwseg   segment RW para public 'DATA'
  44. #        assume  ds:DGROUP, es:DGROUP, ss:DGROUP
  45. #        extrn   h_ctrl:word,h_stat:word
  46. #hwseg   ends
  47. #emuseg  segment public USE32 'CODE'
  48. #        assume  cs:CGROUP
  49. __lib:
  50. # IEEE rounding for integers
  51. # in    bl bit 7 = highest truncated bit
  52. #          bit 6 = OR of all truncated bits
  53. #       ecx bit 31 = sign bit
  54. #       eax = low bits of number
  55. # out   carry set if bump needed
  56. .globl roundi
  57. roundi:
  58. andb $0x0fd,h_stat+1
  59. cmpb $0,%bl #no rounding if already exact
  60. jz rndi99
  61. movb h_ctrl+1,%bh
  62. andb $0x0c,%bh
  63. jnz rndi3 #jump if not the usual "to nearest"
  64. btl $0,%eax
  65. adcb $-1,%bl
  66. jns rndi9
  67. rndi8: #PREEX   precis+rup
  68. orw $precis+rup,h_stat
  69. testb $precis,h_ctrl
  70. jnz LL1
  71. orw $0x8080,h_stat
  72. movl $exret,-4(%ebp)
  73. LL1:
  74. stc
  75. ret
  76. rndi9: #PREEXS  precis
  77. orb $precis,h_stat
  78. testb $precis,h_ctrl
  79. jnz LL2
  80. orw $0x8080,h_stat
  81. movl $exret,-4(%ebp)
  82. LL2:
  83. rndi99: ret
  84. rndi3: cmpb $0x0c,%bh #analyze rounding bits
  85. jz rndi9
  86. rorl $11,%ebx
  87. xorl %ecx,%ebx
  88. js rndi9
  89. jmp rndi8
  90. # IEEE rounding for EP number
  91. # in    bl bit 7 = highest truncated bit
  92. #          bit 6 = OR of all truncated bits
  93. #       ecx:edx:eax = EP number
  94. # out   number rounded
  95. .globl rounde,roundx
  96. roundx: #entry that ignores precision
  97. andb $0x0fd,h_stat+1
  98. movb h_ctrl+1,%bh #get control bits
  99. jmp rnde2
  100. rounde:
  101. andb $0x0fd,h_stat+1
  102. movb h_ctrl+1,%bh #get control bits, jump
  103. testb $1,%bh #   if not 64-bit precision
  104. jz rnde30
  105. rnde2: cmpb $0,%bl #no rounding if mantissa is exact
  106. jz rndx99
  107. andb $0x0c,%bh #jump if not normal "to nearest"
  108. jnz rnde7
  109. btl $0,%eax
  110. adcb $-1,%bl
  111. jns rnde9
  112. rnde8: #PREEX   precis+rup      #this bumps the 64-bit mantissa
  113. orw $precis+rup,h_stat
  114. testb $precis,h_ctrl
  115. jnz LL3
  116. orw $0x8080,h_stat
  117. movl $exret,-4(%ebp)
  118. LL3:
  119. addl $1,%eax
  120. rnde11: adcl $0,%edx
  121. rnde12: jc rnde18
  122. rnde99: orw %cx,%cx
  123. jnz rndx99
  124. btsl $16,%ecx
  125. movl %edx,%ebx
  126. orl %eax,%ebx
  127. jz rndx99
  128. addl $0x00010000,%ecx
  129. rndx99: #PUTEP
  130. movl %eax,(%edi)
  131. movl %edx,4(%edi)
  132. movl %ecx,8(%edi)
  133. ret
  134. rnde18: rcrl $1,%edx
  135. incl %ecx
  136. cmpw $0x7fff,%cx
  137. jnz rnde99
  138. btsl $17,%ecx
  139. jmp rnde99
  140. rnde7: cmpb $0x0c,%bh #analyze rounding option 
  141. jz rnde9
  142. rorl $11,%ebx
  143. xorl %ecx,%ebx
  144. jns rnde8
  145. rnde9: #PREEXS  precis          #rounding done here
  146. orb $precis,h_stat
  147. testb $precis,h_ctrl
  148. jnz LL4
  149. orw $0x8080,h_stat
  150. movl $exret,-4(%ebp)
  151. LL4:
  152. jmp rndx99
  153. rnde30: cmpw $0x7fff,%cx #NaN not rounded
  154. jz rnde99
  155. testb $2,%bh #jump if 24-bit precision
  156. jz rnde40
  157. shrb $1,%bl #calculate new rounding bits
  158. testb $4,%ah
  159. jz rnde3a
  160. orb $0x80,%bl
  161. rnde3a: testl $0x3ff,%eax
  162. jz rnde3b
  163. orb $0x40,%bl
  164. rnde3b: andw $0xf800,%ax #clear extra bits for 53-bit form
  165. cmpb $0,%bl #no rounding if already exact
  166. jz rnde99
  167. testw $0x7fff,%cx #we may have delayed masked underflow
  168. jnz rnde36
  169. orw $underf+precis,h_stat
  170. rnde36: andb $0x0c,%bh #rounding logic for 53-bits
  171. cmpb $0x0c,%bh
  172. jz rnde9
  173. cmpb $0x00,%bh
  174. jnz rnde37
  175. btl $10,%eax
  176. adcb $-1,%bl
  177. js rnde38
  178. jmp rnde9
  179. rnde37: rorl $11,%ebx
  180. xorl %ecx,%ebx
  181. js rnde9
  182. rnde38: #PREEX   precis+rup      #bump the 53-bit mantissa
  183. orw $precis+rup,h_stat
  184. testb $precis,h_ctrl
  185. jnz LL5
  186. orw $0x8080,h_stat
  187. movl $exret,-4(%ebp)
  188. LL5:
  189. addl $0x800,%eax
  190. jmp rnde11
  191. rnde40: addb %dl,%dl #calculate new rounding bits
  192. rcrb $1,%bl
  193. orb %dl,%al
  194. orl %eax,%eax
  195. jz rnde4b
  196. orb $0x40,%bl
  197. rnde4b: xorl %eax,%eax #clear extra bits for 24-bit form
  198. movb $0,%dl
  199. cmpb $0,%bl #no rounding if already exact
  200. jz rnde99
  201. testw $0x7fff,%cx #we may have delayed masked underflow
  202. jnz rnde46
  203. orw $underf+precis,h_stat
  204. rnde46: andb $0x0c,%bh #rounding logic for 24-bits
  205. cmpb $0x0c,%bh
  206. jz rnde9
  207. cmpb $0x00,%bh
  208. jnz rnde47
  209. btl $8,%edx
  210. adcb $-1,%bl
  211. js rnde48
  212. jmp rnde9
  213. rnde47: rorl $11,%ebx
  214. xorl %ecx,%ebx
  215. js rnde9
  216. rnde48: #PREEX   precis+rup      #bump the 24-bit mantissa
  217. orw $precis+rup,h_stat
  218. testb $precis,h_ctrl
  219. jnz LL6
  220. orw $0x8080,h_stat
  221. movl $exret,-4(%ebp)
  222. LL6:
  223. addl $0x100,%edx
  224. jmp rnde12
  225. #multiply mantissa by 10
  226. # in    edx:eax = mantissa
  227. # out   edx:eax multiplied by 10
  228. .globl mul10
  229. mul10:
  230. movl %edx,%ebx #save 1x mantissa
  231. movl %eax,%esi
  232. shldl $2,%eax,%edx #get 4x mantissa
  233. shll $2,%eax
  234. addl %esi,%eax #add 1x to get 5x mantissa
  235. adcl %ebx,%edx
  236. addl %eax,%eax #double to get 10x mantissa
  237. adcl %edx,%edx
  238. ret
  239. #renormalize unsigned EP number
  240. # in    ecx:edx:eax:bl = exponent, mantissa
  241. # out   ecx:edx:eax:bl standard normal or denormal
  242. .globl renorm
  243. renorm:
  244. jc renof #carry set means overflow
  245. orw %cx,%cx #if exponent <= 0, we go normalize
  246. jle ren30
  247. ren2: orl %edx,%edx #here exponent OK, if mantissa normal
  248. js ren8 #   we are done
  249. jnz ren5
  250. orb %bl,%dl
  251. orl %eax,%edx
  252. jz ren8b
  253. xorl %edx,%edx
  254. ren5: decw %cx #if exponent is 1 we drop it to 0
  255. jz ren9a #   else shift mantissa left
  256. addb %bl,%bl
  257. adcl %eax,%eax
  258. adcl %edx,%edx
  259. jns ren5
  260. ren8: cmpw $0x7fff,%cx #assume INF for maximum exponent
  261. jz renof
  262. ret
  263. ren8b: andl $0x80000000,%ecx
  264. btsl $16,%ecx
  265. ret
  266. ren30a: cmpw $-64,%cx #here exponent had underflowed
  267. jg ren32 #   we try to return a denormal
  268. movw $-64,%cx
  269. ren32: shrl $1,%edx
  270. rcrl $1,%eax
  271. rcrb $1,%bl
  272. jnc ren32a
  273. orb $0x20,%bl
  274. ren32a: incw %cx
  275. jle ren32
  276. andl $0x80000000,%ecx
  277. btsl $17,%ecx
  278. ren9: orb %bl,%bl #back to caller
  279. jz ren91
  280. orw $underf+precis,h_stat
  281. ren91: rorl $16,%ecx
  282. movb $2,%cl
  283. orl %edx,%edx
  284. jnz ren92
  285. orl %eax,%eax
  286. jnz ren92
  287. movb $1,%cl
  288. ren92: rorl $16,%ecx
  289. ret
  290. ren9a: testb $underf,h_ctrl
  291. jnz ren9
  292. ren30: testb $underf,h_ctrl
  293. jnz ren30a
  294. addb $0x60,%ch
  295. orw $0x8080+underf,h_stat
  296. movl $exret,-4(%ebp)
  297. jren2: jmp ren2
  298. renof: testb $overf,h_ctrl
  299. jnz reninf
  300. orw $0x8080+overf,h_stat
  301. movl $exret,-4(%ebp)
  302. subb $0x60,%ch
  303. jns jren2
  304. reninf: orb $overf,h_stat
  305. andl $0x80000000,%ecx
  306. movw $0x7ffe,%cx
  307. movl $-1,%edx
  308. movl %edx,%eax
  309. movb %dl,%bl
  310. ret
  311. #temporary normalization of EP number
  312. # in    ecx:edx:eax = exponent, mantissa
  313. # out   ecx:edx:eax with number normalized or zero
  314. .globl tnormal
  315. tnormal:
  316. orl %edx,%edx #return if already normal
  317. js tno11 #   or if all zero
  318. jnz tno5
  319. orl %eax,%edx
  320. jz tno9
  321. xorl %edx,%edx
  322. tno5: decw %cx #shift left untill high bit = 1
  323. addl %eax,%eax
  324. adcl %edx,%edx
  325. jns tno5
  326. jmp tno12
  327. tno11: orw %cx,%cx #handle pseudo-denormal monsters here
  328. jnz tno9
  329. tno12: incw %cx
  330. orb $denorm,h_stat
  331. call exproc
  332. tno9: btrl $17,%ecx
  333. ret
  334. # routine to return answer for a two-argument function when at least
  335. # one argument is either NaN or an unsupported number
  336. # see 387 manual page 3-11
  337. # in    ecx:edx:eax = A
  338. #       [edi]      = B
  339. # out   if NaN present, loads answer into registers,
  340. #       pops the stack, returns to one level up if
  341. # at least one argument is signalling NaN, set exception
  342. #        extrn   xcmp:near
  343. .globl retnan
  344. retnan:
  345. pushl %ebx #save registers
  346. pushl %ecx
  347. shldl $16,%ecx,%ebx
  348. cmpb $3,%bl
  349. movl $0,%ebx
  350. jnz nan3
  351. movb $0x80,%bl
  352. orb $stacku,h_stat
  353. call exproc
  354. jmp nan11
  355. nan3: orw %cx,%cx #set bl bits 7-6 if A is NaN
  356. jz nan11
  357. orl %edx,%edx
  358. jns nan10
  359. cmpw $0x7fff,%cx
  360. jnz nan11
  361. movl %edx,%ecx
  362. addl %ecx,%ecx
  363. orl %eax,%ecx
  364. jz nan11
  365. movl %edx,%ebx
  366. shrl $24,%ebx
  367. andb $0x0c0,%bl
  368. xorb $0x40,%bl
  369. orb $0x80,%bl
  370. jmp nan11
  371. nan10: orb $0x20,%bl #set bl bit 5 if A is unsupported
  372. nan11: cmpb $3,10(%edi)
  373. jnz nan13
  374. movb $0x80,%bh
  375. orb $stacku,h_stat
  376. call exproc
  377. jmp nan30
  378. nan13: movl 8(%edi),%ecx #set bh bits 7-6 if B is NaN
  379. orw %cx,%cx
  380. jz nan21
  381. testb $0x80,7(%edi)
  382. jz nan20
  383. cmpw $0x7fff,%cx
  384. jnz nan21
  385. movl 4(%edi),%ecx
  386. addl %ecx,%ecx
  387. orl (%edi),%ecx
  388. jz nan21
  389. movb 7(%edi),%bh
  390. andb $0x0c0,%bh
  391. xorb $0x40,%bh
  392. orb $0x80,%bh
  393. jmp nan21
  394. nan20: orb $0x20,%bh #set bh bit 5 if A is unsupported
  395. nan21: orw %bx,%bx #if no specials, just return
  396. jnz nan30
  397. popl %ecx
  398. popl %ebx
  399. ret
  400. nan30: cmpl $xcmp,8(%esp) #comp excepts all nans
  401. jnz nan37
  402. testb $1,6(%esp)
  403. jz nan38
  404. nan37: movw %bx,%cx #if signaling NaN or unsupported present,
  405. orb %cl,%ch #   set exception
  406. testb $0x60,%ch
  407. jz nan31
  408. nan38: orb $invop,h_stat
  409. call exproc
  410. nan31: movw %bx,%cx #if unsupported present, return standard NaN
  411. orb %cl,%ch
  412. testb $0x20,%ch
  413. jnz nanrts
  414. movl %ebx,%ecx #if just one argument is NaN,
  415. xorb %cl,%ch #   we return that made quiet
  416. jns nan40
  417. testb $0x80,%bl
  418. jnz nanrta
  419. jmp nanrtb
  420. nan40: testb $0x40,%ch #both are NaN, if just one is quiet,
  421. jz nan50 #   we return that one
  422. testb $0x40,%bl
  423. jz nanrta
  424. jmp nanrtb
  425. nan50: pushl %edx #we have two quiet NaNs or two 
  426. pushl %eax #   signaling NaNs, we return the
  427. #   one with the larger mantissa 
  428. #   (this is a lot of trouble with dubious
  429. subl (%edi),%eax #   use, but that is what the book says)
  430. sbbl 4(%edi),%edx
  431. popl %eax
  432. popl %edx
  433. jc nanrtb
  434. nanrta: btsl $30,%edx #this returns A as quiet
  435. popl %ecx
  436. jmp nan99
  437. nanrts: call getqn #this returns standard NaN
  438. jmp nan98
  439. nanrtb: #GETEP                   #this returns B as quiet
  440. movl (%edi),%eax
  441. movl 4(%edi),%edx
  442. movl 8(%edi),%ecx
  443. btsl $30,%edx
  444. nan98: addl $4,%esp
  445. nan99: addl $4+ADDSIZ,%esp #return skipping a level
  446. xorl %ebx,%ebx
  447. ret
  448. # routine to eliminate illegals from single argument
  449. .globl chkarg
  450. chkarg:
  451. btl $16,%ecx
  452. jc chk27
  453. orw %cx,%cx
  454. jz chk11
  455. orl %edx,%edx
  456. jns chk41
  457. cmpw $0x7fff,%cx
  458. jz chk21
  459. chk9: clc
  460. ret
  461. chk11: orb $denorm,h_stat
  462. call exproc
  463. orl %edx,%edx
  464. jns chk9
  465. incl %ecx
  466. ret
  467. chk21: movl %edx,%ebx
  468. addl %ebx,%ebx
  469. orl %eax,%ebx
  470. jz chk9
  471. btsl $30,%edx
  472. jnc chkinv
  473. ret
  474. chk27: btl $17,%ecx
  475. jnc chk9
  476. chk51: call getqn
  477. orb $stacku,h_stat
  478. jmp chk53
  479. chk41: call getqn
  480. chkinv: orb $invop,h_stat
  481. chk53: call exproc
  482. stc
  483. ret
  484. # shift the works right by cl bits
  485. # in    EP mantissa in edx:eax
  486. # out   EP mantissa shifted right by cl in edx:eax:bl (bl bit 6 sticky bit)
  487. .globl shiftr
  488. shiftr:
  489. xorl %ebx,%ebx
  490. cmpw $32,%cx
  491. jnc shf11
  492. shf3: shrdl %cl,%eax,%ebx
  493. shrdl %cl,%edx,%eax
  494. shrl %cl,%edx
  495. shf4: addl %ebx,%ebx
  496. jz shf8
  497. movb $0x80,%bl
  498. shf8: rcrb $1,%bl
  499. ret
  500. shf11: xchgl %eax,%ebx
  501. xchgl %edx,%eax
  502. subw $32,%cx
  503. jz shf4
  504. shf12: cmpl $1,%ebx
  505. cmc
  506. rcrl $1,%ebx
  507. cmpw $32,%cx
  508. jc shf3
  509. shrl $1,%ebx
  510. orl %eax,%ebx
  511. xorl %eax,%eax
  512. subw $32,%cx
  513. jz shf4
  514. movw $1,%cx
  515. jmp shf12
  516. # return standard NaN in registers
  517. .globl getqn
  518. getqn:
  519. movl $0x80027fff,%ecx
  520. movl $0xc0000000,%edx
  521. xorl %eax,%eax
  522. movb %al,%bl
  523. ret
  524. # routine to process exception
  525. .globl exproc, exprop
  526. exproc:
  527. pushl %eax
  528. movw h_ctrl,%ax
  529. notl %eax
  530. andw h_stat,%ax
  531. testb $0x3f,%al
  532. jz xpp9
  533. orw $0x8080,h_stat
  534. movl %ebp,%esp
  535. jmp exret
  536. exprop:
  537. pushl %eax
  538. movw h_ctrl,%ax
  539. notl %eax
  540. andw h_stat,%ax
  541. testb $0x3f,%al
  542. jz xpp9
  543. orw $0x8080,h_stat
  544. movl $exret,-4(%ebp)
  545. xpp9: popl %eax
  546. ret
  547. #__lib   endp
  548. #emuseg  ends
  549. #        end