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

📄 scale.s

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 S
字号:
////      $Id: scale.S,v 1.1 1998/12/14 23:15:25 joel Exp $////	scale.sa 3.3 7/30/91////	The entry point sSCALE computes the destination operand//	scaled by the source operand.  If the absolute value of//	the source operand is (>= 2^14) an overflow or underflow//	is returned.////	The entry point sscale is called from do_func to emulate//	the fscale unimplemented instruction.////	Input: Double-extended destination operand in FPTEMP, //		double-extended source operand in ETEMP.////	Output: The function returns scale(X,Y) to fp0.////	Modifies: fp0.////	Algorithm://		//		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.//SCALE    idnt    2,1 | Motorola 040 Floating Point Software Package	|section	8#include "fpsp.defs"	|xref	t_ovfl2	|xref	t_unfl	|xref	round	|xref	t_resdnrmSRC_BNDS: .short	0x3fff,0x400c//// This entry point is used by the unimplemented instruction exception// handler.////////	FSCALE//	.global	sscalesscale:	fmovel		#0,%fpcr		//clr user enabled exc	clrl		%d1	movew		FPTEMP(%a6),%d1	//get dest exponent	smi		L_SCR1(%a6)	//use L_SCR1 to hold sign	andil		#0x7fff,%d1	//strip sign	movew		ETEMP(%a6),%d0	//check src bounds	andiw		#0x7fff,%d0	//clr sign bit	cmp2w		SRC_BNDS,%d0	bccs		src_in	cmpiw		#0x400c,%d0	//test for too large	bge		src_out//// The source input is below 1, so we check for denormalized numbers// and set unfl.//src_small:	moveb		DTAG(%a6),%d0	andib		#0xe0,%d0	tstb		%d0	beqs		no_denorm	st		STORE_FLG(%a6)	//dest already contains result	orl		#unfl_mask,USER_FPSR(%a6) //set UNFLden_done:	leal		FPTEMP(%a6),%a0	bra		t_resdnrmno_denorm:	fmovel		USER_FPCR(%a6),%FPCR	fmovex		FPTEMP(%a6),%fp0	//simply return dest	rts//// Source is within 2^14 range.  To perform the int operation,// move it to d0.//src_in:	fmovex		ETEMP(%a6),%fp0	//move in src for int	fmovel		#rz_mode,%fpcr	//force rz for src conversion	fmovel		%fp0,%d0		//int src to d0	fmovel		#0,%FPSR		//clr status from above	tstw		ETEMP(%a6)	//check src sign	blt		src_neg//// Source is positive.  Add the src to the dest exponent.// The result can be denormalized, if src = 0, or overflow,// if the result of the add sets a bit in the upper word.//src_pos:	tstw		%d1		//check for denorm	beq		dst_dnrm	addl		%d0,%d1		//add src to dest exp	beqs		denorm		//if zero, result is denorm	cmpil		#0x7fff,%d1	//test for overflow	bges		ovfl	tstb		L_SCR1(%a6)	beqs		spos_pos	orw		#0x8000,%d1spos_pos:	movew		%d1,FPTEMP(%a6)	//result in FPTEMP	fmovel		USER_FPCR(%a6),%FPCR	fmovex		FPTEMP(%a6),%fp0	//write result to fp0	rtsovfl:	tstb		L_SCR1(%a6)	beqs		sovl_pos	orw		#0x8000,%d1sovl_pos:	movew		FPTEMP(%a6),ETEMP(%a6)	//result in ETEMP	movel		FPTEMP_HI(%a6),ETEMP_HI(%a6)	movel		FPTEMP_LO(%a6),ETEMP_LO(%a6)	bra		t_ovfl2denorm:	tstb		L_SCR1(%a6)	beqs		den_pos	orw		#0x8000,%d1den_pos:	tstl		FPTEMP_HI(%a6)	//check j bit	blts		nden_exit	//if set, not denorm	movew		%d1,ETEMP(%a6)	//input expected in ETEMP	movel		FPTEMP_HI(%a6),ETEMP_HI(%a6)	movel		FPTEMP_LO(%a6),ETEMP_LO(%a6)	orl		#unfl_bit,USER_FPSR(%a6)	//set unfl	leal		ETEMP(%a6),%a0	bra		t_resdnrmnden_exit:	movew		%d1,FPTEMP(%a6)	//result in FPTEMP	fmovel		USER_FPCR(%a6),%FPCR	fmovex		FPTEMP(%a6),%fp0	//write result to fp0	rts//// Source is negative.  Add the src to the dest exponent.// (The result exponent will be reduced).  The result can be// denormalized.//src_neg:	addl		%d0,%d1		//add src to dest	beqs		denorm		//if zero, result is denorm	blts		fix_dnrm	//if negative, result is //					;needing denormalization	tstb		L_SCR1(%a6)	beqs		sneg_pos	orw		#0x8000,%d1sneg_pos:	movew		%d1,FPTEMP(%a6)	//result in FPTEMP	fmovel		USER_FPCR(%a6),%FPCR	fmovex		FPTEMP(%a6),%fp0	//write result to fp0	rts//// The result exponent is below denorm value.  Test for catastrophic// underflow and force zero if true.  If not, try to shift the // mantissa right until a zero exponent exists.//fix_dnrm:	cmpiw		#0xffc0,%d1	//lower bound for normalization	blt		fix_unfl	//if lower, catastrophic unfl	movew		%d1,%d0		//use d0 for exp	movel		%d2,-(%a7)	//free d2 for norm	movel		FPTEMP_HI(%a6),%d1	movel		FPTEMP_LO(%a6),%d2	clrl		L_SCR2(%a6)fix_loop:	addw		#1,%d0		//drive d0 to 0	lsrl		#1,%d1		//while shifting the	roxrl		#1,%d2		//mantissa to the right	bccs		no_carry	st		L_SCR2(%a6)	//use L_SCR2 to capture inexno_carry:	tstw		%d0		//it is finished when	blts		fix_loop	//d0 is zero or the mantissa	tstb		L_SCR2(%a6)	beqs		tst_zero	orl		#unfl_inx_mask,USER_FPSR(%a6)//					;set unfl, aunfl, ainex//// Test for zero. If zero, simply use fmove to return +/- zero// to the fpu.//tst_zero:	clrw		FPTEMP_EX(%a6)	tstb		L_SCR1(%a6)	//test for sign	beqs		tst_con	orw		#0x8000,FPTEMP_EX(%a6) //set sign bittst_con:	movel		%d1,FPTEMP_HI(%a6)	movel		%d2,FPTEMP_LO(%a6)	movel		(%a7)+,%d2	tstl		%d1	bnes		not_zero	tstl		FPTEMP_LO(%a6)	bnes		not_zero//// Result is zero.  Check for rounding mode to set lsb.  If the// mode is rp, and the zero is positive, return smallest denorm.// If the mode is rm, and the zero is negative, return smallest// negative denorm.//	btstb		#5,FPCR_MODE(%a6) //test if rm or rp	beqs		no_dir	btstb		#4,FPCR_MODE(%a6) //check which one	beqs		zer_rmzer_rp:	tstb		L_SCR1(%a6)	//check sign	bnes		no_dir		//if set, neg op, no inc	movel		#1,FPTEMP_LO(%a6) //set lsb	bras		sm_dnrmzer_rm:	tstb		L_SCR1(%a6)	//check sign	beqs		no_dir		//if clr, neg op, no inc	movel		#1,FPTEMP_LO(%a6) //set lsb	orl		#neg_mask,USER_FPSR(%a6) //set N	bras		sm_dnrmno_dir:	fmovel		USER_FPCR(%a6),%FPCR	fmovex		FPTEMP(%a6),%fp0	//use fmove to set cc's	rts//// The rounding mode changed the zero to a smallest denorm. Call // t_resdnrm with exceptional operand in ETEMP.//sm_dnrm:	movel		FPTEMP_EX(%a6),ETEMP_EX(%a6)	movel		FPTEMP_HI(%a6),ETEMP_HI(%a6)	movel		FPTEMP_LO(%a6),ETEMP_LO(%a6)	leal		ETEMP(%a6),%a0	bra		t_resdnrm//// Result is still denormalized.//not_zero:	orl		#unfl_mask,USER_FPSR(%a6) //set unfl	tstb		L_SCR1(%a6)	//check for sign	beqs		fix_exit	orl		#neg_mask,USER_FPSR(%a6) //set Nfix_exit:	bras		sm_dnrm	//// The result has underflowed to zero. Return zero and set// unfl, aunfl, and ainex.//fix_unfl:	orl		#unfl_inx_mask,USER_FPSR(%a6)	btstb		#5,FPCR_MODE(%a6) //test if rm or rp	beqs		no_dir2	btstb		#4,FPCR_MODE(%a6) //check which one	beqs		zer_rm2zer_rp2:	tstb		L_SCR1(%a6)	//check sign	bnes		no_dir2		//if set, neg op, no inc	clrl		FPTEMP_EX(%a6)	clrl		FPTEMP_HI(%a6)	movel		#1,FPTEMP_LO(%a6) //set lsb	bras		sm_dnrm		//return smallest denormzer_rm2:	tstb		L_SCR1(%a6)	//check sign	beqs		no_dir2		//if clr, neg op, no inc	movew		#0x8000,FPTEMP_EX(%a6)	clrl		FPTEMP_HI(%a6)	movel		#1,FPTEMP_LO(%a6) //set lsb	orl		#neg_mask,USER_FPSR(%a6) //set N	bra		sm_dnrm		//return smallest denormno_dir2:	tstb		L_SCR1(%a6)	bges		pos_zeroneg_zero:	clrl		FP_SCR1(%a6)	//clear the exceptional operand	clrl		FP_SCR1+4(%a6)	//for gen_except.	clrl		FP_SCR1+8(%a6)	fmoves		#0x80000000,%fp0		rtspos_zero:	clrl		FP_SCR1(%a6)	//clear the exceptional operand	clrl		FP_SCR1+4(%a6)	//for gen_except.	clrl		FP_SCR1+8(%a6)	fmoves		#0x00000000,%fp0	rts//// The destination is a denormalized number.  It must be handled// by first shifting the bits in the mantissa until it is normalized,// then adding the remainder of the source to the exponent.//dst_dnrm:	moveml		%d2/%d3,-(%a7)		movew		FPTEMP_EX(%a6),%d1	movel		FPTEMP_HI(%a6),%d2	movel		FPTEMP_LO(%a6),%d3dst_loop:	tstl		%d2		//test for normalized result	blts		dst_norm	//exit loop if so	tstl		%d0		//otherwise, test shift count	beqs		dst_fin		//if zero, shifting is done	subil		#1,%d0		//dec src	lsll		#1,%d3	roxll		#1,%d2	bras		dst_loop//// Destination became normalized.  Simply add the remaining // portion of the src to the exponent.//dst_norm:	addw		%d0,%d1		//dst is normalized; add src	tstb		L_SCR1(%a6)	beqs		dnrm_pos	orl		#0x8000,%d1dnrm_pos:	movemw		%d1,FPTEMP_EX(%a6)	moveml		%d2,FPTEMP_HI(%a6)	moveml		%d3,FPTEMP_LO(%a6)	fmovel		USER_FPCR(%a6),%FPCR	fmovex		FPTEMP(%a6),%fp0	moveml		(%a7)+,%d2/%d3	rts//// Destination remained denormalized.  Call t_excdnrm with// exceptional operand in ETEMP.//dst_fin:	tstb		L_SCR1(%a6)	//check for sign	beqs		dst_exit	orl		#neg_mask,USER_FPSR(%a6) //set N	orl		#0x8000,%d1dst_exit:	movemw		%d1,ETEMP_EX(%a6)	moveml		%d2,ETEMP_HI(%a6)	moveml		%d3,ETEMP_LO(%a6)	orl		#unfl_mask,USER_FPSR(%a6) //set unfl	moveml		(%a7)+,%d2/%d3	leal		ETEMP(%a6),%a0	bra		t_resdnrm//// Source is outside of 2^14 range.  Test the sign and branch// to the appropriate exception handler.//src_out:	tstb		L_SCR1(%a6)	beqs		scro_pos	orl		#0x8000,%d1scro_pos:	movel		FPTEMP_HI(%a6),ETEMP_HI(%a6)	movel		FPTEMP_LO(%a6),ETEMP_LO(%a6)	tstw		ETEMP(%a6)	blts		res_negres_pos:	movew		%d1,ETEMP(%a6)	//result in ETEMP	bra		t_ovfl2res_neg:	movew		%d1,ETEMP(%a6)	//result in ETEMP	leal		ETEMP(%a6),%a0	bra		t_unfl	|end

⌨️ 快捷键说明

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