⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pfpsp.s

📁 linux内核源码
💻 S
📖 第 1 页 / 共 5 页
字号:
# was exact, then a branch to _real_inex() is made.	btst		&ovfl_bit,FPSR_EXCEPT(%a6) # was overflow set?	beq.w		fu_out_done		# nofu_out_ovflchk:	btst		&inex2_bit,FPCR_ENABLE(%a6) # was inexact enabled?	beq.w		fu_out_done		# no	bra.w		fu_inex			# yes## The fp move out that took the "Unimplemented Data Type" exception was# being traced. Since the stack frames are similar, get the "current" PC# from FPIAR and put it in the trace stack frame then jump to _real_trace().##		  UNSUPP FRAME		   TRACE FRAME#		*****************	*****************#		*      EA	*	*    Current	*#		*		*	*      PC	*#		*****************	*****************#		* 0x3 *  0x0dc	*	* 0x2 *  0x024	*#		*****************	*****************#		*     Next	*	*     Next	*#		*      PC	*	*      PC	*#		*****************	*****************#		*      SR	*	*      SR	*#		*****************	*****************#fu_out_trace:	mov.w		&0x2024,0x6(%sp)	fmov.l		%fpiar,0x8(%sp)	bra.l		_real_trace# an exception occurred and that exception was enabled.fu_out_exc:	subi.l		&24,%d0			# fix offset to be 0-8# we don't mess with the existing fsave frame. just re-insert it and# jump to the "_real_{}()" handler...	mov.w		(tbl_fu_out.b,%pc,%d0.w*2),%d0	jmp		(tbl_fu_out.b,%pc,%d0.w*1)	swbeg		&0x8tbl_fu_out:	short		tbl_fu_out	- tbl_fu_out	# BSUN can't happen	short		tbl_fu_out	- tbl_fu_out	# SNAN can't happen	short		fu_operr	- tbl_fu_out	# OPERR	short		fu_ovfl		- tbl_fu_out	# OVFL	short		fu_unfl		- tbl_fu_out	# UNFL	short		tbl_fu_out	- tbl_fu_out	# DZ can't happen	short		fu_inex		- tbl_fu_out	# INEX2	short		tbl_fu_out	- tbl_fu_out	# INEX1 won't make it here# for snan,operr,ovfl,unfl, src op is still in FP_SRC so just# frestore it.fu_snan:	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	mov.w		&0x30d8,EXC_VOFF(%a6)	# vector offset = 0xd8	mov.w		&0xe006,2+FP_SRC(%a6)	frestore	FP_SRC(%a6)	unlk		%a6	bra.l		_real_snanfu_operr:	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	mov.w		&0x30d0,EXC_VOFF(%a6)	# vector offset = 0xd0	mov.w		&0xe004,2+FP_SRC(%a6)	frestore	FP_SRC(%a6)	unlk		%a6	bra.l		_real_operrfu_ovfl:	fmovm.x		&0x40,FP_SRC(%a6)	# save EXOP to the stack	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	mov.w		&0x30d4,EXC_VOFF(%a6)	# vector offset = 0xd4	mov.w		&0xe005,2+FP_SRC(%a6)	frestore	FP_SRC(%a6)		# restore EXOP	unlk		%a6	bra.l		_real_ovfl# underflow can happen for extended precision. extended precision opclass# three instruction exceptions don't update the stack pointer. so, if the# exception occurred from user mode, then simply update a7 and exit normally.# if the exception occurred from supervisor mode, check iffu_unfl:	mov.l		EXC_A6(%a6),(%a6)	# restore a6	btst		&0x5,EXC_SR(%a6)	bne.w		fu_unfl_s	mov.l		EXC_A7(%a6),%a0		# restore a7 whether we need	mov.l		%a0,%usp		# to or not...fu_unfl_cont:	fmovm.x		&0x40,FP_SRC(%a6)	# save EXOP to the stack	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	mov.w		&0x30cc,EXC_VOFF(%a6)	# vector offset = 0xcc	mov.w		&0xe003,2+FP_SRC(%a6)	frestore	FP_SRC(%a6)		# restore EXOP	unlk		%a6	bra.l		_real_unflfu_unfl_s:	cmpi.b		SPCOND_FLG(%a6),&mda7_flg # was the <ea> mode -(sp)?	bne.b		fu_unfl_cont# the extended precision result is still in fp0. but, we need to save it# somewhere on the stack until we can copy it to its final resting place# (where the exc frame is currently). make sure it's not at the top of the# frame or it will get overwritten when the exc stack frame is shifted "down".	fmovm.x		&0x80,FP_SRC(%a6)	# put answer on stack	fmovm.x		&0x40,FP_DST(%a6)	# put EXOP on stack	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	mov.w		&0x30cc,EXC_VOFF(%a6)	# vector offset = 0xcc	mov.w		&0xe003,2+FP_DST(%a6)	frestore	FP_DST(%a6)		# restore EXOP	mov.l		(%a6),%a6		# restore frame pointer	mov.l		LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp)	mov.l		LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)	mov.l		LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp)# now, copy the result to the proper place on the stack	mov.l		LOCAL_SIZE+FP_SRC_EX(%sp),LOCAL_SIZE+EXC_SR+0x0(%sp)	mov.l		LOCAL_SIZE+FP_SRC_HI(%sp),LOCAL_SIZE+EXC_SR+0x4(%sp)	mov.l		LOCAL_SIZE+FP_SRC_LO(%sp),LOCAL_SIZE+EXC_SR+0x8(%sp)	add.l		&LOCAL_SIZE-0x8,%sp	bra.l		_real_unfl# fmove in and out enter here.fu_inex:	fmovm.x		&0x40,FP_SRC(%a6)	# save EXOP to the stack	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	mov.w		&0x30c4,EXC_VOFF(%a6)	# vector offset = 0xc4	mov.w		&0xe001,2+FP_SRC(%a6)	frestore	FP_SRC(%a6)		# restore EXOP	unlk		%a6	bra.l		_real_inex##################################################################################################################################################fu_in_pack:# I'm not sure at this point what FPSR bits are valid for this instruction.# so, since the emulation routines re-create them anyways, zero exception field	andi.l		&0x0ff00ff,USER_FPSR(%a6) # zero exception field	fmov.l		&0x0,%fpcr		# zero current control regs	fmov.l		&0x0,%fpsr	bsr.l		get_packed		# fetch packed src operand	lea		FP_SRC(%a6),%a0		# pass ptr to src	bsr.l		set_tag_x		# set src optype tag	mov.b		%d0,STAG(%a6)		# save src optype tag	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg# bit five of the fp extension word separates the monadic and dyadic operations# at this point	btst		&0x5,1+EXC_CMDREG(%a6)	# is operation monadic or dyadic?	beq.b		fu_extract_p		# monadic	cmpi.b		1+EXC_CMDREG(%a6),&0x3a	# is operation an ftst?	beq.b		fu_extract_p		# yes, so it's monadic, too	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		fu_op2_done_p		# no	bsr.l		unnorm_fix		# yes; convert to NORM,DENORM,or ZEROfu_op2_done_p:	mov.b		%d0,DTAG(%a6)		# save dst optype tagfu_extract_p:	clr.l		%d0	mov.b		FPCR_MODE(%a6),%d0	# fetch rnd mode/prec	bfextu		1+EXC_CMDREG(%a6){&1:&7},%d1 # extract extension	lea		FP_SRC(%a6),%a0	lea		FP_DST(%a6),%a1	mov.l		(tbl_unsupp.l,%pc,%d1.l*4),%d1 # fetch routine addr	jsr		(tbl_unsupp.l,%pc,%d1.l*1)## Exceptions in order of precedence:#	BSUN	: none#	SNAN	: all dyadic ops#	OPERR	: fsqrt(-NORM)#	OVFL	: all except ftst,fcmp#	UNFL	: all except ftst,fcmp#	DZ	: fdiv#	INEX2	: all except ftst,fcmp#	INEX1	: all## we determine the highest priority exception(if any) set by the# emulation routine that has also been enabled by the user.	mov.b		FPCR_ENABLE(%a6),%d0	# fetch exceptions enabled	bne.w		fu_in_ena_p		# some are enabledfu_in_cont_p:# fcmp and ftst do not store any result.	mov.b		1+EXC_CMDREG(%a6),%d0	# fetch extension	andi.b		&0x38,%d0		# extract bits 3-5	cmpi.b		%d0,&0x38		# is instr fcmp or ftst?	beq.b		fu_in_exit_p		# yes	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg	bsr.l		store_fpreg		# store the resultfu_in_exit_p:	btst		&0x5,EXC_SR(%a6)	# user or supervisor?	bne.w		fu_in_exit_s_p		# supervisor	mov.l		EXC_A7(%a6),%a0		# update user a7	mov.l		%a0,%uspfu_in_exit_cont_p:	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			# unravel stack frame	btst		&0x7,(%sp)		# is trace on?	bne.w		fu_trace_p		# yes	bra.l		_fpsp_done		# exit to os# the exception occurred in supervisor mode. check to see if the# addressing mode was (a7)+. if so, we'll need to shift the# stack frame "up".fu_in_exit_s_p:	btst		&mia7_bit,SPCOND_FLG(%a6) # was ea mode (a7)+	beq.b		fu_in_exit_cont_p	# no	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			# unravel stack frame# shift the stack frame "up". we don't really care about the <ea> field.	mov.l		0x4(%sp),0x10(%sp)	mov.l		0x0(%sp),0xc(%sp)	add.l		&0xc,%sp	btst		&0x7,(%sp)		# is trace on?	bne.w		fu_trace_p		# yes	bra.l		_fpsp_done		# exit to osfu_in_ena_p:	and.b		FPSR_EXCEPT(%a6),%d0	# keep only ones enabled & set	bfffo		%d0{&24:&8},%d0		# find highest priority exception	bne.b		fu_in_exc_p		# at least one was set## No exceptions occurred that were also enabled. Now:##	if (OVFL && ovfl_disabled && inexact_enabled) {#	    branch to _real_inex() (even if the result was exact!);#	} else {#	    save the result in the proper fp reg (unless the op is fcmp or ftst);#	    return;#	}#	btst		&ovfl_bit,FPSR_EXCEPT(%a6) # was overflow set?	beq.w		fu_in_cont_p		# nofu_in_ovflchk_p:	btst		&inex2_bit,FPCR_ENABLE(%a6) # was inexact enabled?	beq.w		fu_in_cont_p		# no	bra.w		fu_in_exc_ovfl_p	# do _real_inex() now## An exception occurred and that exception was enabled:##	shift enabled exception field into lo byte of d0;#	if (((INEX2 || INEX1) && inex_enabled && OVFL && ovfl_disabled) ||#	    ((INEX2 || INEX1) && inex_enabled && UNFL && unfl_disabled)) {#		/*#		 * this is the case where we must call _real_inex() now or else#		 * there will be no other way to pass it the exceptional operand#		 */#		call _real_inex();#	} else {#		restore exc state (SNAN||OPERR||OVFL||UNFL||DZ||INEX) into the FPU;#	}#fu_in_exc_p:	subi.l		&24,%d0			# fix offset to be 0-8	cmpi.b		%d0,&0x6		# is exception INEX? (6 or 7)	blt.b		fu_in_exc_exit_p	# no# the enabled exception was inexact	btst		&unfl_bit,FPSR_EXCEPT(%a6) # did disabled underflow occur?	bne.w		fu_in_exc_unfl_p	# yes	btst		&ovfl_bit,FPSR_EXCEPT(%a6) # did disabled overflow occur?	bne.w		fu_in_exc_ovfl_p	# yes# here, we insert the correct fsave status value into the fsave frame for the# corresponding exception. the operand in the fsave frame should be the original# src operand.# as a reminder for future predicted pain and agony, we are passing in fsave the# "non-skewed" operand for cases of sgl and dbl src INFs,NANs, and DENORMs.# this is INCORRECT for enabled SNAN which would give to the user the skewed SNAN!!!fu_in_exc_exit_p:	btst		&0x5,EXC_SR(%a6)	# user or supervisor?	bne.w		fu_in_exc_exit_s_p	# supervisor	mov.l		EXC_A7(%a6),%a0		# update user a7	mov.l		%a0,%uspfu_in_exc_exit_cont_p:	mov.w		(tbl_except_p.b,%pc,%d0.w*2),2+FP_SRC(%a6)	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)		# restore src op	unlk		%a6	btst		&0x7,(%sp)		# is trace enabled?	bne.w		fu_trace_p		# yes	bra.l		_fpsp_donetbl_except_p:	short		0xe000,0xe006,0xe004,0xe005	short		0xe003,0xe002,0xe001,0xe001fu_in_exc_ovfl_p:	mov.w		&0x3,%d0	bra.w		fu_in_exc_exit_pfu_in_exc_unfl_p:	mov.w		&0x4,%d0	bra.w		fu_in_exc_exit_pfu_in_exc_exit_s_p:	btst		&mia7_bit,SPCOND_FLG(%a6)	beq.b		fu_in_exc_exit_cont_p	mov.w		(tbl_except_p.b,%pc,%d0.w*2),2+FP_SRC(%a6)	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)	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -