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

📄 bindec.s

📁 Vxworks OS source code
💻 S
📖 第 1 页 / 共 2 页
字号:
	fmovel	#rz_mode,fpcr	| set RZ rounding mode| A9. Scale X -> Y.|     The mantissa is scaled to the desired number of significant|     digits.  The excess digits are collected in INEX2. If mul,|     Check d2 for excess 10 exponential value.  If not zero,|     the iscale value would have caused the __x_pwrten calculation|     to overflow.  Only a negative iscale can cause this, so|     multiply by	d2@(10^), which is now only allowed to be 24,|     with a multiply by 10^8 and 10^16, which is exact since|     10^24 is exact.  If the input was denormalized, we must|     create a busy stack frame with the mul command and the|     two operands, and allow the fpu to complete the multiply.|| 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 __x_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 0x3fff 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	jne 	__x_sc_mul	| if neg (LAMBDA = 0), scale by mul	fdivx	fp1,fp0		| calculate X / SCALE -> Y to fp0	jra 	__A10_st	| branch to A10__x_sc_mul:	tstb	a6@(BINDEC_FLG)	| check for denorm	jeq 	A9_norm		| if norm, continue with mul	fmovemx fp1-fp1,a7@-	| load ETEMP with 10^ISCALE	movel	a0@(8),a7@-	| load FPTEMP with input arg	movel	a0@(4),a7@-	movel	a0@,a7@-	movel	#18,d3		| load count for busy stackA9_loop:	clrl	a7@-		| clear lword on stack	dbf	d3,A9_loop	moveb	a6@(VER_TMP),a7@ 	| write current version number	moveb	#BUSY_SIZE-4,a7@(1) 	| write current busy size	moveb	#0x10,a7@(0x44)		| set fcefpte[15] bit	movew	#0x0023,a7@(0x40)	| load cmdreg1b with mul command	moveb	#0xfe,a7@(0x8)		| load all 1s to cu savepc	frestore	a7@+		| restore frame to fpu for completion	fmulx	a1@(36),fp0		| multiply fp0 by 10^8	fmulx	a1@(48),fp0		| multiply fp0 by 10^16	jra 	__A10_stA9_norm:	tstw	d2		| test for small exp case	jeq 	A9_con		| if zero, continue as normal	fmulx	a1@(36),fp0	| multiply fp0 by 10^8	fmulx	a1@(48),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 occured.  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	a6@(FP_SCR2)|	fp0: Y/Y with lsb adjusted|	fp1: 10^ISCALE/Unchanged|	fp2: x/x__A10_st:	fmovel	FPSR,d0		| get FPSR	fmovex	fp0,a6@(FP_SCR2)	| move Y to memory	lea	a6@(FP_SCR2),a2	| load a2 with ptr to FP_SCR2	btst	#9,d0		| check if INEX2 set	jeq 	__A11_st		| if clear, skip rest	oril	#1,a2@(8)	| or in 1 to lsb of mantissa	fmovex	a6@(FP_SCR2),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 __x_sintdo entry point in the __x_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	a6@(USER_FPCR),a6@(L_SCR1) | save it for later	andil	#0x00000030,a6@(USER_FPCR) | set size to ext,|					| block exceptions/* | A12. Calculate YINT = FINT(Y) according to user's rounding mode. */|      The FPSP routine __x_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 __x_sintdo|	a1: ptr to PTENxx array/Unchanged|	a2: ptr to	a6@(FP_SCR2)/Unchanged|	a6: temp pointer to	a6@(FP_SCR2) - 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/Unchanged__A12_st:	moveml	d0-d1/a0-a1,a7@-	| save regs used by __x_sintd0	movel	a6@(L_SCR1),a7@-	movel	a6@(L_SCR2),a7@-	lea	a6@(FP_SCR2),a0		| a0 is ptr to	a6@(F_SCR2)	fmovex	fp0,a0@		| move Y to memory at	a6@(FP_SCR2)	tstl	a6@(L_SCR2)		| test sign of original operand	jge 	do_fint			| if pos, use Y	orl	#0x80000000,a0@		| if neg, use -Ydo_fint:	movel	a6@(USER_FPSR),a7@-	bsrl	__x_sintdo			| sint routine returns int in fp0	moveb	a7@,a6@(USER_FPSR)	addl	#4,a7	movel	a7@+,a6@(L_SCR2)	movel	a7@+,a6@(L_SCR1)	moveml	a7@+,d0-d1/a0-a1	| restore regs used by __x_sint	movel	a6@(L_SCR2),a6@(FP_SCR2)	| restore original exponent	movel	a6@(L_SCR1),a6@(USER_FPCR) /* | 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	a6@(FP_SCR2)/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/Unchanged__A13_st:	swap	d5		| put ICTR in lower word of d5	tstw	d5		| check if ICTR = 0	jne 	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	jcc 	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 __x_pwrten table entry	tstl	d0		| test if LEN is zero	jne 	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	a6@(BINDEC_FLG)	| check if input was norm	jeq 	__A13_con		| if norm, continue with checking	fabsx	fp0		| take abs of YINT	jra 	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	jra 	__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	jra 	__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	jra 	__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	jcc 	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 __x_pwrten table entry	tstl	d0		| test if LEN is zero	jne 	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 __x_binstr routine is used to convert the LEN digit|      mantissa to bcd in memory.  The input to __x_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 __x_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	a6@(FP_SCR2)/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/Unchanged__A14_st:	fmovel	#rz_mode,fpcr	| force rz for conversion	fdivx	fp2,fp0		| divide abs(YINT) by 10^LEN	lea	a6@(FP_SCR1),a0	fmovex	fp0,a0@	| move abs(YINT)/10^LEN to memory	movel	a0@(4),d2	| move 2nd word of FP_RES to d2	movel	a0@(8),d3	| move 3rd word of FP_RES to d3	clrl	a0@(4)		| zero word 2 of FP_RES	clrl	a0@(8)		| zero word 3 of FP_RES	movel	a0@,d0		| move exponent to d0	swap	d0		| put exponent in lower word	jeq 	no_sft		/* | if zero, don't shift */	subil	#0x3ffd,d0	| sub bias less 2 to make fract	tstl	d0		| check if > 1	jgt 	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	jne 	no_zr		| if not, go on	tstl	d3		| continue zero check	jeq 	zer_m		| if zero, go directly to __x_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 __x_binstr call	addql	#3,a0		| a0 points to M16 byte in result	bsrl	__x_binstr		| call __x_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	a6@(L_SCR1) 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 __x_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	a6@(L_SCR1)|	a1: ptr to PTENxx array/Unchanged|	a2: ptr to	a6@(FP_SCR2)/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 __x_binstr|	L_SCR2:first word of X packed/Unchanged__A15_st:	tstb	a6@(BINDEC_FLG)	| check for denorm	jeq 	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	jra 	convrtden_zero:	tstl	d7		| check sign of the k-factor	jlt 	use_ilog	| if negative, use ILOG	fmoves	F4933,fp0	| force exponent to 4933	jra 	convrt		| do ituse_ilog:	fmovel	d6,fp0		| float ILOG	fabsx	fp0		| get abs of ILOG	jra 	convrtnot_denorm:	ftstx	fp0		| test for zero	fbne	not_zero	| if zero, force exponent	fmoves	FONE,fp0	| force exponent to 1	jra 	convrt		| do itnot_zero:	fmovel	d6,fp0		| float ILOG	fabsx	fp0		| get abs of ILOGconvrt:	fdivx	a1@(24),fp0	| compute ILOG/10^4	fmovex	fp0,a6@(FP_SCR2)	| store fp0 in memory	movel	a2@(4),d2	| move word 2 to d2	movel	a2@(8),d3	| move word 3 to d3	movew	a2@,d0		| move exp to d0	jeq 	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 __x_binstr call	lea	a6@(L_SCR1),a0	| a0 is ptr to L_SCR1 for exp digits	bsrl	__x_binstr		| call __x_binstr to convert exp	movel	a6@(L_SCR1),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,a6@(FP_SCR1){#4:#12} | put e3:e2:e1 in FP_SCR1	lsrl	d1,d0		| shift d0 right by 12	bfins	d0,a6@(FP_SCR1){#16:#4} | put e4 in FP_SCR1	tstb	d0		| check if e4 is zero	jeq 	__A16_st		| if zero, skip rest	orl	#opaop_mask,a6@(USER_FPSR) | 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	a6@(L_SCR1)/Unchanged|	a1: ptr to PTENxx array/Unchanged|	a2: ptr to	a6@(FP_SCR2)/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 __x_binstr|	L_SCR2:first word of X packed/Unchanged__A16_st:	clrl	d0		| clr d0 for collection of signs	andib	#0x0f,a6@(FP_SCR1) | clear first nibble of FP_SCR1	tstl	a6@(L_SCR2)	| check sign of original mantissa	jge 	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	jge 	wr_sgn		/* | if pos, don't set SE */	addql	#1,d0		| set bit 0 in d0 for SEwr_sgn:	bfins	d0,a6@(FP_SCR1){#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 + -