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

📄 res_func.s

📁 优龙2410linux2.6.8内核源代码
💻 S
📖 第 1 页 / 共 4 页
字号:
wi:	moveql	#2,%d0		|set byte count	btstb	#7,STAG(%a6)	|check for extended denorm	bne	int_dnrm	|branch if so	fmovemx ETEMP(%a6),%fp0-%fp0	fcmps	#0x46fffe00,%fp0| 46fffe00 in sgl prec = 400d0000fffe000000000000 in ext prec	fbge	wo_plrg	fcmps	#0xc7000000,%fp0| c7000000 in sgl prec = c00e00008000000000000000 in ext prec	fble	wo_nlrg|| at this point, the answer is between the largest pos and neg values|	movel	USER_FPCR(%a6),%d1	|use user's rounding mode	andil	#0x30,%d1	fmovel	%d1,%fpcr	fmovew	%fp0,L_SCR1(%a6)	|let the 040 perform conversion	fmovel %fpsr,%d1	orl	%d1,USER_FPSR(%a6)	|capture inex2/ainex if set	bra	int_wrtwo_plrg:	movew	#0x7fff,L_SCR1(%a6)	|answer is largest positive int	fbeq	int_wrt			|exact answer	fcmps	#0x46ffff00,%fp0| 46ffff00 in sgl prec = 400d0000ffff000000000000 in ext prec	fbge	int_operr		|set operr	bra	int_inx			|set inexactwo_nlrg:	movew	#0x8000,L_SCR1(%a6)	fbeq	int_wrt			|exact answer	fcmps	#0xc7000080,%fp0| c7000080 in sgl prec = c00e00008000800000000000 in ext prec	fblt	int_operr		|set operr	bra	int_inx			|set inexact|| bi is used to handle a byte integer source specifier|bi:	moveql	#1,%d0		|set byte count	btstb	#7,STAG(%a6)	|check for extended denorm	bne	int_dnrm	|branch if so	fmovemx ETEMP(%a6),%fp0-%fp0	fcmps	#0x42fe0000,%fp0| 42fe0000 in sgl prec = 40050000fe00000000000000 in ext prec	fbge	by_plrg	fcmps	#0xc3000000,%fp0| c3000000 in sgl prec = c00600008000000000000000 in ext prec	fble	by_nlrg|| at this point, the answer is between the largest pos and neg values|	movel	USER_FPCR(%a6),%d1	|use user's rounding mode	andil	#0x30,%d1	fmovel	%d1,%fpcr	fmoveb	%fp0,L_SCR1(%a6)	|let the 040 perform conversion	fmovel %fpsr,%d1	orl	%d1,USER_FPSR(%a6)	|capture inex2/ainex if set	bra	int_wrtby_plrg:	moveb	#0x7f,L_SCR1(%a6)		|answer is largest positive int	fbeq	int_wrt			|exact answer	fcmps	#0x42ff0000,%fp0| 42ff0000 in sgl prec = 40050000ff00000000000000 in ext prec	fbge	int_operr		|set operr	bra	int_inx			|set inexactby_nlrg:	moveb	#0x80,L_SCR1(%a6)	fbeq	int_wrt			|exact answer	fcmps	#0xc3008000,%fp0| c3008000 in sgl prec = c00600008080000000000000 in ext prec	fblt	int_operr		|set operr	bra	int_inx			|set inexact|| Common integer routines|| int_drnrm---account for possible nonzero result for round up with positive| operand and round down for negative answer.  In the first case (result = 1)| byte-width (store in d0) of result must be honored.  In the second case,| -1 in L_SCR1(a6) will cover all contingencies (FMOVE.B/W/L out).int_dnrm:	movel	#0,L_SCR1(%a6)	| initialize result to 0	bfextu	FPCR_MODE(%a6){#2:#2},%d1	| d1 is the rounding mode	cmpb	#2,%d1	bmis	int_inx		| if RN or RZ, done	bnes	int_rp		| if RP, continue below	tstw	ETEMP(%a6)	| RM: store -1 in L_SCR1 if src is negative	bpls	int_inx		| otherwise result is 0	movel	#-1,L_SCR1(%a6)	bras	int_inxint_rp:	tstw	ETEMP(%a6)	| RP: store +1 of proper width in L_SCR1 if|				; source is greater than 0	bmis	int_inx		| otherwise, result is 0	lea	L_SCR1(%a6),%a1	| a1 is address of L_SCR1	addal	%d0,%a1		| offset by destination width -1	subal	#1,%a1	bsetb	#0,(%a1)		| set low bit at a1 addressint_inx:	oril	#inx2a_mask,USER_FPSR(%a6)	bras	int_wrtint_operr:	fmovemx %fp0-%fp0,FPTEMP(%a6)	|FPTEMP must contain the extended|				;precision source that needs to be|				;converted to integer this is required|				;if the operr exception is enabled.|				;set operr/aiop (no inex2 on int ovfl)	oril	#opaop_mask,USER_FPSR(%a6)|				;fall through to perform int_wrtint_wrt:	movel	EXC_EA(%a6),%a1	|load destination address	tstl	%a1		|check to see if it is a dest register	beqs	wrt_dn		|write data register	lea	L_SCR1(%a6),%a0	|point to supervisor source address	bsrl	mem_write	bra	mvouti_endwrt_dn:	movel	%d0,-(%sp)	|d0 currently contains the size to write	bsrl	get_fline	|get_fline returns Dn in d0	andiw	#0x7,%d0		|isolate register	movel	(%sp)+,%d1	|get size	cmpil	#4,%d1		|most frequent case	beqs	sz_long	cmpil	#2,%d1	bnes	sz_con	orl	#8,%d0		|add 'word' size to register#	bras	sz_consz_long:	orl	#0x10,%d0		|add 'long' size to register#sz_con:	movel	%d0,%d1		|reg_dest expects size:reg in d1	bsrl	reg_dest	|load proper data register	bra	mvouti_endxp:	lea	ETEMP(%a6),%a0	bclrb	#sign_bit,LOCAL_EX(%a0)	sne	LOCAL_SGN(%a0)	btstb	#7,STAG(%a6)	|check for extended denorm	bne	xdnrm	clrl	%d0	bras	do_fp		|do normal casesgp:	lea	ETEMP(%a6),%a0	bclrb	#sign_bit,LOCAL_EX(%a0)	sne	LOCAL_SGN(%a0)	btstb	#7,STAG(%a6)	|check for extended denorm	bne	sp_catas	|branch if so	movew	LOCAL_EX(%a0),%d0	lea	sp_bnds,%a1	cmpw	(%a1),%d0	blt	sp_under	cmpw	2(%a1),%d0	bgt	sp_over	movel	#1,%d0		|set destination format to single	bras	do_fp		|do normal casedp:	lea	ETEMP(%a6),%a0	bclrb	#sign_bit,LOCAL_EX(%a0)	sne	LOCAL_SGN(%a0)	btstb	#7,STAG(%a6)	|check for extended denorm	bne	dp_catas	|branch if so	movew	LOCAL_EX(%a0),%d0	lea	dp_bnds,%a1	cmpw	(%a1),%d0	blt	dp_under	cmpw	2(%a1),%d0	bgt	dp_over	movel	#2,%d0		|set destination format to double|				;fall through to do_fp|do_fp:	bfextu	FPCR_MODE(%a6){#2:#2},%d1	|rnd mode in d1	swap	%d0			|rnd prec in upper word	addl	%d0,%d1			|d1 has PREC/MODE info	clrl	%d0			|clear g,r,s	bsrl	round			|round	movel	%a0,%a1	movel	EXC_EA(%a6),%a0	bfextu	CMDREG1B(%a6){#3:#3},%d1	|extract destination format|					;at this point only the dest|					;formats sgl, dbl, ext are|					;possible	cmpb	#2,%d1	bgts	ddbl			|double=5, extended=2, single=1	bnes	dsgl|					;fall through to dextdext:	bsrl	dest_ext	bra	mvout_enddsgl:	bsrl	dest_sgl	bra	mvout_endddbl:	bsrl	dest_dbl	bra	mvout_end|| Handle possible denorm or catastrophic underflow cases here|xdnrm:	bsr	set_xop		|initialize WBTEMP	bsetb	#wbtemp15_bit,WB_BYTE(%a6) |set wbtemp15	movel	%a0,%a1	movel	EXC_EA(%a6),%a0	|a0 has the destination pointer	bsrl	dest_ext	|store to memory	bsetb	#unfl_bit,FPSR_EXCEPT(%a6)	bra	mvout_endsp_under:	bsetb	#etemp15_bit,STAG(%a6)	cmpw	4(%a1),%d0	blts	sp_catas	|catastrophic underflow case	movel	#1,%d0		|load in round precision	movel	#sgl_thresh,%d1	|load in single denorm threshold	bsrl	dpspdnrm	|expects d1 to have the proper|				;denorm threshold	bsrl	dest_sgl	|stores value to destination	bsetb	#unfl_bit,FPSR_EXCEPT(%a6)	bra	mvout_end	|exitdp_under:	bsetb	#etemp15_bit,STAG(%a6)	cmpw	4(%a1),%d0	blts	dp_catas	|catastrophic underflow case	movel	#dbl_thresh,%d1	|load in double precision threshold	movel	#2,%d0	bsrl	dpspdnrm	|expects d1 to have proper|				;denorm threshold|				;expects d0 to have round precision	bsrl	dest_dbl	|store value to destination	bsetb	#unfl_bit,FPSR_EXCEPT(%a6)	bra	mvout_end	|exit|| Handle catastrophic underflow cases here|sp_catas:| Temp fix for z bit set in unf_sub	movel	USER_FPSR(%a6),-(%a7)	movel	#1,%d0		|set round precision to sgl	bsrl	unf_sub		|a0 points to result	movel	(%a7)+,USER_FPSR(%a6)	movel	#1,%d0	subw	%d0,LOCAL_EX(%a0) |account for difference between|				;denorm/norm bias	movel	%a0,%a1		|a1 has the operand input	movel	EXC_EA(%a6),%a0	|a0 has the destination pointer	bsrl	dest_sgl	|store the result	oril	#unfinx_mask,USER_FPSR(%a6)	bra	mvout_enddp_catas:| Temp fix for z bit set in unf_sub	movel	USER_FPSR(%a6),-(%a7)	movel	#2,%d0		|set round precision to dbl	bsrl	unf_sub		|a0 points to result	movel	(%a7)+,USER_FPSR(%a6)	movel	#1,%d0	subw	%d0,LOCAL_EX(%a0) |account for difference between|				;denorm/norm bias	movel	%a0,%a1		|a1 has the operand input	movel	EXC_EA(%a6),%a0	|a0 has the destination pointer	bsrl	dest_dbl	|store the result	oril	#unfinx_mask,USER_FPSR(%a6)	bra	mvout_end|| Handle catastrophic overflow cases here|sp_over:| Temp fix for z bit set in unf_sub	movel	USER_FPSR(%a6),-(%a7)	movel	#1,%d0	leal	FP_SCR1(%a6),%a0	|use FP_SCR1 for creating result	movel	ETEMP_EX(%a6),(%a0)	movel	ETEMP_HI(%a6),4(%a0)	movel	ETEMP_LO(%a6),8(%a0)	bsrl	ovf_res	movel	(%a7)+,USER_FPSR(%a6)	movel	%a0,%a1	movel	EXC_EA(%a6),%a0	bsrl	dest_sgl	orl	#ovfinx_mask,USER_FPSR(%a6)	bra	mvout_enddp_over:| Temp fix for z bit set in ovf_res	movel	USER_FPSR(%a6),-(%a7)	movel	#2,%d0	leal	FP_SCR1(%a6),%a0	|use FP_SCR1 for creating result	movel	ETEMP_EX(%a6),(%a0)	movel	ETEMP_HI(%a6),4(%a0)	movel	ETEMP_LO(%a6),8(%a0)	bsrl	ovf_res	movel	(%a7)+,USER_FPSR(%a6)	movel	%a0,%a1	movel	EXC_EA(%a6),%a0	bsrl	dest_dbl	orl	#ovfinx_mask,USER_FPSR(%a6)	bra	mvout_end||	DPSPDNRM|| This subroutine takes an extended normalized number and denormalizes| it to the given round precision. This subroutine also decrements| the input operand's exponent by 1 to account for the fact that| dest_sgl or dest_dbl expects a normalized number's bias.|| Input: a0  points to a normalized number in internal extended format|	 d0  is the round precision (=1 for sgl; =2 for dbl)|	 d1  is the single precision or double precision|	     denorm threshold|| Output: (In the format for dest_sgl or dest_dbl)|	 a0   points to the destination|	 a1   points to the operand|| Exceptions: Reports inexact 2 exception by setting USER_FPSR bits|dpspdnrm:	movel	%d0,-(%a7)	|save round precision	clrl	%d0		|clear initial g,r,s	bsrl	dnrm_lp		|careful with d0, it's needed by round	bfextu	FPCR_MODE(%a6){#2:#2},%d1 |get rounding mode	swap	%d1	movew	2(%a7),%d1	|set rounding precision	swap	%d1		|at this point d1 has PREC/MODE info	bsrl	round		|round result, sets the inex bit in|				;USER_FPSR if needed	movew	#1,%d0	subw	%d0,LOCAL_EX(%a0) |account for difference in denorm|				;vs norm bias	movel	%a0,%a1		|a1 has the operand input	movel	EXC_EA(%a6),%a0	|a0 has the destination pointer	addw	#4,%a7		|pop stack	rts|| SET_XOP initialized WBTEMP with the value pointed to by a0| input: a0 points to input operand in the internal extended format|set_xop:	movel	LOCAL_EX(%a0),WBTEMP_EX(%a6)	movel	LOCAL_HI(%a0),WBTEMP_HI(%a6)	movel	LOCAL_LO(%a0),WBTEMP_LO(%a6)	bfclr	WBTEMP_SGN(%a6){#0:#8}	beqs	sxop	bsetb	#sign_bit,WBTEMP_EX(%a6)sxop:	bfclr	STAG(%a6){#5:#4}	|clear wbtm66,wbtm1,wbtm0,sbit	rts||	P_MOVE|p_movet:	.long	p_move	.long	p_movez	.long	p_movei	.long	p_moven	.long	p_movep_regd:	.long	p_dyd0	.long	p_dyd1	.long	p_dyd2	.long	p_dyd3	.long	p_dyd4	.long	p_dyd5	.long	p_dyd6	.long	p_dyd7pack_out:	leal	p_movet,%a0	|load jmp table address	movew	STAG(%a6),%d0	|get source tag	bfextu	%d0{#16:#3},%d0	|isolate source bits	movel	(%a0,%d0.w*4),%a0	|load a0 with routine label for tag	jmp	(%a0)		|go to the routinep_write:	movel	#0x0c,%d0	|get byte count	movel	EXC_EA(%a6),%a1	|get the destination address	bsr	mem_write	|write the user's destination	moveb	#0,CU_SAVEPC(%a6) |set the cu save pc to all 0's|| Also note that the dtag must be set to norm here - this is because| the 040 uses the dtag to execute the correct microcode.|        bfclr    DTAG(%a6){#0:#3}  |set dtag to norm	rts| Notes on handling of special case (zero, inf, and nan) inputs:|	1. Operr is not signalled if the k-factor is greater than 18.|	2. Per the manual, status bits are not set.|p_move:	movew	CMDREG1B(%a6),%d0	btstl	#kfact_bit,%d0	|test for dynamic k-factor	beqs	statick		|if clear, k-factor is staticdynamick:	bfextu	%d0{#25:#3},%d0	|isolate register for dynamic k-factor	lea	p_regd,%a0	movel	%a0@(%d0:l:4),%a0	jmp	(%a0)statick:	andiw	#0x007f,%d0	|get k-factor	bfexts	%d0{#25:#7},%d0	|sign extend d0 for bindec	leal	ETEMP(%a6),%a0	|a0 will point to the packed decimal	bsrl	bindec		|perform the convert; data at a6	leal	FP_SCR1(%a6),%a0	|load a0 with result address	bral	p_writep_movez:	leal	ETEMP(%a6),%a0	|a0 will point to the packed decimal	clrw	2(%a0)		|clear lower word of exp	clrl	4(%a0)		|load second lword of ZERO	clrl	8(%a0)		|load third lword of ZERO	bra	p_write		|go write resultsp_movei:	fmovel	#0,%FPSR		|clear aiop	leal	ETEMP(%a6),%a0	|a0 will point to the packed decimal	clrw	2(%a0)		|clear lower word of exp	bra	p_write		|go write the resultp_moven:	leal	ETEMP(%a6),%a0	|a0 will point to the packed decimal	clrw	2(%a0)		|clear lower word of exp	bra	p_write		|go write the result|| Routines to read the dynamic k-factor from Dn.|p_dyd0:	movel	USER_D0(%a6),%d0	bras	statickp_dyd1:	movel	USER_D1(%a6),%d0	bras	statickp_dyd2:	movel	%d2,%d0	bras	statickp_dyd3:	movel	%d3,%d0	bras	statickp_dyd4:	movel	%d4,%d0	bras	statickp_dyd5:	movel	%d5,%d0	bras	statickp_dyd6:	movel	%d6,%d0	bra	statickp_dyd7:	movel	%d7,%d0	bra	statick	|end

⌨️ 快捷键说明

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