V9/libc/sun/Fdtos.s

	.data
	.asciz	"@(#)Fdtos.s 1.1 86/02/03 Copyr 1985 Sun Micro"
	.even
	.text

|	Copyright (c) 1985 by Sun Microsystems, Inc.

#include "fpcrtdefs.h"

RTENTRY(Fdtos)
	movel	d0,a0			| a0 saves x.
	andl	#0x7fffffff,d0		| Clear sign bit.
	cmpl	#0x38100000,d0
	blts	small			| Branch if small exponent.
	cmpl	#0x47f00000,d0
	bges	big			| Branch if big exponent.
	subl	#0x38000000,d0
	lsll	#1,d1			| Shift left three places.
	roxll	#1,d0
	lsll	#1,d1
	roxll	#1,d0
	lsll	#1,d1
	roxll	#1,d0
	addl	#0x80000000,d1		| Add round bit.
	bccs	1f
	addql	#1,d0			| Propagate carry.
1:
	tstl	d1
	bnes	sign			| Branch if not ambiguous.
	andl	#0xfffffffe,d0		| Force round to even.
sign:
	cmpl	#0,a0
	bges	1f			| Branch if sign of x is positive.
	orl	#0x80000000,d0		| Set negative.
1:
	RET

big:
	cmpl	#0x7ff00000,d0
	bgts	nan			| Branch if nan.
	blts	inf			| Branch if overflow.
	tstl	d1
	bnes	nan			| Branch if nan.
inf:
	movel	#0x7f800000,d0		| Make inf.
	clrl	d1
	bras	sign
nan:
	lsll	#1,d1			| Shift left three places.
	roxll	#1,d0
	lsll	#1,d1
	roxll	#1,d0
	lsll	#1,d1
	roxll	#1,d0
	orl	#0x7fc00000,d0		| Force quiet nan.
	bras	sign
small:
	cmpl	#0x36900000,d0
	bges	subnorm			| Branch if possible subnorm.
	clrl	d0
	bras	sign			| Branch if zero.
subnorm:
	lsll	#1,d1			| Shift left three places.
	roxll	#1,d0
	lsll	#1,d1
	roxll	#1,d0
	lsll	#1,d1
	roxll	#1,d0
	tstl	d1
	beqs	1f			| Branch if no lower bits.
	orl	#0x80000000,d1		| Set sticky bit.
	bras	2f
1:
	clrl	d1			| Clear sticky bit.
2:
	swap    d0
	movew	d0,d1
	swap 	d0
	lsrw	#7,d1
	andl	#0x007fffff,d0		| Clear exponent.
	orl	#0x00800000,d0		| Set I bit.
	subw	#0x0180,d1		| Convert to shift count.
	bges	2f

norm:
	lsrl	#1,d0
	bcc	1f
	orl	#0x80000000,d1		| Force sticky bit.
1:
	addqw	#1,d1
	blts	norm

2:
	addql	#1,d0			| Round bit.
	btst	#0,d0
	bnes	2f			| Branch not ambiguous.
	btst	#31,d1
	bnes	2f			| Branch not ambiguous.
	andl	#0x01fffffc,d0		| Force round to even.
2:
	lsrl	#1,d0			| Remove round bit.
	jra	sign