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

📄 pfpsp.s

📁 linux内核源码
💻 S
📖 第 1 页 / 共 5 页
字号:
	mov.l		%usp,%a0		# fetch user stack pointer	mov.l		%a0,EXC_A7(%a6)		# save on stack	bra.b		fu_cont# if the exception is an opclass zero or two unimplemented data type# exception, then the a7' calculated here is wrong since it doesn't# stack an ea. however, we don't need an a7' for this case anyways.fu_s:	lea		0x4+EXC_EA(%a6),%a0	# load old a7'	mov.l		%a0,EXC_A7(%a6)		# save on stackfu_cont:# the FPIAR holds the "current PC" of the faulting instruction# the FPIAR should be set correctly for ALL exceptions passing through# this point.	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)	# store OPWORD and EXTWORD############################	clr.b		SPCOND_FLG(%a6)		# clear special condition flag# Separate opclass three (fpn-to-mem) ops since they have a different# stack frame and protocol.	btst		&0x5,EXC_CMDREG(%a6)	# is it an fmove out?	bne.w		fu_out			# yes# Separate packed opclass two instructions.	bfextu		EXC_CMDREG(%a6){&0:&6},%d0	cmpi.b		%d0,&0x13	beq.w		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		&0x00ff00ff,USER_FPSR(%a6) # zero exception field	fmov.l		&0x0,%fpcr		# zero current control regs	fmov.l		&0x0,%fpsr# Opclass two w/ memory-to-fpn operation will have an incorrect extended# precision format if the src format was single or double and the# source data type was an INF, NAN, DENORM, or UNNORM	lea		FP_SRC(%a6),%a0		# pass ptr to input	bsr.l		fix_skewed_ops# we don't know whether the src operand or the dst operand (or both) is the# UNNORM or DENORM. call the function that tags the operand type. if the# input is an UNNORM, then convert it to a NORM, DENORM, or ZERO.	lea		FP_SRC(%a6),%a0		# pass: ptr to src op	bsr.l		set_tag_x		# tag the operand type	cmpi.b		%d0,&UNNORM		# is operand an UNNORM?	bne.b		fu_op2			# no	bsr.l		unnorm_fix		# yes; convert to NORM,DENORM,or ZEROfu_op2:	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		# monadic	cmpi.b		1+EXC_CMDREG(%a6),&0x3a	# is operation an ftst?	beq.b		fu_extract		# 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		# no	bsr.l		unnorm_fix		# yes; convert to NORM,DENORM,or ZEROfu_op2_done:	mov.b		%d0,DTAG(%a6)		# save dst optype tagfu_extract:	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	: none (packed doesn't go through here)## 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 set	bne.b		fu_in_ena		# some are enabledfu_in_cont:# 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		# yes	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg	bsr.l		store_fpreg		# store the resultfu_in_exit:	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	bra.l		_fpsp_donefu_in_ena:	and.b		FPSR_EXCEPT(%a6),%d0	# keep only ones enabled	bfffo		%d0{&24:&8},%d0		# find highest priority exception	bne.b		fu_in_exc		# there is at least one 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.b		fu_in_cont		# nofu_in_ovflchk:	btst		&inex2_bit,FPCR_ENABLE(%a6) # was inexact enabled?	beq.b		fu_in_cont		# no	bra.w		fu_in_exc_ovfl		# go insert overflow frame## 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:	subi.l		&24,%d0			# fix offset to be 0-8	cmpi.b		%d0,&0x6		# is exception INEX? (6)	bne.b		fu_in_exc_exit		# no# the enabled exception was inexact	btst		&unfl_bit,FPSR_EXCEPT(%a6) # did disabled underflow occur?	bne.w		fu_in_exc_unfl		# yes	btst		&ovfl_bit,FPSR_EXCEPT(%a6) # did disabled overflow occur?	bne.w		fu_in_exc_ovfl		# 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.fu_in_exc_exit:	mov.l		%d0,-(%sp)		# save d0	bsr.l		funimp_skew		# skew sgl or dbl inputs	mov.l		(%sp)+,%d0		# restore d0	mov.w		(tbl_except.b,%pc,%d0.w*2),2+FP_SRC(%a6) # create 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)		# restore src op	unlk		%a6	bra.l		_fpsp_donetbl_except:	short		0xe000,0xe006,0xe004,0xe005	short		0xe003,0xe002,0xe001,0xe001fu_in_exc_unfl:	mov.w		&0x4,%d0	bra.b		fu_in_exc_exitfu_in_exc_ovfl:	mov.w		&0x03,%d0	bra.b		fu_in_exc_exit# If the input operand to this operation was opclass two and a single# or double precision denorm, inf, or nan, the operand needs to be# "corrected" in order to have the proper equivalent extended precision# number.	global		fix_skewed_opsfix_skewed_ops:	bfextu		EXC_CMDREG(%a6){&0:&6},%d0 # extract opclass,src fmt	cmpi.b		%d0,&0x11		# is class = 2 & fmt = sgl?	beq.b		fso_sgl			# yes	cmpi.b		%d0,&0x15		# is class = 2 & fmt = dbl?	beq.b		fso_dbl			# yes	rts					# nofso_sgl:	mov.w		LOCAL_EX(%a0),%d0	# fetch src exponent	andi.w		&0x7fff,%d0		# strip sign	cmpi.w		%d0,&0x3f80		# is |exp| == $3f80?	beq.b		fso_sgl_dnrm_zero	# yes	cmpi.w		%d0,&0x407f		# no; is |exp| == $407f?	beq.b		fso_infnan		# yes	rts					# nofso_sgl_dnrm_zero:	andi.l		&0x7fffffff,LOCAL_HI(%a0) # clear j-bit	beq.b		fso_zero		# it's a skewed zerofso_sgl_dnrm:# here, we count on norm not to alter a0...	bsr.l		norm			# normalize mantissa	neg.w		%d0			# -shft amt	addi.w		&0x3f81,%d0		# adjust new exponent	andi.w		&0x8000,LOCAL_EX(%a0)	# clear old exponent	or.w		%d0,LOCAL_EX(%a0)	# insert new exponent	rtsfso_zero:	andi.w		&0x8000,LOCAL_EX(%a0)	# clear bogus exponent	rtsfso_infnan:	andi.b		&0x7f,LOCAL_HI(%a0)	# clear j-bit	ori.w		&0x7fff,LOCAL_EX(%a0)	# make exponent = $7fff	rtsfso_dbl:	mov.w		LOCAL_EX(%a0),%d0	# fetch src exponent	andi.w		&0x7fff,%d0		# strip sign	cmpi.w		%d0,&0x3c00		# is |exp| == $3c00?	beq.b		fso_dbl_dnrm_zero	# yes	cmpi.w		%d0,&0x43ff		# no; is |exp| == $43ff?	beq.b		fso_infnan		# yes	rts					# nofso_dbl_dnrm_zero:	andi.l		&0x7fffffff,LOCAL_HI(%a0) # clear j-bit	bne.b		fso_dbl_dnrm		# it's a skewed denorm	tst.l		LOCAL_LO(%a0)		# is it a zero?	beq.b		fso_zero		# yesfso_dbl_dnrm:# here, we count on norm not to alter a0...	bsr.l		norm			# normalize mantissa	neg.w		%d0			# -shft amt	addi.w		&0x3c01,%d0		# adjust new exponent	andi.w		&0x8000,LOCAL_EX(%a0)	# clear old exponent	or.w		%d0,LOCAL_EX(%a0)	# insert new exponent	rts################################################################## fmove out took an unimplemented data type exception.# the src operand is in FP_SRC. Call _fout() to write out the result and# to determine which exceptions, if any, to take.fu_out:# Separate packed move outs from the UNNORM and DENORM move outs.	bfextu		EXC_CMDREG(%a6){&3:&3},%d0	cmpi.b		%d0,&0x3	beq.w		fu_out_pack	cmpi.b		%d0,&0x7	beq.w		fu_out_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.# fmove out doesn't affect ccodes.	and.l		&0xffff00ff,USER_FPSR(%a6) # zero exception field	fmov.l		&0x0,%fpcr		# zero current control regs	fmov.l		&0x0,%fpsr# the src can ONLY be a DENORM or an UNNORM! so, don't make any big subroutine# call here. just figure out what it is...	mov.w		FP_SRC_EX(%a6),%d0	# get exponent	andi.w		&0x7fff,%d0		# strip sign	beq.b		fu_out_denorm		# it's a DENORM	lea		FP_SRC(%a6),%a0	bsr.l		unnorm_fix		# yes; fix it	mov.b		%d0,STAG(%a6)	bra.b		fu_out_contfu_out_denorm:	mov.b		&DENORM,STAG(%a6)fu_out_cont:	clr.l		%d0	mov.b		FPCR_MODE(%a6),%d0	# fetch rnd mode/prec	lea		FP_SRC(%a6),%a0		# pass ptr to src operand	mov.l		(%a6),EXC_A6(%a6)	# in case a6 changes	bsr.l		fout			# call fmove out routine# Exceptions in order of precedence:#	BSUN	: none#	SNAN	: none#	OPERR	: fmove.{b,w,l} out of large UNNORM#	OVFL	: fmove.{s,d}#	UNFL	: fmove.{s,d,x}#	DZ	: none#	INEX2	: all#	INEX1	: none (packed doesn't travel through here)# 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_out_ena		# some are enabledfu_out_done:	mov.l		EXC_A6(%a6),(%a6)	# in case a6 changed# on extended precision opclass three instructions using pre-decrement or# post-increment addressing mode, the address register is not updated. is the# address register was the stack pointer used from user mode, then let's update# it here. if it was used from supervisor mode, then we have to handle this# as a special case.	btst		&0x5,EXC_SR(%a6)	bne.b		fu_out_done_s	mov.l		EXC_A7(%a6),%a0		# restore a7	mov.l		%a0,%uspfu_out_done_cont:	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	btst		&0x7,(%sp)		# is trace on?	bne.b		fu_out_trace		# yes	bra.l		_fpsp_done# is the ea mode pre-decrement of the stack pointer from supervisor mode?# ("fmov.x fpm,-(a7)") if so,fu_out_done_s:	cmpi.b		SPCOND_FLG(%a6),&mda7_flg	bne.b		fu_out_done_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.# here, we're counting on the top of the stack to be the old place-holders# for fp0/fp1 which have already been restored. that way, we can write# over those destinations with the shifted stack frame.	fmovm.x		&0x80,FP_SRC(%a6)	# put answer 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.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)# 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	btst		&0x7,(%sp)	bne.b		fu_out_trace	bra.l		_fpsp_donefu_out_ena:	and.b		FPSR_EXCEPT(%a6),%d0	# keep only ones enabled	bfffo		%d0{&24:&8},%d0		# find highest priority exception	bne.b		fu_out_exc		# there is at least one set# no exceptions were set.# if a disabled overflow occurred and inexact was enabled but the result

⌨️ 快捷键说明

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