ttl fast floating point hyperbolics (ffpsinh) *************************************** * (c) copyright 1981 by motorola inc. * *************************************** ************************************************* * ffpsinh/ffpcosh/ffptanh * * fast floating point hyperbolics * * * * input: d7 - floating point argument * * * * output: d7 - hyperbolic result * * * * all other registers are transparent * * * * code size: 36 bytes stack work: 50 bytes * * * * calls: ffpexp, ffpdiv, ffpadd and ffpsub * * * * condition codes: * * z - set if the result is zero * * n - set if the result is negative * * v - set if overflow occurred * * c - undefined * * x - undefined * * * * notes: * * 1) an overflow will produce the maximum * * signed value with the "v" bit set. * * 2) spot checks show at least seven digit * * precision. * * * * time: (8mhz no wait states assumed) * * * * sinh 623 microseconds * * cosh 601 microseconds * * tanh 623 microseconds * * * ************************************************* page ffpsinh idnt 1,2 ffp sinh cosh tanh opt pcs section 9 xdef ffpsinh,ffpcosh,ffptanh entry points xref ffpexp,ffpdiv,ffpadd,ffpsub functions called xref ffpcpyrt copyright stub fpone equ $80000041 floating one ********************************** * ffpcosh * * this function is defined as * * x -x * * e + e * * -------- * * 2 * * we evaluate exactly as defined * ********************************** ffpcosh move.l d6,-(sp) save our one work register and.b #$7f,d7 force positive (results same but exp faster) jsr ffpexp evaluate e to the x bvs.s fhcrtn return if overflow (result is highest number) move.l d7,-(sp) save result move.l d7,d6 setup for divide into one move.l #fpone,d7 load floating point one jsr ffpdiv compute e to -x as the inverse move.l (sp)+,d6 prepare to add together jsr ffpadd create the numerator beq.s fhcrtn return if zero result sub.b #1,d7 divide by two bvc.s fhcrtn return if no underflow move.l #0,d7 return zero if underflow fhcrtn movem.l (sp)+,d6 restore our work register rts return to caller with answer page ********************************** * ffpsinh * * this function is defined as * * x -x * * e - e * * -------- * * 2 * * however, we evaluate it via * * the cosh formula since its * * addition in the numerator * * is safer than our subtraction * * * * thus the function becomes: * * x * * sinh = e - cosh * * * ********************************** ffpsinh move.l d6,-(sp) save our one work register jsr ffpexp evaluate e to the x bvs.s fhsrtn return if overlow for maximum value move.l d7,-(sp) save result move.l d7,d6 setup for divide into one move.l #fpone,d7 load floating point one jsr ffpdiv compute e to -x as the inverse move.l (sp),d6 prepare to add together jsr ffpadd create the numerator beq.s fhszro branch if zero result sub.b #1,d7 divide by two bvc.s fhszro branch if no underflow move.l #0,d7 zero if underflow fhszro move.l d7,d6 move for final subtract move.l (sp)+,d7 reload e to x again and free jsr ffpsub result is e to x minus cosh fhsrtn movem.l (sp)+,d6 restore our work register rts return to caller with answer page ********************************** * ffptanh * * this function is defined as * * sinh/cosh which reduces to: * * 2x * * e - 1 * * ------ * * 2x * * e + 1 * * * * which we evaluate. * ********************************** ffptanh move.l d6,-(sp) save our one work register tst.b d7 ? zero beq.s ffptrtn return true zero if so add.b #1,d7 x times two bvs.s ffptovf branch if overflow/underflow jsr ffpexp evaluate e to the 2x bvs.s ffptovf2 branch if too large move.l d7,-(sp) save result move.l #fpone,d6 load floating point one jsr ffpadd add 1 to e**2x move.l d7,-(sp) save denominator move.l 4(sp),d7 now prepare to subtract jsr ffpsub create numerator move.l (sp)+,d6 restore denominator jsr ffpdiv create result add.l #4,sp free e**2x off of stack ffptrtn move.l (sp)+,d6 restore our work register rts return to caller with answer ffptovf move.l #$80000082,d7 float one with exponent over to left roxr.b #1,d7 shift in correct sign bra.s ffptrtn and return ffptovf2 move.l #fpone,d7 return +1 as result bra.s ffptrtn end