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

📄 x_unfl.s

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 S
字号:
////      $Id: x_unfl.S,v 1.1 1998/12/14 23:15:33 joel Exp $////	x_unfl.sa 3.4 7/1/91////	fpsp_unfl --- FPSP handler for underflow exception//// Trap disabled results//	For 881/2 compatibility, sw must denormalize the intermediate // result, then store the result.  Denormalization is accomplished // by taking the intermediate result (which is always normalized) and // shifting the mantissa right while incrementing the exponent until // it is equal to the denormalized exponent for the destination // format.  After denormalization, the result is rounded to the // destination format.//		// Trap enabled results// 	All trap disabled code applies.	In addition the exceptional // operand needs to made available to the user with a bias of $6000 // added 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	8#include "fpsp.defs"	|xref	denorm	|xref	round	|xref	store	|xref	g_rndpr	|xref	g_opcls	|xref	g_dfmtou	|xref	real_unfl	|xref	real_inex	|xref	fpsp_done	|xref	b1238_fix	.global	fpsp_unflfpsp_unfl:	link		%a6,#-LOCAL_SIZE	fsave		-(%a7)	moveml		%d0-%d1/%a0-%a1,USER_DA(%a6)	fmovemx	%fp0-%fp3,USER_FP0(%a6)	fmoveml	%fpcr/%fpsr/%fpiar,USER_FPCR(%a6)//	bsrl		unf_res	//denormalize, round & store interm op//// If underflow exceptions are not enabled, check for inexact// exception//	btstb		#unfl_bit,FPCR_ENABLE(%a6)	beqs		ck_inex	btstb		#E3,E_BYTE(%a6)	beqs		no_e3_1//// Clear dirty bit on dest resister in the frame before branching// to b1238_fix.//	bfextu		CMDREG3B(%a6){#6:#3},%d0	//get dest reg no	bclrb		%d0,FPR_DIRTY_BITS(%a6)	//clr dest dirty bit	bsrl		b1238_fix		//test for bug1238 case	movel		USER_FPSR(%a6),FPSR_SHADOW(%a6)	orl		#sx_mask,E_BYTE(%a6)no_e3_1:	moveml		USER_DA(%a6),%d0-%d1/%a0-%a1	fmovemx	USER_FP0(%a6),%fp0-%fp3	fmoveml	USER_FPCR(%a6),%fpcr/%fpsr/%fpiar	frestore	(%a7)+	unlk		%a6	bral		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 occurred, we must clean up and branch to the// real inex handler.//ck_inex:	moveb		FPCR_ENABLE(%a6),%d0	andb		FPSR_EXCEPT(%a6),%d0	andib		#0x3,%d0	beqs		unfl_done//// Inexact enabled and reported, and we must take an inexact exception//	take_inex:	btstb		#E3,E_BYTE(%a6)	beqs		no_e3_2//// Clear dirty bit on dest resister in the frame before branching// to b1238_fix.//	bfextu		CMDREG3B(%a6){#6:#3},%d0	//get dest reg no	bclrb		%d0,FPR_DIRTY_BITS(%a6)	//clr dest dirty bit	bsrl		b1238_fix		//test for bug1238 case	movel		USER_FPSR(%a6),FPSR_SHADOW(%a6)	orl		#sx_mask,E_BYTE(%a6)no_e3_2:	moveb		#INEX_VEC,EXC_VEC+1(%a6)	moveml         USER_DA(%a6),%d0-%d1/%a0-%a1	fmovemx        USER_FP0(%a6),%fp0-%fp3	fmoveml        USER_FPCR(%a6),%fpcr/%fpsr/%fpiar	frestore        (%a7)+	unlk            %a6	bral		real_inexunfl_done:	bclrb		#E3,E_BYTE(%a6)	beqs		e1_set		//if set then branch//// Clear dirty bit on dest resister in the frame before branching// to b1238_fix.//	bfextu		CMDREG3B(%a6){#6:#3},%d0		//get dest reg no	bclrb		%d0,FPR_DIRTY_BITS(%a6)	//clr dest dirty bit	bsrl		b1238_fix		//test for bug1238 case	movel		USER_FPSR(%a6),FPSR_SHADOW(%a6)	orl		#sx_mask,E_BYTE(%a6)	moveml		USER_DA(%a6),%d0-%d1/%a0-%a1	fmovemx	USER_FP0(%a6),%fp0-%fp3	fmoveml	USER_FPCR(%a6),%fpcr/%fpsr/%fpiar	frestore	(%a7)+	unlk		%a6	bral		fpsp_donee1_set:	moveml		USER_DA(%a6),%d0-%d1/%a0-%a1	fmovemx	USER_FP0(%a6),%fp0-%fp3	fmoveml	USER_FPCR(%a6),%fpcr/%fpsr/%fpiar	unlk		%a6	bral		fpsp_done////	unf_res --- underflow result calculation//unf_res:	bsrl		g_rndpr		//returns RND_PREC in d0 0=ext,//					;1=sgl, 2=dbl//					;we need the RND_PREC in the//					;upper word for 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.//	btstb		#E3,E_BYTE(%a6)	beqs		unf_E1unf_E3:	lea		WBTEMP(%a6),%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 denorm routine.  Use// the user's precision for the round routine.//	movew		CMDREG3B(%a6),%d1	//check for fsgldiv or fsglmul	andiw		#0x7f,%d1	cmpiw		#0x30,%d1		//check for sgldiv	beqs		unf_sgl	cmpiw		#0x33,%d1		//check for sglmul	bnes		unf_cont	//if not, use fpcr prec in roundunf_sgl:	clrl		%d0	movew		#0x1,(%a7)	//override g_rndpr precision//					;force single	bras		unf_contunf_E1:	lea		FPTEMP(%a6),%a0	//a0 now points to operandunf_cont:	bclrb		#sign_bit,LOCAL_EX(%a0)	//clear sign bit	sne		LOCAL_SGN(%a0)		//store sign	bsrl		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 round subroutine//				;also ensure that a0 isn't corrupted//// Set up d1 for round subroutine d1 contains the PREC/MODE// information respectively on upper/lower register halves.//	bfextu		FPCR_MODE(%a6){#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 denorm and// 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		round		//returns rounded denorm at (a0)//// Differentiate between store to memory vs. store to register//unf_store:	bsrl		g_opcls		//returns opclass in d0{2:0}	cmpib		#0x3,%d0	bnes		not_opc011//// At this point, a store to memory is pending//opc011:	bsrl		g_dfmtou	tstb		%d0	beqs		ext_opc011	//If extended, do not subtract// 				;If destination format is sgl/dbl, 	tstb		LOCAL_HI(%a0)	//If rounded result is normal,don't//					;subtract	bmis		ext_opc011	subqw		#1,LOCAL_EX(%a0)	//account for denorm bias vs.//				;normalized bias//				;          normalized   denormalized//				;single       $7f           $7e//				;double       $3ff          $3fe//ext_opc011:	bsrl		store		//stores to memory	bras		unf_done	//finish up//// At this point, a store to a float register is pending//not_opc011:	bsrl		store	//stores to float register//				;a0 is not corrupted on a store to a//				;float register.//// Set the condition codes according to result//	tstl		LOCAL_HI(%a0)	//check upper mantissa	bnes		ck_sgn	tstl		LOCAL_LO(%a0)	//check lower mantissa	bnes		ck_sgn	bsetb		#z_bit,FPSR_CC(%a6) //set condition codes if zerock_sgn:	btstb 		#sign_bit,LOCAL_EX(%a0)	//check the sign bit	beqs		unf_done	bsetb		#neg_bit,FPSR_CC(%a6)//// Finish.  //unf_done:	btstb		#inex2_bit,FPSR_EXCEPT(%a6)	beqs		no_aunfl	bsetb		#aunfl_bit,FPSR_AEXCEPT(%a6)no_aunfl:	rts	|end

⌨️ 快捷键说明

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