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

VxWorks

开发平台:

C/C++

  1. /* Copyright 1991-1992 Wind River Systems, Inc. */
  2. .data
  3. .globl _copyright_wind_river
  4. .long _copyright_wind_river
  5. /*
  6. modification history
  7. --------------------
  8. 01g,14mar95,tmk  inverted conditional assembly logic for 68000/10 to allow for
  9.  CPUs other than 68020.
  10. 01f,23aug92,jcf  changed bxxx to jxx.
  11. 01e,26may92,rrr  the tree shuffle
  12. 01d,30mar92,kdl  added include of "uss_fp.h"; commented-out ".set" directives
  13.  (SPR #1398).
  14. 01c,04oct91,rrr  passed through the ansification filter
  15.   -changed ASMLANGUAGE to _ASMLANGUAGE
  16.   -changed copyright notice
  17. 01b,29jan91,kdl  added include of vxWorks.h for conditional assembly.
  18. 01a,28jan91,kdl  modified original US Software version to use conditional
  19.  assembly for 68000/10 multiply and divide operations.
  20. */
  21. /*
  22. DESCRIPTION
  23. |       ttl     FPAC 68K/FPOPNS: IEEE Single Precision Operations
  24. |FPOPNS idnt    1,0             ; IEEE Single Precision Operations
  25. |                               ; FPOPNS.A68
  26. |
  27. | * * * * * * * * * *
  28. |
  29. |       Copyright (c) 1985,1989 by
  30. |       United States Software Corporation
  31. |       14215 N.W. Science Park Drive
  32. |       Portland, Oregon  97229
  33. |
  34. |       This software is furnished under a license and may be used
  35. |       and copied only in accordance with the terms of such license
  36. |       and with the inclusion of the above copyright notice.
  37. |       This software or any other copies thereof may not be provided
  38. |       or otherwise made available to any other person.  No title to
  39. |       and ownership of the software is hereby transferred.
  40. |
  41. |       The information in this software is subject to change without
  42. |       notice and should not be construed as a commitment by United
  43. |       States Software Corporation.
  44. |
  45. |       Released:       12 January 1989         V2.0
  46. |
  47. | * * * * * * * * * *
  48. |
  49. NOMANUAL
  50. */
  51. #define _ASMLANGUAGE
  52. #include "vxWorks.h"
  53. #include "uss_fp.h"
  54. |       .set    comp64,0                |the 64 bit multiply/divide flag
  55. |       opt     BRS             ; Default to forward branches SHORT
  56. |
  57.         .globl  FLOAT
  58.         .globl  FIX
  59.         .globl  INT
  60.         .globl  AINT
  61.         .globl  FPADD
  62.         .globl  FPMUL
  63.         .globl  FPDIV
  64.         .globl  FPRDIV
  65.         .globl  FPCMP
  66. |
  67.         .globl  GETFP1,FOPRSL
  68. |
  69.         .globl  FNANRS,FINFRS,FUNFRS,FZERRS
  70. |
  71. |
  72. |       xref    FPERR,NANFLG,INFFLG,UNFFLG
  73. |
  74. |
  75. |       .set    FBIAS,127               | Single precision format exponent bias
  76. |
  77. |
  78. |       .set    CCRC,0x01               | Carry bit in CCR
  79. |       .set    CCRV,0x02               | Overflow bit in CCR
  80. |       .set    CCRZ,0x04               | Zero bit in CCR
  81. |       .set    CCRN,0x08               | Negative bit in CCR
  82. |       .set    CCRX,0x10               | Extend bit in CCR
  83. |
  84. |
  85. |       .set    ERNAN,3
  86. |       .set    EROVF,2
  87. |       .set    ERUNF,1
  88. |
  89. |
  90.         .text           | General code section
  91. /*
  92. |
  93. |       page
  94. |
  95. |  FLOAT
  96. |  =====
  97. |  Float the integer value in D0 into a single precision floating
  98. |  point value on the stack.
  99. |
  100. */
  101. FLOAT:
  102.         moveal  sp@+,a0 | Return addr into a0
  103.         subal   a2,a2           | Set a2 = 0
  104.         andl    d0,d0
  105.         jne     FLT01           | J/ value <> 0
  106. |
  107.         movel   d0,sp@- | Place 0 value on stack
  108.         jmp     a0@             | Return
  109. |
  110. FLT01:
  111.         jge     FLT02           | J/ value > 0
  112.         subql   #1,a2           | Set a2 = -1
  113.         negl    d0
  114. |
  115. FLT02:
  116.         movel   #FBIAS+15,d2    | Default bias value
  117.         swap    d0
  118.         andw    d0,d0
  119.         jeq     FLT03           | J/ 16 bit shift required
  120. |
  121.         swap    d0              | Undo the shift
  122.         addw    #16,d2          | Reflect the larger number
  123. |
  124. FLT03:
  125.         andl    d0,d0
  126.         jmi     FLT06           | J/ value normalized
  127. |
  128. FLT04:
  129.         subqw   #1,d2           | Dec exponent, shift mantissa
  130.         asll    #1,d0
  131.         jpl     FLT04           | J/ more shifts to do
  132. |
  133. FLT06:
  134.         exg     d0,d2           | Position to standard d0/d2/a2 form
  135.         jra     FOPRSL          | J/ single precision result (w/ round)
  136. /*
  137. |
  138. |       page
  139. |
  140. |  FIX
  141. |  ===
  142. |  Routine to convert the single precision argument on the stack
  143. |  to an integer value (with a dropoff flag).
  144. |
  145. */
  146. FIX:
  147.         bsr     GETFP1          | Extract/unpack one single prec val
  148.         bsr     FIX00           | Use internal routine
  149.         jmp     a0@             | Return to caller
  150. |
  151. |
  152. FIX00:
  153.         andw    d0,d0
  154.         jne     FIX01           | J/ value <> 0.0
  155. |
  156.         subl    d0,d0           | Return a zero value, no drop off
  157.         rts
  158. |
  159. FIX01:
  160.         cmpiw   #FBIAS,d0
  161.         jcc     FIX02           | J/ abs() >= 1.0  [BCC == BHS]
  162. |
  163.         subl    d0,d0           | Return a zero value
  164.         orib    #CCRC+CCRX,ccr  | Set carry/extend bits
  165. | ###   ORI     #$11,CCR
  166.         rts
  167. |
  168. FIX02:
  169.         subiw   #FBIAS+31,d0
  170.         jcs     FIX03           | J/ abs() < 2^31
  171. |
  172.         moveq   #-1,d0          | Set d0 to the maximum integer value
  173.         lsrl    #1,d0           | d0 = 0x7FFFFFFF
  174.         subl    a2,d0           | Account for the sign of the arg.
  175.         rts
  176. |
  177. FIX03:
  178.         negw    d0              | Positive shift count
  179.         rorl    d0,d2           | Multibit shift
  180.         moveq   #-1,d1          | Mask for bit dropout check
  181.         lsrl    d0,d1
  182.         notl    d1
  183.         andl    d2,d1           | Bit(s) dropped left in d1
  184.         eorl    d1,d2           | Integer value in d2
  185.         movel   a2,d0
  186.         eorl    d2,d0           | Negate as required, move to d0
  187.         subl    a2,d0
  188.         moveq   #-1,d2
  189.         addl    d2,d1           | Set carry/extend if bits lost
  190.         rts
  191. /*
  192. |
  193. |       page
  194. |
  195. |  INT
  196. |  ===
  197. |  Return the largest integer smaller than the argument provided
  198. |
  199. */
  200. INT:
  201.         bsr     GETFP1
  202.         bsr     FIX00
  203. |
  204.         jcc     INT00           | J/ no bits lost
  205.         cmpaw   #0,a2
  206.         jeq     INT00           | J/ not negative
  207.         subql   #1,d0           | Decrement integer value
  208. INT00:
  209.         jmp     a0@
  210. /*
  211. |
  212. |       page
  213. |
  214. |  AINT
  215. |  ====
  216. |  Floating point corollary to the INT function
  217. |
  218. */
  219. AINT:
  220.         bsr     GETFP1
  221.         cmpiw   #FBIAS+23,d0    | Check for value too large
  222.         jcc     FOPRSL          | J/ return with same value
  223. |
  224.         movew   d0,d3
  225.         subiw   #FBIAS-1,d3
  226.         jgt     AINT02          | J/ abs() >= 1.0
  227. |
  228.         movew   a2,d2
  229.         jne     AINT01          | J/ 0.0 > value > -1.0
  230. |
  231.         movel   #0,sp@- | Return a zero value
  232.         jmp     a0@
  233. |
  234. AINT01:
  235.         movel   #0xBF800000,sp@-        | Return -1.0
  236.         jmp     a0@
  237. |
  238. AINT02:
  239.         moveq   #-1,d1          | Fill d1 with ones
  240.         lsrl    d3,d1           | Shift mask over
  241.         moveq   #1,d3
  242.         addl    d1,d3           | Create increment bit
  243.         andl    d2,d1           | Extract bits to drop
  244.         jeq     FOPRSL          | J/ no drop off, return as provided
  245. |
  246.         eorl    d1,d2           | Remove bits that must be dropped
  247.         cmpaw   #0,a2
  248.         jeq     FOPRSL          | Bits dropped from a positive number
  249. |
  250.         addl    d3,d2           | Bump the magnitude (negative number)
  251.         jcc     AINT03          | J/ no overflow
  252. |
  253.         roxll   #1,d2
  254.         addqw   #1,d0
  255. |
  256. AINT03:
  257.         jra     FOPRSL          | Return computed value
  258. /*
  259. |
  260. |       page
  261. |
  262. |  FPADD
  263. |  =====
  264. |  Single precision add routine
  265. |
  266. */
  267. FPADD:
  268.         bsr     GETFP2          | Fetch both operands
  269.         cmpiw   #0xFF,d0
  270. |
  271.         jne     FPA010          | J/ operand not NaN/INF
  272. |
  273.         lsll    #1,d2           | Remove implicit bit
  274.         jne     FNANRS          | J/  ?  + NaN -> NaN
  275. |
  276.         cmpiw   #0xFF,d1
  277.         jne     FINFRS          | J/  0,num + INF -> INF
  278. |
  279.         lsll    #1,d3           | Remove implicit bit
  280.         jne     FNANRS          | J/ INF + NaN -> NaN
  281. |
  282.         cmpal   a2,a3
  283.         jne     FNANRS          | J/ INF - INF -> NaN
  284.         jra     FINFRS          |    INF + INF -> INF
  285. |
  286. |
  287. FPA010:
  288.         cmpiw   #0xFF,d1
  289.         jne     FPA040          | J/ not NaN or INF
  290. |
  291.         lsll    #1,d3           | Remove implicit bit
  292.         jne     FNANRS          | J/ NaN + 0,num -> NaN
  293. |
  294.         moveal  a3,a2           | Move sign over
  295.         jra     FINFRS          | INF result
  296. |
  297. |
  298. FPXSUB:
  299.         |dsw    0               | Entry for FPCMP
  300. |
  301. FPA040:
  302.         andw    d1,d1
  303.         jeq     FPA041          | J/ 0,num + 0 -> 0,num
  304. |
  305.         andw    d0,d0
  306.         jne     FPA045          | J/ no zeroes involved
  307. |
  308.         movew   d1,d0           | Copy over data
  309.         movel   d3,d2
  310.         moveal  a3,a2
  311. FPA041:
  312.         jra     FOPR02          | Return w/o range check
  313. |
  314. |
  315. FPA045:
  316.         |dsw    0
  317. |
  318.         cmpw    d1,d0
  319.         jcc     FPA060          | J/ op1.exp >= op2.exp
  320. |
  321.         exg     d2,d3           | Flip mantissas
  322.         exg     d0,d1
  323.         exg     a2,a3
  324. |
  325. FPA060:
  326.         subw    d0,d1
  327.         negw    d1
  328.         cmpiw   #24,d1
  329.         jhi     FOPRSL          | J/ op2 too small to matter
  330. |
  331.         lsrl    d1,d3
  332.         cmpal   a2,a3
  333.         jne     FPS100          | J/ subtract operation
  334. |
  335.         addl    d3,d2
  336.         jcc     FOPRSL          | J/ no carry out
  337. |
  338.         roxrl   #1,d2           | Handle carry out
  339.         addqw   #1,d0           | Bump the exponent
  340.         jra     FOPRSL
  341. |
  342. |
  343. FPS100:
  344.         subl    d3,d2           | Do the subtract
  345.         jeq     FZERRS          | J/ zero result
  346.         jcc     FPS110
  347. |
  348.         negl    d2
  349. |
  350.         moveal  a3,a2           | Flip sign
  351. |
  352. FPS110:
  353.         andl    d2,d2           | Normalization section
  354.         jmi     FOPRSL          | J/ normalized
  355. |
  356.         subqw   #1,d0           | Decrease exponent value
  357. FPS120:
  358.         addl    d2,d2           | Left shift d2
  359.         dbmi    d0,FPS120       | J/ not normalized
  360. |
  361.         jra     FOPRSL
  362. /*
  363. |
  364. |       page
  365. |
  366. |  FPMUL
  367. |  =====
  368. |  Single precision multiply routine.
  369. |
  370. */
  371. FPMUL:
  372.         bsr     GETFP2          | Fetch both operands
  373.         movew   a2,d4
  374.         movew   a3,d5
  375.         eorw    d4,d5
  376.         moveaw  d5,a2           | /* Result's sign */
  377. |
  378.         andw    d0,d0
  379.         jne     FPM010          | J/ operand <> 0.0
  380. |
  381.         cmpiw   #0xFF,d1
  382.         jeq     FNANRS          | J/ 0.0 * NaN,INF -> NaN
  383.         jra     FZERRS          | J/ 0.0 * 0.0,num -> 0.0
  384. |
  385. FPM010:
  386.         cmpiw   #0xFF,d0
  387.         jne     FPM020          | J/ operand is a number
  388. |
  389.         lsll    #1,d2
  390.         jne     FNANRS          | J/ NaN *  ?  -> NaN
  391. |
  392.         andw    d1,d1
  393.         jeq     FNANRS          | J/ INF * 0.0 -> NaN
  394. |
  395.         cmpiw   #0xFF,d1
  396.         jne     FINFRS          | J/ INF * num -> INF
  397.         lsll    #1,d3
  398.         jeq     FINFRS          | J/ INF * INF -> INF
  399.         jra     FNANRS          | J/ INF * NaN -> NaN
  400. |
  401. FPM020:
  402.         andw    d1,d1
  403.         jeq     FZERRS          | J/ num * 0.0 -> 0.0
  404. |
  405.         cmpiw   #0xFF,d1
  406.         jne     FPM040          | J/ num * num
  407. |
  408.         lsll    #1,d3
  409.         jeq     FINFRS          | J/ num * INF -> INF
  410.         jra     FNANRS          | J/ num * NaN -> NaN
  411. |
  412. |
  413. FPM040:
  414.         addw    d1,d0           | Calculate result`s exponent
  415.         subw    #FBIAS-1,d0     | Remove double bias, assume shift
  416. |
  417. #if (CPU != MC68000 && CPU != MC68010)
  418.         mulul   d2,d2:d3
  419. #else
  420. |       ifne    comp64-1        ;+++++
  421.         movew   d2,d4           | Copy Lo byte to d4 (B)
  422.         movew   d3,d5           | Copy Lo byte to d5 (D)
  423.         swap    d2              | Position for high byte multiply (A)
  424.         mulu    d2,d5           | A mid multiplication result (AD)
  425.         swap    d3              | Position for high byte multiply (C)
  426.         mulu    d3,d4           | A mid multiplication result (CB)
  427.         mulu    d3,d2           | High order words multiplied (CA)
  428.         addl    d4,d5           | Combine mid multiply results (CB + AD)
  429.         subxw   d5,d5           | Preserve carry while...
  430.         negw    d5              | ...positioning the...
  431.         swap    d5              | ...result before...
  432.         addl    d5,d2           | ...combining partial products
  433. #endif
  434. |       endc                    ;+++++
  435.         jmi     FOPRSL          | Result normalized w/o shift
  436. |
  437.         subqw   #1,d0
  438.         addl    d2,d2           | Do a left shift
  439.         jra     FOPRSL
  440. /*
  441. |
  442. |       page
  443. |
  444. |  FPDIV
  445. |  =====
  446. |  Single precision division operation.
  447. |
  448. */
  449. FPRDIV:
  450.         bsr     GETFP2          | Get both operands
  451.         exg     a2,a3           | Flip the operands
  452.         exg     d0,d1
  453.         exg     d2,d3
  454.         jra     FPD001
  455. |
  456. FPDIV:
  457.         bsr     GETFP2
  458. |
  459. FPD001:
  460.         movew   a2,d4           | /* Compute result's sign */
  461.         movew   a3,d5
  462.         eorw    d4,d5
  463.         moveaw  d5,a2
  464. |
  465.         andw    d0,d0
  466.         jne     FPD010          | J/ divisor is not zero
  467. |
  468.         andw    d1,d1
  469.         jeq     FNANRS          | J/ 0.0 / 0.0 -> NaN
  470.         cmpiw   #0xFF,d1
  471.         jne     FINFRS          | J/ num / 0.0 -> INF
  472.         lsll    #1,d3
  473.         jeq     FINFRS          | J/ INF / 0.0 -> INF
  474.         jra     FNANRS          | J/ NaN / 0.0 -> NaN
  475. |
  476. FPD010:
  477.         cmpiw   #0xFF,d0
  478.         jne     FPD020          | J/ divisor is a normal number
  479. |
  480.         lsll    #1,d2
  481.         jne     FNANRS          | J/  ?  / NaN -> NaN
  482.         andw    d1,d1
  483.         jeq     FZERRS          | J/ 0.0 / INF -> 0.0
  484.         cmpiw   #0xFF,d1
  485.         jne     FUNFRS          | J/ num / INF -> 0.0 (w/ underflow)
  486.         jra     FNANRS          | J/ NaN,INF / INF -> NaN
  487. |
  488. FPD020:
  489.         andw    d1,d1
  490.         jeq     FZERRS          | J/ 0.0 / num -> 0.0
  491.         cmpiw   #0xFF,d1
  492.         jne     FPD040          | J/ num / num
  493. |
  494.         lsll    #1,d3
  495.         jeq     FINFRS          | J/ INF / num -> INF
  496.         jra     FNANRS          | J/ NaN / num -> NaN
  497. /*
  498. |
  499. |
  500. |  Division Algorithm:   A/(B+C) = A/B - A/B*C/B + A/B*(C/B)^2 - ...
  501. |                                = A/B * (1 - C/B + (C/B)^2)
  502. |
  503. |  Choose C to be the low order byte of the 24 bit mantissa.  The
  504. |  third and succeeding corrections terms (C squared and above)
  505. |  can be neglected because they are at least thirty bits down.
  506. |
  507. */
  508. FPD040:
  509.         subw    d1,d0
  510.         negw    d0
  511.         addw    #FBIAS,d0       | Restore bias
  512. #if (CPU != MC68000 && CPU != MC68010)
  513.         lsrl    #1,d3
  514.         clrl    d4
  515.         divul   d2,d3:d4
  516.         movel   d4,d2
  517. #else
  518. |       ifne    comp64-1        ;+++++
  519.         exg     d2,d3
  520. |
  521.         movel   d2,d4           | Copy A
  522.         lsrl    #1,d4           | Insure no overflow during divide
  523.         swap    d3
  524.         divu    d3,d4           | Top fifteen bits of A/B
  525.         movew   d4,d2           | A/B ultimately into d2
  526.         movew   d4,d5           | Copy for later opn (A/B * C)
  527.         swap    d2              | Position MS word
  528.         clrw    d4              | Zero low order bits in d4
  529.         divu    d3,d4           | Division of shifted remainder
  530.         movew   d4,d2           | Complete A/B operation
  531. |
  532.         movel   d3,d4
  533.         clrw    d4              | Create a shifted C in d4
  534.         lsrl    #1,d4           | Insure no division overflow
  535.         divu    d3,d4           | Division (complete since C is 8 bits)
  536. |
  537.         mulu    d5,d4           | A/B * C
  538.         lsrl    #8,d4           | Position A/B * C
  539.         lsrl    #7,d4
  540.         subl    d4,d2
  541. #endif
  542. |       endc                    ;+++++
  543.         jmi     FOPRSL          | J/ result normalized
  544. |
  545.         subqw   #1,d0
  546.         addl    d2,d2           | Normalize it
  547.         jra     FOPRSL
  548. /*
  549. |
  550. |       page
  551. |
  552. |  FPCMP
  553. |  =====
  554. |  Single Precision comparison routine.
  555. |
  556. |  Compare the two arguments provided and set the condition code
  557. |  register bits N, Z, and V as follows:
  558. |
  559. |      N  Z  V   Relation
  560. |      =  =  =   ====================================
  561. |      1  0  0   X > Y   (X is top argument on stack)
  562. |      0  1  0   X = Y   (within FFUZZ specification)
  563. |      0  0  0   X < Y
  564. |      0  0  1   X does not compare to Y
  565. |
  566. |
  567. */
  568. |       .set    FFUZZ,20                | Twenty bits of fuzz
  569. FPCMP:
  570.         bsr     GETFP2
  571.         cmpiw   #0xFF,d0
  572.         jne     FPC020          | J/ X is not INF or NaN
  573. |
  574.         lsll    #1,d2           | Remove implicit bit
  575.         jeq     FPC005          | J/ X is INF
  576. |
  577. FPC001:
  578.         |dsw    0               | **  X does not compare to Y  **
  579.         moveq   #CCRV,d0        | CCR V bit
  580.         movew   d0,ccr
  581.         jmp     a0@             | Return
  582. |
  583. FPC005:
  584.         cmpiw   #0xFF,d1
  585.         jne     FPC009          | J/ Y is not INF or NaN
  586. |
  587.         lsll    #1,d3
  588.         jne     FPC001          | J/ Y is NaN (does not compare)
  589. |
  590.         cmpaw   a2,a3
  591.         jeq     FPC001          | /* J/ INF's with same sign - no compare */
  592. |
  593. FPC009:
  594.         movew   a2,d0           | /* Result based on compl. of X's sign */
  595.         eoriw   #CCRN,d0
  596.         jra     FPC011
  597. |
  598. FPC010:
  599.         movew   a3,d0           | /* Set result based on Y's sign */
  600. FPC011:
  601.         andiw   #CCRN,d0
  602.         movew   d0,ccr
  603.         jmp     a0@
  604. |
  605. |
  606. FPC020:
  607.         cmpiw   #0xFF,d1
  608.         jne     FPC030          | J/ Y is not NaN or INF
  609. |
  610.         lsll    #1,d3
  611.         jne     FPC001          | J/ Y is NaN - no comparison
  612.         jra     FPC010          | /* Result is based on Y's sign */
  613. |
  614. FPC030:
  615.         cmpaw   a2,a3
  616.         jne     FPC010          | /* J/ signs different - use Y's sign */
  617. |
  618.         movew   d0,d4
  619.         movew   d0,d5           | /* Assume X's exp is larger */
  620.         subw    d1,d4           | Calc difference in exponents
  621.         jpl     FPC031          | J/ positive
  622.         movew   d1,d5           | /* Y's exp is larger */
  623.         negw    d4
  624. FPC031:
  625.         |dsw    0
  626. |
  627.         lsrw    #1,d4
  628.         jeq     FPC040          | Must subtract to obtain result
  629. |
  630.         subw    d0,d1
  631.         subxw   d0,d0           | Set d0 to sign of Y[exp]-X[exp]
  632.         movew   a2,d1
  633.         eorw    d1,d0           | Flip if negative values
  634.         jra     FPC011          | Result based on value in d0
  635. |
  636. FPC040:
  637.         movew   d5,sp@- | Save max exp value, return address
  638.         movel   a0,sp@-
  639. |
  640.         movew   a2,d5
  641.         notw    d5              | Flip sign of opnd (force subtract)
  642.         moveaw  d5,a2
  643. |
  644.         pea     FPC041
  645.         movel   sp@+,a0 | Return address in a0
  646. |
  647.         jra     FPXSUB
  648. |
  649. FPC041:
  650.         movel   sp@+,d0
  651.         movel   sp@,a0
  652.         movel   d0,sp@
  653.         movel   a0,sp@-
  654. |
  655.         bsr     GETFP1          | Fetch and unpack result
  656. |
  657.         movew   sp@+,d5 | Recall max exp value
  658. |
  659.         andw    d0,d0
  660.         jeq     FPC050          | J/ zero result
  661. |
  662.         subw    d0,d5
  663.         cmpiw   #FFUZZ,d5
  664.         jge     FPC050          | J/ within FFUZZ specification - zero
  665. |
  666.         movew   a2,d0           | Sign of result into d0
  667.         jra     FPC011          | Comparison result from sign of sub
  668. |
  669. FPC050:
  670.         subw    d0,d0           | Force CCR to say "Z"
  671.         jmp     a0@             | Return
  672. /*
  673. |
  674. |       page
  675. |
  676. |  GETFP2
  677. |  ======
  678. |  Routine called to extract two single precision arguments from
  679. |  the system stack and place them in the 68000`s registers.
  680. |
  681. */
  682. GETFP2:
  683.         moveal  sp@+,a1 | /* GETFP2's return address */
  684.         moveal  sp@+,a0 | Calling routines return address
  685. |
  686.         movel   sp@+,d0 | Get TOS (source) operand
  687.         asll    #1,d0           | Sign bit to carry
  688.         subxw   d2,d2           | Fill d2 with sign bit
  689.         movew   d2,a2           | Sign bit info to a2
  690.         roll    #8,d0           | Left justify mantissa, position exp
  691.         movel   d0,d2           | Copy into mantissa register
  692.         andiw   #0xFF,d0                | Mask to exponent field
  693.         jeq     GETF21          | J/ zero value
  694. |
  695.         andiw   #0xFE00,d2      | Zero sign bit and exponent bits in d2
  696.         lsrl    #1,d2           | Position mantissa
  697.         bset    #31,d2          | Set implicit bit in d2
  698. |
  699. GETF21:
  700.         |dsw    0
  701. |
  702.         movel   sp@+,d1 | Get NOS (source) operand
  703.         asll    #1,d1           | Sign bit to carry
  704.         subxw   d3,d3           | Replicate sign bit throughout d3
  705.         movew   d3,a3           | Sign bit info into a3
  706.         roll    #8,d1           | Left justify mantissa, position exp
  707.         movel   d1,d3           | Copy into mantissa register
  708.         andiw   #0xFF,d1                | Mask to exponent field
  709.         jeq     GETF22          | J/ zero value
  710. |
  711.         andiw   #0xFE00,d3      | Zero sign bit and exponent bits in d3
  712.         lsrl    #1,d3           | Position mantissa
  713.         bset    #31,d3          | Set implicit bit in d3
  714. |
  715. GETF22:
  716.         jmp     a1@             | Return to caller, its ret addr in a0
  717. /*
  718. |
  719. |
  720. |       page
  721. |
  722. |  GETFP1
  723. |  ======
  724. |  Routine called to extract a single precision argument from the
  725. |  system stack and place it (unpacked) into the 68000's registers.
  726. |
  727. */
  728. GETFP1:
  729.         moveal  sp@+,a1 | /* Get GETFP1's return address */
  730.         moveal  sp@+,a0 | Get calling routines return address
  731. |
  732.         movel   sp@+,d0 | Get argument
  733.         asll    #1,d0           | Sign bit into carry
  734.         subxw   d2,d2           | Replicate sign bit throughout d2
  735.         movew   d2,a2           | Sign bit info into a2
  736.         roll    #8,d0           | Left justify mantissa, position exp
  737.         movel   d0,d2
  738.         andiw   #0xFF,d0                | Mask to exponent field
  739.         jeq     GETF11          | J/ zero value
  740. |
  741.         andiw   #0xFE00,d2      | Zero sign bit and exponent bits in d2
  742.         lsrl    #1,d2           | Position mantissa
  743.         bset    #31,d2          | Set implicit bit
  744. |
  745. GETF11:
  746.         jmp     a1@             | Return to caller, its ret addr in a0
  747. /*
  748. |
  749. |
  750. |       page
  751. |
  752. |  FOPRSL
  753. |  ======
  754. |  Single precision floating point result (main entry w/ round).
  755. |  Mantissa in D2, exponent in D0, sign in A2, and return address
  756. |  in A0.  Place a format value on the stack.
  757. |
  758. */
  759. FOPRSL:
  760.         addl    #0x80,d2                | Round the value
  761.         jcc     FOPR01          | J/ no carry out
  762. |
  763.         roxrl   #1,d2           | Adjust mantissa and exponent
  764.         addqw   #1,d0
  765. |
  766. FOPR01:
  767.         andw    d0,d0
  768.         jle     FUNFRS          | J/ underflow
  769. |
  770.         cmpiw   #0xFF,d0                | Check for overflow
  771.         jge     FINFRS          | J/ overflow
  772. |
  773. FOPR02:
  774.         andiw   #0xFF00,d2      | Trim mantissa
  775.         asll    #1,d2           | Drop implicit bit
  776.         addw    d0,d2           | Blend in the exponent
  777.         rorl    #8,d2           | Reposition value
  778.         movew   a2,d0
  779.         aslw    #1,d0           | Sign bit into carry/extend
  780.         roxrl   #1,d2           | Finish construction of value
  781.         movel   d2,sp@-
  782. |
  783.         moveb   #0,FPERR        | No floating point error
  784.         jmp     a0@             | Return
  785. |
  786. |
  787. |
  788. FNANRS:
  789.         moveq   #-1,d0          | Set d0 to 0xFFFFFFFF
  790.         movel   d0,sp@- | NaN value
  791. |
  792.         moveb   #ERNAN,FPERR
  793.         moveb   #-1,NANFLG
  794.         jmp     a0@
  795. |
  796. |
  797. FINFRS:
  798.         movel   a2,d0           | Get sign information
  799.         movel   #0xFF000000,d1
  800.         aslw    #1,d0
  801.         roxrl   #1,d1
  802.         movel   d1,sp@-
  803. |
  804.         moveb   #EROVF,FPERR
  805.         moveb   #-1,INFFLG
  806.         jmp     a0@
  807. |
  808. |
  809. FUNFRS:
  810.         moveb   #ERUNF,FPERR
  811.         moveb   #-1,UNFFLG
  812.         jra     FZER01
  813. |
  814. |
  815. FZERRS:
  816.         moveb   #0,FPERR
  817. |
  818. |
  819. FZER01:
  820.         subl    d0,d0
  821.         movel   d0,sp@-
  822.         jmp     a0@
  823. |
  824. |
  825. |       end