📄 get_op.s
字号:
|| 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.h" .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 orb #0x10,DTAG(%a6)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -