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

📄 x_unfl.s

📁 VXWORKS源代码
💻 S
字号:
/* x_unfl.s - Motorola 68040 FP underflow exception handler (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	x_unflsa 3.3 4/26/91	__x_fpsp_unfl --- FPSP handler for underflow exceptionTrap disabled results	For 881/2 compatibility, sw must denormalize the intermediateresult, then store the result.  Denormalization is accomplishedby taking the intermediate result (which is always normalized) andshifting the mantissa right while incrementing the exponent untilit is equal to the denormalized exponent for the destinationformat.  After denormalizatoin, the result is rounded to thedestination format.Trap enabled results	All trap disabled code applies.	In addition the exceptionaloperand needs to made available to the user with a bias of 0x6000added to the exponent.		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.X_UNFL	idnt    2,1 Motorola 040 Floating Point Software Package	section	8NOMANUAL*/#include "fpsp040E.h"|	xref	__x_denorm|	xref	__x_round|	xref	__x_store|	xref	__x_g_rndpr|	xref	__x_g_opcls|	xref	__x_g_dfmtou|	xref	__x_real_unfl|	xref	__x_real_inex|	xref	__x_fpsp_done|	xref	__x_b1238_fix|	xref	__x_check_force	.text	.globl	__x_fpsp_unfl__x_fpsp_unfl:	link		a6,#-LOCAL_SIZE	fsave		a7@-	moveml		d0-d1/a0-a1,a6@(USER_DA)	fmovemx	fp0-fp3,a6@(USER_FP0)	fmoveml	fpcr/fpsr/fpi,a6@(USER_FPCR)| At this point we need to look at the instructions and see if it is one of| the force-precision ones (fsadd,fdadd,fssub,fdsub,fsmul,fdmul,fsdiv,fddiv,| fssqrt,fdsqrt,fsmove,fdmove,fsabs,fdabs,fsneg,fdneg).  If it is then/* | correct the USER_FPCR to the instruction's rounding precision (s or d). */| Also, we need to check if the instruction is fsgldiv or fsglmul.  If it| is then the USER_FPCR is set to extended rounding precision.  Otherwise| leave the USER_FPCR alone.|	bsrl		__x_check_force|	bsrl		unf_res	| denormalize, round # store interm op|| If underflow exceptions are not enabled, check for inexact| exception|	btst		#__x_unfl_bit,a6@(fpcr_ENABLE)	jeq 		ck_inex	btst		#E3,a6@(E_BYTE)	jeq 		no_e3_1|| Clear dirty bit on dest resister in the frame before branching| to __x_b1238_fix.|	bfextu		a6@(CMDREG3B){#6:#3},d0	| get dest reg no	bclr		d0,a6@(FPR_DIRTY_BITS)	| clr dest dirty bit	bsrl		__x_b1238_fix		| test for bug1238 case	movel		a6@(USER_FPSR),a6@(FPSR_SHADOW)	orl		#sx_mask,a6@(E_BYTE)no_e3_1:	moveml		a6@(USER_DA),d0-d1/a0-a1	fmovemx	a6@(USER_FP0),fp0-fp3	fmoveml	a6@(USER_FPCR),fpcr/fpsr/fpi	frestore	a7@+	unlk		a6	jra 		__x_real_unfl|| It is possible to have either inex2 or inex1 exceptions with the| unfl.  If the inex enable bit is set in the fpcr, and either| inex2 or inex1 occured, we must clean up and branch to the| real inex handler.|ck_inex:	moveb		a6@(fpcr_ENABLE),d0	andb		a6@(FPSR_EXCEPT),d0	andib		#0x3,d0	jeq 		__x_unfl_done|| Inexact enabled and reported, and we must take an inexact exception|take_inex:	btst		#E3,a6@(E_BYTE)	jeq 		no_e3_2|| Clear dirty bit on dest resister in the frame before branching| to __x_b1238_fix.|	bfextu		a6@(CMDREG3B){#6:#3},d0	| get dest reg no	bclr		d0,a6@(FPR_DIRTY_BITS)	| clr dest dirty bit	bsrl		__x_b1238_fix		| test for bug1238 case	movel		a6@(USER_FPSR),a6@(FPSR_SHADOW)	orl		#sx_mask,a6@(E_BYTE)no_e3_2:	moveb		#INEX_VEC,a6@(EXC_VEC+1)	moveml        	a6@(USER_DA),d0-d1/a0-a1	fmovemx       	a6@(USER_FP0),fp0-fp3	fmoveml       	a6@(USER_FPCR),fpcr/fpsr/fpi	frestore       	a7@+	unlk            a6	jra 		__x_real_inex__x_unfl_done:	bclr		#E3,a6@(E_BYTE)	jeq 		e1_set		| if set then branch|| Clear dirty bit on dest resister in the frame before branching| to __x_b1238_fix.|	bfextu		a6@(CMDREG3B){#6:#3},d0		| get dest reg no	bclr		d0,a6@(FPR_DIRTY_BITS)	| clr dest dirty bit	bsrl		__x_b1238_fix		| test for bug1238 case	movel		a6@(USER_FPSR),a6@(FPSR_SHADOW)	orl		#sx_mask,a6@(E_BYTE)	moveml		a6@(USER_DA),d0-d1/a0-a1	fmovemx	a6@(USER_FP0),fp0-fp3	fmoveml	a6@(USER_FPCR),fpcr/fpsr/fpi	frestore	a7@+	unlk		a6	jra 		__x_fpsp_donee1_set:	moveml		a6@(USER_DA),d0-d1/a0-a1	fmovemx	a6@(USER_FP0),fp0-fp3	fmoveml	a6@(USER_FPCR),fpcr/fpsr/fpi	unlk		a6	jra 		__x_fpsp_done||	unf_res --- underflow result calculation|unf_res:	bsrl		__x_g_rndpr		| returns RND_PREC in d0 0=ext,|					| 1=sgl, 2=dbl|					| we need the RND_PREC in the|					| upper word for __x_round	movew		#0,a7@-	movew		d0,a7@-	| copy RND_PREC to stack||| If the exception bit set is E3, the exceptional operand from the| fpu is in WBTEMP|  else it is in FPTEMP.|	btst		#E3,a6@(E_BYTE)	jeq 		unf_E1unf_E3:	lea		a6@(WBTEMP),a0	| a0 now points to operand|| Test for fsgldiv and fsglmul.  If the inst was one of these, then| force the precision to extended for the __x_denorm routine.  Use/* | the user's precision for the __x_round routine. */|	movew		a6@(CMDREG3B),d1	| check for fsgldiv or fsglmul	andiw		#0x7f,d1	cmpiw		#0x30,d1		| check for sgldiv	jeq 		unf_sgl	cmpiw		#0x33,d1		| check for sglmul	jne 		unf_cont	| if not, use fpcr prec in __x_roundunf_sgl:	clrl		d0	movew		#0x1,a7@	| override __x_g_rndpr precision|					| force single	jra 		unf_contunf_E1:	lea		a6@(FPTEMP),a0	| a0 now points to operandunf_cont:	bclr		#sign_bit,a0@(LOCAL_EX)	| clear sign bit	sne		a0@(LOCAL_SGN)		| store sign	bsrl		__x_denorm		| returns denorm, a0 points to it|| WARNING:|				| d0 has guard,round sticky bit|				| make sure that it is not corrupted|				| before it reaches the __x_round subroutine/* |				| also ensure that a0 isn't corrupted */|| Set up d1 for __x_round subroutine d1 contains the PREC/MODE| information respectively on upper/lower register halves.|	bfextu		a6@(fpcr_MODE){#2:#2},d1	| get mode from fpcr|						| mode in lower d1	addl		a7@+,d1		| merge PREC/MODE|| WARNING: a0 and d0 are assumed to be intact between the __x_denorm and| __x_round subroutines. All code between these two subroutines| must not corrupt a0 and d0.||| Perform Round|	Input:		a0 points to input operand|			d0{31:29} has guard, round, sticky|			d1{01:00} has rounding mode|			d1{17:16} has rounding precision|	Output:		a0 points to rounded operand|	bsrl		__x_round		| returns rounded denorm at	a0@|| Differentiate between store to memory vs. store to register|unf_store:	bsrl		__x_g_opcls		| returns opclass in d0{2:0}	cmpib		#0x3,d0	jne 		not_opc011|| At this point, a store to memory is pending|opc011:	bsrl		__x_g_dfmtou	tstb		d0	jeq 		ext_opc011	| If extended, do not subtract| 					| If destination format is sgl/dbl,	tstb		a0@(LOCAL_HI)	/* If rounded result is normal,don't */|					|  subtract	jmi 		ext_opc011	subqw		#1,a0@(LOCAL_EX)	| account for denorm bias vs.|					| normalized bias|					|           normalized   denormalized|					| single       0x7f           0x7e|					| double       0x3ff          0x3fe|ext_opc011:	bsrl		__x_store	| stores to memory	jra 		unf_done	| finish up|| At this point, a store to a float register is pending|not_opc011:	bsrl		__x_store	| stores to float register|					| a0 is not corrupted on a store to a|					| float register.|| Set the condition codes according to result|	tstl		a0@(LOCAL_HI)	| check upper mantissa	jne 		ck_sgn	tstl		a0@(LOCAL_LO)	| check lower mantissa	jne 		ck_sgn	bset		#z_bit,a6@(FPSR_CC) | set condition codes if zerock_sgn:	btst 		#sign_bit,a0@(LOCAL_EX)	| check the sign bit	jeq 		unf_done	bset		#neg_bit,a6@(FPSR_CC)|| Finish.|unf_done:	btst		#__x_inex2_bit,a6@(FPSR_EXCEPT)	jeq 		no_aunfl	bset		#aunfl_bit,a6@(FPSR_AEXCEPT)no_aunfl:	rts|	end

⌨️ 快捷键说明

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