home *** CD-ROM | disk | FTP | other *** search
/ Atari FTP / ATARI_FTP_0693.zip / ATARI_FTP_0693 / Mint / mntlib25.zoo / frexp.cpp < prev    next >
Text File  |  1992-10-01  |  6KB  |  220 lines

  1. #if !defined (__M68881__) && !defined (sfp004)
  2. #
  3.  |-----------------------------------------------------------------------------
  4.  | remove exponent from floating point number
  5.  | C Interface
  6.  | double frexp(double value, int *eptr)
  7.  |
  8.  | returns significand (|significand| < 1)
  9.  |       in *eptr returns n such that value = significand * 2**n
  10.  |-----------------------------------------------------------------------------
  11.  | ported to 68000 by Kai-Uwe Bloem, 12/89
  12.  |  #1  original author: Peter S. Housel 9/21/88,01/17/89,03/19/89,5/24/89
  13.  |  #2    added support for denormalized numbers            -kub-, 01/90
  14.  |  #   ported to gcc  ++jrb 04/90
  15.  |-----------------------------------------------------------------------------
  16.  
  17. BIAS8    =    0x3ff - 1
  18.  
  19.     .text; .even
  20.     .globl _frexp
  21. _frexp:
  22.     movel    sp@(12),a0    | initialize exponent for loop
  23. #ifdef __MSHORT__
  24.     clrw    a0@
  25. #else
  26.     clrl    a0@
  27. #endif
  28.     tstl    sp@(4)        | 1st arg == 0 ?
  29.     bne    nonzero
  30.     tstl    sp@(8)
  31.     bne    nonzero
  32.     clrl    d0
  33.     clrl    d1
  34.     rts
  35. nonzero:
  36.     lea    sp@(4),a1
  37.     moveml    d2-d7,sp@-
  38. 2:
  39.     movew    a1@,d0        | extract value.exp
  40.     movew    d0,d2        | extract value.sign    ++jrb
  41.     lsrw    #4,d0
  42.     andw    #0x7ff,d0    | kill sign bit
  43.     cmpw    #BIAS8,d0    | get out of loop if finally (a1) in [0.5,1.0)
  44.     beq    3f
  45.  
  46.     andw    #0x0f,a1@    | remove exponent from value.mantissa
  47.     tstw    d0        | check for zero exponent - no leading 1
  48.     beq    0f
  49.     orw    #0x10,a1@    | restore implied leading 1
  50.     bra    1f
  51. 0:    addw    #1,d0
  52. 1:
  53.     movel    a1@,d1        | check for zero
  54.     orl    a1@(4),d1
  55.     beq    3f        | if zero, all done : exp = 0, num = 0.0
  56.  
  57.     subw    #BIAS8,d0    | remove bias
  58. #ifdef __MSHORT__        
  59.     addw    d0,a0@        | add current exponent in
  60. #else
  61.     extl    d0
  62.     addl    d0,a0@        | add current exponent in
  63. #endif
  64.  
  65.     movew    #BIAS8,d0    | set bias for return value
  66.     clrw    d1        | rounding = 0
  67.     pea    L0        | call to norm_df (dirty, but dont ...
  68.     moveml    d2-d7,sp@-    | ... need to copy with -mshort)
  69.     moveml    a1@,d4-d5
  70.     jmp    norm_df        | normalize result
  71. L0:
  72.     moveml    d0-d1,a1@
  73.     bra    2b        | loop around to catch denormalized numbers
  74. 3:
  75.     moveml    a1@,d0-d1
  76.     moveml    sp@+,d2-d7
  77.                 | d0-d1 has normalized mantissa
  78.     rts
  79.  
  80. #endif    !__M68881__ && !sfp004
  81. #ifdef    __M68881__
  82.  
  83. |
  84. | remove exponent from floating point number
  85. | C Interface
  86. | double frexp(double value, int *eptr)
  87. |
  88. | returns significand (#significand# < 1)
  89. |       in *eptr returns n such that value = significand * 2**n
  90. |#######################################################################
  91. | hacked for the 68881 by Michael Ritzert, 5.10.90
  92. |#######################################################################
  93. | ported from sfp004 board to real 68881, mjr, August 1991
  94. |#######################################################################
  95. | a0:    pointer to n
  96. |     sp@(12) address of resulting exponent (n)
  97.     
  98.     .text; .even
  99.  
  100. .globl _frexp
  101.  
  102. _frexp:
  103.     moveal    a7@(12),a1        | address of n
  104.     fmoved    a7@(4),fp0        | load first_argument to fp0
  105.     fcmpd    #0r0.0,fp0        | 1st arg == 0 ?
  106.     fjeq    null_            | both parts of result are 0
  107.     fgetexpx fp0,fp1        | get expnent
  108.     fgetmanx fp0,fp0        | get mantissa
  109.     fscaleb #-1,fp0            |
  110. #ifdef __MSHORT__
  111.     fmovew    fp1,a1@            | fetch exp (fmovew from fp1)
  112.     addqw    #1,a1@            | correct result
  113. #else
  114.     fmovel    fp1,a1@            | fetch exp (fmovel from fp1)
  115.     addql    #1,a1@            | correct result
  116. #endif
  117.     fmoved    fp0,a7@-        | now fetch significand
  118.     moveml    a7@+,d0-d1
  119.     rts
  120. null_:
  121.     moveml    a7@(4),d0-d1
  122. #ifdef __MSHORT__
  123.     clrw    a1@
  124. #else
  125.     clrl    a1@
  126. #endif
  127.     rts
  128.  
  129. #endif    __M68881__
  130. #ifdef    sfp004
  131.  
  132. | remove exponent from floating point number
  133. | C Interface
  134. | double frexp(double value, int *eptr)
  135. |
  136. | returns significand (|significand| < 1)
  137. |       in *eptr returns n such that value = significand * 2**n
  138. |
  139. | hacked for the 68881 by Michael Ritzert, 5.10.90/18.12.91
  140. |
  141. | addresses of the 68881 data port. This choice is fastest when much data is
  142. | transferred between the two processors.
  143.  
  144. comm =     -6    |    fpu command reg
  145. resp =    -16    |    fpu response reg
  146. zahl =      0    |    fpu data reg
  147.  
  148. | a1:    fpu base register
  149. | a0:    pointer to n
  150. |     sp@(12) address of resulting exponent (n)
  151.  
  152. | waiting loop ...
  153. |
  154. | wait:
  155. | ww:    cmpiw    #0x8900,a0@(resp)
  156. |     beq    ww
  157. | is coded directly by
  158. |    .long    0x0c688900, 0xfff067f8                 (fpu base a1)
  159. | and
  160. | www:    tst.w    a0@(resp)
  161. |    bmi.b    www
  162. | is coded by
  163. |    .word    0x4a68,0xfff0,0x6bfa        | test
  164.     
  165.     .text; .even
  166.  
  167. .globl _frexp
  168.     
  169.     tstl    sp@(4)        | 1st arg == 0 ?
  170.     bne    nonzero
  171.     tstl    sp@(8)
  172.     bne    nonzero
  173.     movel    sp@(12),a0
  174. #ifdef __MSHORT__
  175.     clrw    a0@
  176. #else
  177.     clrl    a0@
  178. #endif
  179.     clrl    d0
  180.     clrl    d1
  181.     rts
  182. nonzero:
  183.  
  184.     lea    0xfffffa50:w,a0
  185.     movew    #0x5418,a0@(comm)    | load first argument to fp0
  186.     cmpiw    #0x8900,a0@(resp)    | check
  187.     movel    a7@(4),a0@
  188.     movel    a7@(8),a0@
  189.  
  190.     movew    #0x009f,a0@(comm)    | fgetman fp0,fp1
  191.     .word    0x4a68,0xfff0,0x6bfa    | test
  192.  
  193.     movew    #0x001e,a0@(comm)    | fgetexp fp0,fp0
  194.     moveal    a7@(12),a1        | address of n while the fpu is active
  195.     .word    0x4a68,0xfff0,0x6bfa    | test
  196.  
  197.     movew    #5026,a0@(comm)        | fscalew #-1,fp0
  198.     .long    0x0c688900, 0xfff067f8
  199.     movew    #-1,a0@
  200.  
  201. #ifdef __MSHORT__
  202.     movew    #0x7080,a0@(comm)    | fetch exp (fmovew from fp1)
  203.     .long    0x0c688900, 0xfff067f8
  204.     movew    a0@,a1@            | return exp
  205. #else
  206.     movew    #0x7880,a0@(comm)    | fetch exp (fmovel from fp1)
  207.     .long    0x0c688900, 0xfff067f8
  208.     movel    a0@,a1@            | return exp
  209. #endif
  210.     movew    #0x7400,a0@(comm)    | now fetch significand
  211.     .long    0x0c688900, 0xfff067f8
  212.     movel    a0@,d0
  213.     movel    a0@,d1
  214.     btst    #31,a7@(4)        | test sign of 1st arg
  215.     bge    fini            | arg neg ?
  216.     bset    #31,d0            | =>  negate result
  217. fini:    rts
  218.  
  219. #endif    sfp004
  220.