📄 pfpsp.s
字号:
set DST_HI, 4 # value saved in memory.set DST_LO, 8set SRC, 0 # offsets within anset SRC_EX, 0 # extended precisionset SRC_HI, 4 # value saved in memory.set SRC_LO, 8set SGL_LO, 0x3f81 # min sgl prec exponentset SGL_HI, 0x407e # max sgl prec exponentset DBL_LO, 0x3c01 # min dbl prec exponentset DBL_HI, 0x43fe # max dbl prec exponentset EXT_LO, 0x0 # min ext prec exponentset EXT_HI, 0x7ffe # max ext prec exponentset EXT_BIAS, 0x3fff # extended precision biasset SGL_BIAS, 0x007f # single precision biasset DBL_BIAS, 0x03ff # double precision biasset NORM, 0x00 # operand type for STAG/DTAGset ZERO, 0x01 # operand type for STAG/DTAGset INF, 0x02 # operand type for STAG/DTAGset QNAN, 0x03 # operand type for STAG/DTAGset DENORM, 0x04 # operand type for STAG/DTAGset SNAN, 0x05 # operand type for STAG/DTAGset UNNORM, 0x06 # operand type for STAG/DTAG################### FPSR/FPCR bits ###################set neg_bit, 0x3 # negative resultset z_bit, 0x2 # zero resultset inf_bit, 0x1 # infinite resultset nan_bit, 0x0 # NAN resultset q_sn_bit, 0x7 # sign bit of quotient byteset bsun_bit, 7 # branch on unorderedset snan_bit, 6 # signalling NANset operr_bit, 5 # operand errorset ovfl_bit, 4 # overflowset unfl_bit, 3 # underflowset dz_bit, 2 # divide by zeroset inex2_bit, 1 # inexact result 2set inex1_bit, 0 # inexact result 1set aiop_bit, 7 # accrued inexact operation bitset aovfl_bit, 6 # accrued overflow bitset aunfl_bit, 5 # accrued underflow bitset adz_bit, 4 # accrued dz bitset ainex_bit, 3 # accrued inexact bit############################## FPSR individual bit masks ##############################set neg_mask, 0x08000000 # negative bit mask (lw)set inf_mask, 0x02000000 # infinity bit mask (lw)set z_mask, 0x04000000 # zero bit mask (lw)set nan_mask, 0x01000000 # nan bit mask (lw)set neg_bmask, 0x08 # negative bit mask (byte)set inf_bmask, 0x02 # infinity bit mask (byte)set z_bmask, 0x04 # zero bit mask (byte)set nan_bmask, 0x01 # nan bit mask (byte)set bsun_mask, 0x00008000 # bsun exception maskset snan_mask, 0x00004000 # snan exception maskset operr_mask, 0x00002000 # operr exception maskset ovfl_mask, 0x00001000 # overflow exception maskset unfl_mask, 0x00000800 # underflow exception maskset dz_mask, 0x00000400 # dz exception maskset inex2_mask, 0x00000200 # inex2 exception maskset inex1_mask, 0x00000100 # inex1 exception maskset aiop_mask, 0x00000080 # accrued illegal operationset aovfl_mask, 0x00000040 # accrued overflowset aunfl_mask, 0x00000020 # accrued underflowset adz_mask, 0x00000010 # accrued divide by zeroset ainex_mask, 0x00000008 # accrued inexact####################################### FPSR combinations used in the FPSP #######################################set dzinf_mask, inf_mask+dz_mask+adz_maskset opnan_mask, nan_mask+operr_mask+aiop_maskset nzi_mask, 0x01ffffff #clears N, Z, and Iset unfinx_mask, unfl_mask+inex2_mask+aunfl_mask+ainex_maskset unf2inx_mask, unfl_mask+inex2_mask+ainex_maskset ovfinx_mask, ovfl_mask+inex2_mask+aovfl_mask+ainex_maskset inx1a_mask, inex1_mask+ainex_maskset inx2a_mask, inex2_mask+ainex_maskset snaniop_mask, nan_mask+snan_mask+aiop_maskset snaniop2_mask, snan_mask+aiop_maskset naniop_mask, nan_mask+aiop_maskset neginf_mask, neg_mask+inf_maskset infaiop_mask, inf_mask+aiop_maskset negz_mask, neg_mask+z_maskset opaop_mask, operr_mask+aiop_maskset unfl_inx_mask, unfl_mask+aunfl_mask+ainex_maskset ovfl_inx_mask, ovfl_mask+aovfl_mask+ainex_mask########## misc. ##########set rnd_stky_bit, 29 # stky bit pos in longwordset sign_bit, 0x7 # sign bitset signan_bit, 0x6 # signalling nan bitset sgl_thresh, 0x3f81 # minimum sgl exponentset dbl_thresh, 0x3c01 # minimum dbl exponentset x_mode, 0x0 # extended precisionset s_mode, 0x4 # single precisionset d_mode, 0x8 # double precisionset rn_mode, 0x0 # round-to-nearestset rz_mode, 0x1 # round-to-zeroset rm_mode, 0x2 # round-tp-minus-infinityset rp_mode, 0x3 # round-to-plus-infinityset mantissalen, 64 # length of mantissa in bitsset BYTE, 1 # len(byte) == 1 byteset WORD, 2 # len(word) == 2 bytesset LONG, 4 # len(longword) == 2 bytesset BSUN_VEC, 0xc0 # bsun vector offsetset INEX_VEC, 0xc4 # inexact vector offsetset DZ_VEC, 0xc8 # dz vector offsetset UNFL_VEC, 0xcc # unfl vector offsetset OPERR_VEC, 0xd0 # operr vector offsetset OVFL_VEC, 0xd4 # ovfl vector offsetset SNAN_VEC, 0xd8 # snan vector offset############################ SPecial CONDition FLaGs ############################set ftrapcc_flg, 0x01 # flag bit: ftrapcc exceptionset fbsun_flg, 0x02 # flag bit: bsun exceptionset mia7_flg, 0x04 # flag bit: (a7)+ <ea>set mda7_flg, 0x08 # flag bit: -(a7) <ea>set fmovm_flg, 0x40 # flag bit: fmovm instructionset immed_flg, 0x80 # flag bit: &<data> <ea>set ftrapcc_bit, 0x0set fbsun_bit, 0x1set mia7_bit, 0x2set mda7_bit, 0x3set immed_bit, 0x7################################### TRANSCENDENTAL "LAST-OP" FLAGS ###################################set FMUL_OP, 0x0 # fmul instr performed lastset FDIV_OP, 0x1 # fdiv performed lastset FADD_OP, 0x2 # fadd performed lastset FMOV_OP, 0x3 # fmov performed last############## CONSTANTS ##############T1: long 0x40C62D38,0xD3D64634 # 16381 LOG2 LEADT2: long 0x3D6F90AE,0xB1E75CC7 # 16381 LOG2 TRAILPI: long 0x40000000,0xC90FDAA2,0x2168C235,0x00000000PIBY2: long 0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000TWOBYPI: long 0x3FE45F30,0x6DC9C883########################################################################## XDEF **************************************************************** ## _fpsp_ovfl(): 060FPSP entry point for FP Overflow exception. ## ## This handler should be the first code executed upon taking the ## FP Overflow exception in an operating system. ## ## XREF **************************************************************** ## _imem_read_long() - read instruction longword ## fix_skewed_ops() - adjust src operand in fsave frame ## set_tag_x() - determine optype of src/dst operands ## store_fpreg() - store opclass 0 or 2 result to FP regfile ## unnorm_fix() - change UNNORM operands to NORM or ZERO ## load_fpn2() - load dst operand from FP regfile ## fout() - emulate an opclass 3 instruction ## tbl_unsupp - add of table of emulation routines for opclass 0,2 ## _fpsp_done() - "callout" for 060FPSP exit (all work done!) ## _real_ovfl() - "callout" for Overflow exception enabled code ## _real_inex() - "callout" for Inexact exception enabled code ## _real_trace() - "callout" for Trace exception code ## ## INPUT *************************************************************** ## - The system stack contains the FP Ovfl exception stack frame ## - The fsave frame contains the source operand ## ## OUTPUT ************************************************************** ## Overflow Exception enabled: ## - The system stack is unchanged ## - The fsave frame contains the adjusted src op for opclass 0,2 ## Overflow Exception disabled: ## - The system stack is unchanged ## - The "exception present" flag in the fsave frame is cleared ## ## ALGORITHM *********************************************************** ## On the 060, if an FP overflow is present as the result of any ## instruction, the 060 will take an overflow exception whether the ## exception is enabled or disabled in the FPCR. For the disabled case, ## This handler emulates the instruction to determine what the correct ## default result should be for the operation. This default result is ## then stored in either the FP regfile, data regfile, or memory. ## Finally, the handler exits through the "callout" _fpsp_done() ## denoting that no exceptional conditions exist within the machine. ## If the exception is enabled, then this handler must create the ## exceptional operand and plave it in the fsave state frame, and store ## the default result (only if the instruction is opclass 3). For ## exceptions enabled, this handler must exit through the "callout" ## _real_ovfl() so that the operating system enabled overflow handler ## can handle this case. ## Two other conditions exist. First, if overflow was disabled ## but the inexact exception was enabled, this handler must exit ## through the "callout" _real_inex() regardless of whether the result ## was inexact. ## Also, in the case of an opclass three instruction where ## overflow was disabled and the trace exception was enabled, this ## handler must exit through the "callout" _real_trace(). ## ########################################################################## global _fpsp_ovfl_fpsp_ovfl:#$# sub.l &24,%sp # make room for src/dst link.w %a6,&-LOCAL_SIZE # init stack frame fsave FP_SRC(%a6) # grab the "busy" frame movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 fmovm.l %fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs fmovm.x &0xc0,EXC_FPREGS(%a6) # save fp0-fp1 on stack# the FPIAR holds the "current PC" of the faulting instruction mov.l USER_FPIAR(%a6),EXC_EXTWPTR(%a6) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr bsr.l _imem_read_long # fetch the instruction words mov.l %d0,EXC_OPWORD(%a6)############################################################################## btst &0x5,EXC_CMDREG(%a6) # is instr an fmove out? bne.w fovfl_out lea FP_SRC(%a6),%a0 # pass: ptr to src op bsr.l fix_skewed_ops # fix src op# since, I believe, only NORMs and DENORMs can come through here,# maybe we can avoid the subroutine call. lea FP_SRC(%a6),%a0 # pass: ptr to src op bsr.l set_tag_x # tag the operand type mov.b %d0,STAG(%a6) # maybe NORM,DENORM# bit five of the fp extension word separates the monadic and dyadic operations# that can pass through fpsp_ovfl(). remember that fcmp, ftst, and fsincos# will never take this exception. btst &0x5,1+EXC_CMDREG(%a6) # is operation monadic or dyadic? beq.b fovfl_extract # monadic bfextu EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg bsr.l load_fpn2 # load dst into FP_DST lea FP_DST(%a6),%a0 # pass: ptr to dst op bsr.l set_tag_x # tag the operand type cmpi.b %d0,&UNNORM # is operand an UNNORM? bne.b fovfl_op2_done # no bsr.l unnorm_fix # yes; convert to NORM,DENORM,or ZEROfovfl_op2_done: mov.b %d0,DTAG(%a6) # save dst optype tagfovfl_extract:#$# mov.l FP_SRC_EX(%a6),TRAP_SRCOP_EX(%a6)#$# mov.l FP_SRC_HI(%a6),TRAP_SRCOP_HI(%a6)#$# mov.l FP_SRC_LO(%a6),TRAP_SRCOP_LO(%a6)#$# mov.l FP_DST_EX(%a6),TRAP_DSTOP_EX(%a6)#$# mov.l FP_DST_HI(%a6),TRAP_DSTOP_HI(%a6)#$# mov.l FP_DST_LO(%a6),TRAP_DSTOP_LO(%a6) clr.l %d0 mov.b FPCR_MODE(%a6),%d0 # pass rnd prec/mode mov.b 1+EXC_CMDREG(%a6),%d1 andi.w &0x007f,%d1 # extract extension andi.l &0x00ff01ff,USER_FPSR(%a6) # zero all but accured field fmov.l &0x0,%fpcr # zero current control regs fmov.l &0x0,%fpsr lea FP_SRC(%a6),%a0 lea FP_DST(%a6),%a1# maybe we can make these entry points ONLY the OVFL entry points of each routine. mov.l (tbl_unsupp.l,%pc,%d1.w*4),%d1 # fetch routine addr jsr (tbl_unsupp.l,%pc,%d1.l*1)# the operation has been emulated. the result is in fp0.# the EXOP, if an exception occurred, is in fp1.# we must save the default result regardless of whether# traps are enabled or disabled. bfextu EXC_CMDREG(%a6){&6:&3},%d0 bsr.l store_fpreg# the exceptional possibilities we have left ourselves with are ONLY overflow# and inexact. and, the inexact is such that overflow occurred and was disabled# but inexact was enabled. btst &ovfl_bit,FPCR_ENABLE(%a6) bne.b fovfl_ovfl_on btst &inex2_bit,FPCR_ENABLE(%a6) bne.b fovfl_inex_on fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 unlk %a6#$# add.l &24,%sp bra.l _fpsp_done# overflow is enabled AND overflow, of course, occurred. so, we have the EXOP# in fp1. now, simply jump to _real_ovfl()!fovfl_ovfl_on: fmovm.x &0x40,FP_SRC(%a6) # save EXOP (fp1) to stack mov.w &0xe005,2+FP_SRC(%a6) # save exc status fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 frestore FP_SRC(%a6) # do this after fmovm,other f<op>s! unlk %a6 bra.l _real_ovfl# overflow occurred but is disabled. meanwhile, inexact is enabled. therefore,# we must jump to real_inex().fovfl_inex_on: fmovm.x &0x40,FP_SRC(%a6) # save EXOP (fp1) to stack mov.b &0xc4,1+EXC_VOFF(%a6) # vector offset = 0xc4 mov.w &0xe001,2+FP_SRC(%a6) # save exc status fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 frestore FP_SRC(%a6) # do this after fmovm,other f<op>s! unlk %a6 bra.l _real_inex########################################################################fovfl_out:#$# mov.l FP_SRC_EX(%a6),TRAP_SRCOP_EX(%a6)#$# mov.l FP_SRC_HI(%a6),TRAP_SRCOP_HI(%a6)#$# mov.l FP_SRC_LO(%a6),TRAP_SRCOP_LO(%a6)# the src operand is definitely a NORM(!), so tag it as such mov.b &NORM,STAG(%a6) # set src optype tag clr.l %d0 mov.b FPCR_MODE(%a6),%d0 # pass rnd prec/mode and.l &0xffff00ff,USER_FPSR(%a6) # zero all but accured field fmov.l &0x0,%fpcr # zero current control regs fmov.l &0x0,%fpsr lea FP_SRC(%a6),%a0 # pass ptr to src operand bsr.l fout btst &ovfl_bit,FPCR_ENABLE(%a6) bne.w fovfl_ovfl_on btst &inex2_bit,FPCR_ENABLE(%a6) bne.w fovfl_inex_on fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 unlk %a6#$# add.l &24,%sp btst &0x7,(%sp) # is trace on?
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -