📄 get_op.s
字号:
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| ;exitend_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_monset_dya: st DY_MO_FLG(%a6) |set the inst flag type to dyadic rtsset_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 stackmk_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 reloaduns_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 reloadbit_set: bsr uns_op3 |opclass 011reload: 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 formatend_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 branchset_unfl: orw #dnrm_tag,L_SCR1(%a6) |set denorm tag bsetb #unfl_bit,FPSR_EXCEPT(%a6) |set unfl exception bitno_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 denormuns_nrm: orb #norm_tag,L_SCR1(%a6) |set tag to norm rtsuns_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 denormuni_nrm: orb #norm_tag,L_SCR1(%a6) |set tag to norm rtsuni_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 fp0unpack: 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 stackfix_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 finishtry_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 finishpos_zero: clrl ETEMP(%a6) clrl ETEMP_HI(%a6) clrl ETEMP_LO(%a6) bra finishnot_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 stackmfix_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 qnansmn_snan: tstl ETEMP(%a6) |check for sign bge finish |if clr, go on orl #neg_mask,USER_FPSR(%a6) |set N bit bra finishmtry_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 finishmpos_zero: orl #z_mask,USER_FPSR(%a6) |set Z clrl ETEMP(%a6) clrl ETEMP_HI(%a6) clrl ETEMP_LO(%a6) bras finishmnot_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-%fp1finish: 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_nanis_inf: moveb #0x40,STAG(%a6) movel #0x40,%d0 rtsis_nan: moveb #0x60,STAG(%a6) movel #0x60,%d0 rtsz_or_nrm: tstw %d1 bnes is_nrmis_zro:| For a zero, set etemp_15 moveb #0x30,STAG(%a6) movel #0x20,%d0 rtsis_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_nrmset_bit15: moveb #0x10,STAG(%a6)end_is_nrm: movel #0,%d0end_fix: rts end_get: rts |end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -