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

📄 round.s

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 S
📖 第 1 页 / 共 2 页
字号:
////      $Id: round.S,v 1.1 1998/12/14 23:15:23 joel Exp $////	round.sa 3.4 7/29/91////	handle rounding and normalization tasks////////		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.//ROUND	idnt    2,1 | Motorola 040 Floating Point Software Package	|section	8#include "fpsp.defs"////	round --- round result according to precision/mode////	a0 points to the input operand in the internal extended format //	d1(high word) contains rounding precision://		ext = $0000xxxx//		sgl = $0001xxxx//		dbl = $0002xxxx//	d1(low word) contains rounding mode://		RN  = $xxxx0000//		RZ  = $xxxx0001//		RM  = $xxxx0010//		RP  = $xxxx0011//	d0{31:29} contains the g,r,s bits (extended)////	On return the value pointed to by a0 is correctly rounded,//	a0 is preserved and the g-r-s bits in d0 are cleared.//	The result is not typed - the tag field is invalid.  The//	result is still in the internal extended format.////	The INEX bit of USER_FPSR will be set if the rounded result was//	inexact (i.e. if any of the g-r-s bits were set).//	.global	roundround:// If g=r=s=0 then result is exact and round is done, else set // the inex flag in status reg and continue.  //	bsrs	ext_grs			//this subroutine looks at the //					:rounding precision and sets //					;the appropriate g-r-s bits.	tstl	%d0			//if grs are zero, go force	bne	rnd_cont		//lower bits to zero for size		swap	%d1			//set up d1.w for round prec.	bra	truncaternd_cont://// Use rounding mode as an index into a jump table for these modes.//	orl	#inx2a_mask,USER_FPSR(%a6) //set inex2/ainex	lea	mode_tab,%a1	movel	(%a1,%d1.w*4),%a1	jmp	(%a1)//// Jump table indexed by rounding mode in d1.w.  All following assumes// grs != 0.//mode_tab:	.long	rnd_near	.long	rnd_zero	.long	rnd_mnus	.long	rnd_plus////	ROUND PLUS INFINITY////	If sign of fp number = 0 (positive), then add 1 to l.//rnd_plus:	swap 	%d1			//set up d1 for round prec.	tstb	LOCAL_SGN(%a0)		//check for sign	bmi	truncate		//if positive then truncate	movel	#0xffffffff,%d0		//force g,r,s to be all f's	lea	add_to_l,%a1	movel	(%a1,%d1.w*4),%a1	jmp	(%a1)////	ROUND MINUS INFINITY////	If sign of fp number = 1 (negative), then add 1 to l.//rnd_mnus:	swap 	%d1			//set up d1 for round prec.	tstb	LOCAL_SGN(%a0)		//check for sign		bpl	truncate		//if negative then truncate	movel	#0xffffffff,%d0		//force g,r,s to be all f's	lea	add_to_l,%a1	movel	(%a1,%d1.w*4),%a1	jmp	(%a1)////	ROUND ZERO////	Always truncate.rnd_zero:	swap 	%d1			//set up d1 for round prec.	bra	truncate//////	ROUND NEAREST////	If (g=1), then add 1 to l and if (r=s=0), then clear l//	Note that this will round to even in case of a tie.//rnd_near:	swap 	%d1			//set up d1 for round prec.	asll	#1,%d0			//shift g-bit to c-bit	bcc	truncate		//if (g=1) then	lea	add_to_l,%a1	movel	(%a1,%d1.w*4),%a1	jmp	(%a1)////	ext_grs --- extract guard, round and sticky bits//// Input:	d1 =		PREC:ROUND// Output:  	d0{31:29}=	guard, round, sticky//// The ext_grs extract the guard/round/sticky bits according to the// selected rounding precision. It is called by the round subroutine// only.  All registers except d0 are kept intact. d0 becomes an // updated guard,round,sticky in d0{31:29}//// Notes: the ext_grs uses the round PREC, and therefore has to swap d1//	 prior to usage, and needs to restore d1 to original.//ext_grs:	swap	%d1			//have d1.w point to round precision	cmpiw	#0,%d1	bnes	sgl_or_dbl	bras	end_ext_grs sgl_or_dbl:	moveml	%d2/%d3,-(%a7)		//make some temp registers	cmpiw	#1,%d1	bnes	grs_dblgrs_sgl:	bfextu	LOCAL_HI(%a0){#24:#2},%d3	//sgl prec. g-r are 2 bits right	movel	#30,%d2			//of the sgl prec. limits	lsll	%d2,%d3			//shift g-r bits to MSB of d3	movel	LOCAL_HI(%a0),%d2		//get word 2 for s-bit test	andil	#0x0000003f,%d2		//s bit is the or of all other 	bnes	st_stky			//bits to the right of g-r	tstl	LOCAL_LO(%a0)		//test lower mantissa	bnes	st_stky			//if any are set, set sticky	tstl	%d0			//test original g,r,s	bnes	st_stky			//if any are set, set sticky	bras	end_sd			//if words 3 and 4 are clr, exitgrs_dbl:    	bfextu	LOCAL_LO(%a0){#21:#2},%d3	//dbl-prec. g-r are 2 bits right	movel	#30,%d2			//of the dbl prec. limits	lsll	%d2,%d3			//shift g-r bits to the MSB of d3	movel	LOCAL_LO(%a0),%d2		//get lower mantissa  for s-bit test	andil	#0x000001ff,%d2		//s bit is the or-ing of all 	bnes	st_stky			//other bits to the right of g-r	tstl	%d0			//test word original g,r,s	bnes	st_stky			//if any are set, set sticky	bras	end_sd			//if clear, exitst_stky:	bset	#rnd_stky_bit,%d3end_sd:	movel	%d3,%d0			//return grs to d0	moveml	(%a7)+,%d2/%d3		//restore scratch registersend_ext_grs:	swap	%d1			//restore d1 to original	rts//*******************  Local Equates	.set	ad_1_sgl,0x00000100	//  constant to add 1 to l-bit in sgl prec	.set	ad_1_dbl,0x00000800	//  constant to add 1 to l-bit in dbl prec//Jump table for adding 1 to the l-bit indexed by rnd precadd_to_l:	.long	add_ext	.long	add_sgl	.long	add_dbl	.long	add_dbl////	ADD SINGLE//add_sgl:	addl	#ad_1_sgl,LOCAL_HI(%a0)	bccs	scc_clr			//no mantissa overflow	roxrw  LOCAL_HI(%a0)		//shift v-bit back in	roxrw  LOCAL_HI+2(%a0)		//shift v-bit back in	addw	#0x1,LOCAL_EX(%a0)	//and incr exponentscc_clr:	tstl	%d0			//test for rs = 0	bnes	sgl_done	andiw  #0xfe00,LOCAL_HI+2(%a0)	//clear the l-bitsgl_done:	andil	#0xffffff00,LOCAL_HI(%a0) //truncate bits beyond sgl limit	clrl	LOCAL_LO(%a0)		//clear d2	rts////	ADD EXTENDED//add_ext:	addql  #1,LOCAL_LO(%a0)		//add 1 to l-bit	bccs	xcc_clr			//test for carry out	addql  #1,LOCAL_HI(%a0)		//propagate carry	bccs	xcc_clr	roxrw  LOCAL_HI(%a0)		//mant is 0 so restore v-bit	roxrw  LOCAL_HI+2(%a0)		//mant is 0 so restore v-bit	roxrw	LOCAL_LO(%a0)	roxrw	LOCAL_LO+2(%a0)	addw	#0x1,LOCAL_EX(%a0)	//and inc expxcc_clr:	tstl	%d0			//test rs = 0	bnes	add_ext_done	andib	#0xfe,LOCAL_LO+3(%a0)	//clear the l bitadd_ext_done:	rts////	ADD DOUBLE//add_dbl:	addl	#ad_1_dbl,LOCAL_LO(%a0)	bccs	dcc_clr	addql	#1,LOCAL_HI(%a0)		//propagate carry	bccs	dcc_clr	roxrw	LOCAL_HI(%a0)		//mant is 0 so restore v-bit	roxrw	LOCAL_HI+2(%a0)		//mant is 0 so restore v-bit	roxrw	LOCAL_LO(%a0)	roxrw	LOCAL_LO+2(%a0)	addw	#0x1,LOCAL_EX(%a0)	//incr exponentdcc_clr:	tstl	%d0			//test for rs = 0	bnes	dbl_done	andiw	#0xf000,LOCAL_LO+2(%a0)	//clear the l-bitdbl_done:	andil	#0xfffff800,LOCAL_LO(%a0) //truncate bits beyond dbl limit	rtserror:	rts//// Truncate all other bits//trunct:	.long	end_rnd	.long	sgl_done	.long	dbl_done	.long	dbl_donetruncate:	lea	trunct,%a1	movel	(%a1,%d1.w*4),%a1	jmp	(%a1)end_rnd:	rts////	NORMALIZE//// These routines (nrm_zero & nrm_set) normalize the unnorm.  This // is done by shifting the mantissa left while decrementing the // exponent.//// NRM_SET shifts and decrements until there is a 1 set in the integer // bit of the mantissa (msb in d1).//// NRM_ZERO shifts and decrements until there is a 1 set in the integer // bit of the mantissa (msb in d1) unless this would mean the exponent // would go less than 0.  In that case the number becomes a denorm - the // exponent (d0) is set to 0 and the mantissa (d1 & d2) is not // normalized.//// Note that both routines have been optimized (for the worst case) and // therefore do not have the easy to follow decrement/shift loop.////	NRM_ZERO////	Distance to first 1 bit in mantissa = X//	Distance to 0 from exponent = Y//	If X < Y//	Then//	  nrm_set//	Else//	  shift mantissa by Y//	  set exponent = 0////input://	FP_SCR1 = exponent, ms mantissa part, ls mantissa part//output://	L_SCR1{4} = fpte15 or ete15 bit//	.global	nrm_zeronrm_zero:	movew	LOCAL_EX(%a0),%d0	cmpw   #64,%d0          //see if exp > 64 	bmis	d0_less	bsr	nrm_set		//exp > 64 so exp won't exceed 0 	rtsd0_less:	moveml	%d2/%d3/%d5/%d6,-(%a7)	movel	LOCAL_HI(%a0),%d1	movel	LOCAL_LO(%a0),%d2	bfffo	%d1{#0:#32},%d3	//get the distance to the first 1 //				;in ms mant	beqs	ms_clr		//branch if no bits were set	cmpw	%d3,%d0		//of X>Y	bmis	greater		//then exp will go past 0 (neg) if //				;it is just shifted	bsr	nrm_set		//else exp won't go past 0	moveml	(%a7)+,%d2/%d3/%d5/%d6	rts	

⌨️ 快捷键说明

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