Files
Digital-Research-Source-Code/CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/libe/ieffront.s
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

293 lines
15 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