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

📄 r_pow_.s

📁 操作系统SunOS 4.1.3版本的源码
💻 S
字号:
/ /	.data/	.asciz	"@(#)r_pow_.s 1.1 92/07/30 SMI"/	.even/	.text//	Copyright (c) 1988 by Sun Microsystems, Inc./     Note :  0^NaN should not signal "invalid" but this implementation/             does because y is placed on the NPX stack./ Algorithm (SVID msg only applies to double precision) :// x ** 0 is 1				(SVID DOMAIN err if 0**0)/ x ** NaN (except 0) is NaN		(i flag)/ NaN ** y (except 0) is NaN		(i flag)/ x ** 1 is x/ +-(|x| > 1) **  +inf is +inf/ +-(|x| > 1) **  -inf is +0/ +-(|x| < 1) **  +inf is +0/ +-(|x| < 1) **  -inf is +inf/ +-(|x| = 1) ** +-inf is NaN		(i flag)/ +0 ** +y (except 0, NaN)              is +0/ -0 ** +y (except 0, NaN, odd int)     is +0/ +0 ** -y (except 0, NaN)              is +inf (z flag & SVID SING err)/ -0 ** -y (except 0, NaN, odd int)     is +inf (z flag & SING err)/ -0 ** y (odd int)			is - (+0 ** x)/ +inf ** +y (except 0, NaN)    	is +inf/ +inf ** -y (except 0, NaN)    	is +0/ -inf ** +-y (except 0, NaN)   	is -0 ** -+y (NO z flag or SVID msg)/ x ** -1 is 1/x/ x ** 2 is square(x)/ -x ** y (an integer) is (-1)**(y) * (+x)**(y)/ x ** y (x negative & y not integer) is NaN (i flag & SVID neg#**non-int msg)/ if x and y are finite and x**y = 0	print SVID underflow message/ if x and y are finite and x**y = inf	print SVID overflow message	.data	.align	4negzero:	.float	-0.0half:	.float	0.5one:	.float	1.0negone:	.float	-1.0two:	.float	2.0Snan:	.long	0x7f800001pinfinity:	.long	0x7f800000ninfinity:	.long	0xff800000	.text	.globl	r_pow_r_pow_:	pushl	%ebp	movl	%esp,%ebp	subl	$8,%esp	movl	8(%ebp),%eax	flds	0(%eax)			/ x	fxam				/ determine class of x	fnstsw	%ax			/ store status in %ax	movb	%ah,%dh			/ %dh <- condition code of x	movl	12(%ebp),%eax	flds	0(%eax)			/ y , x	fxam				/ determine class of y	fnstsw	%ax			/ store status in %ax	movb	%ah,%dl			/ %dl <- condition code of y	call	_pow_main_	leave	ret_pow_main_:	/ x ** 0 is 1	movb	%dl,%cl	andb	$0x45,%cl	cmpb	$0x40,%cl		/ C3=1 C2=0 C1=? C0=0 when +-0	jne	POWYNOTZERO	fstp	%st(0)			/ x	fstp	%st(0)			/ stack empty	fld1				/ 1	retPOWYNOTZERO:	/ x ** NaN (except 0) is NaN	movb	%dl,%cl	andb	$0x45,%cl	cmpb	$0x01,%cl		/ C3=0 C2=0 C1=? C0=1 when +-NaN	jne	POWYNOTNAN	fstp	%st(1)			/ y	retPOWYNOTNAN:	/ NaN ** y (except 0) is NaN	movb	%dh,%cl	andb	$0x45,%cl	cmpb	$0x01,%cl		/ C3=0 C2=0 C1=? C0=1 when +-NaN	jne	POWXNOTNAN	fstp	%st(0)			/ x	retPOWXNOTNAN:	/ x ** 1 is x	fcoms	one			/ y , x	fnstsw	%ax			/ store status in %ax	sahf				/ 80387 flags in %ax to 80386 flags	je	retx	/ +-(|x| > 1) **  +inf is +inf	/ +-(|x| > 1) **  -inf is +0	/ +-(|x| < 1) **  +inf is +0	/ +-(|x| < 1) **  -inf is +inf	/ +-(|x| = 1) ** +-inf is NaN	movb	%dl,%cl	andb	$0x47,%cl	cmpb	$0x05,%cl		/ C3=0 C2=1 C1=0 C0=1 when +inf	je	yispinf	cmpb	$0x07,%cl		/ C3=0 C2=1 C1=1 C0=1 when -inf	je	yisninf	/ +0 ** +y (except 0, NaN)		is +0	/ -0 ** +y (except 0, NaN, odd int)	is +0	/ +0 ** -y (except 0, NaN)		is +inf (z flag)	/ -0 ** -y (except 0, NaN, odd int)	is +inf (z flag)	/ -0 ** y (odd int)			is - (+0 ** x)	movb	%dh,%cl	andb	$0x47,%cl	cmpb	$0x40,%cl		/ C3=1 C2=0 C1=0 C0=0 when +0	je	xispzero	cmpb	$0x42,%cl		/ C3=1 C2=0 C1=1 C0=0 when -0	je	xisnzero	/ +inf ** +y (except 0, NaN)	is +inf	/ +inf ** -y (except 0, NaN)	is +0	/ -inf ** +-y (except 0, NaN)	is -0 ** -+y (NO z flag)	movb	%dh,%cl	andb	$0x47,%cl	cmpb	$0x05,%cl		/ C3=0 C2=1 C1=0 C0=1 when +inf	je	xispinf	cmpb	$0x07,%cl		/ C3=0 C2=1 C1=1 C0=1 when -inf	je	xisninf	/ x ** -1 is 1/x	fcoms	negone			/ y , x	fnstsw	%ax			/ store status in %ax	sahf				/ 80387 flags in %ax to 80386 flags	jne	POWYNOTN1	fstp	%st(0)			/ x	fdivrs	one			/ 1/x	retPOWYNOTN1:	/ x ** 2 is square(x)	fcoms	two			/ y , x	fnstsw	%ax			/ store status in %ax	sahf				/ 80387 flags in %ax to 80386 flags	jne	POWYNOT2	fstp	%st(0)			/ x	fld	%st(0)			/ x , x	fmul				/ x^2	retPOWYNOT2:	/ -x ** y (an integer) is (-1)**(y) * (+x)**(y)	/ x ** y (x negative & y not integer) is  NaN	/ if x < 0 and y is an odd int then	%ecx = $1	/ else					%ecx = $0	/ px = |x|	movl	$0,%ecx	fld	%st(1)			/ x , y , x	ftst				/ compare %st(0) with 0	fnstsw	%ax			/ store status in %ax	sahf				/ 80387 flags in %ax to 80386 flags	fstp	%st(0)			/ y , x	ja	merge			/ x > 0	/ x < 0	fld	%st(0)			/ y , y , x	frndint				/ [y] , y , x	fucomp				/ y , x	fnstsw	%ax			/ store status in %ax	sahf				/ 80387 flags in %ax to 80386 flags	je	POWXNEGYINT		/ x < 0 & y = int	/ x < 0 & y != int so x**y = NaN (i flag)	fstp	%st(0)			/ x	fstp	%st(0)			/ empty stack	flds	Snan			/ Q_nan - raise invalid flag	retPOWXNEGYINT:	/ x < 0 & y = int	fxch				/ x , y	fchs				/ px = -x , y	fxch				/ y , px	fld	%st(0)			/ y , y , px	fmuls	half			/ y/2 , y , px	fld	%st(0)			/ y/2 , y/2 , y , px	frndint				/ [y/2] , y/2 , y , px	fucompp				/ y , px	fnstsw	%ax			/ store status in %ax	sahf				/ 80387 flags in %ax to 80386 flags	je	merge			/ y = even	movl	$1,%ecxmerge:	/ px > 0	fxch				/ px , y	/ x**y   =   exp(y*ln(x))	fyl2x				/ t=y*log2(px)	fld	%st(0)			/ t , t	frndint				/ [t] , t	fxch				/ t , [t]	fucom	fnstsw	%ax			/ store status in %ax	sahf				/ 80387 flags in %ax to 80386 flags	je	xisint			/ px = int	fsub    %st(1),%st		/ t-[t] , [t]	f2xm1				/ 2**(t-[t])-1 , [t]	fadds	one			/ 2**(t-[t]) , [t]	fscale				/ 2**t = px**y , [t]	jmp	donexisint:	fstp    %st(0)                  / t=[t]	fld1                            / 1 , t	fscale                          / 1*2**t = x**y , tdone:	fstp	%st(1)			/ x**y	cmpl	$1,%ecx	jne	signok	fchs				/ change sign since x<0 & y=-intsignok:	ret/ ------------------------------------------------------------------------xispinf:	ftst				/ compare %st(0) with 0	fnstsw	%ax			/ store status in %ax	sahf				/ 80387 flags in %ax to 80386 flags	ja	retpinf			/ y > 0	jmp	retpzero		/ y < 0xisninf:	/ -inf ** +-y is -0 ** -+y	fchs				/ -y , x	flds	negzero			/ -0 , -y , x	fstp	%st(2)			/ -y , -0	jmp	xisnzeroyispinf:	fld	%st(1)			/ x , y , x	fabs				/ |x| , y , x	fcomps	one			/ y , x	fnstsw	%ax			/ store status in %ax	sahf				/ 80387 flags in %ax to 80386 flags	je	retinvalid		/ |x| = 1	ja	retpinf			/ |x| > 1	jmp	retpzero		/ |x| < 1yisninf:	fld	%st(1)			/ x , y , x	fabs				/ |x| , y , x	fcomps	one			/ y , x	fnstsw	%ax			/ store status in %ax	sahf				/ 80387 flags in %ax to 80386 flags	je	retinvalid		/ |x| = 1	ja	retpzero		/ |x| > 1	jmp	retpinf			/ |x| < 1xispzero:	/ y cannot be 0 or NaN ; stack has	y , x	ftst				/ compare %st(0) with 0	fnstsw	%ax			/ store status in %ax	sahf				/ 80387 flags in %ax to 80386 flags	ja	retpzero		/ y > 0	/ x = +0 & y < 0 so x**y = +inf	jmp	retpinfzflag		/ ret +inf & z flagxisnzero:	/ y cannot be 0 or NaN ; stack has	y , x	fld	%st(0)			/ y , y , x	frndint				/ [y] , y , x	fucomp				/ y , x	fnstsw	%ax			/ store status in %ax	sahf				/ 80387 flags in %ax to 80386 flags	jne	ynotoddint		/ y != int	fld	%st(0)			/ y , y , x	fmuls	half			/ y/2 , y , x	fld	%st(0)			/ y/2 , y/2 , y , x	frndint				/ [y/2] , y/2 , y , x	fucompp				/ y , x	fnstsw	%ax			/ store status in %ax	sahf				/ 80387 flags in %ax to 80386 flags	je	ynotoddint		/ y = even	/ y is an odd integer	ftst				/ compare %st(0) with 0	fnstsw	%ax			/ store status in %ax	sahf				/ 80387 flags in %ax to 80386 flags	ja	retnzero		/ y > 0	/ x = -0 & y < 0 (odd int)	return -inf (z flag)	/ x = -inf & y != 0 or NaN	return -inf (NO z flag)	movb	%dh,%cl	andb	$0x45,%cl	cmpb	$0x05,%cl		/ C3=0 C2=1 C1=? C0=1 when +-inf	je	POWXINF1	jmp	retninfzflag            / ret -inf & z flagPOWXINF1:	jmp	retninf			/ return -inf (NO d flag)ynotoddint:	ftst				/ compare %st(0) with 0	fnstsw	%ax			/ store status in %ax	sahf				/ 80387 flags in %ax to 80386 flags	ja	retpzero		/ y > 0	/ x = -0 & y < 0 (not odd int)	return +inf (z flag)	/ x = -inf & y not 0 or NaN 	return +inf (NO z flag)	movb	%dh,%cl	andb	$0x45,%cl	cmpb	$0x05,%cl		/ C3=0 C2=1 C1=? C0=1 when +-inf	je	POWXINF2	jmp	retpinfzflag		/ ret +inf & z flagPOWXINF2:	jmp	retpinf			/ return +inf (NO z flag)retx:	fstp	%st(0)			/ x	retretpzero:	fstp	%st(0)			/ x	fstp	%st(0)			/ stack empty	fldz				/ +0	retretnzero:	fstp	%st(0)			/ x	fstp	%st(0)			/ stack empty	flds	negzero			/ -0	retretpone:	fstp	%st(0)			/ x	fstp	%st(0)			/ stack empty	fld1				/ 1	retretinvalid:	fstp	%st(0)			/ x	fstp	%st(0)			/ stack empty	flds	Snan			/ Q NaN (i flag)	retretpinf:	fstp	%st(0)			/ x	fstp	%st(0)			/ stack empty	flds	pinfinity		/ +inf	retretninf:	fstp	%st(0)			/ x	fstp	%st(0)			/ stack empty	flds	ninfinity		/ -inf	retretpinfzflag:	fstp	%st(0)			/ x	fstp	%st(0)			/ stack empty	fldz				/ 0	fdivrs	one			/ 1/0 - raise z flag	retretninfzflag:	fstp	%st(0)			/ x	fstp	%st(0)			/ stack empty	fldz				/ 0	fdivrs	negone			/ -1/0 - raise z flag	ret

⌨️ 快捷键说明

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