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

📄 kernel_ex.s

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 S
字号:
////      $Id: kernel_ex.S,v 1.1 1998/12/14 23:15:21 joel Exp $////	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.defs"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 + -