📄 softfp.s
字号:
*/ 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 RT's 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 1's get into the sticky reg or t8,STKBIT # make sure the sticky bit stays set4: 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) srl t8,v0 # shift the sticky register sll t9,t3,v1 or t8,t9 srl 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) srl t8,v0 # shift the sticky register sll t9,t3,v1 or t8,t9 srl t3,v0 # shift the low word of the fraction sll t9,t2,v1 or t3,t9 srl 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 1's get into the sticky reg or t8,STKBIT # make sure the sticky bit stays set7: 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) srl t8,v0 # shift the sticky register sll t9,t7,v1 or t8,t9 srl 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) srl t8,v0 # shift the sticky register sll t9,t7,v1 or t8,t9 srl t7,v0 # shift the low word of the fraction sll t9,t6,v1 or t7,t9 srl t6,v0 # shift the high word of the fraction9: /* * 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 result's 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 of1: /* * RT is smaller so subtract RT from RS and use RS's 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 in3: # 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 RT's sign as the sign * of the result. */ move t0,t4 # use RT's 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 in2: # 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: lw v1,mul_fmt_tab(v0) j v1 .rdatamul_fmt_tab: .word mul_s:1, mul_d:1, mul_e:1, mul_q:1, illfpinst:1 .text/* * Multiplication single RD = RS * RT */.globl mul_smul_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 NaN cases taken care of the sign of the result for all * other operands is just the exclusive or of the signs of the * operands. */ xor t0,t4 /* * Check for multiplication of infinities, and produce the correct * action if so. */ bne t1,SEXP_INF,4f # is RS an infinity? bne t5,SEXP_INF,1f # is RT also an infinity? /* * The operation is just infinity * infinity so the result is just * a properly signed infinity. */ or t2,t0 sll t1,SEXP_SHIFT or t2,t1 move v0,zero b rd_1w1: /* * RS is an infinity and RT is NOT an infinity, if RT is zero then * this is an invalid operation else the result is just the RS infinity. */ bne t5,zero,3f bne t6,zero,3f /* * RS is an infinity and RT is zero thus this is an invalid operation * for addition so set the invalid exception in the fpc_csr (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,SIGFPE jal post_signal li v0,1 b store_fpc_csr /* * 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,SQUIETNAN_LEAST move v0,zero b rd_1w /* * The operation is just infinity (RS) * x (RT) so the result is just * the infinity (RS). */3: or t2,t0 sll t1,SEXP_SHIFT or t2,t1 move v0,zero b rd_1w /* * RS is known NOT to be an infinity so now check RT for an infinity */4: bne t5,SEXP_INF,8f # is RT an infinity? /* * RT is an infinity, if RS is zero then this is an invalid operation * else the result is just the RT infinity. */ bne t1,zero,7f bne t2,zero,7f /* * RS is an infinity and RT is zero thus this is an invalid operation * for addition so set the invalid exception in the fpc_csr (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,6f /* * The invalid trap was enabled so signal a SIGFPE and leave the * result register unmodified. */ li v0,SIGFPE jal post_signal li v0,1 b store_fpc_csr /* * The invalid trap was NOT enabled so the result is a quiet NaN. * So use the default quiet NaN and exit softfp(). */6: li t2,SQUIETNAN_LEAST move v0,zero b rd_1w /* * The operation is just x (RS) * infinity (RT) so the result is just * the infinity (RT). */7: move t2,t0 sll t5,SEXP_SHIFT or t2,t5 move v0,zero b rd_1w8: /* * Check for the multiplication of zeros and produce the correct zero * if so. */ bne t1,zero,1f # check RS for a zero value (first the exp) bne t2,zero,1f # then the fraction # Now RS is known to be zero so return the properly signed zero move t2,t0 move v0,zero b rd_1w1: bne t5,zero,2f # check RT for a zero value (first the exp) bne t6,zero,2f # then the fraction # Now RT is known to be zero so return the properly signed zero move t2,t0 move v0,zero b rd_1w2: /* * 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,-SEXP_BIAS+1 # set denorm's exponent jal rs_renorm_s # normalize it b 2f1: subu t1,SEXP_BIAS # if RS is not denormalized then remove the or t2,SIMP_1BIT # exponent bias, and set the implied 1 bit2: bne t5,zero,3f # check for RT being denormalized li t5,-SEXP_BIAS+1 # set denorm's exponent jal rt_renorm_s # normalize it b 4f3: subu t5,SEXP_BIAS # if RT is not denormalized then remove the or t6,SIMP_1BIT # exponent bias, and set the implied 1 bit4: /* * Calculate the exponent of the result to be used by the norm_s: * code to figure the final exponent. */ addu t1,t5 addu t1,9 multu t2,t6 # multiply RS(fraction) * RT(fraction) mflo t8 # the low 32 bits will be the sticky register mfhi t2 # the high 32 bits will the result b norm_s/* * Multiplication double RD = RS * RT */.globl mul_dmul_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 /* * With the NaN cases taken care of the sign of the result for all * other operands is just the exclusive or of the signs of the * operands. */ xor t0,t4 /* * Check for multiplication of infinities, and produce the correct * action if so. */ bne t1,DEXP_INF,4f # is RS an infinity? bne t5,DEXP_INF,1f # is RT also an infinity? /* * The operation is just infinity * infinity so the result is just * a properly signed infinity. */ or t2,t0 sll t1,DEXP_SHIFT or t2,t1 move v0,zero b rd_2w1: /* * RS is an infinity and RT is NOT an infinity, if RT is zero then * this is an invalid operation else the result is just the RS infinity. */ bne t5,zero,3f bne t6,zero,3f bne t7,zero,3f /* * RS is an infinity and RT is zero thus this is an invalid operation * for addition so set the invalid exception in the fpc_csr (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,SIGFPE jal post_signal li v0,1 b store_fpc_csr /* * 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 /* * The operation is just infinity (RS) * x (RT) so the result is just * the infinity (RS). */3: or t2,t0 sll t1,DEXP_SHIFT or t2,t1 move v0,zero b rd_2w /* * RS is known NOT to be an infinity so now check RT for an infinity */4: bne t5,DEXP_INF,8f # is RT an infinity? /* * RT is an infinity, if RS is zero then this is an invalid operation * else the result is just the RT infinity. */ bne t1,zero,7f bne t2,zero,7f bne t3,zero,7f /* * RS is an infinity and RT is zero thus this is an invalid operation * for addition so set the invalid exception in the fpc_csr (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,6f /* * The invalid trap was enabled so signal a SIGFPE and leave the * result register unmodified. */ li v0,SIGFPE jal post_signal li v0,1 b store_fpc_csr /* * The invalid trap was NOT enabled so the result is a quiet NaN. * So use the default quiet NaN and exit softfp(). */6: li t2,DQUIETNAN_LESS li t3,DQUIETNAN_LEAST move v0,zero b rd_2w /* * The operation is just x (RS) * infinity (RT) so the result is just * the infinity (RT). */7: move t2,t0 sll t5,DEXP_SHIFT or t2,t5 move t3,zero move v0,zero b rd_2w8: /* * Check for the multiplication of zeros and produce the correct zero * if so. */ bne t1,zero,1f # check RS for a zero value (first the exp) bne t2,zero,1f # then the high part of the fraction bne t3,zero,1f # then the low part of the fraction # Now RS is known to be zero so return the properly signed zero move t2,t0 move v0,zero b rd_2w1: bne t5,zero,2f # check RT for a zero value (first the exp)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -