home *** CD-ROM | disk | FTP | other *** search
/ Atari FTP / ATARI_FTP_0693.zip / ATARI_FTP_0693 / Mint / mntlib25.zoo / modf.cpp < prev    next >
Text File  |  1992-09-29  |  4KB  |  174 lines

  1. #if !defined (__M68881__) && !defined (sfp004)
  2.  
  3.  | take floating point to integer and fractional pieces
  4.  | 
  5.  | C interface
  6.  |  double modf( double value, double *iptr)
  7.  |  returns fractional part of value
  8.  |       in *iptr returns the integral part
  9.  |       such that (*iptr + fractional) == value
  10.  | 
  11.  |-----------------------------------------------------------------------------
  12.  | ported to 68000 by Kai-Uwe Bloem, 12/89
  13.  |  #1  original author: Peter S. Housel 9/21/88,01/17/89,03/19/89,5/24/89
  14.  |  #2  replaced shifts by swap if possible for speed increase    -kub-, 01/90
  15.  |  #3  ported to gcc ++jrb 03/90
  16.  |-----------------------------------------------------------------------------
  17.  
  18. BIAS8    =    0x3ff - 1
  19.  
  20.     .text; .even
  21.     .globl _modf
  22. _modf:
  23.     lea    sp@(4),a0    | a0 -> float argument
  24.     movel    sp@(12),a1    | a1 -> ipart result
  25.     moveml    d2-d7,sp@-    | save d2-d7
  26.  
  27.     movew    a0@,d0        | extract value.exp
  28.     movew    d0,d2        | extract value.sign
  29.     lsrw    #4,d0
  30.     andw    #0x7ff,d0    | kill sign bit
  31.  
  32.     cmpw    #BIAS8,d0
  33.     bge    1f        | fabs(value) >= 1.0
  34.  
  35.     clrl    a1@        | store zero as the integer part
  36.     clrl    a1@(4)
  37.     moveml    a0@,d0-d1    | return entire value as fractional part
  38.     jra    L0
  39.  
  40. 1:
  41.     cmpw    #BIAS8+53,d0    | all integer, with no fractional part ?
  42.     blt    2f        | no, mixed
  43.  
  44.     movel    a0@,a1@        | store entire value as the integer part
  45.     movel    a0@(4),a1@(4)
  46.     moveq    #0,d0        | return zero as fractional part
  47.     moveq    #0,d1
  48. L0:
  49.     moveml    sp@+,d2-d7    | restore saved d2-d7
  50.     rts
  51. 2:
  52. |    moveml    d3-d7,sp@-    | save some registers (d2 is pushed already)
  53.     moveml    a0@,d4-d5    | get value
  54.  
  55.     andl    #0x0fffff,d4    | remove exponent from value.mantissa
  56.     orl    #0x100000,d4    | restore implied leading "1"
  57.  
  58.     moveq    #0,d6        | zero fractional part
  59.     moveq    #0,d7
  60. 3:
  61.     cmpw    #BIAS8+37,d0    | fast shift, 16 bits ?
  62.     bgt    4f
  63.     movew    d6,d7        | shift down 16 bits
  64.     movew    d5,d6
  65.     movew    d4,d5
  66.     clrw    d4
  67.     swap    d7
  68.     swap    d6
  69.     swap    d5
  70.     swap    d4
  71.     addw    #16,d0
  72.     bra    3b
  73. 4:
  74.     cmpw    #BIAS8+53,d0    | done ?
  75.     bge    5f
  76.     lsrl    #1,d4        | shift integer part
  77.     roxrl    #1,d5
  78.  
  79.     roxrl    #1,d6        | shift high bit into fractional part
  80.     roxrl    #1,d7
  81.  
  82.     addw    #1,d0        | increment ipart exponent
  83.     bra    4b        | keep shifting
  84. 5:
  85.     | normalize ipart (all values are in correct reggies)
  86.      | save  a1, save d2-d7 that norm_df will pop
  87.     movel    a1,sp@-
  88.     pea    L1        | set up return address
  89.     moveml    d2-d7,sp@-    | norm_df will pop this
  90.     clrw    d1
  91.     jmp    norm_df        | go do it
  92. L1:                | norm_df will rts to here
  93.     movel    sp@+,a1        | pop saved a1
  94.     moveml    d0-d1,a1@    | store result into ipart
  95.     
  96.     | norm fractional part
  97.     movel    d6,d4        | get frac into d4/d5
  98.     movel    d7,d5
  99.     clrw    d1        | rounding = 0
  100.     movew    #BIAS8-11,d0    | set frac part exponent, sign already in d2
  101.     jmp    norm_df        | norm_df will pop d2/d7 we save before
  102.                 | it will return to our caller via rts
  103.                 | with result in d0-d1
  104.  
  105. #endif    /* __M68881__, sfp004    */
  106. #ifdef    __M68881__
  107. |
  108. | modf: compiled by gcc from math-68881.h
  109. |       manually optimized by Michael Ritzert
  110. |
  111. |    double modf( double X, double * IP )
  112. |    
  113. |    30.11.92
  114. |    ritzert@dfg.dbp.de
  115. |
  116.  
  117.     .text; .even
  118.  
  119. .globl _modf
  120.  
  121. _modf:
  122.     fmoved    sp@(4),fp0    | load arg
  123.     movel    sp@(12),a0    | get pointer to IP
  124.     fintrzx    fp0,fp1        | get int part
  125.     fmoved    fp1,a0@        | return it to IP
  126.     fsubx     fp1,fp0        | get remainder
  127.     fmoved    fp0,sp@-    | return it
  128.     moveml    sp@+,d0-d1    |
  129.     rts
  130.  
  131. #endif __M68881__
  132. #ifdef sfp004
  133.  
  134. comm =     -6
  135. resp =    -16
  136. zahl =      0
  137.  
  138. .even
  139. .text
  140.     .globl _modf
  141. .even
  142. _modf:
  143.     movel    a1,a7@-            | save a1 (necessary?)
  144.     lea    0xfffffa50:w,a0
  145.     movew    #0x5403,a0@(comm)    | fintrz X -> fp0
  146.     cmpiw    #0x8900,a0@(resp)    | check
  147.     movel    a7@(8),a0@        | load X_hi
  148.     movel    a7@(12),a0@        | load X_low
  149.  
  150.     movew    #0x5480,a0@(comm)    | X -> fp1
  151.     .long    0x0c688900, 0xfff067f8
  152.     movel    a7@(8),a0@        | load X_hi
  153.     movel    a7@(12),a0@        | load X_low
  154.  
  155. |    000 000 001 0101000        | sub fp0 -> fp1
  156.     movew    #0x00a8,a0@(comm)    | sub fp0 -> fp1
  157.     .word    0x4a68,0xfff0,0x6bfa    | test
  158.  
  159.     movew    #0x7400,a0@(comm)    | fp0 to IntPart
  160.     moveal    a7@(16),a1        | address of IntPart while the fpu is active
  161. | wait
  162.     .long    0x0c688900, 0xfff067f8
  163.     movel    a0@,a1@+
  164.     movel    a0@,a1@+
  165.     movew    #0x7480,a0@(comm)    | Rest to d0/d1
  166. | wait
  167.     .long    0x0c688900, 0xfff067f8
  168.     movel    a0@,d0
  169.     movel    a0@,d1
  170.     movel    a7@+,a1            | restore a1
  171.      rts
  172.  
  173. #endif    sfp004
  174.