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

📄 frexp.s

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 S
字号:
/*	@(#)frexp.s	4.1	(ULTRIX)	7/3/90				      *//* ------------------------------------------------------------------ *//* | Copyright Unpublished, MIPS Computer Systems, Inc.  All Rights | *//* | Reserved.  This software contains proprietary and confidential | *//* | information of MIPS and its suppliers.  Use, disclosure or     | *//* | reproduction is prohibited without the prior express written   | *//* | consent of MIPS.                                               | *//* ------------------------------------------------------------------ *//* $Header: frexp.s,v 1.1 87/02/16 11:17:28 dce Exp $ */#include <mips/regdef.h>#include <mips/asm.h>#include <fp_class.h>#include <mips/softfp.h>#define	FRAME_SIZE	24#define	LOCAL_SIZE	0#define	F12_OFFSET	FRAME_SIZE+4*0#define	A2_OFFSET	FRAME_SIZE+4*2#define	RA_OFFSET	FRAME_SIZE-LOCAL_SIZE-4*1/* * double frexp(value, eptr) * double value; int *eptr; *   In assembly: *	value -- $f12 ($f13,$f12) as a double *	eptr  -- a2 *   and the return values: *      return value -- $f0 *	*eptr        -- 0(a2) * * Frexp() returns a double x such that x = 0 or 0.5 <= |x| < 1.0 * and stores an integer n such that value = x * 2 ** n indirectly * through eptr. */NESTED(frexp, FRAME_SIZE, ra)	.mask	0x80000000, -(LOCAL_SIZE+4)	subu	sp,FRAME_SIZE	s.d	$f12,F12_OFFSET(sp)	sw	a2,A2_OFFSET(sp)	sw	ra,RA_OFFSET(sp)	# get the class of the floating point value and switch on it.	jal	fp_class_d	sll	v0,2		lw	v0,jmp_tbl(v0)	j	v0	.rdatajmp_tbl:	.word	nan	.word	nan	.word	inf	.word	inf	.word	norm	.word	norm	.word	denorm	.word	denorm	.word	zeroval	.word	zeroval	.text	nan:	# For NaN's return a the default quiet nan for both the return	# value and the integer n.	li	a0,DQUIETNAN_LESS	li	a1,DQUIETNAN_LEAST	mtc1	a0,$f1	mtc1	a1,$f0	lw	a2,A2_OFFSET(sp)	li	a0,WQUIETNAN_LEAST	sw	a0,0(a2)	lw	ra,RA_OFFSET(sp)	addu	sp,FRAME_SIZE	j	rainf:	# For infinities return the infinity and return the maximum value	# for the integer n.	l.d	$f0,F12_OFFSET(sp)	lw	a2,A2_OFFSET(sp)	li	a0,WORD_MAX	sw	a0,0(a2)	lw	ra,RA_OFFSET(sp)	addu	sp,FRAME_SIZE	j	ranorm:	# For normalized numbers return the value with the exponent changed	# to -1.  The interger n gets the exponent of the value minus 1.	l.d	$f0,F12_OFFSET(sp)	mfc1	a0,$f1	and	a1,a0,~(DEXP_MASK<<DEXP_SHIFT)	or	a1,((DEXP_BIAS-1)<<DEXP_SHIFT)	mtc1	a1,$f1	lw	a2,A2_OFFSET(sp)	srl	a0,DEXP_SHIFT	and	a0,DEXP_MASK	subu	a0,DEXP_BIAS-1	sw	a0,0(a2)	lw	ra,RA_OFFSET(sp)	addu	sp,FRAME_SIZE	j	radenorm:	# For denormalized numbers return the value with the exponent changed	# to -1 and the value normalized.  The interger n gets the exponent of	# the value minus 1 adjusted for the denorms value.	l.d	$f0,F12_OFFSET(sp)	mfc1	a2,$f1	mfc1	a3,$f0	# set the exponent (a1) separate the fraction (a2,a3) and sign (a0)	and	a0,a2,SIGNBIT	li	a1,-DEXP_BIAS+1-1	and	a2,DFRAC_MASK	/*	 * Renormalize the denormalized double value.	 */	/*	 * The first step in this process is to determine where the first	 * one bit is in the fraction (a2,a3).  After this series of tests	 * the shift count to shift the fraction left so the first 1 bit is	 * in the high bit will be in t9.  This sequence of code uses registers	 * v0,v1 and t9 (it could be done with two but with reorginization this	 * is faster).	 */	move	v0,a2	move	t9,zero	bne	a2,zero,1f	move	v0,a3	addu	t9,321:	srl	v1,v0,16	bne	v1,zero,1f	addu	t9,16	sll	v0,161:	srl	v1,v0,24	bne	v1,zero,2f	addu	t9,8	sll	v0,82:	srl	v1,v0,28	bne	v1,zero,3f	addu	t9,4	sll	v0,43:	srl	v1,v0,30	bne	v1,zero,4f	addu	t9,2	sll	v0,24:	srl	v1,v0,31	bne	v1,zero,5f	addu	t9,15:	/*	 * Now that the it is known where the first one bit is calculate the	 * amount to shift the fraction to put the first one bit in the	 * implied 1 position (also the amount to adjust the exponent by).	 * Then adjust the exponent and shift the fraction.	 */	subu	t9,DFRAC_LEAD0S	# the calulated shift amount	subu	a1,t9		# adjust the exponent	blt	t9,32,1f	subu	t9,32		# shift the fraction for >= 32 bit shifts	sll	a2,a3,t9	move	a3,zero	b	2f1:	negu	v0,t9		# shift the fraction for < 32 bit shifts	addu	v0,32	sll	a2,t9	srl	v1,a3,v0	or	a2,v1	sll	a3,t92:	# Now put the normalized value together with a -1 exponent	and	a2,~DIMP_1BIT	or	a2,((DEXP_BIAS-1)<<DEXP_SHIFT)	or	a2,a0	mtc1	a2,$f1	mtc1	a3,$f0	# Now store the integer n	lw	a2,A2_OFFSET(sp)	sw	a1,0(a2)	lw	ra,RA_OFFSET(sp)	addu	sp,FRAME_SIZE	j	razeroval: # For zeroes return zero for both the return value and the	 # integer n.	l.d	$f0,F12_OFFSET(sp)	lw	a2,A2_OFFSET(sp)	sw	zero,0(a2)	lw	ra,RA_OFFSET(sp)	addu	sp,FRAME_SIZE	j	raEND(frexp)

⌨️ 快捷键说明

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