📄 get_op.s
字号:
//// $Id: get_op.S,v 1.2 1999/07/26 22:11:02 joel Exp $//// 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,BIGRPPIRN: .long 0x40000000,0xc90fdaa2,0x2168c235 //piPIRZRM: .long 0x40000000,0xc90fdaa2,0x2168c234 //piPIRP: .long 0x40000000,0xc90fdaa2,0x2168c235 //pi//round to nearestSMALRN: .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 infinitySMALRZRM: .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 infinitySMALRP: .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 nearestBIGRN: .long 0x3ffe0000,0xb17217f7,0xd1cf79ac //ln(2) .long 0x40000000,0x935d8ddd,0xaaa8ac17 //ln(10) .long 0x3fff0000,0x80000000,0x00000000 //10 ^ 0 .global PTENRNPTENRN: .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 infinityBIGRZRM: .long 0x3ffe0000,0xb17217f7,0xd1cf79ab //ln(2) .long 0x40000000,0x935d8ddd,0xaaa8ac16 //ln(10) .long 0x3fff0000,0x80000000,0x00000000 //10 ^ 0 .global PTENRMPTENRM: .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 infinityBIGRP: .long 0x3ffe0000,0xb17217f7,0xd1cf79ac //ln(2) .long 0x40000000,0x935d8ddd,0xaaa8ac17 //ln(10) .long 0x3fff0000,0x80000000,0x00000000 //10 ^ 0 .global PTENRPPTENRP: .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_getopget_op: clrb DY_MO_FLG(%a6) tstb UFLG_TMP(%a6) //test flag for unsupp/unimp state beq uni_getopuns_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 souns_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/dnrmuni_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 rtsnot_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 rtsdest_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_doubleis_single: movew #0x3f81,%d1 //write bias for sgl denorm bras common //goto the common codeis_double: movew #0x3c01,%d1 //write the bias for a dbl denormcommon: btstb #sign_bit,ETEMP_EX(%a6) //grab sign bit of mantissa beqs pos bset #15,%d1 //set sign bit because it is negativepos: 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 FPTEMPpack_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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -