home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / zip / mint / mntlib16.lzh / MNTLIB16 / MODF.S < prev    next >
Text File  |  1993-08-03  |  3KB  |  104 lines

  1. #APP
  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.