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

📄 res_func.s

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 S
📖 第 1 页 / 共 4 页
字号:
	andiw	#0x8000,%d0	orw	#0x3fff,%d0	//force the exponent to +/- 1	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_dst frc3_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_dst fp3_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//

⌨️ 快捷键说明

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