home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / mint / mntlib18 / _fixdfsi.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-03  |  3.7 KB  |  199 lines

  1. |
  2. |  double float to long conversion routine
  3. |
  4. | M. Ritzert (ritzert@DFG.DBP.DE)
  5.  
  6.     .text
  7.     .even
  8.  
  9. #ifdef ERROR_CHECK
  10.  
  11. _Overflow:
  12.     .ascii "OVERFLOW\0"
  13. _Error_String:
  14.     .ascii "_fixdfsi: %s error\n\0"
  15. .even
  16.  
  17. #endif ERROR_CHECK
  18.  
  19. #ifdef sfp004
  20. |
  21. | 4.10.1990/10.1.1992
  22. |
  23. | addresses of the 68881 data port. This choice is fastest when much data is
  24. | transferred between the two processors.
  25.  
  26. comm =     -6
  27. resp =    -16
  28. zahl =      0
  29.  
  30. | waiting loop ...
  31. |
  32. | wait:
  33. | ww:    cmpiw    #0x8900,a0@(resp)
  34. |     beq    ww
  35. | is coded directly by
  36. |    .long    0x0c688900, 0xfff067f8
  37.  
  38.     .globl    __fixdfsi, ___fixdfsi
  39. __fixdfsi:
  40. ___fixdfsi:
  41.     lea    0xfffa50,a0
  42.     movew    #0x5403,a0@(comm)    | fintrz to fp0
  43.     cmpiw    #0x8900,a0@(resp)    | check
  44.     movel    a7@(4),a0@
  45.     movel    a7@(8),a0@
  46.     movew    #0x6000,a0@(comm)    | result to d0
  47.     .long    0x0c688900, 0xfff067f8
  48.     movel    a0@,d0
  49.         
  50. #endif    sfp004
  51. #ifdef    __M68881__
  52.  
  53. |
  54. | floating point stuff for Atari-gcc using
  55. | an 68030/68881
  56. | developed with gcc/gas
  57. |
  58. | double float to long conversion routine
  59. |
  60. | M. Ritzert (mjr@dfg.dbp.de)
  61. |
  62. | 30.11.1991/10.1.1992
  63. |
  64.  
  65.     .globl    __fixdfsi, ___fixdfsi
  66. __fixdfsi:
  67. ___fixdfsi:
  68.     fintrzd sp@(4),fp0        | convert the arg
  69.     fmovel fp0,d0            | return
  70.  
  71. #endif    __M68881__
  72.  
  73.  
  74. # if !defined (sfp004) && !defined (__M68881__)
  75.  
  76. | double float to long conversion routine
  77. |
  78. | written by Kai-Uwe Bloem (I5110401@dbstu1.bitnet).
  79. | Based on a 80x86 floating point packet from comp.os.minix, written by P.Housel
  80. |
  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.     .text
  97.     .even
  98.     .globl    __fixdfsi, ___fixdfsi
  99.  
  100. __fixdfsi:
  101. ___fixdfsi:
  102.     lea    sp@(4),a0    | pointer to parameters
  103.     moveml    d2/d4/d5,sp@-    | save registers
  104.     moveml    a0@,d4-d5    | get the number
  105.     movew    a0@,d0        | extract exp
  106.     movew    d0,d2        | extract sign
  107.     lsrw    #4,d0
  108.     andw    #0x07ff,d0    | kill sign bit
  109.  
  110.     andl    #0x0fffff,d4    | remove exponent from mantissa
  111.     orl    #0x100000,d4    | restore implied leading "1"
  112.  
  113.     cmpw    #BIAS8,d0    | check exponent
  114.     blt    zero        | strictly factional, no integer part ?
  115.     cmpw    #BIAS8+32,d0    | is it too big to fit in a 32-bit integer ?
  116.     bgt    toobig
  117.  
  118.     subw    #BIAS8+21,d0    | adjust exponent
  119.     bgt    2f        | shift up
  120.     beq    3f        | no shift
  121.  
  122.     cmpw    #-8,d0        | replace far shifts by swap
  123.     bgt    1f
  124.     movew    d4,d5        | shift fast, 16 bits
  125.     swap    d5
  126.     clrw    d4
  127.     swap    d4
  128.     addw    #16,d0        | account for swap
  129.     bgt    2f
  130.     beq    3f
  131.  
  132. 1:    lsrl    #1,d4        | shift down to align radix point;
  133.     addw    #1,d0        | extra bits fall off the end (no rounding)
  134.     blt    1b        | shifted all the way down yet ?
  135.     bra    3f
  136.  
  137. 2:    addl    d5,d5        | shift up to align radix point
  138.     addxl    d4,d4
  139.     subw    #1,d0
  140.     bgt    2b
  141.  
  142. 3:    movel    d4,d0        | put integer into result register
  143.     cmpl    #0x80000000,d0    | -2147483648 is a nasty evil special case
  144.     bne    6f
  145.     tstw    d2        | this had better be -2^31 and not 2^31
  146.     bpl    toobig
  147.     bra    8f
  148. 6:    tstl    d0        | sign bit set ? (i.e. too big)
  149.     bmi    toobig
  150. 7:
  151.     tstw    d2        | is it negative ?
  152.     bpl    8f
  153.     negl    d0        | negate
  154. 8:
  155.     moveml    sp@+,d2/d4/d5
  156.     rts
  157.  
  158. zero:
  159.     clrl    d0        | make the whole thing zero
  160.     bra    7b
  161.  
  162. toobig:
  163.     movel    #0x7fffffff,d0    | ugh. Should cause a trap here.
  164.  
  165. #endif !defined (sfp004) && !defined (__M68881__)
  166.  
  167. #ifdef    ERROR_CHECK
  168.  
  169. | all three versions
  170.     cmpil    #0x7fffffff,d0    | >= long_max
  171.     bge    error_plus    |
  172.     cmpil    #-0x7fffffff,d0    | <= long_min ?
  173.     ble    error_minus    |
  174.     rts            |
  175. error_minus:
  176.     moveml    d0-d1,a7@-
  177.     movel    #63,_errno    | errno = ERANGE
  178.     pea    _Overflow    | for printf
  179.     bra    error_exit    |
  180. error_plus:
  181.     moveml    d0-d1,a7@-
  182.     movel    #63,_errno    | errno = ERANGE
  183.     pea    _Overflow    | for printf
  184.     bra    error_exit    |
  185.  
  186. error_exit:
  187.     pea    _Error_String    |
  188.     pea    __iob+52    |
  189.     jbsr    _fprintf    |
  190.     addl    #12,a7        |
  191.     moveml    a7@+,d0-d1
  192. #endif    ERROR_CHECK
  193.  
  194. # if !defined (sfp004) && !defined (__M68881__)
  195.     bra    7b
  196. #else
  197.     rts
  198. #endif
  199.