home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3137 / sflonum.s < prev    next >
Encoding:
Text File  |  1991-03-27  |  15.0 KB  |  816 lines

  1. #
  2. #    Floating point support code.  What a crock!
  3. #
  4. #    A float looks like:
  5. #
  6. #    |S|E.x.p ... |M.a.n.t.i.s.s.a ... |
  7. #    +-+----------+--------------------+
  8. #
  9. #    where s is the sign bit, Exp is 8 bits of exponent, interpreted
  10. #    as E + 126, and Mantissa is 23 bits of fraction, with a
  11. #    hidden bit.  The point is to the left of the hidden bit.
  12. #    Doubles have another word of mantissa following.
  13. #
  14. #    All these routines have calling sequences like c routines,
  15. #    ie args on stack in backwards order, return values in d0
  16. #
  17.  
  18. # union double_di { double d; int i[2]; };
  19. # union flt_or_int { int i; float f; };
  20. #
  21. ## #ifdef L_divdf3
  22. ## double
  23. ## _divdf3 (a, b)
  24. ##      double a, b;
  25. ## {
  26. ##   return a / b;
  27. ## }
  28. ## #endif
  29. #.text
  30. #    .even
  31. #.globl ___divdf3
  32. #__divdf3:
  33. #    movel    sp@(12),sp@-
  34. #    movel    sp@(8),sp@-
  35. #    jsr    __divsf3
  36. #    addql    #8,sp
  37. #    clrl    d1        | kludge!!!
  38. #    rts            | sigh
  39. ## 
  40. ## #ifdef L_muldf3
  41. ## double
  42. ## _muldf3 (a, b)
  43. ##      double a, b;
  44. ## {
  45. ##   return a * b;
  46. ## }
  47. ## #endif
  48. #
  49. #.text
  50. #    .even
  51. #.globl __muldf3
  52. #__muldf3:
  53. #    movel    sp@(12),sp@-
  54. #    movel    sp@(8),sp@-
  55. #    jsr    __mulsf3
  56. #    addql    #8,sp
  57. #    clrl    d1        | kludge!!!
  58. #    rts            | sigh
  59. ## 
  60. ## #ifdef L_negdf2
  61. ## double
  62. ## _negdf2 (a)
  63. ##      double a;
  64. ## {
  65. ##   return -a;
  66. ## }
  67. ## #endif
  68. #
  69. #.text
  70. #    .even
  71. #.globl __negdf2
  72. #__negdf2:
  73. #    movel    sp@(8),d1        | get a lo
  74. #    movel    sp@(4),d0        | get a hi
  75. #    beq    negdf2_z        | zero, leave it
  76. #    eorl    #0x80000000,d0        | twiddle sign
  77. #negdf2_z:
  78. #    rts
  79. ## 
  80. ## #ifdef L_adddf3
  81. ## double
  82. ## _adddf3 (a, b)
  83. ##      double a, b;
  84. ## {
  85. ##   return a + b;
  86. ## }
  87. ## #endif
  88. #
  89. #.text
  90. #    .even
  91. #.globl __adddf3
  92. #__adddf3:
  93. #    movel    sp@(12),sp@-
  94. #    movel    sp@(8),sp@-
  95. #    jsr    __addsf3
  96. #    addql    #8,sp
  97. #    clrl    d1        | kludge!!!
  98. #    rts            | sigh
  99. ## 
  100. ## #ifdef L_subdf3
  101. ## double
  102. ## _subdf3 (a, b)
  103. ##      double a, b;
  104. ## {
  105. ##   return a - b;
  106. ## }
  107. ## #endif
  108. #
  109. #.text
  110. #    .even
  111. #.globl __subdf3
  112. #__subdf3:
  113. #    movel    sp@(12),sp@-
  114. #    movel    sp@(8),sp@-
  115. #    jsr    __subsf3
  116. #    addql    #8,sp
  117. #    clrl    d1        | kludge!!!
  118. #    rts            | sigh
  119. ## 
  120. ## #ifdef L_cmpdf2
  121. ## int
  122. ## _cmpdf2 (a, b)
  123. ##      double a, b;
  124. ## {
  125. ##   if (a > b)
  126. ##     return 1;
  127. ##   else if (a < b)
  128. ##     return -1;
  129. ##   return 0;
  130. ## }
  131. ## #endif
  132. #
  133. #.text
  134. #    .even
  135. #.globl __cmpdf2
  136. #__cmpdf2:
  137. #    movel    sp@(4),d0    | get b hi
  138. #    movel    sp@(12),d1    | get a hi
  139. #|
  140. #| crockery.  If both neg and not equal, this algorithm lose.  find a better one!
  141. #|
  142. #    bpl    cmpdf2_p
  143. #    tstl    d0
  144. #    bpl    cmpdf2_p
  145. #    cmpl    d1,d0
  146. #    bgt    cmpdf2_m
  147. #    blt    cmpdf2_1
  148. #    beq    cmpdf2_z
  149. #cmpdf2_p:
  150. #    cmpl    d1,d0        | get a hi
  151. #    beq    cmpdf2_z    | if eq, return 0
  152. #    bgt    cmpdf2_1    | if greater, return 1
  153. #cmpdf2_m:
  154. #    movel    #-1,d0        | else return -1
  155. #    rts
  156. #cmpdf2_z:
  157. #    clrl    d0
  158. #    rts
  159. #cmpdf2_1:
  160. #    movel    #1,d0
  161. #    rts            | sigh
  162. ## 
  163. ## #ifdef L_fixunsdfsi
  164. ## _fixunsdfsi (a)
  165. ##      double a;
  166. ## {
  167. ##   return (unsigned int) a;
  168. ## }
  169. ## #endif
  170. #
  171. #.text
  172. #    .even
  173. #.globl __fixunsdfsi
  174. #__fixunsdfsi:
  175. #    clrl d0
  176. #    clrl d1
  177. #    rts            | sigh
  178. ## 
  179. ## #ifdef L_fixunsdfdi
  180. ## double
  181. ## _fixunsdfdi (a)
  182. ##      double a;
  183. ## {
  184. ##   union double_di u;
  185. ##   u.i[LOW] = (unsigned int) a;
  186. ##   u.i[HIGH] = 0;
  187. ##   return u.d;
  188. ## }
  189. ## #endif
  190. #
  191. #.text
  192. #    .even
  193. #.globl __fixunsdfdi
  194. #__fixunsdfdi:
  195. #    clrl d0
  196. #    clrl d1
  197. #    rts            | sigh
  198. ## 
  199. ## #ifdef L_fixdfsi
  200. ## _fixdfsi (a)
  201. ##      double a;
  202. ## {
  203. ##   return (int) a;
  204. ## }
  205. ## #endif
  206. #
  207. #.text
  208. #    .even
  209. #.globl __fixdfsi
  210. #__fixdfsi:
  211. #    link    a6,#0
  212. #    movel    d2,sp@-        | save reg
  213. #    clrl    d2        | sign flag
  214. #    movel    a6@(8),d0    | get the float
  215. #    beq    fixdfsi_ret
  216. #    bpl    fixdfsi_1
  217. #    addql    #1,d2
  218. #fixdfsi_1:
  219. #    movel    d0,d1        | snag the exp
  220. #    lsrl    #7,d1
  221. #    lsrl    #8,d1
  222. #    lsrl    #8,d1
  223. #    andl    #0xFF,d1
  224. #    subl    #126,d1
  225. #    andl    #0x7FFFFF,d0    | zap cruft
  226. #    orl    #0x800000,d0    | put back hidden bit
  227. #|
  228. #| at this point the mantissa looks like 2^24 * integer value.
  229. #| if Exp is 24, were done.  If its less, we shift right,
  230. #| else left
  231. #|
  232. #fixdfsi_2:
  233. #    cmpl    #24,d1
  234. #    beq    fixdfsi_4    | were done
  235. #    bmi    fixdfsi_3    | less, shift right
  236. #    lsll    #1,d0        | greater, shift it left one
  237. #    subql    #1,d1        | and dec exp
  238. #    bra    fixdfsi_2
  239. #fixdfsi_3:
  240. #    lsrl    #1,d0        | shift right one
  241. #    addql    #1,d1        | and inc exp
  242. #    bra    fixdfsi_2
  243. #fixdfsi_4:
  244. #    tstl    d2        | negative?
  245. #    beq    fixdfsi_ret
  246. #    negl    d0
  247. #fixdfsi_ret:
  248. #    movel    sp@+,d2        | get d2 back
  249. #    unlk    a6
  250. #    rts
  251. ## 
  252. ## #ifdef L_fixdfdi
  253. ## double
  254. ## _fixdfdi (a)
  255. ##      double a;
  256. ## {
  257. ##   union double_di u;
  258. ##   u.i[LOW] = (int) a;
  259. ##   u.i[HIGH] = (int) a < 0 ? -1 : 0;
  260. ##   return u.d;
  261. ## }
  262. ## #endif
  263. #
  264. #.text
  265. #    .even
  266. #.globl __fixdfdi
  267. #__fixdfdi:
  268. #    clrl d0
  269. #    clrl d1
  270. #    rts            | sigh
  271. ## 
  272. ## #ifdef L_floatsidf
  273. ## double
  274. ## _floatsidf (a)
  275. ##      int a;
  276. ## {
  277. ##   return (double) a;
  278. ## }
  279. ## #endif
  280. #
  281. #.text
  282. #    .even
  283. #.globl __floatsidf
  284. #__floatsidf:
  285. #    link    a6,#0        | set up frame
  286. #    movel    d2,sp@-        | save d2; sign flag
  287. #    clrl    d2        | not negative yet
  288. #    movel    #24,d1        | exponent so far
  289. #    movel    a6@(8),d0    | get the int
  290. #    beq    floatsidf_ret    | zero?
  291. #    bpl    floatsidf_1    | pos, its ok
  292. #    negl    d0        | negate it
  293. #    addql    #1,d2        | bump sign
  294. #floatsidf_1:
  295. #|
  296. #| normalize right if necessary
  297. #|
  298. #    cmpl    #0xFFFFFF,d0    | too big?
  299. #    ble    floatsidf_2    | nope, see if need to slide left
  300. #    addql    #1,d1        | bump exp
  301. #    lsrl    #1,d0        | and slide mantissa right one
  302. #    bra    floatsidf_1
  303. #floatsidf_2:
  304. #    btst    #23,d0        | got a bit up here yet?
  305. #    bne    floatsidf_3    | nope, go left
  306. #    subql    #1,d1        | dec exp
  307. #    lsll    #1,d0        | and slide mantissa left one
  308. #    bra    floatsidf_2
  309. #floatsidf_3:
  310. #|
  311. #| now put it all together
  312. #|
  313. #    andl    #0x7FFFFF,d0    | zap hidden bit
  314. #    addl    #126,d1        | offset exp
  315. #    andl    #0xFF,d1    | trim it
  316. #    lsll    #8,d1        | shift up
  317. #    lsll    #8,d1
  318. #    lsll    #7,d1
  319. #    orl    d1,d0        | stuff it in
  320. #    tstl    d2        | negative?
  321. #    beq    floatsidf_ret
  322. #    orl    #0x80000000,d0
  323. #floatsidf_ret:
  324. #    movel    sp@+,d2
  325. #    clrl    d1        | ???
  326. #    unlk    a6
  327. #    rts            | sigh
  328. ## 
  329. ## #ifdef L_floatdidf
  330. ## double
  331. ## _floatdidf (u)
  332. ##      union double_di u;
  333. ## {
  334. ##   register double hi
  335. ##     = ((double) u.i[HIGH]) * (double) 0x10000 * (double) 0x10000;
  336. ##   register double low = (unsigned int) u.i[LOW];
  337. ##   return hi + low;
  338. ## }
  339. ## #endif
  340. #
  341. #.text
  342. #    .even
  343. #.globl __floatdidf
  344. #__floatdidf:
  345. #    clrl d0
  346. #    clrl d1
  347. #    rts            | sigh
  348. ## 
  349. # #define INTIFY(FLOATVAL)  (intify.f = (FLOATVAL), intify.i)
  350. # #ifdef L_addsf3
  351. # int
  352. # _addsf3 (a, b)
  353. #      union flt_or_int a, b;
  354. # {
  355. #   union flt_or_int intify;
  356. #   return INTIFY (a.f + b.f);
  357. # }
  358. # #endif
  359.  
  360. .text
  361.     .even
  362. .globl ___addsf3
  363. .globl __addsf3
  364. ___addsf3:
  365. __addsf3:
  366.     link    a6,#0        | dont need any locals
  367.     moveml    #0x3F00,sp@-    | save all data registers
  368.     movel    a6@(8),d0    | get a
  369.     beq    addsf_ret_b    |  zero .. just return b
  370.     movel    #23,d6        | shift count
  371.     movel    d0,d2        | get the exponent
  372.     lsrl    d6,d2        | and shift right
  373.     andl    #0xFF,d2    | no sign bit
  374.     subl    #126,d2        | offset the exponent
  375.     movel    a6@(12),d1    | get b
  376.     beq    addsf_ret_a
  377.     movel    d1,d3        | get the exponent for b
  378.     lsrl    d6,d3        | and shift right, with implicit extend
  379.     andl    #0xFF,d3    | make sure we didnt get a sign bit
  380.     subl    #126,d3        | off set this one too
  381.  
  382.     andl    #0x7FFFFF,d0    | mask a for mantissa
  383.     orl    #0x800000,d0    | and put in hidden bit
  384.     tstl    a6@(8)        | test the original value
  385.     bpl    addsf_1        | pos, ok
  386.     negl    d0        | neg, negate the mantissa
  387. addsf_1:
  388.     andl    #0x7FFFFF,d1    | mask b for mantissa
  389.     orl    #0x800000,d1    | ditto
  390.     tstl    a6@(12)        | test ...
  391.     bpl    addsf_2
  392.     negl    d1        | negate this one
  393. addsf_2:
  394.     cmpl    d2,d3        | compare Ea to Eb
  395.     blt    addsf_3        | Ea > Eb
  396.  
  397.     movel    d3,d5        | get Eb
  398.     subl    d2,d5        | subtract Ea
  399.     asrl    d5,d0        |  yielding count to shift Ma right
  400.     movel    d3,d5        | use this as resultant exponent
  401.     bra    addsf_4        | and go rejoin common part
  402. addsf_3:
  403.     movel    d2,d5        | get Ea
  404.     subl    d3,d5        | subtract Eb
  405.     asrl    d5,d1        |  yielding count to shift Mb right
  406.     movel    d2,d5        | use this as resultant exponent
  407.  
  408. addsf_4:
  409.     clrl    d7        | zap sign flag
  410.     addl    d1,d0        | add Mb to Ma
  411.  
  412.  
  413.     beq    addsf_z        | zero? ok, go return zero
  414.     bpl    addsf_5        | positive? ok, go scale it
  415.     negl    d0        | negate Mr
  416.     movel    #1,d7        | remember sign
  417. addsf_5:
  418.     btst    #24,d0        | carry?
  419.     beq    addsf_6        | nope, its ok as is
  420.     asrl    #1,d0        | shift right one
  421.     addql    #1,d5        | inc exp
  422.  
  423. | zzz check for overflow in here someplace
  424.  
  425. addsf_6:
  426.     btst    #23,d0        | got a bit in the right place yet?
  427.     bne    addsf_7        | yes, were done
  428.     lsll    #1,d0        | shift left one
  429.     subql    #1,d5        | dec exponent
  430.     bra    addsf_6
  431. addsf_7:
  432.     andl    #0x7FFFFF,d0    | zap out hidden bit
  433.     addl    #126,d5        | add offset to exp
  434.     andl    #0xFF,d5    | zap to 8 bits
  435.     movel    #23,d6        | shift count
  436.     lsll    d6,d5        | shift the exp up
  437.     orl    d5,d0        | stick the exp in
  438.     tstl    d7        | negative?
  439.     beq    addsf_ret_a
  440.     orl    #0x80000000,d0    | yup, negate it
  441.     bra    addsf_ret_a
  442. addsf_z:
  443.     clrl    d0
  444.     bra    addsf_ret_a
  445. addsf_ret_b:
  446.     movel    a6@(12),d0
  447. addsf_ret_a:
  448.     moveml    sp@+,#0x00FC    | snarf back all regs
  449.     unlk    a6
  450.     rts            | sigh
  451. # #ifdef L_negsf2
  452. # int
  453. # _negsf2 (a)
  454. #      union flt_or_int a;
  455. # {
  456. #   union flt_or_int intify;
  457. #   return INTIFY (-a.f);
  458. # }
  459. # #endif
  460.  
  461. .text
  462.     .even
  463. .globl ___negsf2
  464. .globl __negsf2
  465. ___negsf2:
  466. __negsf2:
  467.     movel    sp@(4),d0
  468.     beq    negsf2_z
  469.     eorl    #0x80000000,d0
  470. negsf2_z:
  471.     rts            | sigh
  472. # #ifdef L_subsf3
  473. # int
  474. # _subsf3 (a, b)
  475. #      union flt_or_int a, b;
  476. # {
  477. #   union flt_or_int intify;
  478. #   return INTIFY (a.f - b.f);
  479. # }
  480. # #endif
  481.  
  482. .text
  483.     .even
  484. .globl ___subsf3
  485. .globl __subsf3
  486. ___subsf3:
  487. __subsf3:
  488.     tstl    sp@(8)        | kludge.  just negate b and add
  489.     beq    subsf_bz    | zero.  dont bother
  490.     eorl    #0x80000000,sp@(8)    | negate it
  491.     jmp    ___addsf3
  492. subsf_bz:
  493.     movel    sp@(4),d0
  494.     rts
  495.  
  496. # #ifdef L_cmpsf2
  497. # int
  498. # _cmpsf2 (a, b)
  499. #      union flt_or_int a, b;
  500. # {
  501. #   union flt_or_int intify;
  502. #   if (a.f > b.f)
  503. #     return 1;
  504. #   else if (a.f < b.f)
  505. #     return -1;
  506. #   return 0;
  507. # }
  508. # #endif
  509.  
  510. .text
  511.     .even
  512. .globl ___cmpsf2
  513. .globl __cmpsf2
  514. ___cmpsf2:
  515. __cmpsf2:
  516.     movel    sp@(4),d0
  517.     movel    sp@(12),d1    | get a hi
  518. |
  519. | crockery.  If both neg and not equal, this algorithm lose.  find a better one!
  520. |
  521.     bpl    cmpsf2_p
  522.     tstl    d0
  523.     bpl    cmpsf2_p
  524.     cmpl    d1,d0
  525.     bgt    cmpsf2_m
  526.     blt    cmpsf2_1
  527.     beq    cmpsf2_z
  528. cmpsf2_p:
  529.     cmpl    d1,d0
  530.     beq    cmpsf2_z
  531.     bgt    cmpsf2_1
  532. cmpsf2_m:
  533.     movel    #-1,d0
  534.     rts
  535. cmpsf2_z:
  536.     clrl    d0
  537.     rts
  538. cmpsf2_1:
  539.     movel    #1,d0
  540.     rts            | sigh
  541. # #ifdef L_mulsf3
  542. # int
  543. # _mulsf3 (a, b)
  544. #      union flt_or_int a, b;
  545. # {
  546. #   union flt_or_int intify;
  547. #   return INTIFY (a.f * b.f);
  548. # }
  549. # #endif
  550.  
  551. .text
  552.     .even
  553. .globl ___mulsf3
  554. .globl __mulsf3
  555. ___mulsf3:
  556. __mulsf3:
  557. |
  558. | multiply.  take the numbers apart.  shift each exponent down to
  559. | 16 bits.  unsigned multiply those.  shift that down to 24 bits.
  560. | exponent is Ea + Eb.
  561. |
  562.  
  563.     link    a6,#-8        | 64 bit accum for mult
  564.     moveml    #0x3F00,sp@-    | save all data registers
  565.     movel    a6@(8),d0    | get a
  566.     beq    mulsf3_z
  567.     movel    a6@(12),d1    | get b
  568.     beq    mulsf3_z
  569.     movel    #23,d6        | shift count
  570.     movel    d0,d2        | get the exponent
  571.     lsrl    d6,d2        | and shift right
  572.     andl    #0xFF,d2
  573.     subl    #126,d2        | offset the exponent
  574.     movel    d1,d3        | get the exponent for b
  575.     lsrl    d6,d3        | and shift right
  576.     andl    #0xFF,d2
  577.     subl    #126,d3        | off set this one too
  578.  
  579.     clrl    d7        | negative result flag
  580.     andl    #0x7FFFFF,d0    | mask a for mantissa
  581.     orl    #0x800000,d0    | and put in hidden bit
  582.     tstl    a6@(8)        | test the original value
  583.     bpl    mulsf3_1    | pos, ok
  584.     eorl    #1,d7        | remember negative
  585. mulsf3_1:
  586.     andl    #0x7FFFFF,d1    | mask b for mantissa
  587.     orl    #0x800000,d1    | ditto
  588.     tstl    a6@(12)        | test ...
  589.     bpl    mulsf3_2
  590.     eorl    #1,d7
  591. mulsf3_2:
  592. |    lsrl    #8,d1        | shift this one down
  593. |    lsrl    #8,d0        | this one too...
  594. |    mulu    d1,d0        | do the multiply
  595.  
  596. |    beq    mulsf3_ret    | zero? ok, just return
  597. |    lsrl    #8,d0        | shift right again
  598.  
  599. |
  600. | we have mantissas as follows:
  601. |
  602. |    |...ah...|...al...|    |...bh...|...bl...|
  603. |
  604. | product is composed as:
  605. |
  606. |            |....al * bl....|
  607. |        |....al * bh....|
  608. |        |....ah * bl....|
  609. |    |....ah * bh....|
  610. |
  611. | then take the 24 bit chunk thats 16 bits in.
  612.  
  613.     movel    d0,d4
  614.     andl    #0xFFFF,d4    | al
  615.     movel    d1,d5
  616.     andl    #0xFFFF,d5    | bl
  617.     mulu    d5,d4        | thats al * bl
  618.     movel    d4,a6@(-4)    | into the accum
  619.     clrl    a6@(-8)        | zap the top part
  620.  
  621.     movel    d0,d4
  622.     andl    #0xFFFF,d4    | al
  623.     movel    d1,d5
  624.     movel    #16,d6        | shift count
  625.     lsrl    d6,d5        | bh
  626.     mulu    d5,d4        | al * bh
  627.     addl    d4,a6@(-6)
  628.  
  629.     movel    d0,d4
  630.     lsrl    d6,d4        | ah
  631.     movel    d1,d5
  632.     andl    #0xFFFF,d5    | bl
  633.     mulu    d5,d4        | ah * bl
  634.     addl    d4,a6@(-6)
  635.  
  636.     movel    d0,d4
  637.     lsrl    d6,d4        | ah
  638.     movel    d1,d5
  639.     lsrl    d6,d5        | bh
  640.     mulu    d5,d4        | ah * bh
  641.     addl    d4,a6@(-8)
  642.  
  643.     movel    a6@(-6),d0    | get the relevant part
  644.     lsrl    #8,d0        | and shift it down
  645.  
  646. mulsf3_norm:
  647.     btst    #23,d0        | normalized?
  648.     bne    mulsf3_ok
  649.     lsll    #1,d0
  650.     subql    #1,d2
  651.     bra    mulsf3_norm
  652.  
  653. mulsf3_ok:
  654.     andl    #0x7FFFFF,d0    | zap hidden bit
  655.     addl    d3,d2        | add Eb to Ea
  656.     addl    #126,d2        | fix offset
  657.     andl    #0xFF,d2    | whack to 8 bits
  658.     movel    #23,d6        | shift count
  659.     lsll    d6,d2        | shift up to right place
  660.     orl    d2,d0        | shove it in
  661.     tstl    d7        | sign neg?
  662.     beq    mulsf3_ret
  663.     orl    #0x80000000,d0    | set sign bit
  664.     bra    mulsf3_ret
  665. mulsf3_z:
  666.     clrl    d0
  667. mulsf3_ret:
  668.     moveml    sp@+,#0x00FC    | snarf back all regs
  669.     unlk    a6
  670.     rts            | sigh
  671. # #ifdef L_divsf3
  672. # int
  673. # _divsf3 (a, b)
  674. #      union flt_or_int a, b;
  675. # {
  676. #   union flt_or_int intify;
  677. #   return INTIFY (a.f / b.f);
  678. # }
  679. # #endif
  680.  
  681. .text
  682.     .even
  683. .globl ___divsf3
  684. .globl __divsf3
  685. ___divsf3:
  686. __divsf3:
  687. |
  688. | divide.  sort of like mult, exc we do shifts and subtracts to
  689. | do the division of the mantissa.  resultant exponent is Ea - Eb.
  690. |
  691.  
  692.     link    a6,#0        | dont need any locals
  693.     moveml    #0x3F00,sp@-    | save all data registers
  694.     movel    a6@(8),d0    | get a
  695.     movel    a6@(12),d1    | get b
  696.     movel    #23,d6        | shift count
  697.     movel    d0,d2        | get the exponent
  698.     lsrl    d6,d2        | and shift right
  699.     andl    #0xFF,d2
  700.     subl    #127,d2        | offset the exponent
  701.     movel    d1,d3        | get the exponent for b
  702.     lsrl    d6,d3        | and shift right
  703.     andl    #0xFF,d3
  704.     subl    #127,d3        | off set this one too
  705.  
  706.     clrl    d7        | negative result flag
  707.     andl    #0x7FFFFF,d0    | mask a for mantissa
  708.     orl    #0x800000,d0    | and put in hidden bit
  709.     tstl    a6@(8)        | test the original value
  710.     bpl    divsf3_1    | pos, ok
  711.     eorl    #1,d7        | remember negative
  712. divsf3_1:
  713.     andl    #0x7FFFFF,d1    | mask b for mantissa
  714.     orl    #0x800000,d1    | ditto
  715.     tstl    a6@(12)        | test ...
  716.     bpl    divsf3_2
  717.     eorl    #1,d7
  718. divsf3_2:
  719. |
  720. | for now, kludge.  shift Ma left and Mb right, then do an unsigned divide
  721. | and shift the result left.  Blech
  722. |
  723.  
  724. |    lsrl    #8,d1        | shift this one down
  725. |    lsll    #7,d0        | this one up
  726. |    divu    d1,d0        | do the divide
  727. |    andl    #0xFFFF,d0    | and mask off cruft
  728.  
  729. |    beq    divsf3_ret    | zero? ok, just return
  730. |    lsll    #8,d0        | shift left again
  731.  
  732. | same sort of trick as long divide, exc its easier here, cause
  733. | the numbers (mantissas) are already bit-aligned.
  734.  
  735.     clrl    d4        | accumulator
  736.     movel    #0x800000,d5    | bit
  737.     lsll    #7,d0        | buy a little extra accuracy...
  738.     lsll    #7,d1
  739. divsf3_2a:
  740.     cmpl    d1,d0        | compare dividend to divisor
  741.     bmi    divsf3_2b    | nope, no bit here
  742.     orl    d5,d4        | put in the bit
  743.     subl    d1,d0        | and subtract
  744. divsf3_2b:
  745.     lsrl    #1,d1        | slide divisor down
  746.     lsrl    #1,d5        | slide bit down
  747.     bne    divsf3_2a    | and go round again
  748.     movel    d4,d0        | leave the result here
  749.  
  750. divsf3_3:
  751.     btst    #23,d0        | right place yet?
  752.     bne    divsf3_4
  753.     lsll    #1,d0
  754.     subql    #1,d2
  755.     bra    divsf3_3
  756. divsf3_4:
  757.     andl    #0x7FFFFF,d0    | zap hidden bit
  758.     subl    d3,d2        | sub Eb from Ea
  759.     addl    #127,d2        | fix offset
  760.     andl    #0xFF,d2    | whack to 8 bits
  761.     lsll    d6,d2        | shift up to right place
  762.     orl    d2,d0        | shove it in
  763.     tstl    d7        | sign neg?
  764.     beq    divsf3_ret
  765.     orl    #0x80000000,d0    | set sign bit
  766. divsf3_ret:
  767.     moveml    sp@+,#0x00FC    | snarf back all regs
  768.     unlk    a6
  769.  
  770.     rts            | sigh
  771. ## 
  772. ## #ifdef L_truncdfsf2
  773. ## int
  774. ## _truncdfsf2 (a)
  775. ##      double a;
  776. ## {
  777. ##   union flt_or_int intify;
  778. ##   return INTIFY (a);
  779. ## }
  780. ## #endif
  781. #
  782. #.text
  783. #    .even
  784. #.globl __truncdfsf2
  785. #__truncdfsf2:
  786. #    movel    sp@(4),d0
  787. #    rts
  788. #
  789. ## 
  790. ## #ifdef L_extendsfdf2
  791. ## double
  792. ## _extendsfdf2 (a)
  793. ##      union flt_or_int a;
  794. ## {
  795. ##   union flt_or_int intify;
  796. ##   return a.f;
  797. ## }
  798. ## #endif
  799. #
  800. #.text
  801. #    .even
  802. #.globl __extendsfdf2
  803. #__extendsfdf2:
  804. #    movel    sp@(4),d0
  805. #    clrl    d1
  806. #    rts            | sigh
  807. #    .even
  808. #.text
  809.  
  810.