home *** CD-ROM | disk | FTP | other *** search
/ Atari FTP / ATARI_FTP_0693.zip / ATARI_FTP_0693 / Mint / mntlib32.zoo / _fixdfsi.cpp < prev    next >
C/C++ Source or Header  |  1993-06-17  |  3KB  |  173 lines

  1. |
  2. |  double float to long conversion routine
  3. |
  4. | M. Ritzert (ritzert@DFG.DBP.DE)
  5.     .text
  6.     .even
  7.     .globl    __fixdfsi, ___fixdfsi
  8.  
  9. #ifdef ERROR_CHECK
  10. #include "errbase.h"
  11. _Overflow:
  12.     .ascii "OVERFLOW\0"
  13. _Error_String:
  14.     .ascii "_fixdfsi: %s error\n\0"
  15. .even
  16. #endif ERROR_CHECK
  17.  
  18. __fixdfsi:
  19. ___fixdfsi:
  20.  
  21. #ifdef sfp004
  22. |
  23. | 4.10.1990/10.1.1992
  24. |
  25. | addresses of the 68881 data port. This choice is fastest when much data is
  26. | transferred between the two processors.
  27.  
  28. comm =     -6
  29. resp =    -16
  30. zahl =      0
  31.  
  32. | waiting loop ...
  33. |
  34. | wait:
  35. | ww:    cmpiw    #0x8900,a0@(resp)
  36. |     beq    ww
  37. | is coded directly by
  38. |    .long    0x0c688900, 0xfff067f8
  39.  
  40.     lea    0xfffffa50:w,a0
  41.     movew    #0x5403,a0@(comm)    | fintrz to fp0
  42.     cmpiw    #0x8900,a0@(resp)    | check
  43.     movel    sp@(4),a0@
  44.     movel    sp@(8),a0@
  45.     movew    #0x6000,a0@(comm)    | result to d0
  46.     .long    0x0c688900, 0xfff067f8
  47.     movel    a0@,d0
  48.  
  49. #endif    sfp004
  50. #ifdef    __M68881__
  51.  
  52. |
  53. | floating point stuff for Atari-gcc using
  54. | an 68030/68881
  55. | developed with gcc/gas
  56. |
  57. | double float to long conversion routine
  58. |
  59. | M. Ritzert (mjr@dfg.dbp.de)
  60. |
  61. | 30.11.1991/10.1.1992
  62. |
  63.  
  64.     fintrzd sp@(4),fp0        | convert the arg
  65.     fmovel fp0,d0            | return
  66.  
  67. #endif    __M68881__
  68.  
  69.  
  70. # if !defined (sfp004) && !defined (__M68881__)
  71.  
  72. | double float to long conversion routine
  73. |
  74. | written by Kai-Uwe Bloem (I5110401@dbstu1.bitnet).
  75. | Based on a 80x86 floating point packet from comp.os.minix, written by P.Housel
  76. |
  77. | modified by Andreas Schwab (schwab@ls5.informatik.uni-dortmund.de):
  78. | no loop needed for the shift-down case
  79. | testing for far shifts now too slow
  80. | use different registers to gain speed
  81. |
  82. | Revision 1.3, kub 01-90 :
  83. | added support for denormalized numbers
  84. |
  85. | Revision 1.2, kub 01-90 :
  86. | replace far shifts by swaps to gain speed
  87. |
  88. | Revision 1.1, kub 12-89 :
  89. | Ported over to 68k assembler
  90. |
  91. | Revision 1.0:
  92. | original 8088 code from P.S.Housel
  93.  
  94. BIAS8    =    0x3FF-1
  95.  
  96.     lea    sp@(4),a0    | pointer to parameters
  97.     moveml    d2/d3,sp@-    | save registers
  98.     moveml    a0@,d0-d1    | get the number
  99.     movew    a0@,d2        | extract exp
  100.     movew    d2,d3        | extract sign
  101.     bclr    #15,d2        | kill sign bit
  102.     lsrw    #4,d2
  103.  
  104.     andl    #0x0fffff,d0    | remove exponent from mantissa
  105.     bset    #20,d0        | restore implied leading "1"
  106.  
  107.     cmpw    #BIAS8,d2    | check exponent
  108.     blt    zero        | strictly fractional, no integer part ?
  109.     cmpw    #BIAS8+32,d2    | is it too big to fit in a 32-bit integer ?
  110.     bgt    toobig
  111.  
  112.     subw    #BIAS8+21,d2    | adjust exponent
  113.     bgt    2f        | shift up
  114.     beq    7f        | no shift (never too big)
  115.  
  116.     negw    d2
  117.     lsrl    d2,d0        | shift down to align radix point;
  118.                 | extra bits fall off the end (no rounding)
  119.     bra    7f        | never too big
  120.  
  121. 2:    addl    d1,d1        | shift up to align radix point
  122.     addxl    d0,d0
  123.     subqw    #1,d2
  124.     bgt    2b
  125.  
  126. 3:    cmpl    #0x80000000,d0    | -2147483648 is a nasty evil special case
  127.     bne    6f
  128.     tstw    d3        | this had better be -2^31 and not 2^31
  129.     bpl    toobig
  130.     bra    8f
  131. 6:    tstl    d0        | sign bit set ? (i.e. too big)
  132.     bmi    toobig
  133. 7:
  134.     tstw    d3        | is it negative ?
  135.     bpl    8f
  136.     negl    d0        | negate
  137. 8:
  138.     moveml    sp@+,d2/d3
  139.     rts
  140.  
  141. zero:
  142.     clrl    d0        | make the whole thing zero
  143.     bra    8b
  144.  
  145. toobig:
  146.     moveq    #-1,d0        | ugh. Should cause a trap here.
  147.     bclr    #31,d0
  148.     moveml    sp@+,d2/d3
  149.  
  150. #endif /* !defined (sfp004) && !defined (__M68881__) */
  151.  
  152. #ifdef    ERROR_CHECK
  153.  
  154. | all three versions
  155.     cmpil    #0x7fffffff,d0    | >= long_max
  156.     bge    error_msg
  157.     cmpil    #-0x7fffffff,d0    | <= long_min ?
  158.     ble    error_msg
  159.     rts
  160. error_msg:
  161.     moveml    d0-d1,sp@-
  162.     moveq    #Erange,d0
  163.     Emove    d0,Errno
  164.     pea    pc@(_Overflow)    | for printf
  165.     pea    pc@(_Error_String)
  166.     pea    Stderr
  167.     jbsr    _fprintf
  168.     addl    #12,sp
  169.     moveml    sp@+,d0-d1
  170. #endif    /* ERROR_CHECK */
  171.  
  172.     rts
  173.