Annotation of coherent/b/lib/libm/i8087/pow87.m, revision 1.1

1.1     ! root        1: //////////
        !             2: / libm 8087
        !             3: / pow(x, y)
        !             4: //////////
        !             5: 
        !             6: #include "larges.h"
        !             7: #include "ifno8087.h"
        !             8: 
        !             9:        .globl  pow_
        !            10:        .globl  two
        !            11:        .globl  ylog2x
        !            12:        .globl  cfcc87
        !            13:        .globl  tstcc
        !            14:        .globl  edomain
        !            15: 
        !            16: //////////
        !            17: / double
        !            18: / pow(x, y)
        !            19: / double x, y;
        !            20: /
        !            21: / pow is passed x, y on 8087 stack.
        !            22: //////////
        !            23: 
        !            24: x      =       RASIZE          / x arg offset
        !            25: y      =       RASIZE+8        / y arg offset
        !            26: 
        !            27: pow_:
        !            28:        ifno8087(_pow_)
        !            29:        mov     bx, sp
        !            30:        fdld    Pss y(bx)       / Load argument y.
        !            31:        fdld    Pss x(bx)       / Load argument x.
        !            32: 
        !            33: pow:                           / x, y
        !            34:        Gcall   tstcc           / Test if x == 0.
        !            35:        je      0f              / x is zero.
        !            36:        jb      1f              / x is negative.
        !            37:        sub     ax, ax          / x is positive, clear ZF flag
        !            38:        jmp     4f              / to indicate result sign positive.
        !            39: 
        !            40: 0:     fxch                    / y, 0
        !            41:        Gcall   tstcc           / Compare y to 0.
        !            42:        fstp    st              / Pop y, leaving 0.
        !            43:        jbe     2f              / y <= 0, issue EDOM error and return 0.
        !            44:        Gret                    / y > 0, return 0.
        !            45: 
        !            46: 1:     fld     st1             / y, x, y with x negative.
        !            47:        Gcall   tstintp         / Test if y is integral and pop.
        !            48:        je      3f              / y is integral.
        !            49:        fstp    st              / y is nonintegral, pop x
        !            50: 2:     Gjmp    edomain         / and issue EDOM error and return.
        !            51: 
        !            52: 3:     fchs                    / x is negative, force it positive.
        !            53:        fld1                    / 1, x, y
        !            54:        fadd    st, st          / 2, x, y
        !            55:        fdivr   st, st2         / y/2, x, y
        !            56:        Gcall   tstintp         / Test if y/2 is integral.
        !            57: 
        !            58: / At 4:, ZF flag contains the desired result sign.
        !            59: / The 8087 stack contains x > 0, y.
        !            60: 4:     pushf                   / Save the flags.
        !            61:        Gcall   ylog2x          / y * log base 2 of x
        !            62:        Gcall   two             / 2 ^ (y * log base 2 of x) = x ^ y
        !            63:        popf                    / Restore the flags.
        !            64:        je      5f              / No sign change, done.
        !            65:        fchs                    / Flip the result sign.
        !            66: 
        !            67: 5:     Gret
        !            68: 
        !            69: //////////
        !            70: / tstintp tests whether the 8087 stacktop contains
        !            71: / an integral value and sets ZF flag accordingly.
        !            72: / It pops the 8087 stack before returning.
        !            73: / This works with any of the four 8087 rounding modes.
        !            74: //////////
        !            75: tstintp:                       / x
        !            76:        fld     st              / x, x
        !            77:        frndint                 / int(x), x
        !            78:        fcompp                  / Compare int(x) to x and pop both.
        !            79:        Gjmp    cfcc87          / Load condition codes and return.

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.