mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 08:24:18 +00:00
296 lines
16 KiB
ArmAsm
296 lines
16 KiB
ArmAsm
ttl ieee format front-end routines (ieffront)
|
||
ieffront idnt 1,1 ieee format equivalent front-end routines
|
||
******************************************
|
||
* (c) copyright 1981 by motorola inc. *
|
||
******************************************
|
||
|
||
*******************************************************
|
||
* idfsop (internal subroutine) *
|
||
* ieee format equivalent process single operand *
|
||
* *
|
||
* input: d7 - ieee format number argument2 *
|
||
* sp -> +0 return address to caller *
|
||
* +4 original caller's return address *
|
||
* *
|
||
* output: d6 converted to fast floating point *
|
||
* format with user's original registers *
|
||
* d3-d7 stacked or a direct return bypassing*
|
||
* the first-line routine if either *
|
||
* parameter was a nan *
|
||
* *
|
||
* *
|
||
* return is via vectored branch with offset added *
|
||
* to the address on the stack. this allows easy *
|
||
* type descrimination by the caller for selected *
|
||
* data types: *
|
||
* *
|
||
* return +0 if the argument is normalized *
|
||
* (including zero and denormalized) *
|
||
* +2 if argument is an infinity *
|
||
* *
|
||
* the stack appears: s+0 original d3-d7 upon entry*
|
||
* s+20 original caller's return *
|
||
* *
|
||
* condition codes: *
|
||
* *
|
||
* (only if bypassed return done) *
|
||
* *
|
||
* n - undefined *
|
||
* z - cleared *
|
||
* v - set (result is a nan) *
|
||
* c - undefined *
|
||
* x - undefined *
|
||
* *
|
||
* (only if return to immediate caller) *
|
||
* *
|
||
* n - set if value is negative *
|
||
* z - set if value is a zero *
|
||
* v - undeinfed *
|
||
* c - undefined *
|
||
* x - undefined *
|
||
* *
|
||
* this routine is a front end for the ieee format *
|
||
* capatible routines (ief routines). it may *
|
||
* bypass the caller to directly return to the user *
|
||
* code if the argument is a nan (not-a-number) *
|
||
* since the result must be a nan (the same). *
|
||
* the call to this routine must be the *
|
||
* first instruction of the level-1 ief routine, *
|
||
* since it may return directly to the original *
|
||
* caller. also registers must be unaltered before *
|
||
* the call. *
|
||
* *
|
||
* logic: the following decision tree shows the *
|
||
* processing for this routine and what *
|
||
* values are returned for the argument *
|
||
* *
|
||
* if arg is nan then *
|
||
* set the "v" bit in the ccr and bypass the *
|
||
* caller returning with arg (d7) unchanged *
|
||
* *
|
||
* if arg is an infinity then adjust return address *
|
||
* and return with ccr set for plus or minus *
|
||
* at offset +2 *
|
||
* *
|
||
* if arg is denormalized then set it to zero *
|
||
* else it is normalized - convert to ffp format*
|
||
* *
|
||
* return to caller at +0 offset *
|
||
* *
|
||
* notes: *
|
||
* 1) during the conversion of normalized ieee format *
|
||
* numbers to ffp format, the exponent may be too *
|
||
* large for ffp magnitudes. when this is true *
|
||
* then the value is converted to an infinity with *
|
||
* the proper sign. if the exponent is too small *
|
||
* than a zero is returned. see the mc68344 user's*
|
||
* guide for complete details of the range handling*
|
||
* of the fast floating point format conversion. *
|
||
* 2) all zeroes are treated as positive values. *
|
||
* 3) denormalized values are treated as zeroes. *
|
||
* *
|
||
*******************************************************
|
||
|
||
section 9
|
||
|
||
xdef iefsop single operand convert
|
||
|
||
expmsk equ $7f800000 ieee format exponent mask
|
||
vbit equ $0002 condition code "v" bit mask
|
||
cbit equ $0001 condition code "c" bit mask
|
||
|
||
* call internal subroutine to parse argument (d7)
|
||
iefsop lea -16(sp),sp adjust stack for new return address position
|
||
move.l 16(sp),-(sp) move return address to new location
|
||
movem.l d3-d7,4(sp) save original caller's registers
|
||
bsr.s iefprse convert argument two
|
||
bcc.s iefargs branch not infinity
|
||
move.w sr,d5 save ccr [vlh] was sr
|
||
add.l #2,(sp) adjust return address
|
||
move.w d5,ccr restore ccr
|
||
iefargs rts return to caller at proper offset
|
||
page
|
||
*******************************************************
|
||
* idfdop (internal subroutine) *
|
||
* ieee format equivalent process double operand *
|
||
* *
|
||
* input: d6 - ieee format number argument1 *
|
||
* d7 - ieee format number argument2 *
|
||
* sp -> +0 return address to caller *
|
||
* +4 original caller's return address *
|
||
* *
|
||
* output: d6/d7 converted to fast floating point *
|
||
* format with user's original registers *
|
||
* d3-d7 stacked or a direct return bypassing*
|
||
* the first-line routine if either *
|
||
* parameter was a nan *
|
||
* *
|
||
* *
|
||
* return is via vectored branch with offset added *
|
||
* to the address on the stack. this allows easy *
|
||
* type descrimination by the caller for selected *
|
||
* data types: *
|
||
* *
|
||
* return +0 if both arguments normalized *
|
||
* (including zero and denormalized) *
|
||
* +2 if arg2 is an infinity *
|
||
* +4 if arg1 is an infinity *
|
||
* +6 if both arguments are infinities *
|
||
* *
|
||
* the stack appears: s+0 original d3-d7 upon entry*
|
||
* s+20 original caller's return *
|
||
* *
|
||
* condition codes: *
|
||
* *
|
||
* (only if bypassed return done) *
|
||
* *
|
||
* n - undefined *
|
||
* z - cleared *
|
||
* v - set (result is a nan) *
|
||
* c - undefined *
|
||
* x - undefined *
|
||
* *
|
||
* (only if return directly to immediate caller) *
|
||
* *
|
||
* n - set if arg1 is negative *
|
||
* z - set if arg1 is zero *
|
||
* v - undefined *
|
||
* c - set if arg1 is an infinity *
|
||
* x - undefined *
|
||
* *
|
||
* this routine is a front end for the ieee format *
|
||
* capatible routines (ief routines). it may *
|
||
* bypass the caller to directly return to the user *
|
||
* code if an argument is a nan (not-a-number) *
|
||
* since the result must be a nan. it must be the *
|
||
* first instruction of the level-1 ief routine, *
|
||
* since it may return directly to the original *
|
||
* caller. also registers must be unaltered before *
|
||
* the call. *
|
||
* *
|
||
* logic: the following decision tree shows the *
|
||
* processing for this routine and what *
|
||
* values are returned for arg1 and arg2 *
|
||
* *
|
||
* if arg2 is nan then *
|
||
* set the "v" bit in the ccr and bypass the *
|
||
* caller returning with arg2 (d7) unchanged *
|
||
* *
|
||
* if arg1 is nan then *
|
||
* set the "v" bit in the ccr and bypass the *
|
||
* caller returning with arg1 copied to arg2 *
|
||
* *
|
||
* if arg2 is an infinity then adjust return address *
|
||
* *
|
||
* if arg1 is an infinity then adjust return address *
|
||
* *
|
||
* if arg2 is denormalized then set it to zero *
|
||
* else it is normalized - convert to ffp format*
|
||
* *
|
||
* if arg1 is denormalized then set it to zero *
|
||
* else it is normalized - convert to ffp format*
|
||
* *
|
||
* return to caller at proper offset *
|
||
* *
|
||
* notes: *
|
||
* 1) during the conversion of normalized ieee format *
|
||
* numbers to ffp format, the exponent may be too *
|
||
* large for ffp magnitudes. when this is true *
|
||
* then the value is converted to an infinity with *
|
||
* the proper sign. if the exponent is too small *
|
||
* than a zero is returned. see the mc68344 user's*
|
||
* guide for complete details of the range *
|
||
* treatment by the fast floating point conversion.*
|
||
* 2) all zeroes are treated as positive values. *
|
||
* 3) denormalized values are treated as zeroes. *
|
||
* *
|
||
*******************************************************
|
||
|
||
section 9
|
||
|
||
xdef iefdop dual operand convert
|
||
|
||
* call internal subroutine to parse argument 2 (d7)
|
||
iefdop lea -16(sp),sp reset stack for register storage
|
||
move.l 16(sp),-(sp) move return address to new bottom of stack
|
||
movem.l d3-d7,4(sp) save original registers above return address
|
||
bsr.s iefprse convert argument two
|
||
bcc.s iefarg2 branch not infinity
|
||
add.l #2,(sp) adjust return address
|
||
iefarg2 exg.l d6,d7 swap arguments to convert arg1 (nan returns arg1)
|
||
bsr.s iefprse convert second argument
|
||
bcc.s iefnoti branch not infinity
|
||
move.w sr,d5 save ccr [vlh] was sr
|
||
add.l #4,(sp) adjust return address
|
||
move.w d5,ccr restore ccr
|
||
iefnoti exg.l d6,d7 swap arguments back into place
|
||
rts return to caller
|
||
page
|
||
*
|
||
* internal convert subroutine
|
||
* convert the argument in d7 to fast floating point format and return
|
||
* ccr set for test against sign and zero
|
||
*
|
||
* output:
|
||
* if nan - direct return bypassing caller with nan in d7 and "v" set
|
||
* else return with converted value and "c" bit if is an infnity
|
||
*
|
||
iefprse move.l d7,d5 save original argument
|
||
swap.w d7 swap word halves
|
||
ror.l #7,d7 exponent to low byte
|
||
eor.b #$80,d7 convert from excess 127 to two's-complement
|
||
add.b d7,d7 from 8 to 7 bit exponent
|
||
bvs.s iefovf branch will not fit
|
||
add.b #2<<1+1,d7 adjust excess 127 to 64 and set mantissa high bit
|
||
bvs.s iefexh branch exponent too large (overflow)
|
||
eor.b #$80,d7 back to excess 64
|
||
ror.l #1,d7 to fast float representation
|
||
tst.b d7 clear carry
|
||
rts return to caller
|
||
|
||
* overflow detected - caused by one of the following:
|
||
* - false exponent overflow due to difference in excess notations
|
||
* - exponent too high or low to fit in 7 bits (exponent over/underflow)
|
||
* - an exponent of $ff representing an infinity
|
||
* - an exponent of $00 representing a zero, nan, or denormalized value
|
||
iefovf bcc.s iefovlw branch if overflow (exponent $ff or too large)
|
||
* check for false overflow
|
||
cmp.b #$7c,d7 ? will corrected value be ok
|
||
beq.s ieffov yes, branch if false overflow
|
||
cmp.b #$7e,d7 ? will corrected value be in range
|
||
bne.s iefnotf no, branch not false overflow
|
||
ieffov add.b #$80+2<<1+1,d7 back to excess 64 and set mantissa high bit
|
||
ror.l #1,d7 to fast floating point representation
|
||
tst.b d7 insure not illegal zero sign+exponent byte
|
||
bne.s iefcrt no, is ok so return "c" cleared
|
||
* exponent low - is zero, denormalized value, or too small an exponent
|
||
iefnotf move.l #0,d7 return zero for all of these cases ("c" cleared)
|
||
iefcrt rts return to caller
|
||
|
||
* exponent high - check for exponent too high, infinity, or nan
|
||
iefovlw cmp.b #$fe,d7 ? was original exponent $ff
|
||
bne.s iefexh no, branch exponent too large
|
||
lsr.l #8,d7 shift out exponent
|
||
lsr.l #1,d7 shift sign out into "x" bit
|
||
beq.s iefexhi branch if true infinity
|
||
|
||
* arg2 is a nan - bypass caller and return as the result with "v" bit set
|
||
move.l d5,d7 return original argument
|
||
add.l #8,sp skip internal and caller return addresses
|
||
movem.l (sp)+,d3-d6 return registers intact
|
||
add.l #4,sp skip original d7
|
||
or.b #vbit,ccr set v bit on [vlh]
|
||
rts return to original caller
|
||
|
||
* arg2 is infinity or exponent too large so force to infinity (sign is bit 8)
|
||
iefexh lsl.w #8,d7 set "x" ccr bit same as sign
|
||
iefexhi move.l #expmsk<<1,d7 set exponent all ones for infinity and over 1
|
||
roxr.l #1,d7 shift sign and and finished result
|
||
or.b #cbit,ccr set "c" bit on for infinity notice [vlh]
|
||
rts return to conversion routine
|
||
|
||
end
|
||
|
||
|