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

📄 kernel_ex.s

📁 ARM 嵌入式 系统 设计与实例开发 实验教材 二源码
💻 S
字号:
||	kernel_ex.sa 3.3 12/19/90 || This file contains routines to force exception status in the | fpu for exceptional cases detected or reported within the| transcendental functions.  Typically, the t_xx routine will| set the appropriate bits in the USER_FPSR word on the stack.| The bits are tested in gen_except.sa to determine if an exceptional| situation needs to be created on return from the FPSP. ||		Copyright (C) Motorola, Inc. 1990|			All Rights Reserved||	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA |	The copyright notice above does not evidence any  |	actual or intended publication of such source code.KERNEL_EX:    |idnt    2,1 | Motorola 040 Floating Point Software Package	|section    8	.include "fpsp.h"mns_inf:  .long 0xffff0000,0x00000000,0x00000000pls_inf:  .long 0x7fff0000,0x00000000,0x00000000nan:      .long 0x7fff0000,0xffffffff,0xffffffffhuge:     .long 0x7ffe0000,0xffffffff,0xffffffff	|xref	  ovf_r_k	|xref	  unf_sub	|xref	  nrm_set	.global   	  t_dz	.global      t_dz2	.global      t_operr	.global      t_unfl	.global      t_ovfl	.global      t_ovfl2	.global      t_inx2	.global	  t_frcinx	.global	  t_extdnrm	.global	  t_resdnrm	.global	  dst_nan	.global	  src_nan||	DZ exception|||	if dz trap disabled|		store properly signed inf (use sign of etemp) into fp0|		set FPSR exception status dz bit, condition code |		inf bit, and accrued dz bit|		return|		frestore the frame into the machine (done by unimp_hd)||	else dz trap enabled|		set exception status bit & accrued bits in FPSR|		set flag to disable sto_res from corrupting fp register|		return|		frestore the frame into the machine (done by unimp_hd)|| t_dz2 is used by monadic functions such as flogn (from do_func).| t_dz is used by monadic functions such as satanh (from the | transcendental function).|t_dz2:	bsetb	#neg_bit,FPSR_CC(%a6)	|set neg bit in FPSR	fmovel	#0,%FPSR			|clr status bits (Z set)	btstb	#dz_bit,FPCR_ENABLE(%a6)	|test FPCR for dz exc enabled	bnes	dz_ena_end	bras	m_inf			|flogx always returns -inft_dz:	fmovel	#0,%FPSR			|clr status bits (Z set)	btstb	#dz_bit,FPCR_ENABLE(%a6)	|test FPCR for dz exc enabled	bnes	dz_ena||	dz disabled|	btstb	#sign_bit,ETEMP_EX(%a6)	|check sign for neg or pos	beqs	p_inf			|branch if pos signm_inf:	fmovemx mns_inf,%fp0-%fp0		|load -inf	bsetb	#neg_bit,FPSR_CC(%a6)	|set neg bit in FPSR	bras	set_fpsrp_inf:	fmovemx pls_inf,%fp0-%fp0		|load +infset_fpsr:	orl	#dzinf_mask,USER_FPSR(%a6) |set I,DZ,ADZ	rts||	dz enabled|dz_ena:	btstb	#sign_bit,ETEMP_EX(%a6)	|check sign for neg or pos	beqs	dz_ena_end	bsetb	#neg_bit,FPSR_CC(%a6)	|set neg bit in FPSRdz_ena_end:	orl	#dzinf_mask,USER_FPSR(%a6) |set I,DZ,ADZ	st	STORE_FLG(%a6)	rts||	OPERR exception||	if (operr trap disabled)|		set FPSR exception status operr bit, condition code |		nan bit; Store default NAN into fp0|		frestore the frame into the machine (done by unimp_hd)|	|	else (operr trap enabled)|		set FPSR exception status operr bit, accrued operr bit|		set flag to disable sto_res from corrupting fp register|		frestore the frame into the machine (done by unimp_hd)|t_operr:	orl	#opnan_mask,USER_FPSR(%a6) |set NaN, OPERR, AIOP	btstb	#operr_bit,FPCR_ENABLE(%a6) |test FPCR for operr enabled	bnes	op_ena	fmovemx nan,%fp0-%fp0		|load default nan	rtsop_ena:	st	STORE_FLG(%a6)		|do not corrupt destination	rts||	t_unfl --- UNFL exception|| This entry point is used by all routines requiring unfl, inex2,| aunfl, and ainex to be set on exit.|| On entry, a0 points to the exceptional operand.  The final exceptional| operand is built in FP_SCR1 and only the sign from the original operand| is used.|t_unfl:	clrl	FP_SCR1(%a6)		|set exceptional operand to zero	clrl	FP_SCR1+4(%a6)	clrl	FP_SCR1+8(%a6)	tstb	(%a0)			|extract sign from caller's exop	bpls	unfl_signok	bset	#sign_bit,FP_SCR1(%a6)unfl_signok:	leal	FP_SCR1(%a6),%a0	orl	#unfinx_mask,USER_FPSR(%a6)|					;set UNFL, INEX2, AUNFL, AINEXunfl_con:	btstb	#unfl_bit,FPCR_ENABLE(%a6)	beqs	unfl_disunfl_ena:	bfclr	STAG(%a6){#5:#3}		|clear wbtm66,wbtm1,wbtm0	bsetb	#wbtemp15_bit,WB_BYTE(%a6) |set wbtemp15	bsetb	#sticky_bit,STICKY(%a6)	|set sticky bit	bclrb	#E1,E_BYTE(%a6)unfl_dis:	bfextu	FPCR_MODE(%a6){#0:#2},%d0	|get round precision		bclrb	#sign_bit,LOCAL_EX(%a0)	sne	LOCAL_SGN(%a0)		|convert to internal ext format	bsr	unf_sub			|returns IEEE result at a0|					;and sets FPSR_CC accordingly		bfclr	LOCAL_SGN(%a0){#0:#8}	|convert back to IEEE ext format	beqs	unfl_fin	bsetb	#sign_bit,LOCAL_EX(%a0)	bsetb	#sign_bit,FP_SCR1(%a6)	|set sign bit of exc operandunfl_fin:	fmovemx (%a0),%fp0-%fp0		|store result in fp0	rts	||	t_ovfl2 --- OVFL exception (without inex2 returned)|| This entry is used by scale to force catastrophic overflow.  The| ovfl, aovfl, and ainex bits are set, but not the inex2 bit.|t_ovfl2:	orl	#ovfl_inx_mask,USER_FPSR(%a6)	movel	ETEMP(%a6),FP_SCR1(%a6)	movel	ETEMP_HI(%a6),FP_SCR1+4(%a6)	movel	ETEMP_LO(%a6),FP_SCR1+8(%a6)|| Check for single or double round precision.  If single, check if| the lower 40 bits of ETEMP are zero; if not, set inex2.  If double,| check if the lower 21 bits are zero; if not, set inex2.|	moveb	FPCR_MODE(%a6),%d0	andib	#0xc0,%d0	beq	t_work		|if extended, finish ovfl processing	cmpib	#0x40,%d0		|test for single	bnes	t_dblt_sgl:	tstb	ETEMP_LO(%a6)	bnes	t_setinx2	movel	ETEMP_HI(%a6),%d0	andil	#0xff,%d0		|look at only lower 8 bits	bnes	t_setinx2	bra	t_workt_dbl:	movel	ETEMP_LO(%a6),%d0	andil	#0x7ff,%d0	|look at only lower 11 bits	beq	t_workt_setinx2:	orl	#inex2_mask,USER_FPSR(%a6)	bras	t_work||	t_ovfl --- OVFL exception||** Note: the exc operand is returned in ETEMP.|t_ovfl:	orl	#ovfinx_mask,USER_FPSR(%a6)t_work:	btstb	#ovfl_bit,FPCR_ENABLE(%a6) |test FPCR for ovfl enabled	beqs	ovf_disovf_ena:	clrl	FP_SCR1(%a6)		|set exceptional operand	clrl	FP_SCR1+4(%a6)	clrl	FP_SCR1+8(%a6)	bfclr	STAG(%a6){#5:#3}		|clear wbtm66,wbtm1,wbtm0	bclrb	#wbtemp15_bit,WB_BYTE(%a6) |clear wbtemp15	bsetb	#sticky_bit,STICKY(%a6)	|set sticky bit	bclrb	#E1,E_BYTE(%a6)|					;fall through to disabled case| For disabled overflow call 'ovf_r_k'.  This routine loads the| correct result based on the rounding precision, destination| format, rounding mode and sign.|ovf_dis:	bsr	ovf_r_k			|returns unsigned ETEMP_EX|					;and sets FPSR_CC accordingly.	bfclr	ETEMP_SGN(%a6){#0:#8}	|fix sign	beqs	ovf_pos	bsetb	#sign_bit,ETEMP_EX(%a6)	bsetb	#sign_bit,FP_SCR1(%a6)	|set exceptional operand signovf_pos:	fmovemx ETEMP(%a6),%fp0-%fp0		|move the result to fp0	rts||	INEX2 exception|| The inex2 and ainex bits are set.|t_inx2:	orl	#inx2a_mask,USER_FPSR(%a6) |set INEX2, AINEX	rts||	Force Inex2|| This routine is called by the transcendental routines to force| the inex2 exception bits set in the FPSR.  If the underflow bit| is set, but the underflow trap was not taken, the aunfl bit in| the FPSR must be set.|t_frcinx:	orl	#inx2a_mask,USER_FPSR(%a6) |set INEX2, AINEX	btstb	#unfl_bit,FPSR_EXCEPT(%a6) |test for unfl bit set	beqs	no_uacc1		|if clear, do not set aunfl	bsetb	#aunfl_bit,FPSR_AEXCEPT(%a6)no_uacc1:	rts||	DST_NAN|| Determine if the destination nan is signalling or non-signalling,| and set the FPSR bits accordingly.  See the MC68040 User's Manual | section 3.2.2.5 NOT-A-NUMBERS.|dst_nan:	btstb	#sign_bit,FPTEMP_EX(%a6) |test sign of nan	beqs	dst_pos			|if clr, it was positive	bsetb	#neg_bit,FPSR_CC(%a6)	|set N bitdst_pos:	btstb	#signan_bit,FPTEMP_HI(%a6) |check if signalling 	beqs	dst_snan		|branch if signalling	fmovel	%d1,%fpcr			|restore user's rmode/prec	fmovex FPTEMP(%a6),%fp0		|return the non-signalling nan|| Check the source nan.  If it is signalling, snan will be reported.|	moveb	STAG(%a6),%d0	andib	#0xe0,%d0	cmpib	#0x60,%d0	bnes	no_snan	btstb	#signan_bit,ETEMP_HI(%a6) |check if signalling 	bnes	no_snan	orl	#snaniop_mask,USER_FPSR(%a6) |set NAN, SNAN, AIOPno_snan:	rts	dst_snan:	btstb	#snan_bit,FPCR_ENABLE(%a6) |check if trap enabled 	beqs	dst_dis			|branch if disabled	orb	#nan_tag,DTAG(%a6)	|set up dtag for nan	st	STORE_FLG(%a6)		|do not store a result	orl	#snaniop_mask,USER_FPSR(%a6) |set NAN, SNAN, AIOP	rtsdst_dis:	bsetb	#signan_bit,FPTEMP_HI(%a6) |set SNAN bit in sop 	fmovel	%d1,%fpcr			|restore user's rmode/prec	fmovex FPTEMP(%a6),%fp0		|load non-sign. nan 	orl	#snaniop_mask,USER_FPSR(%a6) |set NAN, SNAN, AIOP	rts||	SRC_NAN|| Determine if the source nan is signalling or non-signalling,| and set the FPSR bits accordingly.  See the MC68040 User's Manual | section 3.2.2.5 NOT-A-NUMBERS.|src_nan:	btstb	#sign_bit,ETEMP_EX(%a6) |test sign of nan	beqs	src_pos			|if clr, it was positive	bsetb	#neg_bit,FPSR_CC(%a6)	|set N bitsrc_pos:	btstb	#signan_bit,ETEMP_HI(%a6) |check if signalling 	beqs	src_snan		|branch if signalling	fmovel	%d1,%fpcr			|restore user's rmode/prec	fmovex ETEMP(%a6),%fp0		|return the non-signalling nan	rts	src_snan:	btstb	#snan_bit,FPCR_ENABLE(%a6) |check if trap enabled 	beqs	src_dis			|branch if disabled	bsetb	#signan_bit,ETEMP_HI(%a6) |set SNAN bit in sop 	orb	#norm_tag,DTAG(%a6)	|set up dtag for norm	orb	#nan_tag,STAG(%a6)	|set up stag for nan	st	STORE_FLG(%a6)		|do not store a result	orl	#snaniop_mask,USER_FPSR(%a6) |set NAN, SNAN, AIOP	rtssrc_dis:	bsetb	#signan_bit,ETEMP_HI(%a6) |set SNAN bit in sop 	fmovel	%d1,%fpcr			|restore user's rmode/prec	fmovex ETEMP(%a6),%fp0		|load non-sign. nan 	orl	#snaniop_mask,USER_FPSR(%a6) |set NAN, SNAN, AIOP	rts|| For all functions that have a denormalized input and that f(x)=x,| this is the entry point|t_extdnrm:	orl	#unfinx_mask,USER_FPSR(%a6)|					;set UNFL, INEX2, AUNFL, AINEX	bras	xdnrm_con|| Entry point for scale with extended denorm.  The function does| not set inex2, aunfl, or ainex.  |t_resdnrm:	orl	#unfl_mask,USER_FPSR(%a6)xdnrm_con:	btstb	#unfl_bit,FPCR_ENABLE(%a6)	beqs	xdnrm_dis|| If exceptions are enabled, the additional task of setting up WBTEMP| is needed so that when the underflow exception handler is entered,| the user perceives no difference between what the 040 provides vs.| what the FPSP provides.|xdnrm_ena:	movel	%a0,-(%a7)	movel	LOCAL_EX(%a0),FP_SCR1(%a6)	movel	LOCAL_HI(%a0),FP_SCR1+4(%a6)	movel	LOCAL_LO(%a0),FP_SCR1+8(%a6)	lea	FP_SCR1(%a6),%a0	bclrb	#sign_bit,LOCAL_EX(%a0)	sne	LOCAL_SGN(%a0)		|convert to internal ext format	tstw	LOCAL_EX(%a0)		|check if input is denorm	beqs	xdnrm_dn		|if so, skip nrm_set	bsr	nrm_set			|normalize the result (exponent|					;will be negativexdnrm_dn:	bclrb	#sign_bit,LOCAL_EX(%a0)	|take off false sign	bfclr	LOCAL_SGN(%a0){#0:#8}	|change back to IEEE ext format	beqs	xdep	bsetb	#sign_bit,LOCAL_EX(%a0)xdep:		bfclr	STAG(%a6){#5:#3}		|clear wbtm66,wbtm1,wbtm0	bsetb	#wbtemp15_bit,WB_BYTE(%a6) |set wbtemp15	bclrb	#sticky_bit,STICKY(%a6)	|clear sticky bit	bclrb	#E1,E_BYTE(%a6)	movel	(%a7)+,%a0xdnrm_dis:	bfextu	FPCR_MODE(%a6){#0:#2},%d0	|get round precision	bnes	not_ext			|if not round extended, store|					;IEEE defaultsis_ext:	btstb	#sign_bit,LOCAL_EX(%a0)	beqs	xdnrm_store	bsetb	#neg_bit,FPSR_CC(%a6)	|set N bit in FPSR_CC	bras	xdnrm_storenot_ext:	bclrb	#sign_bit,LOCAL_EX(%a0)	sne	LOCAL_SGN(%a0)		|convert to internal ext format	bsr	unf_sub			|returns IEEE result pointed by|					;a0; sets FPSR_CC accordingly	bfclr	LOCAL_SGN(%a0){#0:#8}	|convert back to IEEE ext format	beqs	xdnrm_store	bsetb	#sign_bit,LOCAL_EX(%a0)xdnrm_store:	fmovemx (%a0),%fp0-%fp0		|store result in fp0	rts|| This subroutine is used for dyadic operations that use an extended| denorm within the kernel. The approach used is to capture the frame,| fix/restore.|	.global	t_avoid_unsuppt_avoid_unsupp:	link	%a2,#-LOCAL_SIZE		|so that a2 fpsp.h negative |					;offsets may be used	fsave	-(%a7)	tstb	1(%a7)			|check if idle, exit if so	beq	idle_end	btstb	#E1,E_BYTE(%a2)		|check for an E1 exception if|					;enabled, there is an unsupp	beq	end_avun		|else, exit	btstb	#7,DTAG(%a2)		|check for denorm destination	beqs	src_den			|else, must be a source denorm|| handle destination denorm|	lea	FPTEMP(%a2),%a0	btstb	#sign_bit,LOCAL_EX(%a0)	sne	LOCAL_SGN(%a0)		|convert to internal ext format	bclrb	#7,DTAG(%a2)		|set DTAG to norm	bsr	nrm_set			|normalize result, exponent|					;will become negative	bclrb	#sign_bit,LOCAL_EX(%a0)	|get rid of fake sign	bfclr	LOCAL_SGN(%a0){#0:#8}	|convert back to IEEE ext format	beqs	ck_src_den		|check if source is also denorm	bsetb	#sign_bit,LOCAL_EX(%a0)ck_src_den:	btstb	#7,STAG(%a2)	beqs	end_avunsrc_den:	lea	ETEMP(%a2),%a0	btstb	#sign_bit,LOCAL_EX(%a0)	sne	LOCAL_SGN(%a0)		|convert to internal ext format	bclrb	#7,STAG(%a2)		|set STAG to norm	bsr	nrm_set			|normalize result, exponent|					;will become negative	bclrb	#sign_bit,LOCAL_EX(%a0)	|get rid of fake sign	bfclr	LOCAL_SGN(%a0){#0:#8}	|convert back to IEEE ext format	beqs	den_com	bsetb	#sign_bit,LOCAL_EX(%a0)den_com:	moveb	#0xfe,CU_SAVEPC(%a2)	|set continue frame	clrw	NMNEXC(%a2)		|clear NMNEXC	bclrb	#E1,E_BYTE(%a2)|	fmove.l	%FPSR,FPSR_SHADOW(%a2)|	bset.b	#SFLAG,E_BYTE(%a2)|	bset.b	#XFLAG,T_BYTE(%a2)end_avun:	frestore (%a7)+	unlk	%a2	rtsidle_end:	addl	#4,%a7	unlk	%a2	rts	|end

⌨️ 快捷键说明

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