diff options
Diffstat (limited to 'c/src/lib/libcpu/m68k/m68040/fpsp/get_op.S')
-rw-r--r-- | c/src/lib/libcpu/m68k/m68040/fpsp/get_op.S | 678 |
1 files changed, 0 insertions, 678 deletions
diff --git a/c/src/lib/libcpu/m68k/m68040/fpsp/get_op.S b/c/src/lib/libcpu/m68k/m68040/fpsp/get_op.S deleted file mode 100644 index a8a114b734..0000000000 --- a/c/src/lib/libcpu/m68k/m68040/fpsp/get_op.S +++ /dev/null @@ -1,678 +0,0 @@ -#include "fpsp-namespace.h" -// -// -// get_op.sa 3.6 5/19/92 -// -// get_op.sa 3.5 4/26/91 -// -// Description: This routine is called by the unsupported format/data -// type exception handler ('unsupp' - vector 55) and the unimplemented -// instruction exception handler ('unimp' - vector 11). 'get_op' -// determines the opclass (0, 2, or 3) and branches to the -// opclass handler routine. See 68881/2 User's Manual table 4-11 -// for a description of the opclasses. -// -// For UNSUPPORTED data/format (exception vector 55) and for -// UNIMPLEMENTED instructions (exception vector 11) the following -// applies: -// -// - For unnormalized numbers (opclass 0, 2, or 3) the -// number(s) is normalized and the operand type tag is updated. -// -// - For a packed number (opclass 2) the number is unpacked and the -// operand type tag is updated. -// -// - For denormalized numbers (opclass 0 or 2) the number(s) is not -// changed but passed to the next module. The next module for -// unimp is do_func, the next module for unsupp is res_func. -// -// For UNSUPPORTED data/format (exception vector 55) only the -// following applies: -// -// - If there is a move out with a packed number (opclass 3) the -// number is packed and written to user memory. For the other -// opclasses the number(s) are written back to the fsave stack -// and the instruction is then restored back into the '040. The -// '040 is then able to complete the instruction. -// -// For example: -// fadd.x fpm,fpn where the fpm contains an unnormalized number. -// The '040 takes an unsupported data trap and gets to this -// routine. The number is normalized, put back on the stack and -// then an frestore is done to restore the instruction back into -// the '040. The '040 then re-executes the fadd.x fpm,fpn with -// a normalized number in the source and the instruction is -// successful. -// -// Next consider if in the process of normalizing the un- -// normalized number it becomes a denormalized number. The -// routine which converts the unnorm to a norm (called mk_norm) -// detects this and tags the number as a denorm. The routine -// res_func sees the denorm tag and converts the denorm to a -// norm. The instruction is then restored back into the '040 -// which re_executes the instruction. -// -// -// Copyright (C) Motorola, Inc. 1990 -// All Rights Reserved -// -// THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA -// The copyright notice above does not evidence any -// actual or intended publication of such source code. - -GET_OP: //idnt 2,1 | Motorola 040 Floating Point Software Package - - |section 8 - -#include "fpsp.defs" - - .global PIRN,PIRZRM,PIRP - .global SMALRN,SMALRZRM,SMALRP - .global BIGRN,BIGRZRM,BIGRP - -PIRN: - .long 0x40000000,0xc90fdaa2,0x2168c235 //pi -PIRZRM: - .long 0x40000000,0xc90fdaa2,0x2168c234 //pi -PIRP: - .long 0x40000000,0xc90fdaa2,0x2168c235 //pi - -//round to nearest -SMALRN: - .long 0x3ffd0000,0x9a209a84,0xfbcff798 //log10(2) - .long 0x40000000,0xadf85458,0xa2bb4a9a //e - .long 0x3fff0000,0xb8aa3b29,0x5c17f0bc //log2(e) - .long 0x3ffd0000,0xde5bd8a9,0x37287195 //log10(e) - .long 0x00000000,0x00000000,0x00000000 //0.0 -// round to zero;round to negative infinity -SMALRZRM: - .long 0x3ffd0000,0x9a209a84,0xfbcff798 //log10(2) - .long 0x40000000,0xadf85458,0xa2bb4a9a //e - .long 0x3fff0000,0xb8aa3b29,0x5c17f0bb //log2(e) - .long 0x3ffd0000,0xde5bd8a9,0x37287195 //log10(e) - .long 0x00000000,0x00000000,0x00000000 //0.0 -// round to positive infinity -SMALRP: - .long 0x3ffd0000,0x9a209a84,0xfbcff799 //log10(2) - .long 0x40000000,0xadf85458,0xa2bb4a9b //e - .long 0x3fff0000,0xb8aa3b29,0x5c17f0bc //log2(e) - .long 0x3ffd0000,0xde5bd8a9,0x37287195 //log10(e) - .long 0x00000000,0x00000000,0x00000000 //0.0 - -//round to nearest -BIGRN: - .long 0x3ffe0000,0xb17217f7,0xd1cf79ac //ln(2) - .long 0x40000000,0x935d8ddd,0xaaa8ac17 //ln(10) - .long 0x3fff0000,0x80000000,0x00000000 //10 ^ 0 - - .global PTENRN -PTENRN: - .long 0x40020000,0xA0000000,0x00000000 //10 ^ 1 - .long 0x40050000,0xC8000000,0x00000000 //10 ^ 2 - .long 0x400C0000,0x9C400000,0x00000000 //10 ^ 4 - .long 0x40190000,0xBEBC2000,0x00000000 //10 ^ 8 - .long 0x40340000,0x8E1BC9BF,0x04000000 //10 ^ 16 - .long 0x40690000,0x9DC5ADA8,0x2B70B59E //10 ^ 32 - .long 0x40D30000,0xC2781F49,0xFFCFA6D5 //10 ^ 64 - .long 0x41A80000,0x93BA47C9,0x80E98CE0 //10 ^ 128 - .long 0x43510000,0xAA7EEBFB,0x9DF9DE8E //10 ^ 256 - .long 0x46A30000,0xE319A0AE,0xA60E91C7 //10 ^ 512 - .long 0x4D480000,0xC9767586,0x81750C17 //10 ^ 1024 - .long 0x5A920000,0x9E8B3B5D,0xC53D5DE5 //10 ^ 2048 - .long 0x75250000,0xC4605202,0x8A20979B //10 ^ 4096 -//round to minus infinity -BIGRZRM: - .long 0x3ffe0000,0xb17217f7,0xd1cf79ab //ln(2) - .long 0x40000000,0x935d8ddd,0xaaa8ac16 //ln(10) - .long 0x3fff0000,0x80000000,0x00000000 //10 ^ 0 - - .global PTENRM -PTENRM: - .long 0x40020000,0xA0000000,0x00000000 //10 ^ 1 - .long 0x40050000,0xC8000000,0x00000000 //10 ^ 2 - .long 0x400C0000,0x9C400000,0x00000000 //10 ^ 4 - .long 0x40190000,0xBEBC2000,0x00000000 //10 ^ 8 - .long 0x40340000,0x8E1BC9BF,0x04000000 //10 ^ 16 - .long 0x40690000,0x9DC5ADA8,0x2B70B59D //10 ^ 32 - .long 0x40D30000,0xC2781F49,0xFFCFA6D5 //10 ^ 64 - .long 0x41A80000,0x93BA47C9,0x80E98CDF //10 ^ 128 - .long 0x43510000,0xAA7EEBFB,0x9DF9DE8D //10 ^ 256 - .long 0x46A30000,0xE319A0AE,0xA60E91C6 //10 ^ 512 - .long 0x4D480000,0xC9767586,0x81750C17 //10 ^ 1024 - .long 0x5A920000,0x9E8B3B5D,0xC53D5DE5 //10 ^ 2048 - .long 0x75250000,0xC4605202,0x8A20979A //10 ^ 4096 -//round to positive infinity -BIGRP: - .long 0x3ffe0000,0xb17217f7,0xd1cf79ac //ln(2) - .long 0x40000000,0x935d8ddd,0xaaa8ac17 //ln(10) - .long 0x3fff0000,0x80000000,0x00000000 //10 ^ 0 - - .global PTENRP -PTENRP: - .long 0x40020000,0xA0000000,0x00000000 //10 ^ 1 - .long 0x40050000,0xC8000000,0x00000000 //10 ^ 2 - .long 0x400C0000,0x9C400000,0x00000000 //10 ^ 4 - .long 0x40190000,0xBEBC2000,0x00000000 //10 ^ 8 - .long 0x40340000,0x8E1BC9BF,0x04000000 //10 ^ 16 - .long 0x40690000,0x9DC5ADA8,0x2B70B59E //10 ^ 32 - .long 0x40D30000,0xC2781F49,0xFFCFA6D6 //10 ^ 64 - .long 0x41A80000,0x93BA47C9,0x80E98CE0 //10 ^ 128 - .long 0x43510000,0xAA7EEBFB,0x9DF9DE8E //10 ^ 256 - .long 0x46A30000,0xE319A0AE,0xA60E91C7 //10 ^ 512 - .long 0x4D480000,0xC9767586,0x81750C18 //10 ^ 1024 - .long 0x5A920000,0x9E8B3B5D,0xC53D5DE6 //10 ^ 2048 - .long 0x75250000,0xC4605202,0x8A20979B //10 ^ 4096 - - |xref nrm_zero - |xref decbin - |xref round - - .global get_op - .global uns_getop - .global uni_getop -get_op: - clrb DY_MO_FLG(%a6) - tstb UFLG_TMP(%a6) //test flag for unsupp/unimp state - beq uni_getop - -uns_getop: - btstb #direction_bit,CMDREG1B(%a6) - bne opclass3 //branch if a fmove out (any kind) - btstb #6,CMDREG1B(%a6) - beqs uns_notpacked - - bfextu CMDREG1B(%a6){#3:#3},%d0 - cmpb #3,%d0 - beq pack_source //check for a packed src op, branch if so -uns_notpacked: - bsr chk_dy_mo //set the dyadic/monadic flag - tstb DY_MO_FLG(%a6) - beqs src_op_ck //if monadic, go check src op -// ;else, check dst op (fall through) - - btstb #7,DTAG(%a6) - beqs src_op_ck //if dst op is norm, check src op - bras dst_ex_dnrm //else, handle destination unnorm/dnrm - -uni_getop: - bfextu CMDREG1B(%a6){#0:#6},%d0 //get opclass and src fields - cmpil #0x17,%d0 //if op class and size fields are $17, -// ;it is FMOVECR; if not, continue -// -// If the instruction is fmovecr, exit get_op. It is handled -// in do_func and smovecr.sa. -// - bne not_fmovecr //handle fmovecr as an unimplemented inst - rts - -not_fmovecr: - btstb #E1,E_BYTE(%a6) //if set, there is a packed operand - bne pack_source //check for packed src op, branch if so - -// The following lines of are coded to optimize on normalized operands - moveb STAG(%a6),%d0 - orb DTAG(%a6),%d0 //check if either of STAG/DTAG msb set - bmis dest_op_ck //if so, some op needs to be fixed - rts - -dest_op_ck: - btstb #7,DTAG(%a6) //check for unsupported data types in - beqs src_op_ck //the destination, if not, check src op - bsr chk_dy_mo //set dyadic/monadic flag - tstb DY_MO_FLG(%a6) // - beqs src_op_ck //if monadic, check src op -// -// At this point, destination has an extended denorm or unnorm. -// -dst_ex_dnrm: - movew FPTEMP_EX(%a6),%d0 //get destination exponent - andiw #0x7fff,%d0 //mask sign, check if exp = 0000 - beqs src_op_ck //if denorm then check source op. -// ;denorms are taken care of in res_func -// ;(unsupp) or do_func (unimp) -// ;else unnorm fall through - leal FPTEMP(%a6),%a0 //point a0 to dop - used in mk_norm - bsr mk_norm //go normalize - mk_norm returns: -// ;L_SCR1{7:5} = operand tag -// ; (000 = norm, 100 = denorm) -// ;L_SCR1{4} = fpte15 or ete15 -// ; 0 = exp > $3fff -// ; 1 = exp <= $3fff -// ;and puts the normalized num back -// ;on the fsave stack -// - moveb L_SCR1(%a6),DTAG(%a6) //write the new tag & fpte15 -// ;to the fsave stack and fall -// ;through to check source operand -// -src_op_ck: - btstb #7,STAG(%a6) - beq end_getop //check for unsupported data types on the -// ;source operand - btstb #5,STAG(%a6) - bnes src_sd_dnrm //if bit 5 set, handle sgl/dbl denorms -// -// At this point only unnorms or extended denorms are possible. -// -src_ex_dnrm: - movew ETEMP_EX(%a6),%d0 //get source exponent - andiw #0x7fff,%d0 //mask sign, check if exp = 0000 - beq end_getop //if denorm then exit, denorms are -// ;handled in do_func - leal ETEMP(%a6),%a0 //point a0 to sop - used in mk_norm - bsr mk_norm //go normalize - mk_norm returns: -// ;L_SCR1{7:5} = operand tag -// ; (000 = norm, 100 = denorm) -// ;L_SCR1{4} = fpte15 or ete15 -// ; 0 = exp > $3fff -// ; 1 = exp <= $3fff -// ;and puts the normalized num back -// ;on the fsave stack -// - moveb L_SCR1(%a6),STAG(%a6) //write the new tag & ete15 - rts //end_getop - -// -// At this point, only single or double denorms are possible. -// If the inst is not fmove, normalize the source. If it is, -// do nothing to the input. -// -src_sd_dnrm: - btstb #4,CMDREG1B(%a6) //differentiate between sgl/dbl denorm - bnes is_double -is_single: - movew #0x3f81,%d1 //write bias for sgl denorm - bras common //goto the common code -is_double: - movew #0x3c01,%d1 //write the bias for a dbl denorm -common: - btstb #sign_bit,ETEMP_EX(%a6) //grab sign bit of mantissa - beqs pos - bset #15,%d1 //set sign bit because it is negative -pos: - movew %d1,ETEMP_EX(%a6) -// ;put exponent on stack - - movew CMDREG1B(%a6),%d1 - andw #0xe3ff,%d1 //clear out source specifier - orw #0x0800,%d1 //set source specifier to extended prec - movew %d1,CMDREG1B(%a6) //write back to the command word in stack -// ;this is needed to fix unsupp data stack - leal ETEMP(%a6),%a0 //point a0 to sop - - bsr mk_norm //convert sgl/dbl denorm to norm - moveb L_SCR1(%a6),STAG(%a6) //put tag into source tag reg - d0 - rts //end_getop -// -// At this point, the source is definitely packed, whether -// instruction is dyadic or monadic is still unknown -// -pack_source: - movel FPTEMP_LO(%a6),ETEMP(%a6) //write ms part of packed -// ;number to etemp slot - bsr chk_dy_mo //set dyadic/monadic flag - bsr unpack - - tstb DY_MO_FLG(%a6) - beqs end_getop //if monadic, exit -// ;else, fix FPTEMP -pack_dya: - bfextu CMDREG1B(%a6){#6:#3},%d0 //extract dest fp reg - movel #7,%d1 - subl %d0,%d1 - clrl %d0 - bsetl %d1,%d0 //set up d0 as a dynamic register mask - fmovemx %d0,FPTEMP(%a6) //write to FPTEMP - - btstb #7,DTAG(%a6) //check dest tag for unnorm or denorm - bne dst_ex_dnrm //else, handle the unnorm or ext denorm -// -// Dest is not denormalized. Check for norm, and set fpte15 -// accordingly. -// - moveb DTAG(%a6),%d0 - andib #0xf0,%d0 //strip to only dtag:fpte15 - tstb %d0 //check for normalized value - bnes end_getop //if inf/nan/zero leave get_op - movew FPTEMP_EX(%a6),%d0 - andiw #0x7fff,%d0 - cmpiw #0x3fff,%d0 //check if fpte15 needs setting - bges end_getop //if >= $3fff, leave fpte15=0 - orb #0x10,DTAG(%a6) - bras end_getop - -// -// At this point, it is either an fmoveout packed, unnorm or denorm -// -opclass3: - clrb DY_MO_FLG(%a6) //set dyadic/monadic flag to monadic - bfextu CMDREG1B(%a6){#4:#2},%d0 - cmpib #3,%d0 - bne src_ex_dnrm //if not equal, must be unnorm or denorm -// ;else it is a packed move out -// ;exit -end_getop: - rts - -// -// Sets the DY_MO_FLG correctly. This is used only on if it is an -// unsupported data type exception. Set if dyadic. -// -chk_dy_mo: - movew CMDREG1B(%a6),%d0 - btstl #5,%d0 //testing extension command word - beqs set_mon //if bit 5 = 0 then monadic - btstl #4,%d0 //know that bit 5 = 1 - beqs set_dya //if bit 4 = 0 then dyadic - andiw #0x007f,%d0 //get rid of all but extension bits {6:0} - cmpiw #0x0038,%d0 //if extension = $38 then fcmp (dyadic) - bnes set_mon -set_dya: - st DY_MO_FLG(%a6) //set the inst flag type to dyadic - rts -set_mon: - clrb DY_MO_FLG(%a6) //set the inst flag type to monadic - rts -// -// MK_NORM -// -// Normalizes unnormalized numbers, sets tag to norm or denorm, sets unfl -// exception if denorm. -// -// CASE opclass 0x0 unsupp -// mk_norm till msb set -// set tag = norm -// -// CASE opclass 0x0 unimp -// mk_norm till msb set or exp = 0 -// if integer bit = 0 -// tag = denorm -// else -// tag = norm -// -// CASE opclass 011 unsupp -// mk_norm till msb set or exp = 0 -// if integer bit = 0 -// tag = denorm -// set unfl_nmcexe = 1 -// else -// tag = norm -// -// if exp <= $3fff -// set ete15 or fpte15 = 1 -// else set ete15 or fpte15 = 0 - -// input: -// a0 = points to operand to be normalized -// output: -// L_SCR1{7:5} = operand tag (000 = norm, 100 = denorm) -// L_SCR1{4} = fpte15 or ete15 (0 = exp > $3fff, 1 = exp <=$3fff) -// the normalized operand is placed back on the fsave stack -mk_norm: - clrl L_SCR1(%a6) - bclrb #sign_bit,LOCAL_EX(%a0) - sne LOCAL_SGN(%a0) //transform into internal extended format - - cmpib #0x2c,1+EXC_VEC(%a6) //check if unimp - bnes uns_data //branch if unsupp - bsr uni_inst //call if unimp (opclass 0x0) - bras reload -uns_data: - btstb #direction_bit,CMDREG1B(%a6) //check transfer direction - bnes bit_set //branch if set (opclass 011) - bsr uns_opx //call if opclass 0x0 - bras reload -bit_set: - bsr uns_op3 //opclass 011 -reload: - cmpw #0x3fff,LOCAL_EX(%a0) //if exp > $3fff - bgts end_mk // fpte15/ete15 already set to 0 - bsetb #4,L_SCR1(%a6) //else set fpte15/ete15 to 1 -// ;calling routine actually sets the -// ;value on the stack (along with the -// ;tag), since this routine doesn't -// ;know if it should set ete15 or fpte15 -// ;ie, it doesn't know if this is the -// ;src op or dest op. -end_mk: - bfclr LOCAL_SGN(%a0){#0:#8} - beqs end_mk_pos - bsetb #sign_bit,LOCAL_EX(%a0) //convert back to IEEE format -end_mk_pos: - rts -// -// CASE opclass 011 unsupp -// -uns_op3: - bsr nrm_zero //normalize till msb = 1 or exp = zero - btstb #7,LOCAL_HI(%a0) //if msb = 1 - bnes no_unfl //then branch -set_unfl: - orw #dnrm_tag,L_SCR1(%a6) //set denorm tag - bsetb #unfl_bit,FPSR_EXCEPT(%a6) //set unfl exception bit -no_unfl: - rts -// -// CASE opclass 0x0 unsupp -// -uns_opx: - bsr nrm_zero //normalize the number - btstb #7,LOCAL_HI(%a0) //check if integer bit (j-bit) is set - beqs uns_den //if clear then now have a denorm -uns_nrm: - orb #norm_tag,L_SCR1(%a6) //set tag to norm - rts -uns_den: - orb #dnrm_tag,L_SCR1(%a6) //set tag to denorm - rts -// -// CASE opclass 0x0 unimp -// -uni_inst: - bsr nrm_zero - btstb #7,LOCAL_HI(%a0) //check if integer bit (j-bit) is set - beqs uni_den //if clear then now have a denorm -uni_nrm: - orb #norm_tag,L_SCR1(%a6) //set tag to norm - rts -uni_den: - orb #dnrm_tag,L_SCR1(%a6) //set tag to denorm - rts - -// -// Decimal to binary conversion -// -// Special cases of inf and NaNs are completed outside of decbin. -// If the input is an snan, the snan bit is not set. -// -// input: -// ETEMP(a6) - points to packed decimal string in memory -// output: -// fp0 - contains packed string converted to extended precision -// ETEMP - same as fp0 -unpack: - movew CMDREG1B(%a6),%d0 //examine command word, looking for fmove's - andw #0x3b,%d0 - beq move_unpack //special handling for fmove: must set FPSR_CC - - movew ETEMP(%a6),%d0 //get word with inf information - bfextu %d0{#20:#12},%d1 //get exponent into d1 - cmpiw #0x0fff,%d1 //test for inf or NaN - bnes try_zero //if not equal, it is not special - bfextu %d0{#17:#3},%d1 //get SE and y bits into d1 - cmpiw #7,%d1 //SE and y bits must be on for special - bnes try_zero //if not on, it is not special -//input is of the special cases of inf and NaN - tstl ETEMP_HI(%a6) //check ms mantissa - bnes fix_nan //if non-zero, it is a NaN - tstl ETEMP_LO(%a6) //check ls mantissa - bnes fix_nan //if non-zero, it is a NaN - bra finish //special already on stack -fix_nan: - btstb #signan_bit,ETEMP_HI(%a6) //test for snan - bne finish - orl #snaniop_mask,USER_FPSR(%a6) //always set snan if it is so - bra finish -try_zero: - movew ETEMP_EX+2(%a6),%d0 //get word 4 - andiw #0x000f,%d0 //clear all but last ni(y)bble - tstw %d0 //check for zero. - bne not_spec - tstl ETEMP_HI(%a6) //check words 3 and 2 - bne not_spec - tstl ETEMP_LO(%a6) //check words 1 and 0 - bne not_spec - tstl ETEMP(%a6) //test sign of the zero - bges pos_zero - movel #0x80000000,ETEMP(%a6) //write neg zero to etemp - clrl ETEMP_HI(%a6) - clrl ETEMP_LO(%a6) - bra finish -pos_zero: - clrl ETEMP(%a6) - clrl ETEMP_HI(%a6) - clrl ETEMP_LO(%a6) - bra finish - -not_spec: - fmovemx %fp0-%fp1,-(%a7) //save fp0 - decbin returns in it - bsr decbin - fmovex %fp0,ETEMP(%a6) //put the unpacked sop in the fsave stack - fmovemx (%a7)+,%fp0-%fp1 - fmovel #0,%FPSR //clr fpsr from decbin - bra finish - -// -// Special handling for packed move in: Same results as all other -// packed cases, but we must set the FPSR condition codes properly. -// -move_unpack: - movew ETEMP(%a6),%d0 //get word with inf information - bfextu %d0{#20:#12},%d1 //get exponent into d1 - cmpiw #0x0fff,%d1 //test for inf or NaN - bnes mtry_zero //if not equal, it is not special - bfextu %d0{#17:#3},%d1 //get SE and y bits into d1 - cmpiw #7,%d1 //SE and y bits must be on for special - bnes mtry_zero //if not on, it is not special -//input is of the special cases of inf and NaN - tstl ETEMP_HI(%a6) //check ms mantissa - bnes mfix_nan //if non-zero, it is a NaN - tstl ETEMP_LO(%a6) //check ls mantissa - bnes mfix_nan //if non-zero, it is a NaN -//input is inf - orl #inf_mask,USER_FPSR(%a6) //set I bit - tstl ETEMP(%a6) //check sign - bge finish - orl #neg_mask,USER_FPSR(%a6) //set N bit - bra finish //special already on stack -mfix_nan: - orl #nan_mask,USER_FPSR(%a6) //set NaN bit - moveb #nan_tag,STAG(%a6) //set stag to NaN - btstb #signan_bit,ETEMP_HI(%a6) //test for snan - bnes mn_snan - orl #snaniop_mask,USER_FPSR(%a6) //set snan bit - btstb #snan_bit,FPCR_ENABLE(%a6) //test for snan enabled - bnes mn_snan - bsetb #signan_bit,ETEMP_HI(%a6) //force snans to qnans -mn_snan: - tstl ETEMP(%a6) //check for sign - bge finish //if clr, go on - orl #neg_mask,USER_FPSR(%a6) //set N bit - bra finish - -mtry_zero: - movew ETEMP_EX+2(%a6),%d0 //get word 4 - andiw #0x000f,%d0 //clear all but last ni(y)bble - tstw %d0 //check for zero. - bnes mnot_spec - tstl ETEMP_HI(%a6) //check words 3 and 2 - bnes mnot_spec - tstl ETEMP_LO(%a6) //check words 1 and 0 - bnes mnot_spec - tstl ETEMP(%a6) //test sign of the zero - bges mpos_zero - orl #neg_mask+z_mask,USER_FPSR(%a6) //set N and Z - movel #0x80000000,ETEMP(%a6) //write neg zero to etemp - clrl ETEMP_HI(%a6) - clrl ETEMP_LO(%a6) - bras finish -mpos_zero: - orl #z_mask,USER_FPSR(%a6) //set Z - clrl ETEMP(%a6) - clrl ETEMP_HI(%a6) - clrl ETEMP_LO(%a6) - bras finish - -mnot_spec: - fmovemx %fp0-%fp1,-(%a7) //save fp0 ,fp1 - decbin returns in fp0 - bsr decbin - fmovex %fp0,ETEMP(%a6) -// ;put the unpacked sop in the fsave stack - fmovemx (%a7)+,%fp0-%fp1 - -finish: - movew CMDREG1B(%a6),%d0 //get the command word - andw #0xfbff,%d0 //change the source specifier field to -// ;extended (was packed). - movew %d0,CMDREG1B(%a6) //write command word back to fsave stack -// ;we need to do this so the 040 will -// ;re-execute the inst. without taking -// ;another packed trap. - -fix_stag: -//Converted result is now in etemp on fsave stack, now set the source -//tag (stag) -// if (ete =$7fff) then INF or NAN -// if (etemp = $x.0----0) then -// stag = INF -// else -// stag = NAN -// else -// if (ete = $0000) then -// stag = ZERO -// else -// stag = NORM -// -// Note also that the etemp_15 bit (just right of the stag) must -// be set accordingly. -// - movew ETEMP_EX(%a6),%d1 - andiw #0x7fff,%d1 //strip sign - cmpw #0x7fff,%d1 - bnes z_or_nrm - movel ETEMP_HI(%a6),%d1 - bnes is_nan - movel ETEMP_LO(%a6),%d1 - bnes is_nan -is_inf: - moveb #0x40,STAG(%a6) - movel #0x40,%d0 - rts -is_nan: - moveb #0x60,STAG(%a6) - movel #0x60,%d0 - rts -z_or_nrm: - tstw %d1 - bnes is_nrm -is_zro: -// For a zero, set etemp_15 - moveb #0x30,STAG(%a6) - movel #0x20,%d0 - rts -is_nrm: -// For a norm, check if the exp <= $3fff; if so, set etemp_15 - cmpiw #0x3fff,%d1 - bles set_bit15 - moveb #0,STAG(%a6) - bras end_is_nrm -set_bit15: - moveb #0x10,STAG(%a6) -end_is_nrm: - movel #0,%d0 -end_fix: - rts - -end_get: - rts - |end |