home *** CD-ROM | disk | FTP | other *** search
/ Atari FTP / ATARI_FTP_0693.zip / ATARI_FTP_0693 / Mint / mntlib32.zoo / modf.cpp < prev    next >
Text File  |  1993-06-17  |  4KB  |  158 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.  |  #4  replaced by a completely new, smaller and faster implementation,
  17.  |        Michal Jaegermann, ntomczak@vm.ucs.ualberta.ca - 05/93
  18.  |-----------------------------------------------------------------------------
  19.  
  20. BIAS8    =    0x3ff - 1
  21.  
  22.     .text; .even
  23.     .globl _modf
  24. _modf:
  25.     lea    sp@(4),a0    | a0 -> float argument
  26.     moveml    d2-d7,sp@-    | save d2-d7
  27.     moveml    a0@+,d0-d1
  28.     movel   a0@,a1        | a1 -> ipart result
  29.  
  30.     movel    d0,d2        | calculate exponent
  31.     swap    d2
  32.     bclr    #15,d2        | kill sign bit
  33.     lsrw    #4,d2        | exponent in lower 12 bits of d2
  34.  
  35.     cmpw    #BIAS8,d2
  36.     bgt    1f        | fabs(value) >= 1.0
  37. |                | return entire value as fractional part
  38.     clrl    a1@+        | d0, d1 already ok
  39.     clrl    a1@        | make integer part 0
  40.  
  41. 0:
  42.     moveml    sp@+,d2-d7    | restore saved d2-d7
  43.     rts
  44.  
  45. 1:
  46.     movew    #BIAS8+53,d3
  47.     subw    d2,d3        | compute position of "binary point"
  48.     bgt    2f        | branch if we do have fractional part
  49.  
  50.     moveml  d0-d1,a1@    | store entire value as the integer part
  51.     moveq    #0,d0        | return zero as fractional part
  52.     movel    d0,d1
  53.     jra    0b
  54. 2:
  55.     movel    d1,d5        | save for computation of fractional part
  56.  
  57.     moveq    #32,d6
  58.     cmpw    d6,d3
  59.     blt    3f        | jump if "binary point" in a lower part
  60.     movel    d0,d4
  61.     subw    d6,d3
  62.     moveq    #0,d6        | compute mask for splitting
  63.     bset    d3,d6
  64.     negl    d6
  65.     andl    d6,d0        | this is integer part
  66.     moveq    #0,d1
  67.     notl    d6
  68.     andl    d6,d4        | and denormalized fractional part
  69.     jra    4f
  70. 3:
  71.     moveq    #0,d6        | splitting on lower part
  72.     bset    d3,d6
  73.     negl    d6
  74.     andl    d6,d1        | this is integer part
  75.     moveq    #0,d4        | nothing in an upper fraction
  76.     notl    d6
  77.     andl    d6,d5        | and clear those unneded bits
  78. 4:
  79.     moveml    d0-d1,a1@    | store computed integer part
  80.  
  81.     swap    d0
  82.     exg    d0,d2        | set registers for norm_df
  83.     clrw    d1        | rounding = 0
  84. |                | normalize fractional part
  85.     jmp    norm_df        | norm_df will pop d2/d7 we saved before
  86.                 | it will return to our caller via rts
  87.                 | with result in d0-d1
  88.  
  89. #endif    /* __M68881__, sfp004    */
  90. #ifdef    __M68881__
  91. |
  92. | modf: compiled by gcc from math-68881.h
  93. |       manually optimized by Michael Ritzert
  94. |
  95. |    double modf( double X, double * IP )
  96. |
  97. |    30.11.92
  98. |    ritzert@dfg.dbp.de
  99. |
  100.  
  101.     .text; .even
  102.  
  103. .globl _modf
  104.  
  105. _modf:
  106.     fmoved    sp@(4),fp0    | load arg
  107.     movel    sp@(12),a0    | get pointer to IP
  108.     fintrzx    fp0,fp1        | get int part
  109.     fmoved    fp1,a0@        | return it to IP
  110.     fsubx     fp1,fp0        | get remainder
  111.     fmoved    fp0,sp@-    | return it
  112.     moveml    sp@+,d0-d1    |
  113.     rts
  114.  
  115. #endif __M68881__
  116. #ifdef sfp004
  117.  
  118. comm =     -6
  119. resp =    -16
  120. zahl =      0
  121.  
  122. .even
  123. .text
  124.     .globl _modf
  125. .even
  126. _modf:
  127.     movel    a1,a7@-            | save a1 (necessary?)
  128.     lea    0xfffffa50:w,a0
  129.     movew    #0x5403,a0@(comm)    | fintrz X -> fp0
  130.     cmpiw    #0x8900,a0@(resp)    | check
  131.     movel    a7@(8),a0@        | load X_hi
  132.     movel    a7@(12),a0@        | load X_low
  133.  
  134.     movew    #0x5480,a0@(comm)    | X -> fp1
  135.     .long    0x0c688900, 0xfff067f8
  136.     movel    a7@(8),a0@        | load X_hi
  137.     movel    a7@(12),a0@        | load X_low
  138.  
  139. |    000 000 001 0101000        | sub fp0 -> fp1
  140.     movew    #0x00a8,a0@(comm)    | sub fp0 -> fp1
  141.     .word    0x4a68,0xfff0,0x6bfa    | test
  142.  
  143.     movew    #0x7400,a0@(comm)    | fp0 to IntPart
  144.     moveal    a7@(16),a1        | address of IntPart while the fpu is active
  145. | wait
  146.     .long    0x0c688900, 0xfff067f8
  147.     movel    a0@,a1@+
  148.     movel    a0@,a1@+
  149.     movew    #0x7480,a0@(comm)    | Rest to d0/d1
  150. | wait
  151.     .long    0x0c688900, 0xfff067f8
  152.     movel    a0@,d0
  153.     movel    a0@,d1
  154.     movel    a7@+,a1            | restore a1
  155.      rts
  156.  
  157. #endif    sfp004
  158.