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

📄 kernel_ex.s

📁 VXWORKS源代码
💻 S
字号:
/* kernel_ex.s - Motorola 68040 FP exception routines (EXC) *//* Copyright 1991-1993 Wind River Systems, Inc. */	.data	.globl	_copyright_wind_river	.long	_copyright_wind_river/*modification history--------------------01e,21jul93,kdl  added .text (SPR #2372).01d,23aug92,jcf  changed bxxx to jxx.01c,26may92,rrr  the tree shuffle01b,10jan92,kdl  added modification history; general cleanup.01a,15aug91,kdl  original version, from Motorola FPSP v2.0.*//*DESCRIPTION	kernel_exsa 3.3 12/19/90This file contains routines to force exception status in thefpu for exceptional cases detected or reported within thetranscendental functions.  Typically, the t_xx routine willset the appropriate bits in the USER_FPSR word on the stack.The bits are tested in __x_gen_exceptsa to determine if an exceptionalsituation 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    8NOMANUAL*/#include "fpsp040E.h"mns_inf:  .long 0xffff0000,0x00000000,0x00000000pls_inf:  .long 0x7fff0000,0x00000000,0x00000000nan:      .long 0x7fff0000,0xffffffff,0xffffffffhuge:     .long 0x7ffe0000,0xffffffff,0xffffffff|	xref	  __x_ovf_r_k|	xref	  __x_unf_sub|	xref	  __x_nrm_set	.globl    __x_t_dz	.globl    __x_t_dz2	.globl    __x_t_operr	.globl    __x_t_unfl	.globl    __x_t_ovfl	.globl    __x_t_ovfl2	.globl    __x_t_inx2	.globl	  __x_t_frcinx	.globl	  __x_t_extdnrm	.globl	  __x_t_resdnrm	.globl	  __x_dst_nan	.globl	  __x_src_nan	.text||	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 __x_sto_res from corrupting fp register|		return|		frestore the frame into the machine (done by unimp_hd)|| __x_t_dz2 is used by monadic functions such as flogn (from __x_do_func).| __x_t_dz is used by monadic functions such as __x_satanh (from the| transcendental function).|__x_t_dz2:	bset	#neg_bit,a6@(FPSR_CC)	| set neg bit in FPSR	fmovel	#0,FPSR			| clr status bits (Z set)	btst	#__x_dz_bit,a6@(fpcr_ENABLE)	| test fpcr for dz exc enabled	jne 	__x_dz_ena_end	jra 	m_inf			| flogx always returns -inf__x_t_dz:	fmovel	#0,FPSR			| clr status bits (Z set)	btst	#__x_dz_bit,a6@(fpcr_ENABLE)	| test fpcr for dz exc enabled	jne 	__x_dz_ena||	__x_dz disabled|	btst	#sign_bit,a6@(ETEMP_EX)	| check sign for neg or pos	jeq 	p_inf			| branch if pos signm_inf:	fmovemx mns_inf,fp0-fp0		| load -inf	bset	#neg_bit,a6@(FPSR_CC)	| set neg bit in FPSR	jra 	set_fpsrp_inf:	fmovemx pls_inf,fp0-fp0		| load +infset_fpsr:	orl	#__x_dzinf_mask,a6@(USER_FPSR) | set I,DZ,ADZ	rts||	__x_dz enabled|__x_dz_ena:	btst	#sign_bit,a6@(ETEMP_EX)	| check sign for neg or pos	jeq 	__x_dz_ena_end	bset	#neg_bit,a6@(FPSR_CC)	| set neg bit in FPSR__x_dz_ena_end:	orl	#__x_dzinf_mask,a6@(USER_FPSR) | set I,DZ,ADZ	st	a6@(STORE_FLG)	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 __x_sto_res from corrupting fp register|		frestore the frame into the machine (done by unimp_hd)|__x_t_operr:	orl	#opnan_mask,a6@(USER_FPSR) | set NaN, OPERR, AIOP	btst	#__x_operr_bit,a6@(fpcr_ENABLE) | test fpcr for operr enabled	jne 	op_ena	fmovemx nan,fp0-fp0		| load default nan	rtsop_ena:	st	a6@(STORE_FLG)		| do not corrupt destination	rts||	__x_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.|__x_t_unfl:	clrl	a6@(FP_SCR1)		| set exceptional operand to zero	clrl	a6@(FP_SCR1+4)	clrl	a6@(FP_SCR1+8)	tstb	a0@			/* | extract sign from caller's exop */	jpl 	__x_unfl_signok	bset	#sign_bit,a6@(FP_SCR1)__x_unfl_signok:	lea	a6@(FP_SCR1),a0	orl	#unfinx_mask,a6@(USER_FPSR)|					| set UNFL, INEX2, AUNFL, AINEX__x_unfl_con:	btst	#__x_unfl_bit,a6@(fpcr_ENABLE)	jeq 	__x_unfl_dis__x_unfl_ena:	bfclr	a6@(STAG){#5:#3}		| clear wbtm66,wbtm1,wbtm0	bset	#wbtemp15_bit,a6@(WB_BYTE) | set wbtemp15	bset	#sticky_bit,a6@(STICKY)	| set sticky bit	bclr	#E1,a6@(E_BYTE)__x_unfl_dis:	bfextu	a6@(fpcr_MODE){#0:#2},d0	| get round precision	bclr	#sign_bit,a0@(LOCAL_EX)	sne	a0@(LOCAL_SGN)		| convert to internal ext format	bsrl	__x_unf_sub			| returns IEEE result at a0|					| and sets FPSR_CC accordingly	bfclr	a0@(LOCAL_SGN){#0:#8}	| convert back to IEEE ext format	jeq 	__x_unfl_fin	bset	#sign_bit,a0@(LOCAL_EX)	bset	#sign_bit,a6@(FP_SCR1)	| set sign bit of exc operand__x_unfl_fin:	fmovemx	a0@,fp0-fp0		| store result in fp0	rts||	__x_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.|__x_t_ovfl2:	orl	#__x_ovfl_inx_mask,a6@(USER_FPSR)	movel	a6@(ETEMP),a6@(FP_SCR1)	movel	a6@(ETEMP_HI),a6@(FP_SCR1+4)	movel	a6@(ETEMP_LO),a6@(FP_SCR1+8)|| 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	a6@(fpcr_MODE),d0	andib	#0xc0,d0	jeq 	t_work		| if extended, finish ovfl processing	cmpib	#0x40,d0		| test for single	jne 	t_dblt_sgl:	tstb	a6@(ETEMP_LO)	jne 	t_setinx2	movel	a6@(ETEMP_HI),d0	andil	#0xff,d0		| look at only lower 8 bits	jne 	t_setinx2	jra 	t_workt_dbl:	movel	a6@(ETEMP_LO),d0	andil	#0x7ff,d0	| look at only lower 11 bits	jeq 	t_workt_setinx2:	orl	#__x_inex2_mask,a6@(USER_FPSR)	jra 	t_work||	__x_t_ovfl --- OVFL exception||** Note: the exc operand is returned in ETEMP.|__x_t_ovfl:	orl	#ovfinx_mask,a6@(USER_FPSR)t_work:	btst	#__x_ovfl_bit,a6@(fpcr_ENABLE) | test fpcr for ovfl enabled	jeq 	ovf_disovf_ena:	clrl	a6@(FP_SCR1)		| set exceptional operand	clrl	a6@(FP_SCR1+4)	clrl	a6@(FP_SCR1+8)	bfclr	a6@(STAG){#5:#3}		| clear wbtm66,wbtm1,wbtm0	bclr	#wbtemp15_bit,a6@(WB_BYTE) | clear wbtemp15	bset	#sticky_bit,a6@(STICKY)	| set sticky bit	bclr	#E1,a6@(E_BYTE)|					| 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:	bsrl	__x_ovf_r_k			| returns unsigned ETEMP_EX|					| and sets FPSR_CC accordingly.	bfclr	a6@(ETEMP_SGN){#0:#8}	| fix sign	jeq 	ovf_pos	bset	#sign_bit,a6@(ETEMP_EX)	bset	#sign_bit,a6@(FP_SCR1)	| set exceptional operand signovf_pos:	fmovemx	a6@(ETEMP),fp0-fp0		| move the result to fp0	rts||	INEX2 exception|| The inex2 and ainex bits are set.|__x_t_inx2:	orl	#inx2a_mask,a6@(USER_FPSR) | 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.|__x_t_frcinx:	orl	#inx2a_mask,a6@(USER_FPSR) | set INEX2, AINEX	btst	#__x_unfl_bit,a6@(FPSR_EXCEPT) | test for unfl bit set	jeq 	no_uacc1		| if clear, do not set aunfl	bset	#aunfl_bit,a6@(FPSR_AEXCEPT)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.|__x_dst_nan:	btst	#sign_bit,a6@(FPTEMP_EX) | test sign of nan	jeq 	dst_pos			| if clr, it was positive	bset	#neg_bit,a6@(FPSR_CC)	| set N bitdst_pos:	btst	#signan_bit,a6@(FPTEMP_HI) | check if signalling	jeq 	dst_snan		| branch if signalling	fmovel	d1,fpcr			/* | restore user's rmode/prec */	fmovex	a6@(FPTEMP),fp0		| return the non-signalling nan|| Check the source nan.  If it is signalling, snan will be reported.|	moveb	a6@(STAG),d0	andib	#0xe0,d0	cmpib	#0x60,d0	jne 	no_snan	btst	#signan_bit,a6@(ETEMP_HI) | check if signalling	jne 	no_snan	orl	#__x_snaniop_mask,a6@(USER_FPSR) | set NAN, SNAN, AIOPno_snan:	rtsdst_snan:	btst	#__x_snan_bit,a6@(fpcr_ENABLE) | check if trap enabled	jeq 	dst_dis			| branch if disabled	orb	#nan_tag,a6@(DTAG)	| set up dtag for nan	st	a6@(STORE_FLG)		| do not store a result	orl	#__x_snaniop_mask,a6@(USER_FPSR) | set NAN, SNAN, AIOP	rtsdst_dis:	bset	#signan_bit,a6@(FPTEMP_HI) | set SNAN bit in sop	fmovel	d1,fpcr			/* | restore user's rmode/prec */	fmovex	a6@(FPTEMP),fp0		| load non-sign. nan	orl	#__x_snaniop_mask,a6@(USER_FPSR) | 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.|__x_src_nan:	btst	#sign_bit,a6@(ETEMP_EX) | test sign of nan	jeq 	src_pos			| if clr, it was positive	bset	#neg_bit,a6@(FPSR_CC)	| set N bitsrc_pos:	btst	#signan_bit,a6@(ETEMP_HI) | check if signalling	jeq 	src_snan		| branch if signalling	fmovel	d1,fpcr			/* | restore user's rmode/prec */	fmovex	a6@(ETEMP),fp0		| return the non-signalling nan	rtssrc_snan:	btst	#__x_snan_bit,a6@(fpcr_ENABLE) | check if trap enabled	jeq 	src_dis			| branch if disabled	bset	#signan_bit,a6@(ETEMP_HI) | set SNAN bit in sop	orb	#__x_norm_tag,a6@(DTAG)	| set up dtag for __x_norm	orb	#nan_tag,a6@(STAG)	| set up stag for nan	st	a6@(STORE_FLG)		| do not store a result	orl	#__x_snaniop_mask,a6@(USER_FPSR) | set NAN, SNAN, AIOP	rtssrc_dis:	bset	#signan_bit,a6@(ETEMP_HI) | set SNAN bit in sop	fmovel	d1,fpcr			/* | restore user's rmode/prec */	fmovex	a6@(ETEMP),fp0		| load non-sign. nan	orl	#__x_snaniop_mask,a6@(USER_FPSR) | set NAN, SNAN, AIOP	rts|| For all functions that have a denormalized input and that f(x)=x,| this is the entry point|__x_t_extdnrm:	orl	#unfinx_mask,a6@(USER_FPSR)|					| set UNFL, INEX2, AUNFL, AINEX	jra 	xdnrm_con|| Entry point for scale with extended denorm.  The function does| not set inex2, aunfl, or ainex.|__x_t_resdnrm:	orl	#__x_unfl_mask,a6@(USER_FPSR)xdnrm_con:	btst	#__x_unfl_bit,a6@(fpcr_ENABLE)	jeq 	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	a0@(LOCAL_EX),a6@(FP_SCR1)	movel	a0@(LOCAL_HI),a6@(FP_SCR1+4)	movel	a0@(LOCAL_LO),a6@(FP_SCR1+8)	lea	a6@(FP_SCR1),a0	bclr	#sign_bit,a0@(LOCAL_EX)	sne	a0@(LOCAL_SGN)		| convert to internal ext format	tstw	a0@(LOCAL_EX)		| check if input is denorm	jeq 	xdnrm_dn		| if so, skip __x_nrm_set	bsrl	__x_nrm_set		| normalize the result (exponent|					| will be negativexdnrm_dn:	bclr	#sign_bit,a0@(LOCAL_EX)	| take off false sign	bfclr	a0@(LOCAL_SGN){#0:#8}	| change back to IEEE ext format	jeq 	xdep	bset	#sign_bit,a0@(LOCAL_EX)xdep:	bfclr	a6@(STAG){#5:#3}		| clear wbtm66,wbtm1,wbtm0	bset	#wbtemp15_bit,a6@(WB_BYTE) | set wbtemp15	bclr	#sticky_bit,a6@(STICKY)	| clear sticky bit	bclr	#E1,a6@(E_BYTE)	movel	a7@+,a0xdnrm_dis:	bfextu	a6@(fpcr_MODE){#0:#2},d0	| get round precision	jne 	not_ext			| if not round extended, store|					| IEEE defaultsis_ext:	btst	#sign_bit,a0@(LOCAL_EX)	jeq 	xdnrm_store	bset	#neg_bit,a6@(FPSR_CC)	| set N bit in FPSR_CC	jra 	xdnrm_storenot_ext:	bclr	#sign_bit,a0@(LOCAL_EX)	sne	a0@(LOCAL_SGN)		| convert to internal ext format	bsrl	__x_unf_sub			| returns IEEE result pointed by|					| a0|  sets FPSR_CC accordingly	bfclr	a0@(LOCAL_SGN){#0:#8}	| convert back to IEEE ext format	jeq 	xdnrm_store	bset	#sign_bit,a0@(LOCAL_EX)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.|	.globl	__x_t_avoid_unsupp__x_t_avoid_unsupp:	link	a2,#-LOCAL_SIZE		| so that a2 fpsp040E.h negative|					| offsets may be used	fsave	a7@-	tstb	a7@(1)			| check if idle, exit if so	jeq 	idle_end	btst	#E1,a2@(E_BYTE)		| check for an E1 exception if|					| enabled, there is an unsupp	jeq 	end_avun		| else, exit	btst	#7,a2@(DTAG)		| check for denorm destination	jeq 	src_den			| else, must be a source denorm|| handle destination denorm|	lea	a2@(FPTEMP),a0	btst	#sign_bit,a0@(LOCAL_EX)	sne	a0@(LOCAL_SGN)		| convert to internal ext format	bclr	#7,a2@(DTAG)		| set DTAG to norm	bsrl	__x_nrm_set			| normalize result, exponent|					| will become negative	bclr	#sign_bit,a0@(LOCAL_EX)	| get rid of fake sign	bfclr	a0@(LOCAL_SGN){#0:#8}	| convert back to IEEE ext format	jeq 	ck_src_den		| check if source is also denorm	bset	#sign_bit,a0@(LOCAL_EX)ck_src_den:	btst	#7,a2@(STAG)	jeq 	end_avunsrc_den:	lea	a2@(ETEMP),a0	btst	#sign_bit,a0@(LOCAL_EX)	sne	a0@(LOCAL_SGN)		| convert to internal ext format	bclr	#7,a2@(STAG)		| set STAG to norm	bsrl	__x_nrm_set			| normalize result, exponent|					| will become negative	bclr	#sign_bit,a0@(LOCAL_EX)	| get rid of fake sign	bfclr	a0@(LOCAL_SGN){#0:#8}	| convert back to IEEE ext format	jeq 	den_com	bset	#sign_bit,a0@(LOCAL_EX)den_com:	moveb	#0xfe,a2@(CU_SAVEPC)	| set continue frame	clrw	a2@(NMNEXC)		| clear NMNEXC	bclr	#E1,a2@(E_BYTE)|	fmovel	FPSR,a2@(FPSR_SHADOW)|	bset	#SFLAG,a2@(E_BYTE)|	bset	#XFLAG,a2@(T_BYTE)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 + -