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

📄 fpsoft.s

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 S
📖 第 1 页 / 共 5 页
字号:
	b	rd_1w2:	subu	v1,t1,t5		/* find the difference of the exponents */	move	v0,v1			/*  in (v1) and the absolute value of */	bge	v1,zero,1f		/*  the difference in (v0) */	negu	v01:	ble	v0,SFRAC_BITS+2,2f	/* is the difference is greater than the */					/*  number of bits of precision? */	li	t8,STKBIT		/* set the sticky register */	bge	v1,zero,1f	/* result is RT added with a sticky bit (for RS) */	move	t1,t5			/* result exponent will be RTs exponent */	move	t2,zero	b	4f1:	/* the result is RS added with a sticky bit (for RT) */	move	t6,zero	b	4f2:	move	t8,zero			/* clear the sticky register */	/*	 * If the exponent difference is greater than zero shift the smaller	 * value right by the exponent difference to align the binary point	 * before the addition.  Also select the exponent of the result to	 * be the largest exponent of the two values.  The result exponent is	 * left in (t1) so only if RS is to be shifted does RTs exponent	 * need to be moved into (t1).	 */	beq	v0,zero,4f		/* - if the exp diff is zero then no shift */	bgt	v1,zero,3f		/* - if the exp diff > 0 shift RT */	move	t1,t5			/* result exponent will be RTs exponent */	/* Shift the fraction value of RS by < 32 (the right shift amount (v0)) */	negu	v1,v0			/* the left shift amount which is 32 */	addu	v1,32			/*  minus right shift amount (v1) */	srlv	t8,t8,v0		/* shift the sticky register */	sllv	t9,t2,v1	or	t8,t9	srlv	t2,t2,v0		/* shift the fraction */	b	4f3:	/* Shift the fraction value of RT by < 32 (the right shift amount (v0)) */	negu	v1,v0			/* the left shift amount which is 32 */	addu	v1,32			/*  minus right shift amount (v1) */	srlv	t8,t8,v0		/* shift the sticky register */	sllv	t9,t6,v1	or	t8,t9	srlv	t6,t6,v0		/* shift the fraction */4:	/*	 * Now if the signs are the same add the two fractions, else if the	 * signs are different then subtract the smaller fraction from the	 * larger fraction and the results sign will be the sign of the	 * larger fraction.	 */	bne	t0,t4,1f		/* - if the signs not the same subtract */	/* Add the fractions */	addu	t2,t6			/* add fraction words */	b	norm_s1:	/*	 * Subtract the smaller fraction from the larger fraction and set the	 * sign of the result to the sign of the larger fraction.	 */	blt	t2,t6,3f		/* determine the smaller fraction */					/*  Note the case where they were equal */					/*  has already been taken care of */1:	/*	 * RT is smaller so subtract RT from RS and use RSs sign as the sign	 * of the result (the sign is already in the correct place (t0)).	 */	sltu	t9,zero,t8		/* set barrow out for sticky register */	subu	t8,zero,t8	/* subtract least signifiant fraction words */	bne	t9,zero,2f		/* see if there is a barrow in */	/* no barrow in to be subtracted out */	subu	t2,t2,t6		/* subtract fractions */	b	norm_s2:	/* barrow in to be subtracted out */	subu	t2,t2,t6		/* subtract least fractions */	subu	t2,1			/* subtract barrow in */	b	norm_s3:	/*	 * RS is smaller so subtract RS from RT and use RTs sign as the sign	 * of the result.	 */	move	t0,t4			/* use RTs sign as the sign of result */	sltu	t9,zero,t8		/* set barrow out for sticky register */	subu	t8,zero,t8	/* subtract least signifiant fraction words */	bne	t9,zero,1f		/* see if there is a barrow in */	/* no barrow in to be subtracted out */	subu	t2,t6,t2		/* subtract least fractions */	b	norm_s1:	/* barrow in to be subtracted out */	subu	t2,t6,t2		/* subtract least fractions */	subu	t2,1			/* subtract barrow in */	b	norm_s/********************************************************************************* add_d -** Add (and subtract) double RD = RS + RT (or RD = RS - RT).  Again the FUNC* field (t8) is zero for adds.*/	.globl	GTEXT(add_d)FUNC_LABEL(add_d)	/*	 * Break out the operands into their fields (sign,exp,fraction) and	 * handle NaN operands by calling {rs,rt}breakout_d() .	 */	li	t9,C1_FMT_DOUBLE*4	li	v1,1	jal	rs_breakout_d	jal	rt_breakout_d	beq	t8,zero,1f	/* - if doing a subtract then negate RT */	lui	v0,(SIGNBIT>>16)&0xffff	xor	t4,v01:	/* Check for addition of infinities, and produce the correct action if so */	bne	t1,DEXP_INF,5f	/* is RS an infinity? */				/* RS is an infinity */	bne	t5,DEXP_INF,4f	/* is RT also an infinity? */				/* RT is an infinity */	beq	t0,t4,3f	/* do the infinities have the same sign? */	/*	 * The infinities do NOT have the same sign thus this is an invalid	 * operation for addition so set the invalid exception in the C1_SR	 * (a3) and setup the result depending if the enable for the invalid	 * exception is set.	 */	or	a3,INVALID_EXC	and	v0,a3,INVALID_ENABLE	beq	v0,zero,2f	/*	 * The invalid trap was enabled so signal a SIGFPE and leave the	 * result register unmodified.	 */	li	v0, IV_FPA_INV_VEC	jal	post_signal	li	v0,1	b	store_C1_SR	/*	 * The invalid trap was NOT enabled so the result is a quiet NaN.	 * So use the default quiet NaN and exit softFp().	 */2:	li	t2,DQUIETNAN_LESS	li	t3,DQUIETNAN_LEAST	move	v0,zero	b	rd_2w	/*	 * This is just a normal infinity + infinity so the result is just	 * an infinity with the sign of the operands.	 */3:	move	t2,t0	sll	t1,t1,DEXP_SHIFT	or	t2,t1	move	v0,zero	b	rd_2w	/*	 * This is infinity + x , where RS is the infinity so the result is	 * just RS (the infinity).	 */4:	move	t2,t0	sll	t1,t1,DEXP_SHIFT	or	t2,t1	move	v0,zero	b	rd_2w	/*	 * Check RT for an infinity value.  At this point it is know that RS	 * is not an infinity.  If RT is an infinity it will be the result.	 */5:	bne	t5,DEXP_INF,6f	move	t2,t4	sll	t5,t5,DEXP_SHIFT	or	t2,t5	move	t3,t7	move	v0,zero	b	rd_2w6:	/* Check for the addition of zeros and produce the correct action if so */	bne	t1,zero,3f	/* check RS for a zero value (first the exp) */	bne	t2,zero,3f	/* then the high part of the fraction */	bne	t3,zero,3f	/* then the low part of the fraction */				/* Now RS is known to be zero */	bne	t5,zero,2f	/* check RT for a zero value (first the exp) */	bne	t6,zero,2f	/* then the high part of the fraction */	bne	t7,zero,2f	/* then the low part of the fraction */	/*	 * Now RS and RT are known to be zeroes so set the correct result	 * according to the rounding mode (in the C1_SR) and exit.	 */	and	v0,a3,CSR_RM_MASK	/* get the rounding mode */	bne	v0,CSR_RM_RMI,1f	/* check for round to - infinity */	or	t2,t0,t4		/* set the result and exit, for round to */	move	v0,zero			/*  - infinity the zero result is the */	b	rd_2w			/*  and of the operands signs */1:	and	t2,t0,t4		/* set the result and exit, for other */	move	v0,zero			/*  rounding modes the zero result is the */	b	rd_2w			/*  or of the operands signs */	/* RS is a zero and RT is non-zero so the result is RT */2:	move	t2,t4	sll	t5,t5,DEXP_SHIFT	or	t2,t5	or	t2,t6	move	t3,t7	move	v0,zero	b	rd_2w	/* RS is now known not to be zero so check RT for a zero value. */3:	bne	t5,zero,4f	/* check RT for a zero value (first the exp) */	bne	t6,zero,4f	/* then the high part of the fraction */	bne	t7,zero,4f	/* then the low part of the fraction */	or	t2,t0		/* RT is a zero so the result is RS */	sll	t1,t1,DEXP_SHIFT	or	t2,t1	move	v0,zero	b	rd_2w4:	/*	 * Now that all the NaN, infinity and zero cases have been taken care	 * of what is left are values that can be added.  So get all values	 * into a format that can be added.  For normalized numbers set the	 * implied one and remove the exponent bias.  For denormalized numbers	 * convert to normalized numbers with the correct exponent.	 */	bne	t1,zero,1f	/* check for RS being denormalized */	li	t1,-DEXP_BIAS+1	/* set denorms exponent */	jal	rs_renorm_d	/* normalize it */	b	2f1:	subu	t1,DEXP_BIAS	/* - if RS is not denormalized then remove the */	or	t2,DIMP_1BIT	/*  exponent bias, and set the implied 1 bit */2:	bne	t5,zero,3f	/* check for RT being denormalized */	li	t5,-DEXP_BIAS+1	/* set denorms exponent */	jal	rt_renorm_d	/* normalize it */	b	4f3:	subu	t5,DEXP_BIAS	/* - if RT is not denormalized then remove the */	or	t6,DIMP_1BIT	/*  exponent bias, and set the implied 1 bit */4:	/*	 * If the two values are the same except the sign return the correct	 * zero according to the rounding mode.	 */	beq	t0,t4,2f		/* - if the signs are the same continue */	bne	t1,t5,2f		/* - if the exps are not the same continue */	bne	t2,t6,2f		/* - if the fractions are not the */	bne	t3,t7,2f		/*  same continue */	and	v0,a3,CSR_RM_MASK	/* get the rounding mode */	bne	v0,CSR_RM_RMI,1f	/* check for round to - infinity */	or	t2,t0,t4		/* set the result and exit, for round to */	move	t3,zero			/*  - infinity the zero result is the */	move	v0,zero			/*  and of the operands signs */	b	rd_2w1:	and	t2,t0,t4		/* set the result and exit, for other */	move	t3,zero			/*  rounding modes the zero result is the */	move	v0,zero			/*  or of the operands signs */	b	rd_2w2:	subu	v1,t1,t5		/* find the difference of the exponents */	move	v0,v1			/*  in (v1) and the absolute value of */	bge	v1,zero,1f		/*  the difference in (v0) */	negu	v01:	ble	v0,DFRAC_BITS+2,3f	/* is the difference is greater than the */					/*  number of bits of precision */	li	t8,STKBIT		/* set the sticky register */	bge	v1,zero,2f	/* result is RT with a STKBIT added (for RS) */	move	t1,t5			/* result exponent will be RTs exponent */	move	t2,zero	move	t3,zero	b	9f2:	/* the result is RS with a STKBIT added (for RT) */	move	t6,zero	move	t7,zero	b	9f3:	move	t8,zero			/* clear the sticky register */	/*	 * If the exponent difference is greater than zero shift the smaller	 * value right by the exponent difference to align the binary point	 * before the addition.  Also select the exponent of the result to	 * be the largest exponent of the two values.  The result exponent is	 * left in (t1) so only if RS is to be shifted does RTs exponent	 * need to be moved into (t1).	 */	beq	v0,zero,9f		/* - if the exp diff is zero then no shift */	bgt	v1,zero,6f		/* if the exp diff > 0 shift RT */	move	t1,t5			/* result exponent will be RTs exponent */	/* Shift the fraction of the RS value */	blt	v0,32,5f		/* check for shifts >= 32 */	move	t8,t3			/* shift the fraction over 32 bits by */	move	t3,t2			/*  moving the words to the right and */	move	t2,zero			/*  fill the highest word with a zero */	beq	t8,zero,4f		/* - if any 1s get into the sticky reg */	or	t8,STKBIT		/*  make sure the sticky bit stays set */4:	subu	v0,32			/* the right shift amount (v0) */	negu	v1,v0			/* the left shift amount which is 32 */	addu	v1,32			/*  minus right shift amount (v1) */	/* Now shift the fraction (only the low two words in this case) */	srlv	t8,t8,v0		/* shift the sticky register */	sllv	t9,t3,v1	or	t8,t9	srlv	t3,t3,v0		/* shift the low word of the fraction */	b	9f5:	/* Shift the fraction value of RS by < 32 (the right shift amount (v0)) */	negu	v1,v0			/* the left shift amount which is 32 */	addu	v1,32			/*  minus right shift amount (v1) */	srlv	t8,t8,v0		/* shift the sticky register */	sllv	t9,t3,v1	or	t8,t9	srlv	t3,t3,v0		/* shift the low word of the fraction */	sllv	t9,t2,v1	or	t3,t9	srlv	t2,t2,v0		/* shift the high word of the fraction */	b	9f6:	/* Shift the fraction of the RT value */	blt	v0,32,8f		/* check for shifts >= 32 */	move	t8,t7			/* shift the fraction over 32 bits by */	move	t7,t6			/*  moving the words to the right and */	move	t6,zero			/*  fill the highest word with a zero */	beq	t8,zero,7f		/* - if any 1s get into the sticky reg */	or	t8,STKBIT		/*  make sure the sticky bit stays set */7:	subu	v0,32			/* the right shift amount (v0) */	negu	v1,v0			/* the left shift amount which is 32 */	addu	v1,32			/*  minus right shift amount (v1) */	/* Now shift the fraction (only the low two words in this case) */	srlv	t8,t8,v0		/* shift the sticky register */	sllv	t9,t7,v1	or	t8,t9	srlv	t7,t7,v0		/* shift the low word of the fraction */	b	9f8:	/* Shift the fraction value of RT by < 32 (the right shift amount (v0)) */	negu	v1,v0			/* the left shift amount which is 32 */	addu	v1,32			/*  minus right shift amount (v1) */	srlv	t8,t8,v0		/* shift the sticky register */	sllv	t9,t7,v1	or	t8,t9	srlv	t7,t7,v0		/* shift the low word of the fraction */	sllv	t9,t6,v1	or	t7,t9	srlv	t6,t6,v0		/* shift the high word of the fraction */9:	/*	 * Now if the signs are the same add the two fractions, else if the	 * signs are different then subtract the smaller fraction from the	 * larger fraction and the results sign will be the sign of the	 * larger fraction.	 */	bne	t0,t4,2f		/* - if the signs not the same subtract */	/* Add the fractions */	not	v0,t3			/* set carry out (t9) for the addition */	sltu	t9,v0,t7		/*  of the least fraction words */	addu	t3,t7			/* add the least fraction words */	/* add the less fraction fraction words with the carry in */	bne	t9,zero,1f		/* see if there is a carry in */	/* no carry in to be added in (carry out is not possible or needed) */	addu	t2,t6			/* add the less fraction words */	b	norm_d	/* a carry in is to be added in (carry out is not possible or needed) */1:	addu	t2,t6			/* add the less fraction words */	addu	t2,1			/* add in the carry in */	b	norm_d2:	/*	 * Subtract the smaller fraction from the larger fraction and set the	 * sign of the result to the sign of the larger fraction.	 */	blt	t2,t6,5f		/* determine the smaller fraction */	bgt	t2,t6,1f		/*  Note the case where they were equal */	bltu	t3,t7,5f		/*  has already been taken care of */1:	/*	 * RT is smaller so subtract RT from RS and use RSs sign as the sign	 * of the result (the sign is already in the correct place (t0)).	 */	sltu	t9,zero,t8		/* set barrow out for sticky register */	subu	t8,zero,t8	/* subtract least signifiant fraction words */	bne	t9,zero,2f		/* see if there is a barrow in */	/* no barrow in to be subtracted out */	sltu	t9,t3,t7		/* set barrow out for least fraction */	subu	t3,t3,t7		/* subtract least fractions */	b	3f2:	/* barrow in to be subtracted out */	sltu	t9,t3,t7		/* set barrow out for least fraction */	subu	t3,t3,t7		/* subtract least fractions */	seq	v0,t3,zero		/* set barrow out for barrow in */	or	t9,v0			/* final barrow out */	subu	t3,1			/* subtract barrow in */3:	/* subtract less signifiant fraction words */	bne	t9,zero,4f		/* see if there is a barrow in */	/* no barrow in to be subtracted out (barrow out not possible or needed) */	subu	t2,t2,t6		/* subtract less fractions */	b	norm_d4:	/* barrow in to be subtracted out (barrow out not possible or needed) */	subu	t2,t2,t6		/* subtract less fractions */	subu	t2,1			/* subtract barrow in */	b	norm_d5:	/*	 * RS is smaller so subtract RS from RT and use RTs sign as the sign	 * of the result.	 */	move	t0,t4			/* use RTs sign as the sign of result */	sltu	t9,zero,t8		/* set barrow out for sticky register */	subu	t8,zero,t8	/* subtract least signifiant fraction words */	bne	t9,zero,1f		/* see if there is a barrow in */	/* no barrow in to be subtracted out */	sltu	t9,t7,t3		/* set barrow out for least fraction */	subu	t3,t7,t3		/* subtract least fractions */	b	2f1:	/* barrow in to be subtracted out */	sltu	t9,t7,t3		/* set barrow out for least fraction */	subu	t3,t7,t3		/* subtract least fractions */	seq	v0,t3,zero		/* set barrow out for barrow in */	or	t9,v0			/* final barrow out */	subu	t3,1			/* subtract barrow in */2:	/* subtract less signifiant fraction words */	bne	t9,zero,3f		/* see if there is a barrow in */	/* no barrow in to be subtracted out (barrow out not possible or needed) */	subu	t2,t6,t2		/* subtract less fractions */	b	norm_d3:	/* barrow in to be subtracted out (barrow out not possible or needed) */	subu	t2,t6,t2		/* subtract least fractions */	subu	t2,1			/* subtract barrow in */	b	norm_dadd_e:add_q:	b	illfpinstfunc_mul:	la	v1,mul_fmt_tab	addu	v1, v0, v1	j	v1	.set	noreordermul_fmt_tab:	b	mul_s;	nop	b	mul_d;	nop	b	mul_e;	nop	b	mul_q;	nop	b	illfpinst; nop	b	illfpinst; nop	.set	reorder/********************************************************************************* mul_s - Multiplication single RD = RS * RT**/	.globl GTEXT(mul_s)FUNC_LABEL(mul_s)	/*	 * Break out the operands into their fields (sign,exp,fraction) and	 * handle NaN operands by calling {rs,rt}breakout_s() .	 */	li	t9,C1_FMT_SINGLE*4	li	v1,1	jal	rs_breakout_s	jal	rt_breakout_s	/*	 * With the Na

⌨️ 快捷键说明

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