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

📄 res_func.s

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 S
📖 第 1 页 / 共 4 页
字号:
// wi is used to handle a word integer source specifier//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_end xp:	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_end	sp_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_end	dp_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 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 + -