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

📄 res_func.s

📁 优龙2410linux2.6.8内核源代码
💻 S
📖 第 1 页 / 共 4 页
字号:
	movew	%d0,FPTEMP_EX(%a6) |in the denorm	movel	USER_FPCR(%a6),%d0	andil	#0x30,%d0	fmovel	%d0,%fpcr		|set up users rmode and X	fmovex	FPTEMP(%a6),%fp0	fsubx	ETEMP(%a6),%fp0	fmovel	%fpsr,%d1	orl	%d1,USER_FPSR(%a6) |capture cc's and inex from fadd	leal	WBTEMP(%a6),%a0	|point a0 to wbtemp in frame	fmovex	%fp0,WBTEMP(%a6)	|write result to memory	lsrl	#4,%d0		|put rmode in lower 2 bits	movel	USER_FPCR(%a6),%d1	andil	#0xc0,%d1	lsrl	#6,%d1		|put precision in upper word	swap	%d1	orl	%d0,%d1		|set up for round call	clrl	%d0		|force sticky to zero	bclrb	#sign_bit,WBTEMP_EX(%a6)	sne	WBTEMP_SGN(%a6)	bsrl	round		|round result to users rmode & prec	bfclr	WBTEMP_SGN(%a6){#0:#8}	|convert back to IEEE ext format	beq	frcfpnr	bsetb	#sign_bit,WBTEMP_EX(%a6)	bra	frcfpnrsub_u_srcd:	movew	ETEMP_EX(%a6),%d0	andiw	#0x8000,%d0	orw	#0x3fff,%d0	|force the exponent to +/- 1	movew	%d0,ETEMP_EX(%a6) |in the denorm	movel	USER_FPCR(%a6),%d0	andil	#0x30,%d0	fmovel	%d0,%fpcr		|set up users rmode and X	fmovex	FPTEMP(%a6),%fp0	fsubx	ETEMP(%a6),%fp0	fmovel	%fpsr,%d1	orl	%d1,USER_FPSR(%a6) |capture cc's and inex from fadd	leal	WBTEMP(%a6),%a0	|point a0 to wbtemp in frame	fmovex	%fp0,WBTEMP(%a6)	|write result to memory	lsrl	#4,%d0		|put rmode in lower 2 bits	movel	USER_FPCR(%a6),%d1	andil	#0xc0,%d1	lsrl	#6,%d1		|put precision in upper word	swap	%d1	orl	%d0,%d1		|set up for round call	clrl	%d0		|force sticky to zero	bclrb	#sign_bit,WBTEMP_EX(%a6)	sne	WBTEMP_SGN(%a6)	bsrl	round		|round result to users rmode & prec	bfclr	WBTEMP_SGN(%a6){#0:#8}	|convert back to IEEE ext format	beq	frcfpnr	bsetb	#sign_bit,WBTEMP_EX(%a6)	bra	frcfpnr|| Signs are unlike:|sub_diff:	cmpb	#0x0f,DNRM_FLG(%a6) |is dest the denorm?	bnes	sub_s_srcdsub_s_destd:	leal	ETEMP(%a6),%a0	movel	USER_FPCR(%a6),%d0	andil	#0x30,%d0	lsrl	#4,%d0		|put rmode in lower 2 bits	movel	USER_FPCR(%a6),%d1	andil	#0xc0,%d1	lsrl	#6,%d1		|put precision in upper word	swap	%d1	orl	%d0,%d1		|set up for round call	movel	#0x20000000,%d0	|set sticky for round|| Since the dest is the denorm, the sign is the opposite of the| norm sign.|	eoriw	#0x8000,ETEMP_EX(%a6)	|flip sign on result	tstw	ETEMP_EX(%a6)	bgts	sub_s_dwr	orl	#neg_mask,USER_FPSR(%a6)sub_s_dwr:	bclrb	#sign_bit,ETEMP_EX(%a6)	sne	ETEMP_SGN(%a6)	bsrl	round		|round result to users rmode & prec	bfclr	ETEMP_SGN(%a6){#0:#8}	|convert back to IEEE ext format	beqs	sub_s_dclr	bsetb	#sign_bit,ETEMP_EX(%a6)sub_s_dclr:	leal	WBTEMP(%a6),%a0	movel	ETEMP(%a6),(%a0)	|write result to wbtemp	movel	ETEMP_HI(%a6),4(%a0)	movel	ETEMP_LO(%a6),8(%a0)	bra	sub_ckovfsub_s_srcd:	leal	FPTEMP(%a6),%a0	movel	USER_FPCR(%a6),%d0	andil	#0x30,%d0	lsrl	#4,%d0		|put rmode in lower 2 bits	movel	USER_FPCR(%a6),%d1	andil	#0xc0,%d1	lsrl	#6,%d1		|put precision in upper word	swap	%d1	orl	%d0,%d1		|set up for round call	movel	#0x20000000,%d0	|set sticky for round	bclrb	#sign_bit,FPTEMP_EX(%a6)	sne	FPTEMP_SGN(%a6)	bsrl	round		|round result to users rmode & prec	bfclr	FPTEMP_SGN(%a6){#0:#8}	|convert back to IEEE ext format	beqs	sub_s_sclr	bsetb	#sign_bit,FPTEMP_EX(%a6)sub_s_sclr:	leal	WBTEMP(%a6),%a0	movel	FPTEMP(%a6),(%a0)	|write result to wbtemp	movel	FPTEMP_HI(%a6),4(%a0)	movel	FPTEMP_LO(%a6),8(%a0)	tstw	FPTEMP_EX(%a6)	bgt	sub_ckovf	orl	#neg_mask,USER_FPSR(%a6)sub_ckovf:	movew	WBTEMP_EX(%a6),%d0	andiw	#0x7fff,%d0	cmpiw	#0x7fff,%d0	bne	frcfpnr|| The result has overflowed to $7fff exponent.  Set I, ovfl,| and aovfl, and clr the mantissa (incorrectly set by the| round routine.)|	orl	#inf_mask+ovfl_inx_mask,USER_FPSR(%a6)	clrl	4(%a0)	bra	frcfpnr|| Inst is fcmp.|wrap_cmp:	cmpb	#0xff,DNRM_FLG(%a6) |if both ops denorm,	beq	fix_stk		 |restore to fpu|| One of the ops is denormalized.  Test for wrap condition| and complete the instruction.|	cmpb	#0x0f,DNRM_FLG(%a6) |check for dest denorm	bnes	cmp_srcdcmp_destd:	bsrl	ckinf_ns	bne	fix_stk	bfextu	ETEMP_EX(%a6){#1:#15},%d0	|get src exp (always pos)	bfexts	FPTEMP_EX(%a6){#1:#15},%d1	|get dest exp (always neg)	subl	%d1,%d0			|subtract dest from src	cmpl	#0x8000,%d0	blt	fix_stk			|if less, not wrap case	tstw	ETEMP_EX(%a6)		|set N to ~sign_of(src)	bge	cmp_setn	rtscmp_srcd:	bsrl	ckinf_nd	bne	fix_stk	bfextu	FPTEMP_EX(%a6){#1:#15},%d0	|get dest exp (always pos)	bfexts	ETEMP_EX(%a6){#1:#15},%d1	|get src exp (always neg)	subl	%d1,%d0			|subtract src from dest	cmpl	#0x8000,%d0	blt	fix_stk			|if less, not wrap case	tstw	FPTEMP_EX(%a6)		|set N to sign_of(dest)	blt	cmp_setn	rtscmp_setn:	orl	#neg_mask,USER_FPSR(%a6)	rts|| Inst is fmul.|wrap_mul:	cmpb	#0xff,DNRM_FLG(%a6) |if both ops denorm,	beq	force_unf	|force an underflow (really!)|| One of the ops is denormalized.  Test for wrap condition| and complete the instruction.|	cmpb	#0x0f,DNRM_FLG(%a6) |check for dest denorm	bnes	mul_srcdmul_destd:	bsrl	ckinf_ns	bne	fix_stk	bfextu	ETEMP_EX(%a6){#1:#15},%d0	|get src exp (always pos)	bfexts	FPTEMP_EX(%a6){#1:#15},%d1	|get dest exp (always neg)	addl	%d1,%d0			|subtract dest from src	bgt	fix_stk	bra	force_unfmul_srcd:	bsrl	ckinf_nd	bne	fix_stk	bfextu	FPTEMP_EX(%a6){#1:#15},%d0	|get dest exp (always pos)	bfexts	ETEMP_EX(%a6){#1:#15},%d1	|get src exp (always neg)	addl	%d1,%d0			|subtract src from dest	bgt	fix_stk|| This code handles the case of the instruction resulting in| an underflow condition.|force_unf:	bclrb	#E1,E_BYTE(%a6)	orl	#unfinx_mask,USER_FPSR(%a6)	clrw	NMNEXC(%a6)	clrb	WBTEMP_SGN(%a6)	movew	ETEMP_EX(%a6),%d0		|find the sign of the result	movew	FPTEMP_EX(%a6),%d1	eorw	%d1,%d0	andiw	#0x8000,%d0	beqs	frcunfcont	st	WBTEMP_SGN(%a6)frcunfcont:	lea	WBTEMP(%a6),%a0		|point a0 to memory location	movew	CMDREG1B(%a6),%d0	btstl	#6,%d0			|test for forced precision	beqs	frcunf_fpcr	btstl	#2,%d0			|check for double	bnes	frcunf_dbl	movel	#0x1,%d0			|inst is forced single	bras	frcunf_rndfrcunf_dbl:	movel	#0x2,%d0			|inst is forced double	bras	frcunf_rndfrcunf_fpcr:	bfextu	FPCR_MODE(%a6){#0:#2},%d0	|inst not forced - use fpcr precfrcunf_rnd:	bsrl	unf_sub			|get correct result based on|					;round precision/mode.  This|					;sets FPSR_CC correctly	bfclr	WBTEMP_SGN(%a6){#0:#8}	|convert back to IEEE ext format	beqs	frcfpn	bsetb	#sign_bit,WBTEMP_EX(%a6)	bra	frcfpn|| Write the result to the user's fpn.  All results must be HUGE to be| written; otherwise the results would have overflowed or underflowed.| If the rounding precision is single or double, the ovf_res routine| is needed to correctly supply the max value.|frcfpnr:	movew	CMDREG1B(%a6),%d0	btstl	#6,%d0			|test for forced precision	beqs	frcfpn_fpcr	btstl	#2,%d0			|check for double	bnes	frcfpn_dbl	movel	#0x1,%d0			|inst is forced single	bras	frcfpn_rndfrcfpn_dbl:	movel	#0x2,%d0			|inst is forced double	bras	frcfpn_rndfrcfpn_fpcr:	bfextu	FPCR_MODE(%a6){#0:#2},%d0	|inst not forced - use fpcr prec	tstb	%d0	beqs	frcfpn			|if extended, write what you gotfrcfpn_rnd:	bclrb	#sign_bit,WBTEMP_EX(%a6)	sne	WBTEMP_SGN(%a6)	bsrl	ovf_res			|get correct result based on|					;round precision/mode.  This|					;sets FPSR_CC correctly	bfclr	WBTEMP_SGN(%a6){#0:#8}	|convert back to IEEE ext format	beqs	frcfpn_clr	bsetb	#sign_bit,WBTEMP_EX(%a6)frcfpn_clr:	orl	#ovfinx_mask,USER_FPSR(%a6)|| Perform the write.|frcfpn:	bfextu	CMDREG1B(%a6){#6:#3},%d0	|extract fp destination register	cmpib	#3,%d0	bles	frc0123			|check if dest is fp0-fp3	movel	#7,%d1	subl	%d0,%d1	clrl	%d0	bsetl	%d1,%d0	fmovemx WBTEMP(%a6),%d0	rtsfrc0123:	cmpib	#0,%d0	beqs	frc0_dst	cmpib	#1,%d0	beqs	frc1_dst	cmpib	#2,%d0	beqs	frc2_dstfrc3_dst:	movel	WBTEMP_EX(%a6),USER_FP3(%a6)	movel	WBTEMP_HI(%a6),USER_FP3+4(%a6)	movel	WBTEMP_LO(%a6),USER_FP3+8(%a6)	rtsfrc2_dst:	movel	WBTEMP_EX(%a6),USER_FP2(%a6)	movel	WBTEMP_HI(%a6),USER_FP2+4(%a6)	movel	WBTEMP_LO(%a6),USER_FP2+8(%a6)	rtsfrc1_dst:	movel	WBTEMP_EX(%a6),USER_FP1(%a6)	movel	WBTEMP_HI(%a6),USER_FP1+4(%a6)	movel	WBTEMP_LO(%a6),USER_FP1+8(%a6)	rtsfrc0_dst:	movel	WBTEMP_EX(%a6),USER_FP0(%a6)	movel	WBTEMP_HI(%a6),USER_FP0+4(%a6)	movel	WBTEMP_LO(%a6),USER_FP0+8(%a6)	rts|| Write etemp to fpn.| A check is made on enabled and signalled snan exceptions,| and the destination is not overwritten if this condition exists.| This code is designed to make fmoveins of unsupported data types| faster.|wr_etemp:	btstb	#snan_bit,FPSR_EXCEPT(%a6)	|if snan is set, and	beqs	fmoveinc		|enabled, force restore	btstb	#snan_bit,FPCR_ENABLE(%a6) |and don't overwrite	beqs	fmoveinc		|the dest	movel	ETEMP_EX(%a6),FPTEMP_EX(%a6)	|set up fptemp sign for|						;snan handler	tstb	ETEMP(%a6)		|check for negative	blts	snan_neg	rtssnan_neg:	orl	#neg_bit,USER_FPSR(%a6)	|snan is negative; set N	rtsfmoveinc:	clrw	NMNEXC(%a6)	bclrb	#E1,E_BYTE(%a6)	moveb	STAG(%a6),%d0		|check if stag is inf	andib	#0xe0,%d0	cmpib	#0x40,%d0	bnes	fminc_cnan	orl	#inf_mask,USER_FPSR(%a6) |if inf, nothing yet has set I	tstw	LOCAL_EX(%a0)		|check sign	bges	fminc_con	orl	#neg_mask,USER_FPSR(%a6)	bra	fminc_confminc_cnan:	cmpib	#0x60,%d0			|check if stag is NaN	bnes	fminc_czero	orl	#nan_mask,USER_FPSR(%a6) |if nan, nothing yet has set NaN	movel	ETEMP_EX(%a6),FPTEMP_EX(%a6)	|set up fptemp sign for|						;snan handler	tstw	LOCAL_EX(%a0)		|check sign	bges	fminc_con	orl	#neg_mask,USER_FPSR(%a6)	bra	fminc_confminc_czero:	cmpib	#0x20,%d0			|check if zero	bnes	fminc_con	orl	#z_mask,USER_FPSR(%a6)	|if zero, set Z	tstw	LOCAL_EX(%a0)		|check sign	bges	fminc_con	orl	#neg_mask,USER_FPSR(%a6)fminc_con:	bfextu	CMDREG1B(%a6){#6:#3},%d0	|extract fp destination register	cmpib	#3,%d0	bles	fp0123			|check if dest is fp0-fp3	movel	#7,%d1	subl	%d0,%d1	clrl	%d0	bsetl	%d1,%d0	fmovemx ETEMP(%a6),%d0	rtsfp0123:	cmpib	#0,%d0	beqs	fp0_dst	cmpib	#1,%d0	beqs	fp1_dst	cmpib	#2,%d0	beqs	fp2_dstfp3_dst:	movel	ETEMP_EX(%a6),USER_FP3(%a6)	movel	ETEMP_HI(%a6),USER_FP3+4(%a6)	movel	ETEMP_LO(%a6),USER_FP3+8(%a6)	rtsfp2_dst:	movel	ETEMP_EX(%a6),USER_FP2(%a6)	movel	ETEMP_HI(%a6),USER_FP2+4(%a6)	movel	ETEMP_LO(%a6),USER_FP2+8(%a6)	rtsfp1_dst:	movel	ETEMP_EX(%a6),USER_FP1(%a6)	movel	ETEMP_HI(%a6),USER_FP1+4(%a6)	movel	ETEMP_LO(%a6),USER_FP1+8(%a6)	rtsfp0_dst:	movel	ETEMP_EX(%a6),USER_FP0(%a6)	movel	ETEMP_HI(%a6),USER_FP0+4(%a6)	movel	ETEMP_LO(%a6),USER_FP0+8(%a6)	rtsopclass3:	st	CU_ONLY(%a6)	movew	CMDREG1B(%a6),%d0	|check if packed moveout	andiw	#0x0c00,%d0	|isolate last 2 bits of size field	cmpiw	#0x0c00,%d0	|if size is 011 or 111, it is packed	beq	pack_out	|else it is norm or denorm	bra	mv_out||	MOVE OUT|mv_tbl:	.long	li	.long	sgp	.long	xp	.long	mvout_end	|should never be taken	.long	wi	.long	dp	.long	bi	.long	mvout_end	|should never be takenmv_out:	bfextu	CMDREG1B(%a6){#3:#3},%d1	|put source specifier in d1	leal	mv_tbl,%a0	movel	%a0@(%d1:l:4),%a0	jmp	(%a0)|| This exit is for move-out to memory.  The aunfl bit is| set if the result is inex and unfl is signalled.|mvout_end:	btstb	#inex2_bit,FPSR_EXCEPT(%a6)	beqs	no_aufl	btstb	#unfl_bit,FPSR_EXCEPT(%a6)	beqs	no_aufl	bsetb	#aunfl_bit,FPSR_AEXCEPT(%a6)no_aufl:	clrw	NMNEXC(%a6)	bclrb	#E1,E_BYTE(%a6)	fmovel	#0,%FPSR			|clear any cc bits from res_func|| Return ETEMP to extended format from internal extended format so| that gen_except will have a correctly signed value for ovfl/unfl| handlers.|	bfclr	ETEMP_SGN(%a6){#0:#8}	beqs	mvout_con	bsetb	#sign_bit,ETEMP_EX(%a6)mvout_con:	rts|| This exit is for move-out to int register.  The aunfl bit is| not set in any case for this move.|mvouti_end:	clrw	NMNEXC(%a6)	bclrb	#E1,E_BYTE(%a6)	fmovel	#0,%FPSR			|clear any cc bits from res_func|| Return ETEMP to extended format from internal extended format so| that gen_except will have a correctly signed value for ovfl/unfl| handlers.|	bfclr	ETEMP_SGN(%a6){#0:#8}	beqs	mvouti_con	bsetb	#sign_bit,ETEMP_EX(%a6)mvouti_con:	rts|| li is used to handle a long integer source specifier|li:	moveql	#4,%d0		|set byte count	btstb	#7,STAG(%a6)	|check for extended denorm	bne	int_dnrm	|if so, branch	fmovemx ETEMP(%a6),%fp0-%fp0	fcmpd	#0x41dfffffffc00000,%fp0| 41dfffffffc00000 in dbl prec = 401d0000fffffffe00000000 in ext prec	fbge	lo_plrg	fcmpd	#0xc1e0000000000000,%fp0| c1e0000000000000 in dbl prec = c01e00008000000000000000 in ext prec	fble	lo_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	fmovel	%fp0,L_SCR1(%a6)	|let the 040 perform conversion	fmovel %fpsr,%d1	orl	%d1,USER_FPSR(%a6)	|capture inex2/ainex if set	bra	int_wrtlo_plrg:	movel	#0x7fffffff,L_SCR1(%a6)	|answer is largest positive int	fbeq	int_wrt			|exact answer	fcmpd	#0x41dfffffffe00000,%fp0| 41dfffffffe00000 in dbl prec = 401d0000ffffffff00000000 in ext prec	fbge	int_operr		|set operr	bra	int_inx			|set inexactlo_nlrg:	movel	#0x80000000,L_SCR1(%a6)	fbeq	int_wrt			|exact answer	fcmpd	#0xc1e0000000100000,%fp0| c1e0000000100000 in dbl prec = c01e00008000000080000000 in ext prec	fblt	int_operr		|set operr	bra	int_inx			|set inexact|| wi is used to handle a word integer source specifier|

⌨️ 快捷键说明

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