mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 16:34:07 +00:00
158 lines
6.4 KiB
ArmAsm
158 lines
6.4 KiB
ArmAsm
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
|