📄 round.s
字号:
greater: movel %d2,%d6 //save ls mant in d6 lsll %d0,%d2 //shift ls mant by count lsll %d0,%d1 //shift ms mant by count movel #32,%d5 subl %d0,%d5 //make op a denorm by shifting bits lsrl %d5,%d6 //by the number in the exp, then // ;set exp = 0. orl %d6,%d1 //shift the ls mant bits into the ms mant movel #0,%d0 //same as if decremented exp to 0 // ;while shifting movew %d0,LOCAL_EX(%a0) movel %d1,LOCAL_HI(%a0) movel %d2,LOCAL_LO(%a0) moveml (%a7)+,%d2/%d3/%d5/%d6 rtsms_clr: bfffo %d2{#0:#32},%d3 //check if any bits set in ls mant beqs all_clr //branch if none set addw #32,%d3 cmpw %d3,%d0 //if X>Y bmis greater //then branch bsr nrm_set //else exp won't go past 0 moveml (%a7)+,%d2/%d3/%d5/%d6 rtsall_clr: movew #0,LOCAL_EX(%a0) //no mantissa bits set. Set exp = 0. moveml (%a7)+,%d2/%d3/%d5/%d6 rts//// NRM_SET// .global nrm_setnrm_set: movel %d7,-(%a7) bfffo LOCAL_HI(%a0){#0:#32},%d7 //find first 1 in ms mant to d7) beqs lower //branch if ms mant is all 0's movel %d6,-(%a7) subw %d7,LOCAL_EX(%a0) //sub exponent by count movel LOCAL_HI(%a0),%d0 //d0 has ms mant movel LOCAL_LO(%a0),%d1 //d1 has ls mant lsll %d7,%d0 //shift first 1 to j bit position movel %d1,%d6 //copy ls mant into d6 lsll %d7,%d6 //shift ls mant by count movel %d6,LOCAL_LO(%a0) //store ls mant into memory moveql #32,%d6 subl %d7,%d6 //continue shift lsrl %d6,%d1 //shift off all bits but those that will// ;be shifted into ms mant orl %d1,%d0 //shift the ls mant bits into the ms mant movel %d0,LOCAL_HI(%a0) //store ms mant into memory moveml (%a7)+,%d7/%d6 //restore registers rts//// We get here if ms mant was = 0, and we assume ls mant has bits // set (otherwise this would have been tagged a zero not a denorm).//lower: movew LOCAL_EX(%a0),%d0 //d0 has exponent movel LOCAL_LO(%a0),%d1 //d1 has ls mant subw #32,%d0 //account for ms mant being all zeros bfffo %d1{#0:#32},%d7 //find first 1 in ls mant to d7) subw %d7,%d0 //subtract shift count from exp lsll %d7,%d1 //shift first 1 to integer bit in ms mant movew %d0,LOCAL_EX(%a0) //store ms mant movel %d1,LOCAL_HI(%a0) //store exp clrl LOCAL_LO(%a0) //clear ls mant movel (%a7)+,%d7 rts//// denorm --- denormalize an intermediate result//// Used by underflow.//// Input: // a0 points to the operand to be denormalized// (in the internal extended format)// // d0: rounding precision// Output:// a0 points to the denormalized result// (in the internal extended format)//// d0 is guard,round,sticky//// d0 comes into this routine with the rounding precision. It // is then loaded with the denormalized exponent threshold for the // rounding precision.// .global denormdenorm: btstb #6,LOCAL_EX(%a0) //check for exponents between $7fff-$4000 beqs no_sgn_ext bsetb #7,LOCAL_EX(%a0) //sign extend if it is sono_sgn_ext: cmpib #0,%d0 //if 0 then extended precision bnes not_ext //else branch clrl %d1 //load d1 with ext threshold clrl %d0 //clear the sticky flag bsr dnrm_lp //denormalize the number tstb %d1 //check for inex beq no_inex //if clr, no inex bras dnrm_inex //if set, set inexnot_ext: cmpil #1,%d0 //if 1 then single precision beqs load_sgl //else must be 2, double precload_dbl: movew #dbl_thresh,%d1 //put copy of threshold in d1 movel %d1,%d0 //copy d1 into d0 subw LOCAL_EX(%a0),%d0 //diff = threshold - exp cmpw #67,%d0 //if diff > 67 (mant + grs bits) bpls chk_stky //then branch (all bits would be // ; shifted off in denorm routine) clrl %d0 //else clear the sticky flag bsr dnrm_lp //denormalize the number tstb %d1 //check flag beqs no_inex //if clr, no inex bras dnrm_inex //if set, set inexload_sgl: movew #sgl_thresh,%d1 //put copy of threshold in d1 movel %d1,%d0 //copy d1 into d0 subw LOCAL_EX(%a0),%d0 //diff = threshold - exp cmpw #67,%d0 //if diff > 67 (mant + grs bits) bpls chk_stky //then branch (all bits would be // ; shifted off in denorm routine) clrl %d0 //else clear the sticky flag bsr dnrm_lp //denormalize the number tstb %d1 //check flag beqs no_inex //if clr, no inex bras dnrm_inex //if set, set inexchk_stky: tstl LOCAL_HI(%a0) //check for any bits set bnes set_stky tstl LOCAL_LO(%a0) //check for any bits set bnes set_stky bras clr_mantset_stky: orl #inx2a_mask,USER_FPSR(%a6) //set inex2/ainex movel #0x20000000,%d0 //set sticky bit in return valueclr_mant: movew %d1,LOCAL_EX(%a0) //load exp with threshold movel #0,LOCAL_HI(%a0) //set d1 = 0 (ms mantissa) movel #0,LOCAL_LO(%a0) //set d2 = 0 (ms mantissa) rtsdnrm_inex: orl #inx2a_mask,USER_FPSR(%a6) //set inex2/ainexno_inex: rts//// dnrm_lp --- normalize exponent/mantissa to specified threshold//// Input:// a0 points to the operand to be denormalized// d0{31:29} initial guard,round,sticky// d1{15:0} denormalization threshold// Output:// a0 points to the denormalized operand// d0{31:29} final guard,round,sticky// d1.b inexact flag: all ones means inexact result//// The LOCAL_LO and LOCAL_GRS parts of the value are copied to FP_SCR2// so that bfext can be used to extract the new low part of the mantissa.// Dnrm_lp can be called with a0 pointing to ETEMP or WBTEMP and there // is no LOCAL_GRS scratch word following it on the fsave frame.// .global dnrm_lpdnrm_lp: movel %d2,-(%sp) //save d2 for temp use btstb #E3,E_BYTE(%a6) //test for type E3 exception beqs not_E3 //not type E3 exception bfextu WBTEMP_GRS(%a6){#6:#3},%d2 //extract guard,round, sticky bit movel #29,%d0 lsll %d0,%d2 //shift g,r,s to their positions movel %d2,%d0not_E3: movel (%sp)+,%d2 //restore d2 movel LOCAL_LO(%a0),FP_SCR2+LOCAL_LO(%a6) movel %d0,FP_SCR2+LOCAL_GRS(%a6) movel %d1,%d0 //copy the denorm threshold subw LOCAL_EX(%a0),%d1 //d1 = threshold - uns exponent bles no_lp //d1 <= 0 cmpw #32,%d1 blts case_1 //0 = d1 < 32 cmpw #64,%d1 blts case_2 //32 <= d1 < 64 bra case_3 //d1 >= 64//// No normalization necessary//no_lp: clrb %d1 //set no inex2 reported movel FP_SCR2+LOCAL_GRS(%a6),%d0 //restore original g,r,s rts//// case (0<d1<32)//case_1: movel %d2,-(%sp) movew %d0,LOCAL_EX(%a0) //exponent = denorm threshold movel #32,%d0 subw %d1,%d0 //d0 = 32 - d1 bfextu LOCAL_EX(%a0){%d0:#32},%d2 bfextu %d2{%d1:%d0},%d2 //d2 = new LOCAL_HI bfextu LOCAL_HI(%a0){%d0:#32},%d1 //d1 = new LOCAL_LO bfextu FP_SCR2+LOCAL_LO(%a6){%d0:#32},%d0 //d0 = new G,R,S movel %d2,LOCAL_HI(%a0) //store new LOCAL_HI movel %d1,LOCAL_LO(%a0) //store new LOCAL_LO clrb %d1 bftst %d0{#2:#30} beqs c1nstky bsetl #rnd_stky_bit,%d0 st %d1c1nstky: movel FP_SCR2+LOCAL_GRS(%a6),%d2 //restore original g,r,s andil #0xe0000000,%d2 //clear all but G,R,S tstl %d2 //test if original G,R,S are clear beqs grs_clear orl #0x20000000,%d0 //set sticky bit in d0grs_clear: andil #0xe0000000,%d0 //clear all but G,R,S movel (%sp)+,%d2 rts//// case (32<=d1<64)//case_2: movel %d2,-(%sp) movew %d0,LOCAL_EX(%a0) //unsigned exponent = threshold subw #32,%d1 //d1 now between 0 and 32 movel #32,%d0 subw %d1,%d0 //d0 = 32 - d1 bfextu LOCAL_EX(%a0){%d0:#32},%d2 bfextu %d2{%d1:%d0},%d2 //d2 = new LOCAL_LO bfextu LOCAL_HI(%a0){%d0:#32},%d1 //d1 = new G,R,S bftst %d1{#2:#30} bnes c2_sstky //bra if sticky bit to be set bftst FP_SCR2+LOCAL_LO(%a6){%d0:#32} bnes c2_sstky //bra if sticky bit to be set movel %d1,%d0 clrb %d1 bras end_c2c2_sstky: movel %d1,%d0 bsetl #rnd_stky_bit,%d0 st %d1end_c2: clrl LOCAL_HI(%a0) //store LOCAL_HI = 0 movel %d2,LOCAL_LO(%a0) //store LOCAL_LO movel FP_SCR2+LOCAL_GRS(%a6),%d2 //restore original g,r,s andil #0xe0000000,%d2 //clear all but G,R,S tstl %d2 //test if original G,R,S are clear beqs clear_grs orl #0x20000000,%d0 //set sticky bit in d0clear_grs: andil #0xe0000000,%d0 //get rid of all but G,R,S movel (%sp)+,%d2 rts//// d1 >= 64 Force the exponent to be the denorm threshold with the// correct sign.//case_3: movew %d0,LOCAL_EX(%a0) tstw LOCAL_SGN(%a0) bges c3conc3neg: orl #0x80000000,LOCAL_EX(%a0)c3con: cmpw #64,%d1 beqs sixty_four cmpw #65,%d1 beqs sixty_five//// Shift value is out of range. Set d1 for inex2 flag and// return a zero with the given threshold.// clrl LOCAL_HI(%a0) clrl LOCAL_LO(%a0) movel #0x20000000,%d0 st %d1 rtssixty_four: movel LOCAL_HI(%a0),%d0 bfextu %d0{#2:#30},%d1 andil #0xc0000000,%d0 bras c3com sixty_five: movel LOCAL_HI(%a0),%d0 bfextu %d0{#1:#31},%d1 andil #0x80000000,%d0 lsrl #1,%d0 //shift high bit into R bitc3com: tstl %d1 bnes c3ssticky tstl LOCAL_LO(%a0) bnes c3ssticky tstb FP_SCR2+LOCAL_GRS(%a6) bnes c3ssticky clrb %d1 bras c3endc3ssticky: bsetl #rnd_stky_bit,%d0 st %d1c3end: clrl LOCAL_HI(%a0) clrl LOCAL_LO(%a0) rts |end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -