home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / zip / gnu / mntlib16.lzh / MNTLIB16 / LDEXP.CPP < prev    next >
Text File  |  1993-07-29  |  2KB  |  77 lines

  1.  | add exponent to floating point number
  2.  | C Interface
  3.  | double ldexp(double value, unsigned int exp);
  4.  | returns value * 2**exp
  5.  | (int is 16 bits if -mshort, 32 bits if !-mshort)
  6.  |-----------------------------------------------------------------------------
  7.  | ported to 68000 by Kai-Uwe Bloem, 12/89
  8.  |  #1  original author: Peter S. Housel 9/21/88,01/17/89,03/19/89,5/24/89
  9.  |  #2    added support for denormalized numbers            -kub-, 01/90
  10.  |  #3  ported to gcc  ++jrb  04/90
  11.  |  #4  handle exponent overflow when ints are 32 bits        -kub-, 04/90
  12.  |-----------------------------------------------------------------------------
  13.  
  14.     .text; .even
  15.     .globl _ldexp
  16.     .globl __infinitydf
  17. _ldexp:
  18.     lea    sp@(4),a1
  19.     moveml    d2-d7,sp@-    | save d2-d7
  20.  
  21.     movew    a1@,d0        | extract value.exp
  22.     movew    d0,d2        | extract value.sign
  23.     lsrw    #4,d0
  24.     andw    #0x7ff,d0    | kill sign bit
  25.  
  26.     andw    #0x0f,a1@    | remove exponent from value.mantissa
  27.     tstw    d0        | check for zero exponent - no leading 1
  28.     beq    0f
  29.     orw    #0x10,a1@    | restore implied leading 1
  30.     bra    1f
  31. 0:    addw    #1,d0
  32. 1:
  33. #ifdef __MSHORT__
  34.     addw    a1@(8),d0    | add in exponent
  35.     extl    d0
  36. #else
  37.     extl    d0
  38.     addl    a1@(8),d0    | add in exponent
  39. #endif
  40.     cmpl    #-53,d0        | hmm. works only if 1 in implied position...
  41.     ble    retz        | range error - underflow
  42.     cmpl    #2047,d0
  43.     bge    rangerr        | range error - overflow
  44.  
  45.     clrw    d1        | zero rounding bits
  46.     moveml    a1@,d4-d5    | value into d4,d5
  47.     jmp    norm_df        | norm_df will pop d2-d7 and rts
  48.  
  49.  
  50.     .globl    _errno        | from <errno.h>
  51. ERANGE    =    34
  52.  
  53. retz:
  54. #ifdef __MSHORT__
  55.     movew    #ERANGE,_errno    | set errno
  56. #else
  57.     movel    #ERANGE,_errno    | set errno
  58. #endif
  59.     moveq    #0,d0        | zero return value
  60.     moveq    #0,d1
  61.     jra    L0
  62.  
  63. rangerr:
  64. #ifdef __MSHORT__
  65.     movew    #ERANGE,_errno    | set errno
  66. #else
  67.     movel    #ERANGE,_errno    | set errno
  68. #endif
  69.     moveml    __infinitydf,d0-d1 | return HUGE_VAL (same as in <math.h>)
  70.     andw    #0x8000,d2    | get sign bit of argument
  71.     swap    d2
  72.     clrw    d2
  73.     orl    d2,d0
  74. L0:
  75.     moveml    sp@+,d2-d7    | pop saved reggies
  76.     rts
  77.