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

📄 util.s

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 S
📖 第 1 页 / 共 2 页
字号:
////      $Id: util.S,v 1.2 1999/07/26 22:11:02 joel Exp $////	util.sa 3.7 7/29/91////	This file contains routines used by other programs.////	ovf_res: used by overflow to force the correct//		 result. ovf_r_k, ovf_r_x2, ovf_r_x3 are //		 derivatives of this routine.//	get_fline: get user's opcode word//	g_dfmtou: returns the destination format.//	g_opcls: returns the opclass of the float instruction.//	g_rndpr: returns the rounding precision. //	reg_dest: write byte, word, or long data to Dn//////		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.//UTIL	idnt    2,1 | Motorola 040 Floating Point Software Package	|section	8#include "fpsp.defs"	|xref	mem_read	.global	g_dfmtou	.global	g_opcls	.global	g_rndpr	.global	get_fline	.global	reg_dest//// Final result table for ovf_res. Note that the negative counterparts// are unnecessary as ovf_res always returns the sign separately from// the exponent.//					;+infEXT_PINF:	.long	0x7fff0000,0x00000000,0x00000000,0x00000000	//					;largest +extEXT_PLRG:	.long	0x7ffe0000,0xffffffff,0xffffffff,0x00000000	//					;largest magnitude +sgl in extSGL_PLRG:	.long	0x407e0000,0xffffff00,0x00000000,0x00000000	//					;largest magnitude +dbl in extDBL_PLRG:	.long	0x43fe0000,0xffffffff,0xfffff800,0x00000000	//					;largest -exttblovfl:	.long	EXT_RN	.long	EXT_RZ	.long	EXT_RM	.long	EXT_RP	.long	SGL_RN	.long	SGL_RZ	.long	SGL_RM	.long	SGL_RP	.long	DBL_RN	.long	DBL_RZ	.long	DBL_RM	.long	DBL_RP	.long	error	.long	error	.long	error	.long	error////	ovf_r_k --- overflow result calculation//// This entry point is used by kernel_ex.  //// This forces the destination precision to be extended//// Input:	operand in ETEMP// Output:	a result is in ETEMP (internal extended format)//	.global	ovf_r_kovf_r_k:	lea	ETEMP(%a6),%a0	//a0 points to source operand		bclrb	#sign_bit,ETEMP_EX(%a6)	sne	ETEMP_SGN(%a6)	//convert to internal IEEE format////	ovf_r_x2 --- overflow result calculation//// This entry point used by x_ovfl.  (opclass 0 and 2)//// Input		a0  points to an operand in the internal extended format// Output	a0  points to the result in the internal extended format//// This sets the round precision according to the user's FPCR unless the// instruction is fsgldiv or fsglmul or fsadd, fdadd, fsub, fdsub, fsmul,// fdmul, fsdiv, fddiv, fssqrt, fsmove, fdmove, fsabs, fdabs, fsneg, fdneg.// If the instruction is fsgldiv of fsglmul, the rounding precision must be// extended.  If the instruction is not fsgldiv or fsglmul but a force-// precision instruction, the rounding precision is then set to the force// precision.	.global	ovf_r_x2ovf_r_x2:	btstb	#E3,E_BYTE(%a6)		//check for nu exception	beql	ovf_e1_exc		//it is cu exceptionovf_e3_exc:	movew	CMDREG3B(%a6),%d0		//get the command word	andiw	#0x00000060,%d0		//clear all bits except 6 and 5	cmpil	#0x00000040,%d0	beql	ovff_sgl		//force precision is single	cmpil	#0x00000060,%d0	beql	ovff_dbl		//force precision is double	movew	CMDREG3B(%a6),%d0		//get the command word again	andil	#0x7f,%d0			//clear all except operation	cmpil	#0x33,%d0				beql	ovf_fsgl		//fsglmul or fsgldiv	cmpil	#0x30,%d0	beql	ovf_fsgl			bra	ovf_fpcr		//instruction is none of the above//					;use FPCRovf_e1_exc:	movew	CMDREG1B(%a6),%d0		//get command word	andil	#0x00000044,%d0		//clear all bits except 6 and 2	cmpil	#0x00000040,%d0	beql	ovff_sgl		//the instruction is force single	cmpil	#0x00000044,%d0	beql	ovff_dbl		//the instruction is force double	movew	CMDREG1B(%a6),%d0		//again get the command word	andil	#0x0000007f,%d0		//clear all except the op code	cmpil	#0x00000027,%d0	beql	ovf_fsgl		//fsglmul	cmpil 	#0x00000024,%d0	beql	ovf_fsgl		//fsgldiv	bra	ovf_fpcr		//none of the above, use FPCR// //// Inst is either fsgldiv or fsglmul.  Force extended precision.//ovf_fsgl:	clrl	%d0	bra	ovf_resovff_sgl:	movel	#0x00000001,%d0		//set single	bra	ovf_resovff_dbl:	movel	#0x00000002,%d0		//set double	bra	ovf_res//// The precision is in the fpcr.//ovf_fpcr:	bfextu	FPCR_MODE(%a6){#0:#2},%d0 //set round precision	bra	ovf_res	//////	ovf_r_x3 --- overflow result calculation//// This entry point used by x_ovfl. (opclass 3 only)//// Input		a0  points to an operand in the internal extended format// Output	a0  points to the result in the internal extended format//// This sets the round precision according to the destination size.//	.global	ovf_r_x3ovf_r_x3:	bsr	g_dfmtou	//get dest fmt in d0{1:0}//				;for fmovout, the destination format//				;is the rounding precision////	ovf_res --- overflow result calculation//// Input://	a0 	points to operand in internal extended format// Output://	a0 	points to result in internal extended format//	.global	ovf_resovf_res:	lsll	#2,%d0		//move round precision to d0{3:2}	bfextu	FPCR_MODE(%a6){#2:#2},%d1 //set round mode	orl	%d1,%d0		//index is fmt:mode in d0{3:0}	leal	tblovfl,%a1	//load a1 with table address	movel	%a1@(%d0:l:4),%a1	//use d0 as index to the table	jmp	(%a1)		//go to the correct routine////case DEST_FMT = EXT//EXT_RN:	leal	EXT_PINF,%a1	//answer is +/- infinity	bsetb	#inf_bit,FPSR_CC(%a6)	bra	set_sign	//now go set the sign	EXT_RZ:	leal	EXT_PLRG,%a1	//answer is +/- large number	bra	set_sign	//now go set the signEXT_RM:	tstb	LOCAL_SGN(%a0)	//if negative overflow	beqs	e_rm_pose_rm_neg:	leal	EXT_PINF,%a1	//answer is negative infinity	orl	#neginf_mask,USER_FPSR(%a6)	bra	end_ovfre_rm_pos:	leal	EXT_PLRG,%a1	//answer is large positive number	bra	end_ovfrEXT_RP:	tstb	LOCAL_SGN(%a0)	//if negative overflow	beqs	e_rp_pose_rp_neg:	leal	EXT_PLRG,%a1	//answer is large negative number	bsetb	#neg_bit,FPSR_CC(%a6)	bra	end_ovfre_rp_pos:	leal	EXT_PINF,%a1	//answer is positive infinity	bsetb	#inf_bit,FPSR_CC(%a6)	bra	end_ovfr////case DEST_FMT = DBL//DBL_RN:	leal	EXT_PINF,%a1	//answer is +/- infinity	bsetb	#inf_bit,FPSR_CC(%a6)	bra	set_signDBL_RZ:	leal	DBL_PLRG,%a1	//answer is +/- large number	bra	set_sign	//now go set the signDBL_RM:	tstb	LOCAL_SGN(%a0)	//if negative overflow	beqs	d_rm_posd_rm_neg:	leal	EXT_PINF,%a1	//answer is negative infinity	orl	#neginf_mask,USER_FPSR(%a6)	bra	end_ovfr	//inf is same for all precisions (ext,dbl,sgl)d_rm_pos:	leal	DBL_PLRG,%a1	//answer is large positive number	bra	end_ovfrDBL_RP:	tstb	LOCAL_SGN(%a0)	//if negative overflow	beqs	d_rp_posd_rp_neg:	leal	DBL_PLRG,%a1	//answer is large negative number	bsetb	#neg_bit,FPSR_CC(%a6)	bra	end_ovfrd_rp_pos:	leal	EXT_PINF,%a1	//answer is positive infinity	bsetb	#inf_bit,FPSR_CC(%a6)	bra	end_ovfr////case DEST_FMT = SGL//SGL_RN:	leal	EXT_PINF,%a1	//answer is +/-  infinity	bsetb	#inf_bit,FPSR_CC(%a6)	bras	set_signSGL_RZ:	leal	SGL_PLRG,%a1	//answer is +/- large number	bras	set_signSGL_RM:	tstb	LOCAL_SGN(%a0)	//if negative overflow	beqs	s_rm_poss_rm_neg:	leal	EXT_PINF,%a1	//answer is negative infinity	orl	#neginf_mask,USER_FPSR(%a6)	bras	end_ovfrs_rm_pos:	leal	SGL_PLRG,%a1	//answer is large positive number	bras	end_ovfrSGL_RP:	tstb	LOCAL_SGN(%a0)	//if negative overflow	beqs	s_rp_poss_rp_neg:	leal	SGL_PLRG,%a1	//answer is large negative number	bsetb	#neg_bit,FPSR_CC(%a6)	bras	end_ovfrs_rp_pos:	leal	EXT_PINF,%a1	//answer is positive infinity	bsetb	#inf_bit,FPSR_CC(%a6)	bras	end_ovfrset_sign:	tstb	LOCAL_SGN(%a0)	//if negative overflow	beqs	end_ovfrneg_sign:	bsetb	#neg_bit,FPSR_CC(%a6)end_ovfr:	movew	LOCAL_EX(%a1),LOCAL_EX(%a0) //do not overwrite sign	movel	LOCAL_HI(%a1),LOCAL_HI(%a0)	movel	LOCAL_LO(%a1),LOCAL_LO(%a0)	rts////	ERROR//error:	rts////	get_fline --- get f-line opcode of interrupted instruction////	Returns opcode in the low word of d0.//get_fline:	movel	USER_FPIAR(%a6),%a0	//opcode address	movel	#0,-(%a7)	//reserve a word on the stack	leal	2(%a7),%a1	//point to low word of temporary	movel	#2,%d0		//count	bsrl	mem_read	movel	(%a7)+,%d0	rts//// 	g_rndpr --- put rounding precision in d0{1:0}//	//	valid return codes are://		00 - extended //		01 - single//		10 - double//// begin// get rounding precision (cmdreg3b{6:5})// begin//  case	opclass = 011 (move out)//	get destination format - this is the also the rounding precision////  case	opclass = 0x0//	if E3//	    *case RndPr(from cmdreg3b{6:5} = 11  then RND_PREC = DBL//	    *case RndPr(from cmdreg3b{6:5} = 10  then RND_PREC = SGL//	     case RndPr(from cmdreg3b{6:5} = 00 | 01//		use precision from FPCR{7:6}//			case 00 then RND_PREC = EXT//			case 01 then RND_PREC = SGL//			case 10 then RND_PREC = DBL//	else E1//	     use precision in FPCR{7:6}//	     case 00 then RND_PREC = EXT//	     case 01 then RND_PREC = SGL//	     case 10 then RND_PREC = DBL// end//g_rndpr:	bsr	g_opcls		//get opclass in d0{2:0}	cmpw	#0x0003,%d0	//check for opclass 011	bnes	op_0x0//// For move out instructions (opclass 011) the destination format// is the same as the rounding precision.  Pass results from g_dfmtou.//	bsr 	g_dfmtou		rtsop_0x0:	btstb	#E3,E_BYTE(%a6)	beql	unf_e1_exc	//branch to e1 underflowunf_e3_exc:	movel	CMDREG3B(%a6),%d0	//rounding precision in d0{10:9}	bfextu	%d0{#9:#2},%d0	//move the rounding prec bits to d0{1:0}	cmpil	#0x2,%d0	beql	unff_sgl	//force precision is single	cmpil	#0x3,%d0		//force precision is double	beql	unff_dbl	movew	CMDREG3B(%a6),%d0	//get the command word again	andil	#0x7f,%d0		//clear all except operation	cmpil	#0x33,%d0				beql	unf_fsgl	//fsglmul or fsgldiv	cmpil	#0x30,%d0	beql	unf_fsgl	//fsgldiv or fsglmul	bra	unf_fpcrunf_e1_exc:	movel	CMDREG1B(%a6),%d0	//get 32 bits off the stack, 1st 16 bits//				;are the command word

⌨️ 快捷键说明

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