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

📄 dtoa.s

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 S
字号:
/* --------------------------------------------------- *//* | Copyright (c) 1986 MIPS Computer Systems, Inc.  | *//* | All Rights Reserved.                            | *//* --------------------------------------------------- *//* $Header: dtoa.s,v 1.3 89/06/25 13:24:25 cprice Exp $ */#include <regdef.h>/* _dtoa (buffer, ndigit, x, fflag) *//* Store sign, ndigits of x, and null in buffer.  Digits are in ascii.   1 <= ndigits <= 17.  Return exponent.  If fflag set then generate   Fortran F-format; i.e. ndigits after decimal point. */.globl _dtoa.ent _dtoa_dtoa:	.frame	sp, 0, t9	move	t9, ra	/* Sign */	li	t1, 32#if MIPSEL	bgez	a3, 1f	li	t1, 451:	sll	t5, a3, 1	srl	t0, a2, 31	or	t5, t0	sll	t4, a2, 1#else	bgez	a2, 1f	li	t1, 451:	sll	t5, a2, 1	srl	t0, a3, 31	or	t5, t0	sll	t4, a3, 1#endif	sb	t1, (a0)	addu	a0, 1	/* log10 approximation */	li	t2, 0x4D104D42 >> 21	# log10(2), shifted so . between hi/lo	subu	t1, t5, 1023 << 21	bgez	t1, 2f	addu	t2, 12:	mult	t1, t2	srl	t8, t5, 21	beq	t8, 0, 10f	beq	t8, 2047, 20f	/* Convert to fixed point number in range [1,100) by multiplication	   by appropriate power of 10. */	sll	t5, 11	srl	t5, 11	or	t5, 1 << 21	mfhi	v0			# approximate exponent15:	neg	t0, v0	jal	_tenscale	subu	t8, 1023+20	addu	t8, v1	neg	t8	/* Extract first digit */	srl	a2, t3, t8	sll	a3, a2, t8	subu	t3, a3	sltu	t4, a2, 10		# first digit > 9?	/* Handle F-format */	lw	t5, 16(sp)		# fflag	beq	t5, 0, 18f	# add corrected exponent+1 to digits after point to get	# the number of digits to produce	subu	t5, t4, v0		# ndigit - ((ld < 10) - v0) + 2	subu	a1, t5			# = ndigit + v0 + (ld >= 10) + 1	addu	a1, 2				bgtz	a1, 17f	## ndigit <= 0	xor	t5, t4, 1	addu	v0, t5	bltz	a1, 6f			# return null string if ndigit < 0	## ndigit = 0, return "" if round-down, or "1" if round-up	bne	t4, 0, 19f		# first digit < 10	bltu	a2, 50, 6f	bgtu	a2, 50, 7f	b	55f17:	ble	a1, 17, 18f		# no more than 17 digits	li	a1, 1718:	addu	a1, a0			# a1: stop point in buffer	bne	t4, 0, 3f	/* log10 approximation was low by 1, so we got first "digit" > 9 */	addu	v0, 1#if 1	/* is this necessary?? */	divu	a3, a2, 10	remu	a2, 10	addu	a3, 48#else	/* or will this suffice?? */	li	a3, 48+1	subu	a2, 10#endif	sb	a3, (a0)		# store extra digit	addu	a0, 1	bne	a0, a1, 3f19:	bltu	a2, 5, 6f	bgtu	a2, 5, 7f	b	55f3:	addu	a2, 48			# store digit	sb	a2, (a0)	addu	a0, 1	beq	a0, a1, 5f		# that may be it	/* Now produce digits by multiplying fraction by 10 and taking	   integer part.  Actually multiply 5 (it's easier) and take	   integer part from decreasing bit positions. */4:	srl	t7, t0, 30	sll	t5, t0, 2	not	t6, t5	sltu	t6, t6, t0	addu	t4, t7, t6	addu	t0, t5	srl	t7, t1, 30	sll	t5, t1, 2	not	t6, t5	sltu	t6, t6, t1	addu	t1, t5	addu	t7, t6	not	t6, t4	sltu	t6, t6, t1	addu	t1, t4	addu	t4, t7, t6	srl	t7, t2, 30	sll	t5, t2, 2	not	t6, t5	sltu	t6, t6, t2	addu	t2, t5	addu	t7, t6	not	t6, t4	sltu	t6, t6, t2	addu	t2, t4	addu	t4, t7, t6	sll	t5, t3, 2	addu	t3, t5	addu	t3, t4	subu	t8, 1	srl	a2, t3, t8	sll	a3, a2, t8	subu	t3, a3	addu	a2, 48	sb	a2, (a0)	addu	a0, 1	bne	a0, a1, 4b5:	/* digit production complete.  now round */	subu	t8, 1	srl	a3, t3, t8	beq	a3, 0, 6f55:	bne	t2, 0, 7f	subu	a3, t3, 1	bne	t1, 0, 7f	and	a3, t3	bne	t0, 0, 7f	and	a2, 1	bne	a3, 0, 7f	bne	a2, 0, 7f6:	/* round down, i.e. done */	sb	$0, (a0)	j	t97:	/* round up (in ascii!) */	subu	t1, a0, 175:.set noreorder	lbu	t0, (t1)	beq	t0, 48+9, 8f	bltu	t0, 48, 9f		/* ' ' and '-' both < '0' */	 addu	t0, 1.set reorder	sb	t0, (t1)	sb	$0, (a0)	j	t98:	li	t0, 48	sb	t0, (t1)	subu	t1, 1	b	75b9:	/* tried to round into sign position */	addu	v0, 1	lw	t5, 16(sp)		# fflag	li	t0, 48+1	beq	t5, 0, 91f	li	t4, 48	sb	t4, 0(a0)	addu	a0, 191:	sb	t0, 1(t1)	sb	$0, (a0)	j	t9	10:	/* output 0 or denorm */	bne	t5, 0, 12f	bne	t4, 0, 12f	/* zero */	/*	 * Neither 4.3BSD nor SunOS 3.something-or-other	 * output an extra zero for f-format (from fcvt)	 * compared to e-format (ecvt) for zero.	 * That is, they don't seem to believe that a zero	 * is 0.0000 and requires a digit preceeding	 * the decimal -- at least in this context.	 *	 * This code is removed for compatibility since what the	 * "real" answer is isn't obvious to me.	 * The code is left here in case it turns out that this	 * is a mistake and should be "un"-repaired.	 *	 * lw	t0, 16(sp)	 * addu	a1, t0	 */	li	t2, 48	blez	a1, 40f	addu	a1, a011:	sb	t2, (a0)	addu	a0, 1	bne	a0, a1, 11b40:	sb	$0, (a0)	li	v0, 0	j	t912:	/* denorm */	/* normalize with slow but small loop (denorm speed is unimportant) */	li	t8, -1022	li	t2, 1 << 2113:	subu	t8, 1	sll	t5, 1	srl	t0, t4, 31	or	t5, t0	sll	t4, 1	and	t0, t5, t2	beq	t0, 0, 13b14:	/* log10 approximation */		sll	t1, t8, 20	addu	t1, t5	subu	t1, t2	li	t2, (0x4D104D42 >> 20) + 1	mult	t1, t2	addu	t8, 1023	mfhi	v0	b	15b20:	/* output +-Infinity or Nan */	addu	a1, a0	la	t0, nan	bne	t4, 0, 22f	sll	t1, t5, 11	bne	t1, 0, 22f	la	t0, infinity22:	lbu	t1, (t0)	addu	a0, 1	sb	t1, -1(a0)	beq	t1, 0, 23f	addu	t0, 1	bne	a0, a1, 22b23:	li	v0, 0x80000000	j	t9.end _dtoa.rdatainfinity:	.asciiz "Infinity"nan:	.asciiz "NaN"

⌨️ 快捷键说明

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