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

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. 01h,04sep98,yh   fixed DAINT for floor function.
  9. 01g,14mar95,tmk  inverted conditional assembly logic for 68000/10 to allow for
  10.  CPUs other than 68020.
  11. 01f,23aug92,jcf  changed bxxx to jxx.
  12. 01e,26may92,rrr  the tree shuffle
  13. 01d,30mar92,kdl  added include of "uss_fp.h"; commented-out ".set" directives
  14.  (SPR #1398).
  15. 01c,04oct91,rrr  passed through the ansification filter
  16.   -changed ASMLANGUAGE to _ASMLANGUAGE
  17.   -changed copyright notice
  18. 01b,29jan91,kdl  added include of vxWorks.h for conditional assembly.
  19. 01a,28jan91,kdl  modified original US Software version to use conditional
  20.  assembly for 68000/10 multiply and divide operations.
  21. */
  22. /*
  23. DESCRIPTION
  24. |       ttl     FPAC 68K/DPOPNS: IEEE Double Precision Operations
  25. |DPOPNS idnt    1,0             ; IEEE Double Precision Operations
  26. |                               ; DPOPNS.A68
  27. |
  28. | * * * * * * * * * *
  29. |
  30. |       Copyright (c) 1985,1989 by
  31. |       United States Software Corporation
  32. |       14215 N.W. Science Park Drive
  33. |       Portland, Oregon  97229
  34. |
  35. |       This software is furnished under a license and may be used
  36. |       and copied only in accordance with the terms of such license
  37. |       and with the inclusion of the above copyright notice.
  38. |       This software or any other copies thereof may not be provided
  39. |       or otherwise made available to any other person.  No title to
  40. |       and ownership of the software is hereby transferred.
  41. |
  42. |       The information in this software is subject to change without
  43. |       notice and should not be construed as a commitment by United
  44. |       States Software Corporation.
  45. |
  46. |       Released:       12 January 1989         V2.0
  47. |
  48. | * * * * * * * * * *
  49. |
  50. |
  51. NOMANUAL
  52. */
  53. #define _ASMLANGUAGE
  54. #include "vxWorks.h"
  55. #include "uss_fp.h"
  56. |      .set    comp64,0                |flag for 64 bit multiply/divide
  57. |       opt     BRS             ; Default to forward branches SHORT
  58. |
  59.         .globl  DFLOAT
  60.         .globl  DFIX
  61.         .globl  DINT
  62.         .globl  DAINT
  63.         .globl  DPADD
  64.         .globl  DPMUL
  65.         .globl  DPDIV
  66.         .globl  DPRDIV
  67.         .globl  DPCMP
  68. |
  69.         .globl  DNANRS
  70.         .globl  DINFRS
  71.         .globl  DUNFRS
  72.         .globl  DZERRS
  73. |
  74.         .globl  GETDP1,DOPRSL
  75. |
  76. |
  77. |
  78. |       .set    DBIAS,1023              | Double precision format exponent bias
  79. |
  80. |
  81. |       .set    CCRC,0x01               | Carry bit in CCR
  82. |       .set    CCRV,0x02               | Overflow bit in CCR
  83. |       .set    CCRZ,0x04               | Zero bit in CCR
  84. |       .set    CCRN,0x08               | Negative bit in CCR
  85. |       .set    CCRX,0x10               | Extend bit in CCR
  86. |
  87. |
  88. |       .set    ERNAN,3
  89. |       .set    EROVF,2
  90. |       .set    ERUNF,1
  91. |
  92. |       xref    FPERR
  93. |       xref    NANFLG
  94. |       xref    INFFLG
  95. |       xref    UNFFLG
  96. |
  97. |
  98.         .text
  99. |
  100. /*
  101. |       page
  102. |
  103. |  DFLOAT
  104. |  ======
  105. |  Float the integer value in D0:D1 into a double precision floating
  106. |  point value on the stack.
  107. |
  108. */
  109. DFLOAT:
  110.         moveal  sp@+,a0 | Return addr into a0
  111.         subal   a2,a2           | Set a2 = 0
  112.         andl    d0,d0
  113.         jne     DFLT01          | J/ value <> 0
  114.         andl    d1,d1
  115.         jne     DFLT02          | J/ value > 0
  116. |
  117.         movel   d0,sp@- | Place 0 value on stack
  118.         movel   d0,sp@-
  119.         jmp     a0@             | Return
  120. |
  121. DFLT01:
  122.         jge     DFLT02          | J/ value > 0
  123.         subql   #1,a2           | Set a2 = -1
  124.         negl    d1
  125.         negxl   d0
  126. |
  127. DFLT02:
  128.         movel   #DBIAS+63,d2    | Default bias value
  129.         andl    d0,d0
  130.         jne     DFLT03          | J/ 32 bit shift not required
  131. |
  132.         subw    #32,d2          | Reduce exponent
  133.         exg     d0,d1           | Do shift (since d0 is zero)
  134. |
  135. DFLT03:
  136.         cmpil   #0x0000FFFF,d0
  137.         jhi     DFLT04          | J/ 16 bit shift not required
  138. |
  139.         swap    d0              | Do the shift
  140.         swap    d1
  141.         movew   d1,d0
  142.         clrw    d1
  143.         subiw   #16,d2
  144. |
  145. DFLT04:
  146.         andl    d0,d0
  147.         jmi     DFLT07          | J/ value normalized
  148. |
  149. DFLT05:
  150.         subqw   #1,d2           | Dec exponent, shift mantissa
  151.         asll    #1,d1
  152.         roxll   #1,d0
  153.         jpl     DFLT05          | J/ more shifts to do
  154. |
  155. DFLT07:
  156.         exg     d0,d2           | Position to standard d0/d2:d3/a2 form
  157.         movel   d1,d3
  158.         jra     DOPRSL          | J/ double precision result (w/ round)
  159. /*
  160. |
  161. |       page
  162. |
  163. |  DFIX
  164. |  ====
  165. |  Routine to convert the double precision argument on the stack
  166. |  to an integer value (with a dropoff flag).
  167. |
  168. */
  169. DFIX:
  170.         bsr     GETDP1          | Extract/unpack one double prec val
  171.         bsr     DFIX00          | Use internal routine
  172.         jmp     a0@             | Return to caller
  173. |
  174. |
  175. DFIX00:
  176.         andw    d0,d0
  177.         jne     DFIX01          | J/ value <> 0.0
  178. |
  179.         subl    d0,d0           | Return a zero value, no drop off
  180.         clrl    d1
  181.         rts
  182. |
  183. DFIX01:
  184.         cmpiw   #DBIAS,d0
  185.         jcc     DFIX02          | J/ abs() >= 1.0  [BCC == BHS]
  186. |
  187.         clrl    d0              | Return a zero value
  188.         clrl    d1
  189.         orib    #CCRC+CCRX,ccr  | Set carry/extend bits
  190. | ##    ORI     #$11,CCR
  191.         rts
  192. |
  193. DFIX02:
  194.         subiw   #DBIAS+63,d0
  195.         jlt     DFIX03          | J/ abs() < 2^63
  196. |
  197.         moveq   #-1,d0          | Set d0:d1 to the maximum integer value
  198.         moveq   #-1,d1
  199.         lsrl    #1,d0           | d0:d1 = 0x7FFFFFFFFFFFFFFF
  200.         movel   a2,d2
  201.         subl    d2,d1           | Account for the sign of the arg.
  202.         subxl   d2,d0
  203.         rts
  204. |
  205. DFIX03:
  206.         clrl    d1              | Clear bit drop off accum
  207. |
  208.         negw    d0              | Positive shift count
  209.         cmpiw   #32,d0
  210.         jlt     DFIX04          | J/ less than a word shift
  211. |
  212.         andl    d3,d3
  213.         sne     d1              | Set d1 = 0FFH if d3 <> 0
  214. |
  215.         movel   d2,d3
  216.         clrl    d2
  217. |
  218.         subiw   #32,d0
  219. |
  220. DFIX04:
  221.         cmpiw   #16,d0
  222.         jlt     DFIX05          | J/ less than a swap left
  223. |
  224.         orw     d3,d1           | Accum any bits dropped off
  225. |
  226.         movew   d2,d3           | Do a swap shift (16 bits)
  227.         swap    d3
  228.         clrw    d2
  229.         swap    d2
  230. |
  231.         subiw   #16,d0
  232. |
  233. DFIX05:
  234.         subqw   #1,d0
  235.         jlt     DFIX07          | J/ shifting complete
  236. |
  237. DFIX06:
  238.         lsrl    #1,d2
  239.         roxrl   #1,d3
  240. |
  241.         roxll   #1,d1
  242. |
  243.         dbra    d0,DFIX06
  244. |
  245. DFIX07:
  246.         cmpaw   #0,a2           | Check for negative value
  247.         jeq     DFIX08          | J/ positive
  248. |
  249.         negl    d3
  250.         negxl   d2
  251. |
  252. DFIX08:
  253.         moveq   #-1,d0
  254.         addl    d1,d0           | Set carry if bits lost
  255. |
  256.         exg     d2,d0           | Move integer result to d0:d1
  257.         exg     d3,d1
  258.         rts
  259. /*
  260. |
  261. |       page
  262. |
  263. |  DINT
  264. |  ====
  265. |  Return the largest integer smaller than the argument provided
  266. |
  267. */
  268. DINT:
  269.         bsr     GETDP1
  270.         bsr     DFIX00
  271. |
  272.         jcc     DINT00          | J/ no bits lost
  273.         cmpaw   #0,a2
  274.         jeq     DINT00          | J/ not negative
  275.         subql   #1,d1           | Decrement integer value
  276.         jcc     DINT00          | J/ no borrow
  277.         subql   #1,d0
  278. DINT00:
  279.         jmp     a0@
  280. /*
  281. |
  282. |       page
  283. |
  284. |  DAINT
  285. |  =====
  286. |  Floating point corollary to the DINT function
  287. |
  288. */
  289. DAINT:
  290.         bsr     GETDP1
  291.         cmpiw   #DBIAS+52,d0    | Check for value too large
  292.         jcc     DAIN10          | J/ return with same value
  293. |
  294.         movew   d0,d4           | Copy the exponent value
  295.         subiw   #DBIAS-1,d4
  296.         jgt     DAIN02          | J/ abs() >= 1.0
  297. |
  298. cmpiw   #0, d2          | check if mantissa is zero
  299. jne     DAIN09
  300. cmpiw   #0, d3
  301. jeq     DAIN08
  302. DAIN09:
  303.         movew   a2,d4
  304.         jne     DAIN01          | J/ 0.0 > value > -1.0
  305. |
  306. DAIN08:
  307.         clrl    sp@-            | Return a zero value
  308.         clrl    sp@-
  309.         jmp     a0@
  310. |
  311. DAIN01:
  312.         clrl    sp@-            | Return -1.0
  313.         movel   #0xBFF00000,sp@-
  314.         jmp     a0@
  315. |
  316. DAIN02:
  317.         moveq   #-1,d1          | Fill d1 with ones
  318. |
  319.         cmpiw   #32,d4          | See which word needs to be masked
  320.         jle     DAIN03          | J/ low order word zeroed, mask hi wd
  321. |
  322.         subiw   #32,d4
  323.         lsrl    d4,d1           | Adjust mask
  324.         movel   d3,d4
  325.         andl    d1,d4           | Extract bits to drop
  326.         jeq     DAIN10          | J/ no drop off, return as provided
  327. |
  328.         eorl    d4,d3           | Strip the bits
  329.         cmpaw   #0,a2
  330.         jeq     DAIN10          | J/ positive number
  331. |
  332.         clrl    d4              | (for ADDX below)
  333.         addql   #1,d1           | Change mask to increment value
  334.         addl    d1,d3
  335.         addxl   d4,d2           | Perform any carry
  336.         jra     DAIN04          | J/ rejoin flow
  337. |
  338. DAIN03:
  339.         lsrl    d4,d1           | Adjust high word mask
  340.         movel   d2,d4
  341.         andl    d1,d4           | Get bits to strip
  342.         eorl    d4,d2           | Strip bits
  343. |
  344.         orl     d3,d4           | Record any dropped bits from lo word
  345.         clrl    d3              | Clear the low word
  346. |
  347.         tstl    d4
  348.         jeq     DAIN10          | J/ no dropoff
  349.         cmpaw   #0,a2
  350.         jeq     DAIN10          | J/ positive number
  351. |
  352.         addql   #1,d1           | Turn mask into increment value
  353.         addl    d1,d2
  354. |
  355. DAIN04:
  356.         jcc     DAIN10          | J/ no overflow
  357. |
  358.         roxrl   #1,d2           | Right shift the mantissa
  359. |**     ROXR.L  #1,D3           ; (not nec -> mantissa = 80..00)
  360.         addqw   #1,d0           | Bump the exponent
  361. |
  362. DAIN10:
  363.         jra     DOPRSL          | Return computed value
  364. /*
  365. |
  366. |       page
  367. |
  368. |  DPADD
  369. |  =====
  370. |  Double precision add routine
  371. |
  372. */
  373. DPADD:
  374.         bsr     GETDP2          | Fetch both operands
  375.         cmpiw   #0x7FF,d0
  376. |
  377.         jne     DPA010          | J/ operand not NaN/INF
  378. |
  379.         lsll    #1,d2           | Remove implicit bit
  380.         jne     DNANRS          | J/  ?  + NaN -> NaN
  381. |
  382.         cmpiw   #0x7FF,d1
  383.         jne     DINFRS          | J/  0,num + INF -> INF
  384. |
  385.         lsll    #1,d4           | Remove implicit bit
  386.         jne     DNANRS          | J/ INF + NaN -> NaN
  387. |
  388.         cmpal   a2,a3
  389.         jne     DNANRS          | J/ INF - INF -> NaN
  390.         jra     DINFRS          |    INF + INF -> INF
  391. |
  392. |
  393. DPA010:
  394.         cmpiw   #0x7FF,d1
  395.         jne     DPA040          | J/ not NaN or INF
  396. |
  397.         lsll    #1,d4           | Remove implicit bit
  398.         jne     DNANRS          | J/ NaN + 0,num -> NaN
  399. |
  400.         moveal  a3,a2           | Move sign over
  401.         jra     DINFRS          | INF result
  402. |
  403. |
  404. DPXSUB:
  405.         |dsw    0               | Entry for DPCMP
  406. |
  407. DPA040:
  408.         andw    d1,d1
  409.         jeq     DOPRSL          | J/ 0,num + 0 -> 0,num
  410. |
  411.         andw    d0,d0
  412.         jne     DPA045          | J/ no zeroes involved
  413. |
  414.         movew   d1,d0           | Copy over data
  415.         movel   d4,d2
  416.         movel   d5,d3
  417.         moveal  a3,a2
  418.         jra     DOPRSL
  419. |
  420. |
  421. DPA045:
  422.         |dsw    0
  423. |
  424.         cmpw    d1,d0
  425.         jcc     DPA060          | J/ op1.exp >= op2.exp
  426. |
  427.         exg     d2,d4           | Flip mantissas
  428.         exg     d3,d5
  429.         exg     d0,d1
  430.         exg     a2,a3
  431. |
  432. DPA060:
  433.         subw    d0,d1
  434.         negw    d1
  435.         cmpiw   #53,d1
  436.         jhi     DOPRSL          | J/ op2 too small to matter
  437. |
  438.         cmpiw   #32,d1
  439.         jlt     DPA061          | J/ less than a word shift
  440. |
  441.         movel   d4,d5
  442.         clrl    d4
  443. |
  444.         subiw   #32,d1
  445. |
  446. DPA061:
  447.         cmpiw   #16,d1
  448.         jlt     DPA062          | J/ less than a swap shift left
  449. |
  450.         movew   d4,d5           | Do a swap shift (16 bits)
  451.         clrw    d4
  452.         swap    d5
  453.         swap    d4
  454. |
  455.         subiw   #16,d1
  456. |
  457. DPA062:
  458.         moveq   #-1,d7          | Mask in d7
  459.         lsrl    d1,d7
  460.         rorl    d1,d4
  461.         rorl    d1,d5
  462.         andl    d7,d5           | Trim bits
  463.         eorl    d4,d5           | Mix in d4 -> d5 bits
  464.         andl    d7,d4           | Strip d4 -> d5 bits
  465.         eorl    d4,d5           | Finish   LSL  d0,d4:d5
  466. |
  467.         cmpal   a2,a3
  468.         jne     DPS100          | J/ subtract operation
  469. |
  470.         addl    d5,d3
  471.         addxl   d4,d2
  472.         jcc     DOPRSL          | J/ no carry out
  473. |
  474.         roxrl   #1,d2           | Handle carry out
  475.         roxrl   #1,d3
  476.         addqw   #1,d0           | Bump the exponent
  477.         jra     DOPRSL
  478. |
  479. |
  480. DPS100:
  481.         subl    d5,d3           | Do the subtract
  482.         subxl   d4,d2
  483.         jcc     DPS110
  484. |
  485.         negl    d3
  486.         negxl   d2
  487. |
  488.         moveal  a3,a2           | Flip sign
  489. |
  490. DPS110:
  491.         andl    d2,d2           | Normalization section
  492.         jne     DPS115          | J/ top word is not zero
  493. |
  494.         exg     d2,d3
  495.         subiw   #32,d0          | Reduce exponent appropriately
  496. |
  497.         andl    d2,d2
  498.         jeq     DZERRS          | J/ zero result
  499. |
  500. DPS115:
  501.         cmpil   #0x0000FFFF,d2
  502.         jhi     DPS118          | J/ less than a swap shift left
  503. |
  504.         swap    d2              | Do a swap shift (16 bits)
  505.         swap    d3
  506.         movew   d3,d2
  507.         clrw    d3
  508. |
  509.         subiw   #16,d0
  510. |
  511. DPS118:
  512.         tstl    d2
  513.         jmi     DOPRSL          | J/ normalized
  514. |
  515.         subqw   #1,d0           | Decrease exponent value
  516. DPS120:
  517.         lsll    #1,d3
  518.         roxll   #1,d2
  519.         dbmi    d0,DPS120       | J/ not normalized
  520. |
  521.         jra     DOPRSL
  522. /*
  523. |
  524. |       page
  525. |
  526. |  DPMUL
  527. |  =====
  528. |  Single precision multiply routine.
  529. |
  530. */
  531. DPMUL:
  532.         bsr     GETDP2          | Fetch both operands
  533.         movew   a2,d6
  534.         movew   a3,d7
  535.         eorw    d6,d7
  536.         moveaw  d7,a2           | /* Result's sign */
  537. |
  538.         andw    d0,d0
  539.         jne     DPM010          | J/ operand <> 0.0
  540. |
  541.         cmpiw   #0x7FF,d1
  542.         jeq     DNANRS          | J/ 0.0 * NaN,INF -> NaN
  543.         jra     DZERRS          | J/ 0.0 * 0.0,num -> 0.0
  544. |
  545. DPM010:
  546.         cmpiw   #0x7FF,d0
  547.         jne     DPM020          | J/ operand is a number
  548. |
  549.         lsll    #1,d2
  550.         jne     DNANRS          | J/ NaN *  ?  -> NaN
  551. |
  552.         andw    d1,d1
  553.         jeq     DNANRS          | J/ INF * 0.0 -> NaN
  554. |
  555.         cmpiw   #0x7FF,d1
  556.         jne     DINFRS          | J/ INF * num -> INF
  557.         lsll    #1,d4
  558.         jeq     DINFRS          | J/ INF * INF -> INF
  559.         jra     DNANRS          | J/ INF * NaN -> NaN
  560. |
  561. DPM020:
  562.         andw    d1,d1
  563.         jeq     DZERRS          | J/ num * 0.0 -> 0.0
  564. |
  565.         cmpiw   #0x7FF,d1
  566.         jne     DPM040          | J/ num * num
  567. |
  568.         lsll    #1,d4
  569.         jeq     DINFRS          | J/ num * INF -> INF
  570.         jra     DNANRS          | J/ num * NaN -> NaN
  571. |
  572. |
  573. DPM040:
  574.         addw    d1,d0           | Calculate result`s exponent
  575.         subw    #DBIAS-1,d0     | Remove double bias, assume shift
  576.         movew   d0,a3           | Save exponent in a3, free up d0
  577. |
  578. DPM050:
  579.         |dsw    0               | Entry for DPDIV......
  580.         movel   d2,d0           | A * D
  581.         movel   d5,d1
  582. #if (CPU != MC68000 && CPU != MC68010)
  583. |       ifne    comp64-1        ;+++++
  584.         mulul   d0,d0:d1
  585. #else
  586.         bsr     DPM500          | 32 x 32 partial multiply
  587. #endif
  588. |       endc                    ;+++++
  589.         movel   d0,d5           | Save word
  590. |
  591.         movel   d3,d0           | B * C
  592.         movel   d4,d1
  593. #if (CPU != MC68000 && CPU != MC68010)
  594. |       ifne    comp64-1        ;+++++
  595.         mulul   d0,d0:d1
  596. #else
  597.         bsr     DPM500          | 32 x 32 partial multiply
  598. #endif
  599. |       endc                    ;+++++
  600.         movel   d0,d3
  601. |
  602.         movel   d2,d0           | A * C
  603.         movel   d4,d1
  604. #if (CPU != MC68000 && CPU != MC68010)
  605. |       ifne    comp64-1        ;+++++
  606.         mulul   d0,d0:d1
  607. #else
  608.         bsr     DPM500          | 32 x 32 partial multiply
  609. #endif
  610. |       endc                    ;+++++
  611. |
  612.         clrl    d2              | Sum partial multiply results
  613.         addl    d5,d3
  614.         addxl   d2,d2           | Preserve possible carry out
  615.         addl    d1,d3
  616.         addxl   d0,d2
  617.         movew   a3,d0           | Restore exponent
  618. |
  619.         tstl    d2              | Check for normalized result
  620.         jmi     DOPRSL          | J/ result normalized
  621. |
  622.         asll    #1,d3           | One left shift to normalize
  623.         roxll   #1,d2
  624.         subqw   #1,d0
  625.         jra     DOPRSL
  626. #if (CPU == MC68000 || CPU == MC68010)
  627. |       ifne    comp64-1        ;+++++
  628. |
  629. |  DPM500: 32 x 32 partial multiply routine
  630. |
  631. |  Multiply D0 by D1 (long words) yielding a 64 bit result.
  632. |
  633. DPM500:
  634.         movew   d0,d6           | Copy over B
  635.         swap    d1
  636.         mulu    d1,d6           | Produce BC
  637.         swap    d0
  638.         swap    d1
  639.         movew   d1,d7
  640.         mulu    d0,d7           | Produce AD
  641.         addl    d6,d7           | Produce BC+AD in d6:d7
  642.         subxl   d6,d6
  643.         negl    d6
  644.         swap    d6              | Properly position BC+AD
  645.         swap    d7
  646.         movew   d7,d6
  647. |
  648.         movew   d1,d7           | Save D (slide in under BC+AD)
  649.         swap    d1
  650.         mulu    d0,d1           | Produce AC
  651.         swap    d0
  652.         mulu    d7,d0
  653.         clrw    d7              | Restore d6:d7
  654.         exg     d0,d1           | AC:BD, then result, in d0:d1
  655.         addl    d7,d1
  656.         addxl   d6,d0
  657.         rts
  658. #endif
  659. /*
  660. |       endc                    ;+++++
  661. |
  662. |       page
  663. |
  664. |  DPDIV
  665. |  =====
  666. |  Double precision division operation.
  667. |
  668. */
  669. DPRDIV:
  670.         bsr     GETDP2          | Get both operands
  671.         exg     a2,a3           | Flip the operands
  672.         exg     d0,d1
  673.         exg     d2,d4
  674.         exg     d3,d5
  675.         jra     DPD001
  676. |
  677. DPDIV:
  678.         bsr     GETDP2
  679. |
  680. DPD001:
  681.         movew   a2,d6           | /* Compute result's sign */
  682.         movew   a3,d7
  683.         eorw    d6,d7
  684.         moveaw  d7,a2
  685. |
  686.         andw    d0,d0
  687.         jne     DPD010          | J/ divisor is not zero
  688. |
  689.         andw    d1,d1
  690.         jeq     DNANRS          | J/ 0.0 / 0.0 -> NaN
  691.         cmpiw   #0x7FF,d1
  692.         jne     DINFRS          | J/ num / 0.0 -> INF
  693.         lsll    #1,d4
  694.         jeq     DINFRS          | J/ INF / 0.0 -> INF
  695.         jra     DNANRS          | J/ NaN / 0.0 -> NaN
  696. |
  697. DPD010:
  698.         cmpiw   #0x7FF,d0
  699.         jne     DPD020          | J/ divisor is a normal number
  700. |
  701.         lsll    #1,d2
  702.         jne     DNANRS          | J/  ?  / NaN -> NaN
  703.         andw    d1,d1
  704.         jeq     DZERRS          | J/ 0.0 / INF -> 0.0
  705.         cmpiw   #0x7FF,d1
  706.         jne     DUNFRS          | J/ num / INF -> 0.0 (w/ underflow)
  707.         jra     DNANRS          | J/ NaN,INF / INF -> NaN
  708. |
  709. DPD020:
  710.         andw    d1,d1
  711.         jeq     DZERRS          | J/ 0.0 / num -> 0.0
  712.         cmpiw   #0x7FF,d1
  713.         jne     DPD040          | J/ num / num
  714. |
  715.         lsll    #1,d4
  716.         jeq     DINFRS          | J/ INF / num -> INF
  717.         jra     DNANRS          | J/ NaN / num -> NaN
  718. DPD040:
  719. #if (CPU != MC68000 && CPU != MC68010)
  720.         subw    d0,d1
  721.         addw    #DBIAS,d1
  722.         movew   d1,d0
  723.         lsrl    #1,d4
  724.         roxrl   #1,d5
  725.         divul   d2,d4:d5
  726.         movel   d5,d7
  727.         mulul   d3,d6:d7
  728.         negl    d7
  729.         subxl   d6,d4
  730.         jcc     dpd54
  731. dpd53:
  732.         subl    #1,d5
  733.         addl    d3,d7
  734.         addxl   d2,d4
  735.         jcc     dpd53
  736.         cmpl    d2,d4
  737.         jne     dpd54
  738.         addl    #1,d5
  739.         clrl    d3
  740.         jra     dpd55
  741. dpd54:
  742.         divul   d2,d4:d7
  743.         movel   d7,d3
  744. dpd55:
  745.         movel   d5,d2
  746.         jmi     dpd52
  747.         addl    d3,d3
  748.         addxl   d2,d2
  749.         subl    #1,d0
  750. dpd52:
  751.         jra     DOPRSL
  752. #else
  753. |       ifne    comp64-1        ;+++++
  754. |
  755. /*
  756. |  Division Algorithm:
  757. |
  758. |  (1)  Use a two stage recipication approximation to obtain 1/B
  759. |       (a)  X0 = 1 / (B0 + B1)    (B0 is ms 16 bits of B, B1 = B - B0)
  760. |               = 1/B0 * (1 - B1/B0)  { accurate to 28+ bits)
  761. |       (b)  X1 = X0 * (2 - B*X0)  (N-R iteration, 55+ bits accuracy)
  762. |  (2)  Use DPMUL entry to produce A * X1 (64 bit computation)
  763. */
  764. |
  765. |
  766. |DPD040:
  767.         subw    d0,d1
  768.         addw    #DBIAS,d1               | Restore bias
  769.         movew   d1,a3           | Save exponent in a3
  770. |
  771.         movel   d5,sp@- | Save dividend mantissa on stack
  772.         movel   d4,sp@-
  773. |
  774.         moveq   #1,d6           | Create a 1.0 entry
  775.         rorl    #2,d6           | Set d4 = 4000 0000H
  776.         swap    d2
  777.         divu    d2,d6           | Top fifteen bits of 1/B
  778.         movew   d6,d4           | 1/B ultimately into d4:d5
  779.         movew   d6,d7           | Save for correction term
  780.         swap    d4              | Position MS word
  781.         clrw    d6              | Zero low order bits in d6
  782.         divu    d2,d6           | Division of shifted remainder
  783.         movew   d6,d4           | Complete 1/B approximation
  784. |
  785.         movel   d2,d6
  786.         clrw    d6              | Create a shifted C in d6 (16 bits)
  787.         lsrl    #1,d6           | Insure no division overflow
  788.         divu    d2,d6           | C/B approximation
  789.         mulu    d7,d6
  790.         lsrl    #8,d6           | Position correction term
  791.         lsrl    #7,d6
  792.         subl    d6,d4
  793.         lsll    #1,d4           | Left shift approximation
  794.         subxl   d6,d6           | Do not overflow
  795.         orl     d6,d4           | 28+ bit 1/B approx in d4, B in d2:d3
  796.         swap    d2
  797. |
  798.         movel   d4,d0           | Save X0 in d0
  799.         bsr     DPD500          | d4 * d2:d3 -> d2:d3 (in place)
  800.         negl    d3
  801.         negxl   d2
  802.         movel   d0,d4
  803.         bsr     DPD500
  804. |
  805.         asll    #1,d3
  806.         roxll   #1,d2
  807.         jcc     DPD080          | J/ no shift out
  808.         moveq   #-1,d2          | Set d2:d3 to FFFFFFFF:FFFFFFFF
  809.         moveq   #-1,d3
  810. DPD080:
  811.         |dsw    0
  812. |
  813.         movel   sp@+,d4 | Fetch dividend
  814.         movel   sp@+,d5
  815.         jra     DPM050
  816. |
  817. |  DPD500:  Multiply D2:D3 by D4, top 64 bits of result in D2:D3
  818. |
  819. DPD500:
  820.         movew   d2,d1
  821.         mulu    d4,d1           | BY partial product
  822.         swap    d2
  823.         swap    d3
  824.         movew   d3,d7
  825.         movew   d2,d6
  826.         mulu    d4,d7
  827.         mulu    d4,d6           | AY:CY in d6:d7
  828.         movew   d6,d7
  829.         clrw    d6
  830.         swap    d6
  831.         swap    d7              | LSR #16,d6:d7
  832.         addl    d1,d7
  833.         clrl    d1
  834.         addxl   d1,d6           | 00:BY + 0A:YC
  835. |
  836.         swap    d4
  837.         movew   d3,d5
  838.         movew   d2,d1
  839.         mulu    d4,d5
  840.         mulu    d4,d1           | AX:CX in d1:d5
  841.         addl    d5,d7
  842.         addxl   d1,d6           | AX:CX + 00:BY + 0A:CY
  843. |
  844.         swap    d2
  845.         swap    d3
  846.         mulu    d4,d3
  847.         mulu    d4,d2           | BX:DX in d2:d3
  848.         movew   d2,d3
  849.         clrw    d2
  850.         swap    d2
  851.         swap    d3              | LSR #16,d2:d3
  852.         addl    d7,d3
  853.         addxl   d6,d2           | Result in d2:d3
  854. |
  855.         swap    d4              | Restore d4
  856.         rts
  857. #endif
  858. |       endc                    ;+++++
  859. /*
  860. |
  861. |       page
  862. |
  863. |  DPCMP
  864. |  =====
  865. |  Single Precision comparison routine.
  866. |
  867. |  Compare the two arguments provided and set the condition code
  868. |  register bits N, Z, and V as follows:
  869. |
  870. |      N  Z  V   Relation
  871. |      =  =  =   ====================================
  872. |      1  0  0   X > Y   (X is top argument on stack)
  873. |      0  1  0   X = Y   (within FFUZZ specification)
  874. |      0  0  0   X < Y
  875. |      0  0  1   X does not compare to Y
  876. |
  877. |
  878. |
  879. |
  880. */
  881. |       .set    DFUZZ,51                | Fifty-one bits of fuzz
  882. DPCMP:
  883.         bsr     GETDP2
  884.         cmpiw   #0x7FF,d0
  885.         jne     DPC020          | J/ X is not INF or NaN
  886. |
  887.         lsll    #1,d2           | Remove implicit bit
  888.         jeq     DPC005          | J/ X is INF
  889. |
  890. DPC001:
  891.         |dsw    0               | **  X does not compare to Y  **
  892.         moveq   #CCRV,d0        | CCR V bit
  893.         movew   d0,ccr
  894.         jmp     a0@             | Return
  895. |
  896. DPC005:
  897.         cmpiw   #0x7FF,d1
  898.         jne     DPC009          | J/ Y is not INF or NaN
  899. |
  900.         lsll    #1,d4
  901.         jne     DPC001          | J/ Y is NaN (does not compare)
  902. |
  903.         cmpaw   a2,a3
  904.         jeq     DPC001          | /* J/ INF's with same sign - no compare */
  905. |
  906. DPC009:
  907.         movew   a2,d0           | /* Result based on compl. of X's sign */
  908.         eoriw   #CCRN,d0
  909.         jra     DPC011
  910. |
  911. DPC010:
  912.         movew   a3,d0           | /* Set result based on Y's sign */
  913. DPC011:
  914.         andiw   #CCRN,d0
  915.         movew   d0,ccr
  916.         jmp     a0@
  917. |
  918. |
  919. DPC020:
  920.         cmpiw   #0x7FF,d1
  921.         jne     DPC030          | J/ Y is not NaN or INF
  922. |
  923.         lsll    #1,d4
  924.         jne     DPC001          | J/ Y is NaN - no comparison
  925.         jra     DPC010          | /* Result is based on Y's sign */
  926. |
  927. DPC030:
  928.         cmpaw   a2,a3
  929.         jne     DPC010          | /* J/ signs different - use Y's sign */
  930. |
  931.         movew   d0,d6
  932.         movew   d0,d7           | /* Assume X's exp is larger */
  933.         subw    d1,d6           | Calc difference in exponents
  934.         jpl     DPC031          | J/ positive
  935.         movew   d1,d7           | /* Y's exp is larger */
  936.         negw    d6
  937. DPC031:
  938.         |dsw    0
  939. |
  940.         lsrw    #1,d6
  941.         jeq     DPC040          | Must subtract to obtain result
  942. |
  943.         subw    d0,d1
  944.         subxw   d0,d0           | Set d0 to sign of Y[exp]-X[exp]
  945.         movew   a2,d1
  946.         eorw    d1,d0           | Flip if negative values
  947.         jra     DPC011          | Result based on value in d0
  948. |
  949. DPC040:
  950.         movew   d7,sp@- | Save max exp value, return address
  951.         movel   a0,sp@-
  952. |
  953.         movew   a2,d7
  954.         notw    d7              | Flip sign of opnd (force subtract)
  955.         moveaw  d7,a2
  956. |
  957.         pea     DPC041
  958.         movel   sp@+,a0 | Return address in a0
  959. |
  960.         jra     DPXSUB
  961. |
  962. DPC041:
  963.         movel   sp@+,d0
  964.         movel   sp@+,d1
  965.         moveal  sp@,a0
  966.         movel   d1,sp@
  967.         movel   d0,sp@-
  968.         movel   a0,sp@-
  969.         bsr     GETDP1          | Fetch and unpack result
  970. |
  971.         movew   sp@+,d5 | Recall max exp value
  972. |
  973.         andw    d0,d0
  974.         jeq     DPC050          | J/ zero result
  975. |
  976.         subw    d0,d5
  977.         cmpiw   #DFUZZ,d5
  978.         jge     DPC050          | J/ within FFUZZ specification - zero
  979. |
  980.         movew   a2,d0           | Sign of result into d0
  981.         jra     DPC011          | Comparison result from sign of sub
  982. |
  983. DPC050:
  984.         subw    d0,d0           | Force CCR to say "Z"
  985.         jmp     a0@             | Return
  986. /*
  987. |
  988. |       page
  989. |
  990. |  GETDP2
  991. |  ======
  992. |  Routine called to extract two double precision arguments from
  993. |  the system stack and place them in the 68000`s registers.
  994. |
  995. */
  996. GETDP2:
  997.         moveal  sp@+,a1 | /* GETDP2's return address */
  998.         moveal  sp@+,a0 | Calling routines return address
  999. |
  1000.         movel   sp@+,d0 | Get TOS (source) operand
  1001.         movel   sp@+,d3 | Get low long word
  1002.         subw    d2,d2           | Clear carry
  1003.         roxll   #1,d0           | Sign bit to bit 0
  1004.         subxw   d2,d2           | Fill d2 with sign bit
  1005.         moveaw  d2,a2           | Sign bit info to a2
  1006.         roll    #8,d0           | Left justify mantissa, position exp
  1007.         roll    #3,d0
  1008.         movel   d0,d2           | Copy into mantissa register
  1009.         andiw   #0x7FF,d0       | Mask to exponent field
  1010.         jeq     GETD21          | J/ zero value
  1011. |
  1012.         eorw    d0,d2           | Zero exponent bits in d2
  1013.         lsrl    #1,d2           | Position mantissa
  1014.         bset    #31,d2          | Set implicit bit in d2
  1015.         roll    #8,d3           | Position lo long word of mantissa
  1016.         roll    #3,d3
  1017.         eorw    d3,d2           | Clever use of EOR to move bits
  1018.         andiw   #0xF800,d3      | Trim off bits moved into d2
  1019.         eorw    d3,d2           | Remove noise in d2
  1020. |
  1021. GETD21:
  1022.         |dsw    0
  1023. |
  1024.         movel   sp@+,d1 | Get NOS (source) operand
  1025.         movel   sp@+,d5
  1026.         subw    d4,d4           | Clear carry
  1027.         roxll   #1,d1           | Sign bit carry
  1028.         subxw   d4,d4           | Replicate sign bit throughout d4
  1029.         moveaw  d4,a3           | Sign bit info into a3
  1030.         roll    #8,d1           | Left justify mantissa, position exp
  1031.         roll    #3,d1
  1032.         movel   d1,d4           | Copy into mantissa register
  1033.         andiw   #0x7FF,d1       | Mask to exponent field
  1034.         jeq     GETD22          | J/ zero value
  1035. |
  1036.         eorw    d1,d4           | Zero exponent bits in d4
  1037.         lsrl    #1,d4           | Position mantissa
  1038.         bset    #31,d4          | Set implicit bit in d4
  1039.         roll    #8,d5           | Position low long word of mantissa
  1040.         roll    #3,d5
  1041.         eorw    d5,d4           | Clever use of EOR to move bits
  1042.         andiw   #0xF800,d5      | Trim off bits moved into d4
  1043.         eorw    d5,d4           | Remove noise in d4
  1044. |
  1045. GETD22:
  1046.         jmp     a1@             | Return to caller, its ret addr in a0
  1047. /*
  1048. |
  1049. |
  1050. |       page
  1051. |
  1052. |  GETDP1
  1053. |  ======
  1054. |  Routine called to extract a double precision argument from the
  1055. |  system stack and place it (unpacked) into the 68000's registers.
  1056. |
  1057. */
  1058. GETDP1:
  1059.         moveal  sp@+,a1 | /* Get GETDP1's return address */
  1060.         moveal  sp@+,a0 | Get calling routines return address
  1061. |
  1062.         movel   sp@+,d0 | Get argument
  1063.         movel   sp@+,d3
  1064.         subw    d2,d2           | Clear carry
  1065.         roxll   #1,d0           | Sign bit into carry
  1066.         subxw   d2,d2           | Replicate sign bit throughout d2
  1067.         moveaw  d2,a2           | Sign bit info into a2
  1068.         roll    #8,d0           | Left justify mantissa, position exp
  1069.         roll    #3,d0
  1070.         movel   d0,d2
  1071.         andiw   #0x7FF,d0       | Mask to exponent field
  1072.         jeq     GETD11          | J/ zero value
  1073. |
  1074.         eorw    d0,d2           | Zero exponent bits in d2
  1075.         lsrl    #1,d2           | Position mantissa
  1076.         bset    #31,d2          | Set implicit bit
  1077.         roll    #8,d3           | Position lo long word of mantissa
  1078.         roll    #3,d3
  1079.         eorw    d3,d2           | Clever use of EOR to move bits
  1080.         andiw   #0xF800,d3      | Trim off bits moved to d3
  1081.         eorw    d3,d2           | Remove noise in d2
  1082. |
  1083. GETD11:
  1084.         jmp     a1@             | Return to caller, its ret addr in a0
  1085. /*
  1086. |
  1087. |
  1088. |       page
  1089. |
  1090. |  DOPRSL
  1091. |  ======
  1092. |  Double precision floating point result (main entry w/ round).
  1093. |  Mantissa in D2:D3, exponent in D0, sign in A2, and return address
  1094. |  in A0.  Place a formatted value on the stack.
  1095. |
  1096. */
  1097. DOPRSL:
  1098.         addl    #0x400,d3       | Round the value
  1099.         jcc     DOPR01          | J/ no carry out
  1100.         addql   #1,d2
  1101.         jcc     DOPR01          | J/ no carry out
  1102. |
  1103.         roxrl   #1,d2           | Adjust mantissa and exponent
  1104.         roxrl   #1,d3
  1105.         addqw   #1,d0
  1106. |
  1107. DOPR01:
  1108.         andw    d0,d0
  1109.         jle     DUNFRS          | J/ underflow
  1110. |
  1111.         cmpiw   #0x7FF,d0       | Check for overflow
  1112.         jge     DINFRS          | J/ overflow
  1113. |
  1114.         andiw   #0xF800,d3      | Trim mantissa
  1115.         eorw    d2,d3           | EOR to move over 11 bits
  1116.         andiw   #0xF800,d2      | Remove bits moved
  1117.         eorw    d2,d3           | Remove noise in d3
  1118.         subw    d1,d1           | Clear carry
  1119.         roxll   #1,d2           | Implicit bit into carry
  1120.         addw    d0,d2           | Exponent into d2
  1121.         rorl    #8,d2           | Reposition high word
  1122.         rorl    #3,d2
  1123.         movew   a2,d0           | Sign bit into carry
  1124.         aslw    #1,d0
  1125.         roxrl   #1,d2
  1126.         rorl    #8,d3
  1127.         rorl    #3,d3
  1128.         movel   d3,sp@- | Place value on stack
  1129.         movel   d2,sp@-
  1130. |
  1131.         moveb   #0,FPERR        | No floating point error
  1132.         jmp     a0@             | Return
  1133. |
  1134. |
  1135. |
  1136. DNANRS:
  1137.         moveq   #-1,d0          | Set d0 to 0xFFFFFFFF
  1138.         movel   d0,sp@- | NaN value
  1139.         movel   d0,sp@-
  1140. |
  1141.         moveb   #ERNAN,FPERR
  1142.         moveb   #-1,NANFLG
  1143.         jmp     a0@
  1144. |
  1145. |
  1146. DINFRS:
  1147.         movel   a2,d0           | Get sign information
  1148.         movel   #0xFFE00000,d1
  1149.         aslw    #1,d0           | Sign bit into carry
  1150.         roxrl   #1,d1
  1151.         clrl    sp@-            | Low long word = 00000000
  1152.         movel   d1,sp@-
  1153. |
  1154.         moveb   #EROVF,FPERR
  1155.         moveb   #-1,INFFLG
  1156.         jmp     a0@
  1157. |
  1158. |
  1159. DUNFRS:
  1160.         moveb   #ERUNF,FPERR
  1161.         moveb   #-1,UNFFLG
  1162.         jra     DZER01
  1163. |
  1164. |
  1165. DZERRS:
  1166.         moveb   #0,FPERR
  1167. |
  1168. |
  1169. DZER01:
  1170.         clrl    sp@-
  1171.         clrl    sp@-
  1172.         jmp     a0@
  1173. |
  1174. |       end