home *** CD-ROM | disk | FTP | other *** search
/ Atari FTP / ATARI_FTP_0693.zip / ATARI_FTP_0693 / Mint / mntlib25.zoo / ldexp.cpp < prev    next >
C/C++ Source or Header  |  1992-09-29  |  6KB  |  223 lines

  1.     .text
  2.     .globl _ldexp
  3.     .globl __infinitydf
  4.     .even
  5. #ifdef    ERROR_CHECK
  6. #include "errbase.h"
  7. _Overflow:
  8.     .ascii "ldexp: OVERFLOW\12\15\0"
  9. # if defined(__M68881__) || defined(sfp004)
  10. _Domain:
  11.     .ascii "ldexp: NAN\12\15\0"
  12.     .even
  13. double_max:
  14.     .long    0x7fee42d1
  15.     .long    0x30273b76
  16. double_min:
  17.     .long    0xffee42d1
  18.     .long    0x30273b76
  19. NaN:
  20.     .long    0x7fffffff
  21.     .long    0xffffffff
  22. p_Inf:
  23.     .long    0x7ff00000
  24.     .long    0x00000000
  25. m_Inf:
  26.     .long    0xfff00000
  27.     .long    0x00000000
  28. # endif
  29.     .even
  30. #endif    ERROR_CHECK
  31. _ldexp:
  32. #if !defined (__M68881__) && !defined (sfp004)
  33.  
  34.  | add exponent to floating point number
  35.  | C Interface
  36.  | double ldexp(double value, unsigned int exp);
  37.  | returns value * 2**exp
  38.  | (int is 16 bits if -mshort, 32 bits if !-mshort)
  39.  |-----------------------------------------------------------------------------
  40.  | ported to 68000 by Kai-Uwe Bloem, 12/89
  41.  |  #1  original author: Peter S. Housel 9/21/88,01/17/89,03/19/89,5/24/89
  42.  |  #2    added support for denormalized numbers            -kub-, 01/90
  43.  |  #3  ported to gcc  ++jrb  04/90
  44.  |  #4  handle exponent overflow when ints are 32 bits        -kub-, 04/90
  45.  |-----------------------------------------------------------------------------
  46.  
  47.     lea    sp@(4),a1
  48.     moveml    d2-d7,sp@-    | save d2-d7
  49.  
  50.     movew    a1@,d0        | extract value.exp
  51.     movew    d0,d2        | extract value.sign
  52.     lsrw    #4,d0
  53.     andw    #0x7ff,d0    | kill sign bit
  54.  
  55.     andw    #0x0f,a1@    | remove exponent from value.mantissa
  56.     tstw    d0        | check for zero exponent - no leading 1
  57.     beq    0f
  58.     orw    #0x10,a1@    | restore implied leading 1
  59.     bra    1f
  60. 0:    addw    #1,d0
  61. 1:
  62. #ifdef __MSHORT__
  63.     addw    a1@(8),d0    | add in exponent
  64.     extl    d0
  65. #else
  66.     extl    d0
  67.     addl    a1@(8),d0    | add in exponent
  68. #endif
  69.     cmpl    #-53,d0        | hmm. works only if 1 in implied position...
  70.     ble    retz        | range error - underflow
  71.     cmpl    #2047,d0
  72.     bge    rangerr        | range error - overflow
  73.  
  74.     clrw    d1        | zero rounding bits
  75.     moveml    a1@,d4-d5    | value into d4,d5
  76.     jmp    norm_df        | norm_df will pop d2-d7 and rts
  77.  
  78. retz:
  79.     moveq    #0,d0        | zero return value
  80.     moveq    #0,d1
  81.     jra    L0
  82.  
  83. rangerr:
  84.  
  85. #ifdef ERROR_CHECK
  86.     moveq    #ERANGE,d0
  87.     Emove    d0,Errno
  88.     pea    pc@(_Overflow)    | for printf
  89.     pea    Stderr        |
  90.     jbsr    _fprintf    |
  91.     addql    #8,a7        |
  92. #endif ERROR_CHECK
  93.  
  94.     moveml    __infinitydf,d0-d1 | return HUGE_VAL (same as in <math.h>)
  95.     andw    #0x8000,d2    | get sign bit of argument
  96.     swap    d2
  97.     clrw    d2
  98.     orl    d2,d0
  99. L0:
  100.     moveml    sp@+,d2-d7    | pop saved reggies
  101.     rts
  102.  
  103. #else    __M68881__ || sfp004
  104. #ifdef    __M68881__
  105. |#######################################################################
  106. |
  107. |# add exponent to floating point number
  108. |# C Interface
  109. |# double ldexp(double value, unsigned int exp);
  110. |# returns value * 2**exp
  111. |# (int is 16 bits if -mshort, 32 bits if !-mshort)
  112. |# performed entirely on the 68881 to avoid overfow as good as possible
  113. |##############################################################################
  114. |# hacked for the 68881 by Michael Ritzert, 5.10.90
  115. |##############################################################################
  116. |# ported fromt sfp004 to real coprocessor, mjr, August 1991
  117. |##############################################################################
  118.  
  119. #ifdef __MSHORT__
  120.     movew    a7@(12),d0        | get exponent
  121.     extl    d0
  122. #else
  123.     movel    a7@(12),d0        | get exponent
  124. #endif
  125.     fgetexpd a7@(4),fp1        | extract exponent of 1st arg
  126.     fmovel    fp1,d1            | d1 serves as accumulator
  127.     addl    d0,d1            | sum of exp_s of both args
  128.  
  129.     ftwotoxl d0,fp0            | ftwotox to fp0 (as long int!)
  130.     fmuld    a7@(4),fp0        | fmul value,fp0
  131.     fmoved    fp0,a7@-        | get double from fp0
  132.     moveml    a7@+,d0-d1
  133.  
  134. #endif  __M68881__
  135. #ifdef    sfp004
  136.  
  137. | add exponent to floating point number
  138. | C Interface
  139. | double ldexp(double value, unsigned int exp);
  140. | returns value * 2**exp
  141. | (int is 16 bits if -mshort, 32 bits if !-mshort)
  142. | performed entirely on the 68881 to avoid overfow as good as possible
  143. |
  144. | hacked for the 68881 by Michael Ritzert, 5.10.90
  145. |
  146.  
  147. | addresses of the 68881 data port. This choice is fastest when much data is
  148. | transferred between the two processors.
  149.  
  150. comm =     -6    |    fpu command reg
  151. resp =    -16    |    fpu response reg
  152. zahl =      0    |    fpu data reg
  153.  
  154. | waiting loop ...
  155. |
  156. | wait:
  157. | ww:    cmpiw    #0x8900,a1@(resp)
  158. |     beq    ww
  159. | is coded directly by
  160. |    .byte    0x0c,0x69,0x89,0x00,0xff,0xf0,0x67,0xf8 (a1)
  161. |    or
  162. |    .long    0x0c6889000, 0x000067f8            (a0)
  163.  
  164. #ifdef __MSHORT__
  165.     movew    sp@(12),d0        | get exponent
  166.     extl    d0
  167. #else
  168.     movel    sp@(12),d0        | get exponent
  169. #endif
  170.     lea    0xfffffa50:w,a0        | fpu address
  171.     movew    #0x549e,a0@(comm)    | fgetexpd sp@(4),fp1
  172.     cmpiw    #0x8900,a0@(resp)
  173.     movel    sp@(4),a0@
  174.     movel    sp@(8),a0@
  175.     movew    #0x6080,a0@(comm)    | fmovel fp1,d1
  176.     .long    0x0c688900, 0xfff067f8
  177.     movel    a0@,d1
  178.     addl    d0,d1
  179.     movew    #0x4011,a0@(comm)    | ftwotoxl d0,fp0
  180.     .long    0x0c688900, 0xfff067f8
  181.     movel    d0,a0@
  182.     movew    #0x5423,a0@(comm)    | fmuld sp@(4),fp0
  183.     .long    0x0c688900, 0xfff067f8
  184.     movel    sp@(4),a0@
  185.     movel    sp@(8),a0@
  186.     movew    #0x7400,a0@(comm)    | fmoved fp0,d0/d1
  187.     .long    0x0c688900, 0xfff067f8
  188.     movel    a0@,d0
  189.     movel    a0@,d1
  190. #endif    sfp004
  191.  
  192. #ifdef    ERROR_CHECK
  193.     lea    double_max,a0    |
  194.     swap    d0        | exponent into lower word
  195.     cmpw    a0@(16),d0    | == NaN ?
  196.     beq    error_nan    |
  197.     cmpw    a0@(24),d0    | == + Infinity ?
  198.     beq    error_plus    |
  199.     swap    d0        | result ok,
  200.     rts            | restore d0
  201. error_plus:
  202.     swap    d0
  203.     moveml    d0-d1,a7@-    | print error message
  204.     moveq    #ERANGE,d0    | Overflow: errno = ERANGE
  205.     Emove    d0,Errno
  206.     pea    pc@(_Domain)    | for printf
  207.     bra    error_exit    |
  208. error_nan:
  209.     moveq    #EDOM,d0    | NAN => errno = EDOM
  210.     Emove    d0,Errno
  211.     moveml    a0@(24),d0-d1    | result = +inf
  212.     moveml    d0-d1,a7@-    | print error message
  213.     pea    pc@(_Overflow)    | for printf
  214. error_exit:
  215.     pea    Stderr        |
  216.     jbsr    _fprintf    |
  217.     addql    #8,a7        |
  218.     moveml    a7@+,d0-d1
  219. #endif    ERROR_CHECK
  220.     rts
  221.  
  222. #endif    /* !__M68881__ && !sfp004    */
  223.