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