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

📄 bindec.s

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 S
📖 第 1 页 / 共 2 页
字号:
|| Register usage:|	Input/Output|	d0: FPCR with RZ mode/Unchanged|	d2: 0 or 24/unchanged|	d3: x/x|	d4: LEN/Unchanged|	d5: ICTR:LAMBDA|	d6: ILOG/Unchanged|	d7: k-factor/Unchanged|	a0: ptr for original operand/final result|	a1: ptr to PTENRM array/Unchanged|	a2: x/x|	fp0: float(ILOG)/X adjusted for SCALE (Y)|	fp1: 10^ISCALE/Unchanged|	fp2: x/x|	F_SCR1:x/x|	F_SCR2:Abs(X) with $3fff exponent/Unchanged|	L_SCR1:x/x|	L_SCR2:first word of X packed/UnchangedA9_str:		fmovex	(%a0),%fp0	|load X from memory	fabsx	%fp0		|use abs(X)	tstw	%d5		|LAMBDA is in lower word of d5	bne	sc_mul		|if neg (LAMBDA = 1), scale by mul	fdivx	%fp1,%fp0		|calculate X / SCALE -> Y to fp0	bras	A10_st		|branch to A10sc_mul:	tstb	BINDEC_FLG(%a6)	|check for denorm	beqs	A9_norm		|if norm, continue with mul	fmovemx %fp1-%fp1,-(%a7)	|load ETEMP with 10^ISCALE	movel	8(%a0),-(%a7)	|load FPTEMP with input arg	movel	4(%a0),-(%a7)	movel	(%a0),-(%a7)	movel	#18,%d3		|load count for busy stackA9_loop:	clrl	-(%a7)		|clear lword on stack	dbf	%d3,A9_loop		moveb	VER_TMP(%a6),(%a7) |write current version number	moveb	#BUSY_SIZE-4,1(%a7) |write current busy size 	moveb	#0x10,0x44(%a7)	|set fcefpte[15] bit	movew	#0x0023,0x40(%a7)	|load cmdreg1b with mul command	moveb	#0xfe,0x8(%a7)	|load all 1s to cu savepc	frestore (%a7)+		|restore frame to fpu for completion	fmulx	36(%a1),%fp0	|multiply fp0 by 10^8	fmulx	48(%a1),%fp0	|multiply fp0 by 10^16	bras	A10_stA9_norm:	tstw	%d2		|test for small exp case	beqs	A9_con		|if zero, continue as normal	fmulx	36(%a1),%fp0	|multiply fp0 by 10^8	fmulx	48(%a1),%fp0	|multiply fp0 by 10^16A9_con:	fmulx	%fp1,%fp0		|calculate X * SCALE -> Y to fp0| A10. Or in INEX.|      If INEX is set, round error occurred.  This is compensated|      for by 'or-ing' in the INEX2 flag to the lsb of Y.|| Register usage:|	Input/Output|	d0: FPCR with RZ mode/FPSR with INEX2 isolated|	d2: x/x|	d3: x/x|	d4: LEN/Unchanged|	d5: ICTR:LAMBDA|	d6: ILOG/Unchanged|	d7: k-factor/Unchanged|	a0: ptr for original operand/final result|	a1: ptr to PTENxx array/Unchanged|	a2: x/ptr to FP_SCR2(a6)|	fp0: Y/Y with lsb adjusted|	fp1: 10^ISCALE/Unchanged|	fp2: x/xA10_st:		fmovel	%FPSR,%d0		|get FPSR	fmovex	%fp0,FP_SCR2(%a6)	|move Y to memory	leal	FP_SCR2(%a6),%a2	|load a2 with ptr to FP_SCR2	btstl	#9,%d0		|check if INEX2 set	beqs	A11_st		|if clear, skip rest	oril	#1,8(%a2)	|or in 1 to lsb of mantissa	fmovex	FP_SCR2(%a6),%fp0	|write adjusted Y back to fpu| A11. Restore original FPCR; set size ext.|      Perform FINT operation in the user's rounding mode.  Keep|      the size to extended.  The sintdo entry point in the sint|      routine expects the FPCR value to be in USER_FPCR for|      mode and precision.  The original FPCR is saved in L_SCR1.A11_st:		movel	USER_FPCR(%a6),L_SCR1(%a6) |save it for later	andil	#0x00000030,USER_FPCR(%a6) |set size to ext, |					;block exceptions| A12. Calculate YINT = FINT(Y) according to user's rounding mode.|      The FPSP routine sintd0 is used.  The output is in fp0.|| Register usage:|	Input/Output|	d0: FPSR with AINEX cleared/FPCR with size set to ext|	d2: x/x/scratch|	d3: x/x|	d4: LEN/Unchanged|	d5: ICTR:LAMBDA/Unchanged|	d6: ILOG/Unchanged|	d7: k-factor/Unchanged|	a0: ptr for original operand/src ptr for sintdo|	a1: ptr to PTENxx array/Unchanged|	a2: ptr to FP_SCR2(a6)/Unchanged|	a6: temp pointer to FP_SCR2(a6) - orig value saved and restored|	fp0: Y/YINT|	fp1: 10^ISCALE/Unchanged|	fp2: x/x|	F_SCR1:x/x|	F_SCR2:Y adjusted for inex/Y with original exponent|	L_SCR1:x/original USER_FPCR|	L_SCR2:first word of X packed/UnchangedA12_st:	moveml	%d0-%d1/%a0-%a1,-(%a7)	|save regs used by sintd0		movel	L_SCR1(%a6),-(%a7)	movel	L_SCR2(%a6),-(%a7)	leal	FP_SCR2(%a6),%a0		|a0 is ptr to F_SCR2(a6)	fmovex	%fp0,(%a0)		|move Y to memory at FP_SCR2(a6)	tstl	L_SCR2(%a6)		|test sign of original operand	bges	do_fint			|if pos, use Y 	orl	#0x80000000,(%a0)		|if neg, use -Ydo_fint:	movel	USER_FPSR(%a6),-(%a7)	bsr	sintdo			|sint routine returns int in fp0	moveb	(%a7),USER_FPSR(%a6)	addl	#4,%a7	movel	(%a7)+,L_SCR2(%a6)	movel	(%a7)+,L_SCR1(%a6)	moveml	(%a7)+,%d0-%d1/%a0-%a1	|restore regs used by sint		movel	L_SCR2(%a6),FP_SCR2(%a6)	|restore original exponent	movel	L_SCR1(%a6),USER_FPCR(%a6) |restore user's FPCR| A13. Check for LEN digits.|      If the int operation results in more than LEN digits,|      or less than LEN -1 digits, adjust ILOG and repeat from|      A6.  This test occurs only on the first pass.  If the|      result is exactly 10^LEN, decrement ILOG and divide|      the mantissa by 10.  The calculation of 10^LEN cannot|      be inexact, since all powers of ten upto 10^27 are exact|      in extended precision, so the use of a previous power-of-ten|      table will introduce no error.||| Register usage:|	Input/Output|	d0: FPCR with size set to ext/scratch final = 0|	d2: x/x|	d3: x/scratch final = x|	d4: LEN/LEN adjusted|	d5: ICTR:LAMBDA/LAMBDA:ICTR|	d6: ILOG/ILOG adjusted|	d7: k-factor/Unchanged|	a0: pointer into memory for packed bcd string formation|	a1: ptr to PTENxx array/Unchanged|	a2: ptr to FP_SCR2(a6)/Unchanged|	fp0: int portion of Y/abs(YINT) adjusted|	fp1: 10^ISCALE/Unchanged|	fp2: x/10^LEN|	F_SCR1:x/x|	F_SCR2:Y with original exponent/Unchanged|	L_SCR1:original USER_FPCR/Unchanged|	L_SCR2:first word of X packed/UnchangedA13_st:		swap	%d5		|put ICTR in lower word of d5	tstw	%d5		|check if ICTR = 0	bne	not_zr		|if non-zero, go to second test|| Compute 10^(LEN-1)|	fmoves	FONE,%fp2	|init fp2 to 1.0	movel	%d4,%d0		|put LEN in d0	subql	#1,%d0		|d0 = LEN -1	clrl	%d3		|clr table indexl_loop:		lsrl	#1,%d0		|shift next bit into carry	bccs	l_next		|if zero, skip the mul	fmulx	(%a1,%d3),%fp2	|mul by 10**(d3_bit_no)l_next:	addl	#12,%d3		|inc d3 to next pwrten table entry	tstl	%d0		|test if LEN is zero	bnes	l_loop		|if not, loop|| 10^LEN-1 is computed for this test and A14.  If the input was| denormalized, check only the case in which YINT > 10^LEN.|	tstb	BINDEC_FLG(%a6)	|check if input was norm	beqs	A13_con		|if norm, continue with checking	fabsx	%fp0		|take abs of YINT	bra	test_2|| Compare abs(YINT) to 10^(LEN-1) and 10^LEN|A13_con:	fabsx	%fp0		|take abs of YINT	fcmpx	%fp2,%fp0		|compare abs(YINT) with 10^(LEN-1)	fbge	test_2		|if greater, do next test	subql	#1,%d6		|subtract 1 from ILOG	movew	#1,%d5		|set ICTR	fmovel	#rm_mode,%FPCR	|set rmode to RM	fmuls	FTEN,%fp2	|compute 10^LEN 	bra	A6_str		|return to A6 and recompute YINTtest_2:	fmuls	FTEN,%fp2	|compute 10^LEN	fcmpx	%fp2,%fp0		|compare abs(YINT) with 10^LEN	fblt	A14_st		|if less, all is ok, go to A14	fbgt	fix_ex		|if greater, fix and redo	fdivs	FTEN,%fp0	|if equal, divide by 10	addql	#1,%d6		| and inc ILOG	bras	A14_st		| and continue elsewherefix_ex:	addql	#1,%d6		|increment ILOG by 1	movew	#1,%d5		|set ICTR	fmovel	#rm_mode,%FPCR	|set rmode to RM	bra	A6_str		|return to A6 and recompute YINT|| Since ICTR <> 0, we have already been through one adjustment, | and shouldn't have another; this is to check if abs(YINT) = 10^LEN| 10^LEN is again computed using whatever table is in a1 since the| value calculated cannot be inexact.|not_zr:	fmoves	FONE,%fp2	|init fp2 to 1.0	movel	%d4,%d0		|put LEN in d0	clrl	%d3		|clr table indexz_loop:	lsrl	#1,%d0		|shift next bit into carry	bccs	z_next		|if zero, skip the mul	fmulx	(%a1,%d3),%fp2	|mul by 10**(d3_bit_no)z_next:	addl	#12,%d3		|inc d3 to next pwrten table entry	tstl	%d0		|test if LEN is zero	bnes	z_loop		|if not, loop	fabsx	%fp0		|get abs(YINT)	fcmpx	%fp2,%fp0		|check if abs(YINT) = 10^LEN	fbne	A14_st		|if not, skip this	fdivs	FTEN,%fp0	|divide abs(YINT) by 10	addql	#1,%d6		|and inc ILOG by 1	addql	#1,%d4		| and inc LEN	fmuls	FTEN,%fp2	| if LEN++, the get 10^^LEN| A14. Convert the mantissa to bcd.|      The binstr routine is used to convert the LEN digit |      mantissa to bcd in memory.  The input to binstr is|      to be a fraction; i.e. (mantissa)/10^LEN and adjusted|      such that the decimal point is to the left of bit 63.|      The bcd digits are stored in the correct position in |      the final string area in memory.||| Register usage:|	Input/Output|	d0: x/LEN call to binstr - final is 0|	d1: x/0|	d2: x/ms 32-bits of mant of abs(YINT)|	d3: x/ls 32-bits of mant of abs(YINT)|	d4: LEN/Unchanged|	d5: ICTR:LAMBDA/LAMBDA:ICTR|	d6: ILOG|	d7: k-factor/Unchanged|	a0: pointer into memory for packed bcd string formation|	    /ptr to first mantissa byte in result string|	a1: ptr to PTENxx array/Unchanged|	a2: ptr to FP_SCR2(a6)/Unchanged|	fp0: int portion of Y/abs(YINT) adjusted|	fp1: 10^ISCALE/Unchanged|	fp2: 10^LEN/Unchanged|	F_SCR1:x/Work area for final result|	F_SCR2:Y with original exponent/Unchanged|	L_SCR1:original USER_FPCR/Unchanged|	L_SCR2:first word of X packed/UnchangedA14_st:		fmovel	#rz_mode,%FPCR	|force rz for conversion	fdivx	%fp2,%fp0		|divide abs(YINT) by 10^LEN	leal	FP_SCR1(%a6),%a0	fmovex	%fp0,(%a0)	|move abs(YINT)/10^LEN to memory	movel	4(%a0),%d2	|move 2nd word of FP_RES to d2	movel	8(%a0),%d3	|move 3rd word of FP_RES to d3	clrl	4(%a0)		|zero word 2 of FP_RES	clrl	8(%a0)		|zero word 3 of FP_RES	movel	(%a0),%d0		|move exponent to d0	swap	%d0		|put exponent in lower word	beqs	no_sft		|if zero, don't shift	subil	#0x3ffd,%d0	|sub bias less 2 to make fract	tstl	%d0		|check if > 1	bgts	no_sft		|if so, don't shift	negl	%d0		|make exp positivem_loop:	lsrl	#1,%d2		|shift d2:d3 right, add 0s 	roxrl	#1,%d3		|the number of places	dbf	%d0,m_loop	|given in d0no_sft:	tstl	%d2		|check for mantissa of zero	bnes	no_zr		|if not, go on	tstl	%d3		|continue zero check	beqs	zer_m		|if zero, go directly to binstrno_zr:	clrl	%d1		|put zero in d1 for addx	addil	#0x00000080,%d3	|inc at bit 7	addxl	%d1,%d2		|continue inc	andil	#0xffffff80,%d3	|strip off lsb not used by 882zer_m:	movel	%d4,%d0		|put LEN in d0 for binstr call	addql	#3,%a0		|a0 points to M16 byte in result	bsr	binstr		|call binstr to convert mant| A15. Convert the exponent to bcd.|      As in A14 above, the exp is converted to bcd and the|      digits are stored in the final string.||      Digits are stored in L_SCR1(a6) on return from BINDEC as:||  	 32               16 15                0|	-----------------------------------------|  	|  0 | e3 | e2 | e1 | e4 |  X |  X |  X ||	-----------------------------------------|| And are moved into their proper places in FP_SCR1.  If digit e4| is non-zero, OPERR is signaled.  In all cases, all 4 digits are| written as specified in the 881/882 manual for packed decimal.|| Register usage:|	Input/Output|	d0: x/LEN call to binstr - final is 0|	d1: x/scratch (0);shift count for final exponent packing|	d2: x/ms 32-bits of exp fraction/scratch|	d3: x/ls 32-bits of exp fraction|	d4: LEN/Unchanged|	d5: ICTR:LAMBDA/LAMBDA:ICTR|	d6: ILOG|	d7: k-factor/Unchanged|	a0: ptr to result string/ptr to L_SCR1(a6)|	a1: ptr to PTENxx array/Unchanged|	a2: ptr to FP_SCR2(a6)/Unchanged|	fp0: abs(YINT) adjusted/float(ILOG)|	fp1: 10^ISCALE/Unchanged|	fp2: 10^LEN/Unchanged|	F_SCR1:Work area for final result/BCD result|	F_SCR2:Y with original exponent/ILOG/10^4|	L_SCR1:original USER_FPCR/Exponent digits on return from binstr|	L_SCR2:first word of X packed/UnchangedA15_st:		tstb	BINDEC_FLG(%a6)	|check for denorm	beqs	not_denorm	ftstx	%fp0		|test for zero	fbeq	den_zero	|if zero, use k-factor or 4933	fmovel	%d6,%fp0		|float ILOG	fabsx	%fp0		|get abs of ILOG	bras	convrtden_zero:	tstl	%d7		|check sign of the k-factor	blts	use_ilog	|if negative, use ILOG	fmoves	F4933,%fp0	|force exponent to 4933	bras	convrt		|do ituse_ilog:	fmovel	%d6,%fp0		|float ILOG	fabsx	%fp0		|get abs of ILOG	bras	convrtnot_denorm:	ftstx	%fp0		|test for zero	fbne	not_zero	|if zero, force exponent	fmoves	FONE,%fp0	|force exponent to 1	bras	convrt		|do itnot_zero:		fmovel	%d6,%fp0		|float ILOG	fabsx	%fp0		|get abs of ILOGconvrt:	fdivx	24(%a1),%fp0	|compute ILOG/10^4	fmovex	%fp0,FP_SCR2(%a6)	|store fp0 in memory	movel	4(%a2),%d2	|move word 2 to d2	movel	8(%a2),%d3	|move word 3 to d3	movew	(%a2),%d0		|move exp to d0	beqs	x_loop_fin	|if zero, skip the shift	subiw	#0x3ffd,%d0	|subtract off bias	negw	%d0		|make exp positivex_loop:	lsrl	#1,%d2		|shift d2:d3 right 	roxrl	#1,%d3		|the number of places	dbf	%d0,x_loop	|given in d0x_loop_fin:	clrl	%d1		|put zero in d1 for addx	addil	#0x00000080,%d3	|inc at bit 6	addxl	%d1,%d2		|continue inc	andil	#0xffffff80,%d3	|strip off lsb not used by 882	movel	#4,%d0		|put 4 in d0 for binstr call	leal	L_SCR1(%a6),%a0	|a0 is ptr to L_SCR1 for exp digits	bsr	binstr		|call binstr to convert exp	movel	L_SCR1(%a6),%d0	|load L_SCR1 lword to d0 	movel	#12,%d1		|use d1 for shift count	lsrl	%d1,%d0		|shift d0 right by 12	bfins	%d0,FP_SCR1(%a6){#4:#12} |put e3:e2:e1 in FP_SCR1	lsrl	%d1,%d0		|shift d0 right by 12	bfins	%d0,FP_SCR1(%a6){#16:#4} |put e4 in FP_SCR1 	tstb	%d0		|check if e4 is zero	beqs	A16_st		|if zero, skip rest	orl	#opaop_mask,USER_FPSR(%a6) |set OPERR & AIOP in USER_FPSR| A16. Write sign bits to final string.|	   Sigma is bit 31 of initial value; RHO is bit 31 of d6 (ILOG).|| Register usage:|	Input/Output|	d0: x/scratch - final is x|	d2: x/x|	d3: x/x|	d4: LEN/Unchanged|	d5: ICTR:LAMBDA/LAMBDA:ICTR|	d6: ILOG/ILOG adjusted|	d7: k-factor/Unchanged|	a0: ptr to L_SCR1(a6)/Unchanged|	a1: ptr to PTENxx array/Unchanged|	a2: ptr to FP_SCR2(a6)/Unchanged|	fp0: float(ILOG)/Unchanged|	fp1: 10^ISCALE/Unchanged|	fp2: 10^LEN/Unchanged|	F_SCR1:BCD result with correct signs|	F_SCR2:ILOG/10^4|	L_SCR1:Exponent digits on return from binstr|	L_SCR2:first word of X packed/UnchangedA16_st:	clrl	%d0		|clr d0 for collection of signs	andib	#0x0f,FP_SCR1(%a6) |clear first nibble of FP_SCR1 	tstl	L_SCR2(%a6)	|check sign of original mantissa	bges	mant_p		|if pos, don't set SM	moveql	#2,%d0		|move 2 in to d0 for SMmant_p:	tstl	%d6		|check sign of ILOG	bges	wr_sgn		|if pos, don't set SE	addql	#1,%d0		|set bit 0 in d0 for SE wr_sgn:	bfins	%d0,FP_SCR1(%a6){#0:#2} |insert SM and SE into FP_SCR1| Clean up and restore all registers used.	fmovel	#0,%FPSR		|clear possible inex2/ainex bits	fmovemx (%a7)+,%fp0-%fp2	moveml	(%a7)+,%d2-%d7/%a2	rts	|end

⌨️ 快捷键说明

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