mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 16:34:07 +00:00
188 lines
9.4 KiB
ArmAsm
188 lines
9.4 KiB
ArmAsm
ttl ieee format equivalent back-end routines (iefback)
|
|
iefback idnt 1,1 ieee format equivalent back-end routines
|
|
******************************************
|
|
* (c) copyright 1981 by motorola inc. *
|
|
******************************************
|
|
|
|
section 9
|
|
|
|
****************************************************************
|
|
* iefrtnan (internal routine) *
|
|
* ieee format equivalent fast floating point return nan *
|
|
* *
|
|
* input: sp -> +0 original callers d3-d7 registers *
|
|
* +20 original callers return address *
|
|
* *
|
|
* output: d7 - a newly created nan (not-a-number) *
|
|
* ccr - the "v" bit is forced on *
|
|
* *
|
|
* and direct return to the original caller *
|
|
* *
|
|
* purpose: called whenever the result of an operation *
|
|
* is illegal or undefined and a nan result must *
|
|
* be generated as the final result. *
|
|
* *
|
|
* the ieee format defined nan is determined by an exponent *
|
|
* of all one's and a non-zero significand. the sign bit *
|
|
* is a don't care. the ieee standard leaves up to each *
|
|
* implementation what is placed in the significand. here *
|
|
* we will generate the low order 23 bits of the original *
|
|
* caller's return address. however, this may not be *
|
|
* sufficient - if all 23 bits happen to be zero or the *
|
|
* address is larger than 23 bits this would lead to an *
|
|
* incorrect result. therfore, if this happens only the low *
|
|
* order significand bit is set on with the rest zeroes. *
|
|
* this represents an odd address (illegal with current m68000*
|
|
* instruction alignment restrictions) and any interested *
|
|
* party can tell if such a substitution has taken place. *
|
|
* also, if this was illegally assumed to be an address and *
|
|
* used, an address exception trap would ensue thus not *
|
|
* allowing its use as a valid address. *
|
|
* *
|
|
****************************************************************
|
|
|
|
signmsk equ $80000000 ieee format sign isolation mask
|
|
expmsk equ $7f800000 ieee format exponent mask
|
|
vbit equ $0002 condition code "v" bit mask
|
|
zbit equ $0004 condition code "z" bit mask
|
|
|
|
xdef iefrtnan return nan result routine
|
|
|
|
iefrtnan movem.l (sp)+,d3-d7 restore callers registers
|
|
move.l (sp),d7 load up return address
|
|
and.l #signmsk+expmsk,d7 verify not larger than 23 bits
|
|
bne.s iefnone it is, cannot use it - return a one
|
|
move.l (sp),d7 load up return address
|
|
and.l #$007fffff,d7 isolate address bits required
|
|
bne.s iefnzro branch if not zero
|
|
iefnone move.l #1,d7 set only low bit on
|
|
iefnzro or.l #expmsk,d7 force exponent all ones
|
|
or.b #vbit,ccr return with "v" bit set [vlh]
|
|
rts return to original caller
|
|
page
|
|
**********************************************************
|
|
* ieftieee (internal subroutine) *
|
|
* ieee format compatible convert ffp to ieee format *
|
|
* *
|
|
* input: d7 - result of fast floating point operation *
|
|
* ccr - set for above result *
|
|
* sp -> +0 original callers saved d3-d7 *
|
|
* +20 original callers return address *
|
|
* *
|
|
* output: d7 - ieee format equivalent of the result *
|
|
* *
|
|
* condition code: *
|
|
* *
|
|
* n - set if the result is negative *
|
|
* z - set if the result is zero *
|
|
* v - cleared (not nan) *
|
|
* c - cleared *
|
|
* x - undefined *
|
|
* *
|
|
* all fast floating point numbers have an exact *
|
|
* ieee format representation. since the fast *
|
|
* floating point routines always set the "v" bit *
|
|
* for overflows and returns the proper sign, we *
|
|
* can easily change the result to an ieee infinity *
|
|
* and unflag the "v" bit. *
|
|
* *
|
|
**********************************************************
|
|
|
|
xdef ieftieee return ieee result to original caller
|
|
|
|
ieftieee bvs.s iefvset branch if overflow ffp result
|
|
add.l d7,d7 delete mantissa high bit
|
|
beq.s ieftrtn branch zero as finished
|
|
eor.b #$80,d7 to twos complement exponent
|
|
asr.b #1,d7 form 8-bit exponent
|
|
sub.b #$82,d7 adjust 64 to 127 and excessize
|
|
swap.w d7 swap for high byte placement
|
|
rol.l #7,d7 set sign+exp in high byte
|
|
ieftrtn tst.l d7 test "z" and "n", clear "v" and "c" in ccr
|
|
movem.l (sp)+,d3-d6 restore d3 thru d6 callers registers
|
|
add.l #4,sp skip original d7
|
|
rts return to original caller with result
|
|
|
|
* overflow - set to proper ieee format infinity
|
|
iefvset add.b d7,d7 save sign bit in "x"
|
|
move.l #expmsk<<1,d7 set exponent of ones shifted left
|
|
roxr.l #1,d7 insert proper sign
|
|
jmp ieftrtn and return to original caller
|
|
page
|
|
*******************************************************************
|
|
* general purpose return routines *
|
|
* *
|
|
* the following routines return a specific final result *
|
|
* to the original caller with the proper condition codes *
|
|
* set as follows: *
|
|
* *
|
|
* n - the result is negative *
|
|
* z - the result is a zero *
|
|
* v - cleared (not a nan) *
|
|
* c - undefined *
|
|
* x - undefined *
|
|
* *
|
|
* the routines are as follows: *
|
|
* *
|
|
* iefrtd7 - return the current contents of d7 *
|
|
* iefrtod7 - return the original contents of d7 *
|
|
* iefrtsz - return a signed zero (sign is bit 31 of d7) *
|
|
* iefrtie - return infinity with sign exclusive or of *
|
|
* original argument signs *
|
|
* iefrtsze - return signed zero with sign exclusiv or *
|
|
* of original argument signs *
|
|
* *
|
|
*******************************************************************
|
|
|
|
xdef iefrtd7,iefrtsz,iefrtod7,iefrtie,iefrtsze
|
|
|
|
**********************
|
|
* return original d7 *
|
|
* (cant be neg zero) *
|
|
**********************
|
|
iefrtod7 move.l 16(sp),d7 load original d7 into d7
|
|
|
|
*********************
|
|
* return current d7 *
|
|
* (cant be neg zero)*
|
|
*********************
|
|
iefrtd7 movem.l (sp)+,d3-d6 load all but d7 registers back up
|
|
add.l #4,sp skip original d7 on stack
|
|
add.l d7,d7 check for signed zero
|
|
beq.s iefwasz branch if was a zero
|
|
roxr.l #1,d7 value back into position set ccr ("v" clear)
|
|
rts return to caller with ccr and result
|
|
|
|
**************************************
|
|
* return signed zero with sign being *
|
|
* eor of the original operands *
|
|
**************************************
|
|
iefrtsze movem.l 12(sp),d6-d7 load original arguments
|
|
eor.l d6,d7 produce proper sign
|
|
|
|
**********************
|
|
* return signed zero *
|
|
* d7 bit31 has sign *
|
|
**********************
|
|
iefrtsz movem.l (sp)+,d3-d6 load all but d7 back up
|
|
add.l #4,sp skip original d7 on stack
|
|
add.l d7,d7 set sign bit into carry
|
|
move.l #0,d7 zero d7
|
|
iefwasz roxr.l #1,d7 set sign bit back in ("v" cleared)
|
|
or.b #zbit,ccr force zero bit on in ccr [vlh]
|
|
rts
|
|
|
|
*********************************
|
|
* return infinity with eor sign *
|
|
* of original arguments *
|
|
*********************************
|
|
iefrtie movem.l (sp)+,d3-d7 restore original arguments
|
|
eor.l d6,d7 produce proper sign
|
|
add.l d7,d7 shift sign out
|
|
move.l #expmsk<<1,d7 setup infinity (exponent all ones)
|
|
roxr.l #1,d7 set sign back in ("v" cleared)
|
|
rts return with result and ccr set
|
|
|
|
end
|
|
|