|
|
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.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.