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

📄 scale.s

📁 优龙2410linux2.6.8内核源代码
💻 S
字号:
||	scale.sa 3.3 7/30/91||	The entry point sSCALE computes the destination operand|	scaled by the source operand.  If the absolute value of|	the source operand is (>= 2^14) an overflow or underflow|	is returned.||	The entry point sscale is called from do_func to emulate|	the fscale unimplemented instruction.||	Input: Double-extended destination operand in FPTEMP,|		double-extended source operand in ETEMP.||	Output: The function returns scale(X,Y) to fp0.||	Modifies: fp0.||	Algorithm:||		Copyright (C) Motorola, Inc. 1990|			All Rights Reserved||	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA|	The copyright notice above does not evidence any|	actual or intended publication of such source code.|SCALE    idnt    2,1 | Motorola 040 Floating Point Software Package	|section	8#include "fpsp.h"	|xref	t_ovfl2	|xref	t_unfl	|xref	round	|xref	t_resdnrmSRC_BNDS: .short	0x3fff,0x400c|| This entry point is used by the unimplemented instruction exception| handler.||||	FSCALE|	.global	sscalesscale:	fmovel		#0,%fpcr		|clr user enabled exc	clrl		%d1	movew		FPTEMP(%a6),%d1	|get dest exponent	smi		L_SCR1(%a6)	|use L_SCR1 to hold sign	andil		#0x7fff,%d1	|strip sign	movew		ETEMP(%a6),%d0	|check src bounds	andiw		#0x7fff,%d0	|clr sign bit	cmp2w		SRC_BNDS,%d0	bccs		src_in	cmpiw		#0x400c,%d0	|test for too large	bge		src_out|| The source input is below 1, so we check for denormalized numbers| and set unfl.|src_small:	moveb		DTAG(%a6),%d0	andib		#0xe0,%d0	tstb		%d0	beqs		no_denorm	st		STORE_FLG(%a6)	|dest already contains result	orl		#unfl_mask,USER_FPSR(%a6) |set UNFLden_done:	leal		FPTEMP(%a6),%a0	bra		t_resdnrmno_denorm:	fmovel		USER_FPCR(%a6),%FPCR	fmovex		FPTEMP(%a6),%fp0	|simply return dest	rts|| Source is within 2^14 range.  To perform the int operation,| move it to d0.|src_in:	fmovex		ETEMP(%a6),%fp0	|move in src for int	fmovel		#rz_mode,%fpcr	|force rz for src conversion	fmovel		%fp0,%d0		|int src to d0	fmovel		#0,%FPSR		|clr status from above	tstw		ETEMP(%a6)	|check src sign	blt		src_neg|| Source is positive.  Add the src to the dest exponent.| The result can be denormalized, if src = 0, or overflow,| if the result of the add sets a bit in the upper word.|src_pos:	tstw		%d1		|check for denorm	beq		dst_dnrm	addl		%d0,%d1		|add src to dest exp	beqs		denorm		|if zero, result is denorm	cmpil		#0x7fff,%d1	|test for overflow	bges		ovfl	tstb		L_SCR1(%a6)	beqs		spos_pos	orw		#0x8000,%d1spos_pos:	movew		%d1,FPTEMP(%a6)	|result in FPTEMP	fmovel		USER_FPCR(%a6),%FPCR	fmovex		FPTEMP(%a6),%fp0	|write result to fp0	rtsovfl:	tstb		L_SCR1(%a6)	beqs		sovl_pos	orw		#0x8000,%d1sovl_pos:	movew		FPTEMP(%a6),ETEMP(%a6)	|result in ETEMP	movel		FPTEMP_HI(%a6),ETEMP_HI(%a6)	movel		FPTEMP_LO(%a6),ETEMP_LO(%a6)	bra		t_ovfl2denorm:	tstb		L_SCR1(%a6)	beqs		den_pos	orw		#0x8000,%d1den_pos:	tstl		FPTEMP_HI(%a6)	|check j bit	blts		nden_exit	|if set, not denorm	movew		%d1,ETEMP(%a6)	|input expected in ETEMP	movel		FPTEMP_HI(%a6),ETEMP_HI(%a6)	movel		FPTEMP_LO(%a6),ETEMP_LO(%a6)	orl		#unfl_bit,USER_FPSR(%a6)	|set unfl	leal		ETEMP(%a6),%a0	bra		t_resdnrmnden_exit:	movew		%d1,FPTEMP(%a6)	|result in FPTEMP	fmovel		USER_FPCR(%a6),%FPCR	fmovex		FPTEMP(%a6),%fp0	|write result to fp0	rts|| Source is negative.  Add the src to the dest exponent.| (The result exponent will be reduced).  The result can be| denormalized.|src_neg:	addl		%d0,%d1		|add src to dest	beqs		denorm		|if zero, result is denorm	blts		fix_dnrm	|if negative, result is|					;needing denormalization	tstb		L_SCR1(%a6)	beqs		sneg_pos	orw		#0x8000,%d1sneg_pos:	movew		%d1,FPTEMP(%a6)	|result in FPTEMP	fmovel		USER_FPCR(%a6),%FPCR	fmovex		FPTEMP(%a6),%fp0	|write result to fp0	rts|| The result exponent is below denorm value.  Test for catastrophic| underflow and force zero if true.  If not, try to shift the| mantissa right until a zero exponent exists.|fix_dnrm:	cmpiw		#0xffc0,%d1	|lower bound for normalization	blt		fix_unfl	|if lower, catastrophic unfl	movew		%d1,%d0		|use d0 for exp	movel		%d2,-(%a7)	|free d2 for norm	movel		FPTEMP_HI(%a6),%d1	movel		FPTEMP_LO(%a6),%d2	clrl		L_SCR2(%a6)fix_loop:	addw		#1,%d0		|drive d0 to 0	lsrl		#1,%d1		|while shifting the	roxrl		#1,%d2		|mantissa to the right	bccs		no_carry	st		L_SCR2(%a6)	|use L_SCR2 to capture inexno_carry:	tstw		%d0		|it is finished when	blts		fix_loop	|d0 is zero or the mantissa	tstb		L_SCR2(%a6)	beqs		tst_zero	orl		#unfl_inx_mask,USER_FPSR(%a6)|					;set unfl, aunfl, ainex|| Test for zero. If zero, simply use fmove to return +/- zero| to the fpu.|tst_zero:	clrw		FPTEMP_EX(%a6)	tstb		L_SCR1(%a6)	|test for sign	beqs		tst_con	orw		#0x8000,FPTEMP_EX(%a6) |set sign bittst_con:	movel		%d1,FPTEMP_HI(%a6)	movel		%d2,FPTEMP_LO(%a6)	movel		(%a7)+,%d2	tstl		%d1	bnes		not_zero	tstl		FPTEMP_LO(%a6)	bnes		not_zero|| Result is zero.  Check for rounding mode to set lsb.  If the| mode is rp, and the zero is positive, return smallest denorm.| If the mode is rm, and the zero is negative, return smallest| negative denorm.|	btstb		#5,FPCR_MODE(%a6) |test if rm or rp	beqs		no_dir	btstb		#4,FPCR_MODE(%a6) |check which one	beqs		zer_rmzer_rp:	tstb		L_SCR1(%a6)	|check sign	bnes		no_dir		|if set, neg op, no inc	movel		#1,FPTEMP_LO(%a6) |set lsb	bras		sm_dnrmzer_rm:	tstb		L_SCR1(%a6)	|check sign	beqs		no_dir		|if clr, neg op, no inc	movel		#1,FPTEMP_LO(%a6) |set lsb	orl		#neg_mask,USER_FPSR(%a6) |set N	bras		sm_dnrmno_dir:	fmovel		USER_FPCR(%a6),%FPCR	fmovex		FPTEMP(%a6),%fp0	|use fmove to set cc's	rts|| The rounding mode changed the zero to a smallest denorm. Call| t_resdnrm with exceptional operand in ETEMP.|sm_dnrm:	movel		FPTEMP_EX(%a6),ETEMP_EX(%a6)	movel		FPTEMP_HI(%a6),ETEMP_HI(%a6)	movel		FPTEMP_LO(%a6),ETEMP_LO(%a6)	leal		ETEMP(%a6),%a0	bra		t_resdnrm|| Result is still denormalized.|not_zero:	orl		#unfl_mask,USER_FPSR(%a6) |set unfl	tstb		L_SCR1(%a6)	|check for sign	beqs		fix_exit	orl		#neg_mask,USER_FPSR(%a6) |set Nfix_exit:	bras		sm_dnrm|| The result has underflowed to zero. Return zero and set| unfl, aunfl, and ainex.|fix_unfl:	orl		#unfl_inx_mask,USER_FPSR(%a6)	btstb		#5,FPCR_MODE(%a6) |test if rm or rp	beqs		no_dir2	btstb		#4,FPCR_MODE(%a6) |check which one	beqs		zer_rm2zer_rp2:	tstb		L_SCR1(%a6)	|check sign	bnes		no_dir2		|if set, neg op, no inc	clrl		FPTEMP_EX(%a6)	clrl		FPTEMP_HI(%a6)	movel		#1,FPTEMP_LO(%a6) |set lsb	bras		sm_dnrm		|return smallest denormzer_rm2:	tstb		L_SCR1(%a6)	|check sign	beqs		no_dir2		|if clr, neg op, no inc	movew		#0x8000,FPTEMP_EX(%a6)	clrl		FPTEMP_HI(%a6)	movel		#1,FPTEMP_LO(%a6) |set lsb	orl		#neg_mask,USER_FPSR(%a6) |set N	bra		sm_dnrm		|return smallest denormno_dir2:	tstb		L_SCR1(%a6)	bges		pos_zeroneg_zero:	clrl		FP_SCR1(%a6)	|clear the exceptional operand	clrl		FP_SCR1+4(%a6)	|for gen_except.	clrl		FP_SCR1+8(%a6)	fmoves		#0x80000000,%fp0	rtspos_zero:	clrl		FP_SCR1(%a6)	|clear the exceptional operand	clrl		FP_SCR1+4(%a6)	|for gen_except.	clrl		FP_SCR1+8(%a6)	fmoves		#0x00000000,%fp0	rts|| The destination is a denormalized number.  It must be handled| by first shifting the bits in the mantissa until it is normalized,| then adding the remainder of the source to the exponent.|dst_dnrm:	moveml		%d2/%d3,-(%a7)	movew		FPTEMP_EX(%a6),%d1	movel		FPTEMP_HI(%a6),%d2	movel		FPTEMP_LO(%a6),%d3dst_loop:	tstl		%d2		|test for normalized result	blts		dst_norm	|exit loop if so	tstl		%d0		|otherwise, test shift count	beqs		dst_fin		|if zero, shifting is done	subil		#1,%d0		|dec src	lsll		#1,%d3	roxll		#1,%d2	bras		dst_loop|| Destination became normalized.  Simply add the remaining| portion of the src to the exponent.|dst_norm:	addw		%d0,%d1		|dst is normalized; add src	tstb		L_SCR1(%a6)	beqs		dnrm_pos	orl		#0x8000,%d1dnrm_pos:	movemw		%d1,FPTEMP_EX(%a6)	moveml		%d2,FPTEMP_HI(%a6)	moveml		%d3,FPTEMP_LO(%a6)	fmovel		USER_FPCR(%a6),%FPCR	fmovex		FPTEMP(%a6),%fp0	moveml		(%a7)+,%d2/%d3	rts|| Destination remained denormalized.  Call t_excdnrm with| exceptional operand in ETEMP.|dst_fin:	tstb		L_SCR1(%a6)	|check for sign	beqs		dst_exit	orl		#neg_mask,USER_FPSR(%a6) |set N	orl		#0x8000,%d1dst_exit:	movemw		%d1,ETEMP_EX(%a6)	moveml		%d2,ETEMP_HI(%a6)	moveml		%d3,ETEMP_LO(%a6)	orl		#unfl_mask,USER_FPSR(%a6) |set unfl	moveml		(%a7)+,%d2/%d3	leal		ETEMP(%a6),%a0	bra		t_resdnrm|| Source is outside of 2^14 range.  Test the sign and branch| to the appropriate exception handler.|src_out:	tstb		L_SCR1(%a6)	beqs		scro_pos	orl		#0x8000,%d1scro_pos:	movel		FPTEMP_HI(%a6),ETEMP_HI(%a6)	movel		FPTEMP_LO(%a6),ETEMP_LO(%a6)	tstw		ETEMP(%a6)	blts		res_negres_pos:	movew		%d1,ETEMP(%a6)	|result in ETEMP	bra		t_ovfl2res_neg:	movew		%d1,ETEMP(%a6)	|result in ETEMP	leal		ETEMP(%a6),%a0	bra		t_unfl	|end

⌨️ 快捷键说明

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