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

📄 l_round.s

📁 Vxworks OS source code
💻 S
📖 第 1 页 / 共 2 页
字号:
/* l_round.s - Motorola 68040 FP rounding routines (LIB) *//* Copyright 1991-1993 Wind River Systems, Inc. */	.data	.globl	_copyright_wind_river	.long	_copyright_wind_river/*modification history--------------------01f,21jul93,kdl  added .text (SPR #2372).01e,23aug92,jcf  changed bxxx to jxx.01d,26may92,rrr  the tree shuffle01c,01jan92,jcf	reversed order of cmp <reg>,<reg>01b,17dec91,kdl	put in changes from Motorola v3.4 (from FPSP 2.1):		add check for negative loop count in __l_dnrm_lp.01a,31jul91,kdl	from Motorola FPSP v2.0.*//*DESCRIPTION	roundsa 3.2 2/18/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	8NOMANUAL*/#include "fpsp040L.h"||	__l_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 = 0x0000xxxx|		sgl = 0x0001xxxx|		dbl = 0x0002xxxx|	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).|	.text	.globl	__l_round__l_round:| If g=r=s=0 then result is exact and round is done, else set| the inex flag in status reg and continue.|	bsrl	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	jne 	rnd_cont		| lower bits to zero for size	swap	d1			| set up d1:w for round prec.	jra 	truncaternd_cont:|| Use rounding mode as an index into a jump table for these modes.|	orl	#inx2a_mask,a6@(USER_FPSR) | 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	a0@(LOCAL_SGN)		| check for sign	jmi 	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	a0@(LOCAL_SGN)		| check for sign	jpl 	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.	jra 	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	jcc 	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	jne 	sgl_or_dbl	jra 	end_ext_grssgl_or_dbl:	moveml	d2/d3,a7@-		| make some temp registers	cmpiw	#1,d1	jne 	grs_dblgrs_sgl:	bfextu	a0@(LOCAL_HI){#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	a0@(LOCAL_HI),d2		| get word 2 for s-bit test	andil	#0x0000003f,d2			| s bit is the or of all other	jne 	st_stky				| bits to the right of g-r	tstl	a0@(LOCAL_LO)			| test lower mantissa	jne 	st_stky				| if any are set, set sticky	tstl	d0				| test original g,r,s	jne 	st_stky				| if any are set, set sticky	jra 	end_sd				| if words 3 and 4 are clr, exitgrs_dbl:	bfextu	a0@(LOCAL_LO){#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 MSB of d3	movel	a0@(LOCAL_LO),d2		| get lower mantissa  for s-bit test	andil	#0x000001ff,d2			| s bit is the or-ing of all	jne 	st_stky				| other bits to the right of g-r	tstl	d0				| test word original g,r,s	jne 	st_stky				| if any are set, set sticky	jra 	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#define	ad_1_sgl 	0x00000100	/* constant to add 1 to l-bit in sgl prec */#define	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,a0@(LOCAL_HI)	jcc 	scc_clr			| no mantissa overflow	roxrw 	a0@(LOCAL_HI)		| shift v-bit back in	roxrw 	a0@(LOCAL_HI+2)		| shift v-bit back in	addw	#0x1,a0@(LOCAL_EX)	| and incr exponentscc_clr:	tstl	d0			| test for rs = 0	jne 	sgl_done	andiw  #0xfe00,a0@(LOCAL_HI+2)	| clear the l-bitsgl_done:	andil	#0xffffff00,a0@(LOCAL_HI) | truncate bits beyond sgl limit	clrl	a0@(LOCAL_LO)		| clear d2	rts||	ADD EXTENDED|add_ext:	addql  #1,a0@(LOCAL_LO)		| add 1 to l-bit	jcc 	xcc_clr			| test for carry out	addql  #1,a0@(LOCAL_HI)		| propogate carry	jcc 	xcc_clr	roxrw 	a0@(LOCAL_HI)		| mant is 0 so restore v-bit	roxrw 	a0@(LOCAL_HI+2)		| mant is 0 so restore v-bit	roxrw	a0@(LOCAL_LO)	roxrw	a0@(LOCAL_LO+2)	addw	#0x1,a0@(LOCAL_EX)	| and inc expxcc_clr:	tstl	d0			| test rs = 0	jne 	add_ext_done	andib	#0xfe,a0@(LOCAL_LO+3)	| clear the l bitadd_ext_done:	rts||	ADD DOUBLE|add_dbl:	addl	#ad_1_dbl,a0@(LOCAL_LO)	jcc 	dcc_clr	addql	#1,a0@(LOCAL_HI)	| propogate carry	jcc 	dcc_clr	roxrw	a0@(LOCAL_HI)		| mant is 0 so restore v-bit	roxrw	a0@(LOCAL_HI+2)		| mant is 0 so restore v-bit	roxrw	a0@(LOCAL_LO)	roxrw	a0@(LOCAL_LO+2)	addw	#0x1,a0@(LOCAL_EX)	| incr exponentdcc_clr:	tstl	d0			| test for rs = 0	jne 	dbl_done	andiw	#0xf000,a0@(LOCAL_LO+2)	| clear the l-bitdbl_done:	andil	#0xfffff800,a0@(LOCAL_LO) | 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 # __l_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|	  __l_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|	.globl	__l_nrm_zero__l_nrm_zero:	movew	a0@(LOCAL_EX),d0	cmpw   #64,d0          | see if exp > 64	jmi 	d0_less	bsrl	__l_nrm_set		/* | exp > 64 so exp won't exceed 0  */

⌨️ 快捷键说明

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