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

📄 decbin.s

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 S
📖 第 1 页 / 共 2 页
字号:
//  2n.(negative exp)//   2. Check the digits in lwords 3 and 2 in descending order.//   3. Add one for each zero encountered until a non-zero digit.//   4. Add the count to the exp.//   5. Check if the exp has crossed zero in #3 above; clear SE.//   6. Divide the mantissa by 10**count.////  *Why 27?  If the adjusted exponent is within -28 < expA < 28, than//   any adjustment due to append/strip zeros will drive the resultant//   exponent towards zero.  Since all pwrten constants with a power//   of 27 or less are exact, there is no need to use this routine to//   attempt to lessen the resultant exponent.//// Register usage:////  ap_st_z://	(*)  d0: temp digit storage//	(*)  d1: zero count//	(*)  d2: digit count//	(*)  d3: offset pointer//	( )  d4: first word of bcd//	(*)  d5: lword counter//	( )  a0: pointer to working bcd value//	( )  FP_SCR1: working copy of original bcd value//	( )  L_SCR1: copy of original exponent word////// First check the absolute value of the exponent to see if this// routine is necessary.  If so, then check the sign of the exponent// and do append (+) or strip (-) zeros accordingly.// This section handles a positive adjusted exponent.//ap_st_z:	movel	L_SCR1(%a6),%d1	//load expA for range test	cmpl	#27,%d1		//test is with 27	ble	pwrten		//if abs(expA) <28, skip ap/st zeros	btst	#30,(%a0)	//check sign of exp	bne	ap_st_n		//if neg, go to neg side	clrl	%d1		//zero count reg	movel	(%a0),%d4		//load lword 1 to d4	bfextu	%d4{#28:#4},%d0	//get M16 in d0	bnes	ap_p_fx		//if M16 is non-zero, go fix exp	addql	#1,%d1		//inc zero count	moveql	#1,%d5		//init lword counter	movel	(%a0,%d5.L*4),%d4	//get lword 2 to d4	bnes	ap_p_cl		//if lw 2 is zero, skip it	addql	#8,%d1		//and inc count by 8	addql	#1,%d5		//inc lword counter	movel	(%a0,%d5.L*4),%d4	//get lword 3 to d4ap_p_cl:	clrl	%d3		//init offset reg	moveql	#7,%d2		//init digit counterap_p_gd:	bfextu	%d4{%d3:#4},%d0	//get digit	bnes	ap_p_fx		//if non-zero, go to fix exp	addql	#4,%d3		//point to next digit	addql	#1,%d1		//inc digit counter	dbf	%d2,ap_p_gd	//get next digitap_p_fx:	movel	%d1,%d0		//copy counter to d2	movel	L_SCR1(%a6),%d1	//get adjusted exp from memory	subl	%d0,%d1		//subtract count from exp	bges	ap_p_fm		//if still pos, go to pwrten	negl	%d1		//now its neg; get abs	movel	(%a0),%d4		//load lword 1 to d4	orl	#0x40000000,%d4	// and set SE in d4	orl	#0x40000000,(%a0)	// and in memory//// Calculate the mantissa multiplier to compensate for the striping of// zeros from the mantissa.//ap_p_fm:	movel	#PTENRN,%a1	//get address of power-of-ten table	clrl	%d3		//init table index	fmoves	FONE,%fp1	//init fp1 to 1	moveql	#3,%d2		//init d2 to count bits in counterap_p_el:	asrl	#1,%d0		//shift lsb into carry	bccs	ap_p_en		//if 1, mul fp1 by pwrten factor	fmulx	(%a1,%d3),%fp1	//mul by 10**(d3_bit_no)ap_p_en:	addl	#12,%d3		//inc d3 to next rtable entry	tstl	%d0		//check if d0 is zero	bnes	ap_p_el		//if not, get next bit	fmulx	%fp1,%fp0		//mul mantissa by 10**(no_bits_shifted)	bra	pwrten		//go calc pwrten//// This section handles a negative adjusted exponent.//ap_st_n:	clrl	%d1		//clr counter	moveql	#2,%d5		//set up d5 to point to lword 3	movel	(%a0,%d5.L*4),%d4	//get lword 3	bnes	ap_n_cl		//if not zero, check digits	subl	#1,%d5		//dec d5 to point to lword 2	addql	#8,%d1		//inc counter by 8	movel	(%a0,%d5.L*4),%d4	//get lword 2ap_n_cl:	movel	#28,%d3		//point to last digit	moveql	#7,%d2		//init digit counterap_n_gd:	bfextu	%d4{%d3:#4},%d0	//get digit	bnes	ap_n_fx		//if non-zero, go to exp fix	subql	#4,%d3		//point to previous digit	addql	#1,%d1		//inc digit counter	dbf	%d2,ap_n_gd	//get next digitap_n_fx:	movel	%d1,%d0		//copy counter to d0	movel	L_SCR1(%a6),%d1	//get adjusted exp from memory	subl	%d0,%d1		//subtract count from exp	bgts	ap_n_fm		//if still pos, go fix mantissa	negl	%d1		//take abs of exp and clr SE	movel	(%a0),%d4		//load lword 1 to d4	andl	#0xbfffffff,%d4	// and clr SE in d4	andl	#0xbfffffff,(%a0)	// and in memory//// Calculate the mantissa multiplier to compensate for the appending of// zeros to the mantissa.//ap_n_fm:	movel	#PTENRN,%a1	//get address of power-of-ten table	clrl	%d3		//init table index	fmoves	FONE,%fp1	//init fp1 to 1	moveql	#3,%d2		//init d2 to count bits in counterap_n_el:	asrl	#1,%d0		//shift lsb into carry	bccs	ap_n_en		//if 1, mul fp1 by pwrten factor	fmulx	(%a1,%d3),%fp1	//mul by 10**(d3_bit_no)ap_n_en:	addl	#12,%d3		//inc d3 to next rtable entry	tstl	%d0		//check if d0 is zero	bnes	ap_n_el		//if not, get next bit	fdivx	%fp1,%fp0		//div mantissa by 10**(no_bits_shifted)////// Calculate power-of-ten factor from adjusted and shifted exponent.//// Register usage:////  pwrten://	(*)  d0: temp//	( )  d1: exponent//	(*)  d2: {FPCR[6:5],SM,SE} as index in RTABLE; temp//	(*)  d3: FPCR work copy//	( )  d4: first word of bcd//	(*)  a1: RTABLE pointer//  calc_p://	(*)  d0: temp//	( )  d1: exponent//	(*)  d3: PWRTxx table index//	( )  a0: pointer to working copy of bcd//	(*)  a1: PWRTxx pointer//	(*) fp1: power-of-ten accumulator//// Pwrten calculates the exponent factor in the selected rounding mode// according to the following table://	//	Sign of Mant  Sign of Exp  Rounding Mode  PWRTEN Rounding Mode////	ANY	  ANY	RN	RN////	 +	   +	RP	RP//	 -	   +	RP	RM//	 +	   -	RP	RM//	 -	   -	RP	RP////	 +	   +	RM	RM//	 -	   +	RM	RP//	 +	   -	RM	RP//	 -	   -	RM	RM////	 +	   +	RZ	RM//	 -	   +	RZ	RM//	 +	   -	RZ	RP//	 -	   -	RZ	RP////pwrten:	movel	USER_FPCR(%a6),%d3 //get user's FPCR	bfextu	%d3{#26:#2},%d2	//isolate rounding mode bits	movel	(%a0),%d4		//reload 1st bcd word to d4	asll	#2,%d2		//format d2 to be	bfextu	%d4{#0:#2},%d0	// {FPCR[6],FPCR[5],SM,SE}	addl	%d0,%d2		//in d2 as index into RTABLE	leal	RTABLE,%a1	//load rtable base	moveb	(%a1,%d2),%d0	//load new rounding bits from table	clrl	%d3			//clear d3 to force no exc and extended	bfins	%d0,%d3{#26:#2}	//stuff new rounding bits in FPCR	fmovel	%d3,%FPCR		//write new FPCR	asrl	#1,%d0		//write correct PTENxx table	bccs	not_rp		//to a1	leal	PTENRP,%a1	//it is RP	bras	calc_p		//go to init sectionnot_rp:	asrl	#1,%d0		//keep checking	bccs	not_rm	leal	PTENRM,%a1	//it is RM	bras	calc_p		//go to init sectionnot_rm:	leal	PTENRN,%a1	//it is RNcalc_p:	movel	%d1,%d0		//copy exp to d0;use d0	bpls	no_neg		//if exp is negative,	negl	%d0		//invert it	orl	#0x40000000,(%a0)	//and set SE bitno_neg:	clrl	%d3		//table index	fmoves	FONE,%fp1	//init fp1 to 1e_loop:	asrl	#1,%d0		//shift next bit into carry	bccs	e_next		//if zero, skip the mul	fmulx	(%a1,%d3),%fp1	//mul by 10**(d3_bit_no)e_next:	addl	#12,%d3		//inc d3 to next rtable entry	tstl	%d0		//check if d0 is zero	bnes	e_loop		//not zero, continue shifting//////  Check the sign of the adjusted exp and make the value in fp0 the//  same sign. If the exp was pos then multiply fp1*fp0;//  else divide fp0/fp1.//// Register Usage://  norm://	( )  a0: pointer to working bcd value//	(*) fp0: mantissa accumulator//	( ) fp1: scaling factor - 10**(abs(exp))//norm:	btst	#30,(%a0)	//test the sign of the exponent	beqs	mul		//if clear, go to multiplydiv:	fdivx	%fp1,%fp0		//exp is negative, so divide mant by exp	bras	end_decmul:	fmulx	%fp1,%fp0		//exp is positive, so multiply by exp////// Clean up and return with result in fp0.//// If the final mul/div in decbin incurred an inex exception,// it will be inex2, but will be reported as inex1 by get_op.//end_dec:	fmovel	%FPSR,%d0		//get status register		bclrl	#inex2_bit+8,%d0	//test for inex2 and clear it	fmovel	%d0,%FPSR		//return status reg w/o inex2	beqs	no_exc		//skip this if no exc	orl	#inx1a_mask,USER_FPSR(%a6) //set inex1/ainexno_exc:	moveml	(%a7)+,%d2-%d5	rts	|end

⌨️ 快捷键说明

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