// TITLE("Alpha AXP Exponential") //++ // // Copyright (c) 1993, 1994 Digital Equipment Corporation // // Module Name: // // exp.s // // Abstract: // // This module implements a high-performance Alpha AXP specific routine // for IEEE double format exponential. // // Author: // // Bob Hanek 30-Jun-1993 // // Environment: // // User mode. // // Revision History: // // Thomas Van Baak (tvb) 6-Feb-1994 // // Adapted for NT. // //-- #include "ksalpha.h" // // Define DPML exception record for NT. // .struct 0 ErErr: .space 4 // error code ErCxt: .space 4 // context ErPlat: .space 4 // platform ErEnv: .space 4 // environment ErRet: .space 4 // return value pointer ErName: .space 4 // function name ErType: .space 8 // flags and fill ErVal: .space 8 // return value ErArg0: .space 8 // arg 0 ErArg1: .space 8 // arg 1 ErArg2: .space 8 // arg 2 ErArg3: .space 8 // arg 3 DpmlExceptionLength: // // Define stack frame. // .struct 0 Temp: .space 8 // save argument ExRec: .space DpmlExceptionLength // exception record .space 0 // for 16-byte stack alignment FrameLength: // // Define lower and upper 32-bit parts of 64-bit double. // #define LowPart 0x0 #define HighPart 0x4 SBTTL("Exponential") //++ // // double // exp ( // IN double x // ) // // Routine Description: // // This function returns the exponential of the given double argument. // // Arguments: // // x (f16) - Supplies the argument value. // // Return Value: // // The double exponential result is returned as the function value in f0. // //-- NESTED_ENTRY(exp, FrameLength, ra) lda sp, -FrameLength(sp) // allocate stack frame mov ra, t6 // save return address PROLOGUE_END // // do some range checks and load some constants // ornot zero, zero, t1 stt f16, Temp(sp) ldl v0, Temp + HighPart(sp) srl t1, 33, t1 ldah t2, 0x3c90(zero) // small_x zapnot v0, 0xf, t0 and t0, t1, t1 lda v0, __exp_t_table ldah t3, 0x3f6(zero) // big_x - small_x subq t1, t2, t2 lda t3, 0x232b(t3) // big_x - small_x ldt f1, 0x10(v0) // two_pow_l_over_ln2 cmpult t2, t3, t2 beq t2, 10f mov zero, t3 br zero, 30f // // check for possible problems // 10: ldah t4, 0x4086(zero) // big_x ldah t2, 0x7ff0(zero) // exp mask lda t4, 0x232b(t4) cmpult t1, t2, t3 cmpult t1, t4, t1 beq t3, 80f beq t1, 20f ldt f0, One br zero, done // // check for under/over flow // 20: lda t1, 1(zero) ldah t4, 0x4086(zero) sll t1, 31, t1 mov t0, t3 lda t4, 0x2e42(t4) // overflow_x cmpule t3, t4, t4 mov 1, t3 bne t4, 30f cmpult t0, t1, t1 bne t1, 70f ldq t4, Under // underflow_x cmpult t0, t4, t0 beq t0, 60f // // rejoin normal path // 30: mult f16, f1, f1 ldt f12, 0x48(v0) // load poly coef ldt f0, Two52 ldt f13, 0x38(v0) // load poly coef ldt f15, 0x40(v0) // load poly coef cpys f16, f0, f10 ldt f0, 0(v0) addt f1, f10, f1 subt f1, f10, f1 // flt_int_N ldt f10, 8(v0) mult f1, f0, f0 mult f1, f10, f10 subt f16, f0, f0 addt f0, f10, f11 mult f11, f11, f14 mult f12, f11, f12 mult f13, f11, f11 ldt f13, 0x30(v0) // load poly coef mult f14, f14, f17 addt f15, f12, f12 addt f13, f11, f11 cvttqc f1, f15 mult f17, f12, f12 mult f14, f11, f11 stt f15, Temp(sp) ldq t1, Temp(sp) and t1, 0x3f, t0 sll t0, 4, t0 addt f11, f12, f11 addl v0, t0, v0 sra t1, 6, t1 ldt f17, 0x50(v0) // powers of two ldt f14, 0x58(v0) lda t4, 0x3ff(t1) addt f10, f11, f10 addt f17, f14, f1 sll t4, 20, t4 stl t4, Temp + HighPart(sp) stl zero, Temp(sp) ldt f13, Temp(sp) addt f0, f10, f0 mult f1, f0, f0 addt f14, f0, f0 addt f17, f0, f17 bne t3, 40f mult f17, f13, f0 br zero, done // // do check // 40: stt f17, Temp(sp) ldl v0, Temp + HighPart(sp) subq t1, 1, t1 sll t1, 20, t1 zapnot v0, 0xf, v0 ldah t4, 0x7fe0(zero) addq v0, t1, t0 mov t0, t3 cmpult t3, t4, t4 beq t4, 50f ldah t5, 0x10(zero) addq t3, t5, t5 stl t5, Temp + HighPart(sp) ldt f0, Temp(sp) br zero, done // // must check for abnormals // 50: bgt t1, 70f ldah t5, 0x350(zero) addq t3, t5, t5 blt t5, 60f subq v0, t3, v0 stl zero, Temp(sp) stl v0, Temp + HighPart(sp) ldt f15, Temp(sp) addt f17, f15, f17 stt f17, Temp(sp) cmpteq f17, f15, f15 fbne f15, 60f ldl t4, Temp + HighPart(sp) ldah t3, 0x7ff0(zero) zapnot t4, 0xf, t4 subq t4, v0, v0 stl v0, Temp + HighPart(sp) and v0, t3, v0 ldt f16, Temp(sp) bne v0, retarg // // underflow // 60: lda t0, expName ldah t5, 0x800(zero) stl t0, ExRec + ErName(sp) stt f16, ExRec + ErArg0(sp) lda t5, 0x1f(t5) stl t5, ExRec + ErErr(sp) lda v0, ExRec(sp) bsr ra, __dpml_exception ldt f0, 0(v0) br zero, done // // overflow // 70: lda t0, expName ldah t3, 0x800(zero) stl t0, ExRec + ErName(sp) stt f16, ExRec + ErArg0(sp) lda t3, 0x1e(t3) stl t3, ExRec + ErErr(sp) lda v0, ExRec(sp) bsr ra, __dpml_exception ldt f0, 0(v0) br zero, done // // nan or inf check // 80: stt f16, Temp(sp) ldl t1, Temp + HighPart(sp) ldl ra, Temp(sp) zapnot t1, 0xf, t3 zapnot ra, 0xf, ra and t3, t2, t5 cmpeq t5, t2, t2 beq t2, 90f zapnot t1, 0xf, t3 ldq v0, Mask52 and t3, v0, v0 bis v0, ra, v0 cmpult zero, v0, v0 and t2, v0, t2 bne t2, retarg // // call exception dispatcher for inf // 90: lda t4, 1(zero) sll t4, 31, t4 mov 0x21, t5 and t0, t4, t0 cmoveq t0, 0x20, t5 ldah t1, 0x800(zero) bis t5, t1, t1 stl t1, ExRec + ErErr(sp) lda ra, expName stl ra, ExRec + ErName(sp) lda v0, ExRec(sp) stt f16, ExRec + ErArg0(sp) bsr ra, __dpml_exception ldt f16, 0(v0) // // just return x // retarg: cpys f16, f16, f0 // // Return with result in f0. // done: lda sp, FrameLength(sp) // deallocate stack frame ret zero, (t6) // return through saved ra in t6 .end exp SBTTL("Exponential Helper") // // exp special entry point (for sinh, cosh etc) // NESTED_ENTRY(__dpml_exp_special_entry_point, 0x10, ra) lda sp, -0x10(sp) PROLOGUE_END lda t0, __exp_t_table ldt f0, 0x10(t0) ldt f1, Two52 ldt f12, 0x38(t0) mult f16, f0, f0 ldt f11, 0x48(t0) cpys f16, f1, f10 ldt f1, 0(t0) ldt f14, 0x40(t0) addt f0, f10, f0 subt f0, f10, f0 ldt f10, 8(t0) mult f0, f1, f1 mult f0, f10, f10 subt f16, f1, f1 addt f1, f10, f16 mult f16, f16, f13 mult f11, f16, f11 mult f12, f16, f12 ldt f16, 0x30(t0) mult f13, f13, f15 addt f14, f11, f11 addt f16, f12, f12 cvttqc f0, f14 mult f15, f11, f11 stt f14, Temp(sp) mult f13, f12, f12 ldq v0, Temp(sp) and v0, 0x3f, t1 sll t1, 4, t1 addt f12, f11, f11 addl t0, t1, t0 ldt f0, 0x50(t0) ldt f15, 0x58(t0) addt f10, f11, f10 addt f0, f15, f13 addt f1, f10, f1 mult f13, f1, f1 addt f15, f1, f1 stt f1, 0(a2) stq v0, 0(a1) lda sp, 0x10(sp) ret zero, (ra) .end __dpml_exp_special_entry_point .align 3 .rdata Under: .long 0xc0874386 // underflow_x .long 0x0 Two52: .quad 0x4330000000000000 // 2^52 (4503599627370496.0) Mask52: .quad 0x000fffffffffffff // 52-bit mantissa mask One: .double 1.0 // // Function name for _dpml_exception. // expName: .ascii "exp\0" // // exp table data // .align 3 __exp_t_table: // // misc constants // .quad 0x3f862e42fefa0000 .quad 0xbd1cf79abc9e3b3a .quad 0x40571547652b82fe .quad 0x0000000042b8aa3b .quad 0x3fe00001ebfbdb81 .quad 0x3fc55555555551c2 // // poly coefs // .quad 0x3fdfffffffffe5bc .quad 0x3fc5555555556bd8 .quad 0x3fa555570aa6fd1d .quad 0x3f81111111110f6f // // 2^(j/2^L) for j = 0 to 2^L - 1 in hi and lo pieces // .quad 0x3ff0000000000000 .quad 0x0000000000000000 .quad 0x3ff02c9a3e778040 .quad 0x3d007737be56527b .quad 0x3ff059b0d3158540 .quad 0x3d0a1d73e2a475b4 .quad 0x3ff0874518759bc0 .quad 0x3ce01186be4bb284 .quad 0x3ff0b5586cf98900 .quad 0x3ceec5317256e308 .quad 0x3ff0e3ec32d3d180 .quad 0x3d010103a1727c57 .quad 0x3ff11301d0125b40 .quad 0x3cf0a4ebbf1aed93 .quad 0x3ff1429aaea92dc0 .quad 0x3cffb34101943b25 .quad 0x3ff172b83c7d5140 .quad 0x3d0d6e6fbe462875 .quad 0x3ff1a35beb6fcb40 .quad 0x3d0a9e5b4c7b4968 .quad 0x3ff1d4873168b980 .quad 0x3d053c02dc0144c8 .quad 0x3ff2063b88628cc0 .quad 0x3cf63b8eeb029509 .quad 0x3ff2387a6e756200 .quad 0x3d0c3360fd6d8e0a .quad 0x3ff26b4565e27cc0 .quad 0x3cfd257a673281d3 .quad 0x3ff29e9df51fdec0 .quad 0x3d009612e8afad12 .quad 0x3ff2d285a6e40300 .quad 0x3ce680123aa6da0e .quad 0x3ff306fe0a31b700 .quad 0x3cf52de8d5a46305 .quad 0x3ff33c08b26416c0 .quad 0x3d0fa64e43086cb3 .quad 0x3ff371a7373aa9c0 .quad 0x3ce54e28aa05e8a8 .quad 0x3ff3a7db34e59fc0 .quad 0x3d0b750de494cf05 .quad 0x3ff3dea64c123400 .quad 0x3d011ada0911f09e .quad 0x3ff4160a21f72e00 .quad 0x3d04fc2192dc79ed .quad 0x3ff44e0860618900 .quad 0x3d068189b7a04ef8 .quad 0x3ff486a2b5c13cc0 .quad 0x3cf013c1a3b69062 .quad 0x3ff4bfdad5362a00 .quad 0x3d038ea1cbd7f621 .quad 0x3ff4f9b2769d2c80 .quad 0x3d035699ec5b4d50 .quad 0x3ff5342b569d4f80 .quad 0x3cbdf0a83c49d86a .quad 0x3ff56f4736b527c0 .quad 0x3cfa66ecb004764e .quad 0x3ff5ab07dd485400 .quad 0x3d04ac64980a8c8f .quad 0x3ff5e76f15ad2140 .quad 0x3ce0dd37c9840732 .quad 0x3ff6247eb03a5580 .quad 0x3cd2c7c3e81bf4b6 .quad 0x3ff6623882552200 .quad 0x3d024893ecf14dc7 .quad 0x3ff6a09e667f3bc0 .quad 0x3ce921165f626cdd .quad 0x3ff6dfb23c651a00 .quad 0x3d0779107165f0dd .quad 0x3ff71f75e8ec5f40 .quad 0x3d09ee91b8797785 .quad 0x3ff75feb564267c0 .quad 0x3ce17edd35467491 .quad 0x3ff7a11473eb0180 .quad 0x3cdb5f54408fdb36 .quad 0x3ff7e2f336cf4e40 .quad 0x3d01082e815d0abc .quad 0x3ff82589994cce00 .quad 0x3cf28acf88afab34 .quad 0x3ff868d99b4492c0 .quad 0x3d0640720ec85612 .quad 0x3ff8ace5422aa0c0 .quad 0x3cfb5ba7c55a192c .quad 0x3ff8f1ae99157700 .quad 0x3d0b15cc13a2e397 .quad 0x3ff93737b0cdc5c0 .quad 0x3d027a280e1f92a0 .quad 0x3ff97d829fde4e40 .quad 0x3cef173d241f23d1 .quad 0x3ff9c49182a3f080 .quad 0x3cf01c7c46b071f2 .quad 0x3ffa0c667b5de540 .quad 0x3d02594d6d45c655 .quad 0x3ffa5503b23e2540 .quad 0x3cfc8b424491caf8 .quad 0x3ffa9e6b5579fd80 .quad 0x3d0fa1f5921deffa .quad 0x3ffae89f995ad380 .quad 0x3d06af439a68bb99 .quad 0x3ffb33a2b84f15c0 .quad 0x3d0d7b5fe873deca .quad 0x3ffb7f76f2fb5e40 .quad 0x3cdbaa9ec206ad4f .quad 0x3ffbcc1e904bc1c0 .quad 0x3cf2247ba0f45b3d .quad 0x3ffc199bdd855280 .quad 0x3cfc2220cb12a091 .quad 0x3ffc67f12e57d140 .quad 0x3ce694426ffa41e5 .quad 0x3ffcb720dcef9040 .quad 0x3d048a81e5e8f4a4 .quad 0x3ffd072d4a078940 .quad 0x3d0dc68791790d0a .quad 0x3ffd5818dcfba480 .quad 0x3cdc976816bad9b8 .quad 0x3ffda9e603db3280 .quad 0x3cd5c2300696db53 .quad 0x3ffdfc97337b9b40 .quad 0x3cfeb968cac39ed2 .quad 0x3ffe502ee78b3fc0 .quad 0x3d0b139e8980a9cc .quad 0x3ffea4afa2a490c0 .quad 0x3cf9858f73a18f5d .quad 0x3ffefa1bee615a00 .quad 0x3d03bb8fe90d496d .quad 0x3fff50765b6e4540 .quad 0x3c99d3e12dd8a18a .quad 0x3fffa7c1819e90c0 .quad 0x3cf82e90a7e74b26 // // End of table. //