Files
Digital-Research-Source-Code/CPM OPERATING SYSTEMS/CPM 68K/1.2 SOURCE/8/IEFFRONT.S
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

296 lines
16 KiB
ArmAsm
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
d
d
d