📄 round.s
字号:
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 + -