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

📄 fmuls.s

📁 操作系统SunOS 4.1.3版本的源码
💻 S
字号:
	.data|	.asciz	"@(#)Fmuls.s 1.1 92/07/30 SMI"	.even	.text|	Copyright (c) 1987 by Sun Microsystems, Inc.#include "fpcrtdefs.h"/* *	ieee single floating multiply *	copyright 1981, 1982 Richard E. James III *	translated to SUN idiom 14 March 1983 rt *//* *	entry conditions: *	    first argument in d0 *	    second argument in d1 *	exit conditions: *	    result (4 bytes) in d0 * *	register conventions: *	    d0		operand1/upper1 *	    d1		operand2/upper2 *	    d2		9/lower1 *	    d3		lower2 *	    d4		exponent *	    d5		sign */	NSAVED   = 5*4		| 5 registers * sizeof(register)RTENTRY(Fsqrs)	movel	d0,d1		| Copy second argument.	bras	Fmuls2RTENTRY(Fmuls)|	save registersFmuls2:	moveml	d2-d5/a2,sp@-	| registers 	| save sign of result	movl	d0,d5	eorl	d1,d5		| sign of result	asll	#1,d0		| toss sign	asll	#1,d1		| EEmmmm0	cmpl	d1,d0	| order operands (exponents at least)	blss	eswap	exg	d0,d1		| d1 = larger	| extract and check exponentseswap:	roll	#8,d0	roll	#8,d1		| mmmmm0ee	clrw	d4	movb	d0,d4	clrw	d3	movb	d1,d3	addw	d3,d4		| result exp	cmpb	#0xff, d1	beqs	ofl		| infinity or nan	tstb	d0	beqs	ufl		| 0 or gu (denormalized)	| clear exponent; set hidden bit	movb	#1,d0	rorl	#1,d0back:	movb	#1,d1	rorl	#1,d1	movl	d0,d2		| d2 gets x.	movl	d1,d3		| d3 gets y.	swap	d0		| d0 gets xu.	swap	d1		| d1 gets yu.	movw	d1,d5		| d5 gets yu.	mulu	d2,d1		| d1 gets xl*yu.	mulu	d3,d2		| d2 gets xl*yl.	mulu	d0,d3		| d3 gets xu*yl.	mulu	d5,d0		| d0 gets xu*yu.	addl	d3,d1		| d1 gets middle = xu*yl+xl*yu.	bccs	1$		| Branch if no carry occurred.	addl	#0x10000,d0	| Propagate carry to upper product.1$:	swap	d1		| d1 gets middle(m) (ml,mu).	clrl	d3			movw	d1,d3		| d3 gets (0,mu).	clrw	d1		| d1 gets (ml,0).	addl	d2,d1		| d1 gets lower part of final product.	addxl	d3,d0		| d0 gets upper part of final product.	tstl	d1	beqs	2$		| Branch if lower part is exact.	bset	#0,d0		| Set sticky bit if lower part has bits.2$: 			subw	#126,d4		| toss extra bias	JBSR(f_rcp,a2)		| round check, pack	| build answermbuild:	rorl	#8,d0	roxll	#1,d5	roxrl	#1,d0		| append sign	| answer in d0mexit:	moveml	sp@+,d2-d5/a2	RET	| EXCEPTION HANDLINGofl:	clrb	d1	tstl	d1		| larger mantissa	bnes	mni		| user larger nan	tstl	d0	beqs	m_gennan		| 0*infmni:	movb	#0xff,d1	| inf or nan	movl	d1,d0	bras	mbuildufl:	tstl	d0		| mantissa of smaller	beqs	mbuild	| normalizing mode is embodied int the next few lines:	bmis	backnormden:subql	#1,d4		| adj exponent	lsll	#1,d0	bpls	normden	bras	backm_gennan:movl	#0x7f800002, d0	bras	mexit/* *	ieee single floating divide *	copyright 1981, Richard E. James III *	translated to SUN idiom 14 March 1983 rt *//* *	entry conditions: *	    first argument in d0 *	    second argument in d1 *	exit conditions: *	    result (4 bytes) in d0 * *	register conventions: *	    d0		top; ab;  rq *	    d1		bot; c *	    d2		     q *	    d3		bottom exp; d *	    d4		top/ final exp *	    d5		sign  */||	same as for multiply, above|	NSAVED   = 5*4		| 5 registers * sizeof(register)RTENTRY(Fdivs)|	save registers	moveml	d2-d5/a2,sp@-	| registers 	| determine sign	movl	d0,d5	eorl	d1,d5		| sign in bit 31	| split out exponent	roll	#1,d0	roll	#1,d1	roll	#8,d0	roll	#8,d1	clrw	d3	clrw	d4	movb	d0,d4		| exp of top	movb	d1,d3		| exp of bottom	andw	#0xfe00,d0	| clear out s, exp	andw	#0xfe00,d1	| clear out s, exp	| test exponents	addqb	#1,d4		| top	subqw	#1,d4	bles	toperr	addqb	#1,d0		| hidden bitbacktop:addqb	#1,d3	subqw	#1,d3		| bottom	jle	boterr	addqb	#1,d1		| hidden bit	| position mantissasbackbot:rorl	#2,d1		| 01X... 	(c*w+d) w = 2**16	rorl	#4,d0		| 0001X... 	(a*w+b)	| compute tentative exponent	subw	d3,d4	movew	d4,d5		| d5 saves sign | exponent.	| to compute ab/cd:	|    first do ab/c -> q, remainder -> r	movw	d1,d3		| save d	movl	d1,d4		| d4 saves 	(c*w+d).	swap	d1		| get c		(d*w+c)	divu	d1,d0		| ab/c 29/15->15 bits (q*w+r)	movw	d0,d2		| save q	mulu	d2,d3		| q*d	clrw	d0		| r in top	subl	d3,d0		| r-q*d = +-31 * w	asrl	#2,d0		| avoid overflow	divs	d1,d0		| more quotient	movl	d0,d1		| d1 gets remainder in upper word.	movw	d4,d3		| d3 gets d.	muls	d0,d3		| d3 gets signed(q2)*unsigned(d).	btst	#15,d4	beqs	99$		| Branch if d appeared positive in muls.	swap	d3		| If d appeared negative, correct product.	addw	d0,d3	swap	d399$:				|	extl	d2		| q	extl	d0		| second quot	swap	d2	asll	#2,d0	addl	d2,d0	asll	#1,d0	clrw	d1		| d1 gets remainder in upper, 0 lower.	subl	d3,d1		| d1 gets revised remainder.	cmpl	d4,d1	blts	1f		| Branch if remainder < 8 * (c*w+d).	addql	#8,d0		| Increment quotient.	subl	d4,d1		| Decrement remainder.1:	tstl	d1	beqs	adjexp		| Branch if exact.	bmis	decr		| Branch if remainder negative.	bset	#0,d0		| inexact => set sticky.	bras	adjexpdecr:	subql	#1,d0		| Subtract sticky bit for negative remainder.adjexp: 			| adjust exponent, round, check extremes, pack	addw	#127,d5	movew	d5,d4	JBSR(f_rcp, a2)	| reposition and append signdrepk:	rorl	#8,d0	lsll	#1,d5		| sign -> x	roxrl	#1,d0		| insert signdexit:	moveml	sp@+,d2-d5/a2	RET	| EXCEPTIONStoperr:	bnes	2$	|top is 0 or gu, normalize and return1$:	subqw	#1,d4	roll	#1,d0	bhis	1$		| loop til normalized, fall if 0	addqw	#1,d4	jra	backtop		| 0 or gu	| top is inf or nan2$:	cmpb	d3,d4	beqs	dinvop		| both inf/nan -> nan	tstl	d0	beqs	geninf		| inf/ ... = +- inf	bras	dinvop		| nan/...  =    nanboterr:	beqs	botlow		| .../(0|gu)				| .../(inf|nan)	tstl	d1	bnes	dinvop		| .../nan = nan	clrl	d0		| .../inf = +-0	bras	drepkbotlow:	tstl	d1	beqs	5$		| .../0				| .../gu:4$:	subqw	#1,d3	roll	#1,d1	bccs	4$		| loop til normalized	addqw	#1,d3	jra 	backbot	| bottom is zero5$:	tstl	d0	beqs	d_gennan		| 0/0       =   nan				| nonzero/0 = +-inf	| generate infinity for answergeninf:	movl	#0xff,d0	bras	drepk	| invalid operand/ operationdinvop:	cmpl	d0,d1	bcss	8$		| use larger nan	tstl	d1	beqs	d_gennan	| both are infinity, generate a nan	exg	d1,d0		| larger nan8$:	lsrl	#8,d0	lsrl	#1,d0	bras	bldnan		| return nand_gennan:moveq	#4,d0		| nan 4bldnan:	orl	#0x7f800000,d0	bras	dexit	EXP	= d2	TYPE	= d3	/* type values: */	    ZERO  = 1 | wonderful	    GU    = 2	    PLAIN = 3	    INF   = 4	    NAN   = 5RTENTRY(Fscaleis)	moveml	d2-d7/a2,sp@-	| state save	movel	d1,d4		| Save argument i.	movel	d0,d1		| What a crock!	JBSR(f_unpk, a2)	cmpb	#PLAIN,TYPE	| is it a funny number?	bgts	gohome		| yes -- return argument	cmpb	#ZERO,TYPE	beqs	gohome		| is zero -- return arg	| normal path through here	movw	EXP,d7			extl	d7		| d7 gets long exponent.	addl	d4,d7		| d7 gets modified exponent.	bvcs	nooflo		| Branch if no overflow.	bmis	posov		| Branch if positive overflow to -.				| Branch if negative overflow to +.negov:	movw	#-2000,EXP	bras	gohomeposov:		movw	#2000,EXP	bras	gohomenooflo:	cmpl	#2000,d7	bges	posov	cmpl	#-2000,d7	bles	negov	movw	d7,EXP		| Final OK exponent.gohome:	JBSR(f_pack,a2)	movel	d1,d0		| What a crock!gone:	moveml	sp@+,d2-d7/a2	RET

⌨️ 快捷键说明

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