home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / Samples / CASM.ARJ / LDEXP.ASM < prev    next >
Assembly Source File  |  1988-04-21  |  2KB  |  113 lines

  1. ;_ ldexp.asm   Thu Apr 21 1988   Modified by: Walter Bright */
  2. ; Written by Walter Bright
  3. ; Copyright (C) 1984-1988 by Northwest Software
  4. ; All rights reserved
  5.  
  6.     include    macros.asm
  7.  
  8.     .8087
  9.  
  10.     begdata
  11.     c_extrn    _8087,word
  12.     enddata
  13.  
  14.     if LCODE
  15.     c_extrn    CXFERR,far
  16.     else
  17.     c_extrn    CXFERR,near
  18.     endif
  19.  
  20.     begcode    ldexp
  21.  
  22. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  23. ;
  24. ;    double ldexp(value,exp)
  25. ;    double value;
  26. ;    int exp;
  27. ; Returns:
  28. ;    value*(2**exp)
  29.  
  30.     c_public ldexp
  31.  
  32. sgn        equ    08000h        ;mask for sign bit
  33. longexp        equ    07FF0h        ;mask for long exponent
  34. longhid        equ    00010h        ;mask for hidden bit
  35. longbias    equ    03FFh        ;exponent bias
  36.  
  37. func    ldexp
  38.     push    BP
  39.     mov    BP,SP
  40.     .if    _8087 e 0, LD2        ;if 8087 not installed
  41.     fild    word ptr P+8[BP]    ;load exp
  42.     fld    qword ptr P[BP]        ;load value
  43.     fscale                ;ST(0) = ST(0) * (2**ST(1))
  44.     fstp    qword ptr P[BP]
  45.     fstp    ST            ;leave stack as we found it
  46.                     ;(also doing an fwait, MASM doesn't
  47.                     ; recognize fnstp !@#$%^&)
  48.     mov    AX,P+6[BP]
  49.     mov    BX,P+4[BP]
  50.     mov    CX,P+2[BP]
  51.     mov    DX,P+0[BP]        ;transfer result to AX..DX
  52.     pop    BP
  53.     ret
  54.  
  55. LD2:    .save    <SI>
  56.     mov    AX,P+6[BP]
  57.     mov    BX,P+4[BP]
  58.     mov    CX,P+2[BP]
  59.     mov    DX,P+0[BP]        ;transfer double to AX..DX
  60.  
  61.     mov    SI,AX
  62.     shl    SI,1
  63.     or    SI,BX
  64.     or    SI,CX
  65.     or    SI,DX
  66.     jz    LD3            ;if value is 0, result is 0
  67.  
  68.     mov    SI,AX
  69.     and    SI,longexp        ;mask off exponent bits
  70.     xor    AX,SI            ;clear exponent bits in AX
  71.  
  72.     shr    SI,1
  73.     shr    SI,1
  74.     shr    SI,1
  75.     shr    SI,1            ;right justify exponent
  76.  
  77.     add    SI,P+8[BP]        ;add exp
  78.     test    SI,0F800h        ;see if underflow or overflow
  79.     jnz    L6            ;yes
  80.     shl    SI,1
  81.     shl    SI,1
  82.     shl    SI,1
  83.     shl    SI,1
  84. ;    and    SI,longexp    ;dump extraneous bits (not necessary)
  85.     or    AX,SI        ;install exponent
  86.  
  87. LD3:    .restore <SI>
  88.     pop    BP
  89.     ret
  90.  
  91.  
  92. L6:    mov    AL,1        ;assume underflow
  93.     js    L7        ;right
  94.     inc    AX        ;overflow
  95. L7:    push    AX
  96.     callm    CXFERR
  97.     pop    AX
  98.     cwd            ;DX = 0
  99.     mov    CX,DX
  100.     mov    BX,DX
  101.     dec    AX
  102.     jz    LD3        ;0 is result for underflow
  103.     mov    AX,P+6[BP]
  104.     and    AX,sgn        ;isolate sign
  105.     or    AX,longexp
  106.     jmp    LD3        ;infinity is result for overflow (with sign)
  107.  
  108. c_endp    ldexp
  109.  
  110.     endcode    ldexp
  111.  
  112.     end
  113.