📄 softfp.s
字号:
bne t6,zero,2f # then the high part of the fraction bne t7,zero,2f # then the low part of the fraction # Now RT is known to be zero so return the properly signed zero move t2,t0 move t3,zero move v0,zero b rd_2w2: /* * 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 denorm's 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 bit2: bne t5,zero,3f # check for RT being denormalized li t5,-DEXP_BIAS+1 # set denorm's 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 bit4: /* * Calculate the exponent of the result to be used by the norm_d: * code to figure the final exponent. */ addu t1,t5 addu t1,12 /* * Since the norm_d: code expects the fraction to be in t2,t3,t8 * RS's fraction is moved to t4,t5 so to free up t2,t3 to hold * the accululated result of the partal products. */ move t4,t2 move t5,t3 multu t5,t7 # multiply RS(low) * RT(low) fractions mflo ra # all the low 32 bits (ra) go into the sticky sne ra,ra,zero # bit so set it if there are any one bits mfhi t8 # get the high 32 bits (t8) multu t5,t6 # multiply RS(low) * RT(high) fractions mflo v1 # the low 32 bits will be added to t8 mfhi t3 # the high 32 bits will go into t3 move t2,zero # the highest accumulator word is zero'ed not v0,v1 # set the carry out of t8 and low 32 bits sltu t9,v0,t8 # of the mult (v1) addu t8,v1 # do the add of t8 and the low 32 bits (v1) beq t9,zero,1f # if no carry out continue addu t3,1 # add the carry in seq t2,t3,zero # set the carry out into t31: multu t4,t7 # multiply RS(high) * RT(low) fractions mflo v1 # the low 32 bits will be added to t8 mfhi t5 # the high 32 bits will be added to t3 not v0,v1 # set the carry out of t8 and low 32 bits sltu t9,v0,t8 # of the mult (v1) addu t8,v1 # do the add of t8 and the low 32 bits (v1) beq t9,zero,2f # branch if no carry out # add t3 and the high 32 bits of the mult (t5) and the carry in not v0,t5 # set the carry out of t3 and high 32 bits sltu t9,v0,t3 # of the mult (t5) addu t3,t5 # do the add of t3 and the high 32 bits (t5) addu t3,1 # add the carry in seq v0,t3,zero # set the carry out of the carry in or t9,v0 # set the final carry out b 3f2: # add t3 and the high 32 bits of the mult (t5) and no carry in not v0,t5 # set the carry out of t3 and high 32 bits sltu t9,v0,t3 # of the mult (t5) addu t3,t5 # do the add of t3 and the high 32 bits (t5)3: addu t2,t9 # add the carry out to t2 multu t4,t6 # multiply RS(high) * RT(high) fractions mflo v1 # the low 32 bits will be added to t3 mfhi t5 # the high 32 bits will be added to t2 not v0,v1 # set the carry out of t3 and low 32 bits sltu t9,v0,t3 # of the mult (v1) addu t3,v1 # do the add of t3 and the low 32 bits (v1) beq t9,zero,4f # branch if no carry out # add t2 and the high 32 bits of the mult (t5) and the carry in addu t2,1 # add the carry in4: addu t2,t5 # do the add of t2 and the high 32 bits (t5) or t8,ra b norm_dmul_e:mul_q: b illfpinstfunc_div: lw v1,div_fmt_tab(v0) j v1 .rdatadiv_fmt_tab: .word div_s:1, div_d:1, div_e:1, div_q:1, illfpinst:1 .text/* * Division single RD = RS / RT */.globl div_sdiv_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 division of infinities, and produce the correct * action if so. */ bne t1,SEXP_INF,3f # is RS an infinity? bne t5,SEXP_INF,2f # is RT also an infinity? /* * The operation is infinity / infinity which is an invalid operation. * 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,1f /* * 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(). */1: li t2,SQUIETNAN_LEAST move v0,zero b rd_1w /* * RS is an infinity and RT is NOT an infinity so the result is just a * a properly signed infinity (even if RT is zero). */2: 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 */3: bne t5,SEXP_INF,4f # is RT an infinity? /* * RT is an infinity and RS is NOT an infinity so the result is just a * a properly signed zero. */ move t2,t0 move v0,zero b rd_1w4: /* * Check for the division with zeros and produce the correct action * if so. */ bne t5,zero,4f # check RT for a zero value (first the exp) bne t6,zero,4f # then the fraction /* * Now RT is known to be zero, if RS is zero it is an invalid operation * if not it is a divide by zero. */ bne t1,zero,2f # check RS for a zero value (first the exp) bne t2,zero,2f # then the fraction /* * The operation is 0 / 0 which is an invalid operation. * 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,1f /* * 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(). */1: li t2,SQUIETNAN_LEAST move v0,zero b rd_1w /* * The operation is x / 0 which is a divide by zero excrption. So set * the divide by zero exception in the fpc_csr (a3) and setup the * result depending if the enable for the divide by zero exception * is set. */2: or a3,DIVIDE0_EXC and v0,a3,DIVIDE0_ENABLE beq v0,zero,3f /* * The divide by zero 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 divide by zero trap was NOT enabled so the result is a properly * signed infinity. */3: or t2,t0,SEXP_INF<<SEXP_SHIFT move v0,zero b rd_1w /* * Now RT is known NOT to be zero, if RS is zero the result is just * a properly signed zero. */4: bne t1,zero,5f # check RS for a zero value (first the exp) bne t2,zero,5f # then the fraction move t2,t0 move v0,zero b rd_1w5: /* * Now that all the NaN, infinity and zero cases have been taken care * of what is left are values that can be divded. So get all values * into a format that can be divded. 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. */ subu t1,t5 subu t1,8 /* * Since the norm_s: code expects the fraction to be in t2,t8 * RS's fraction is moved to t4 so to free up t2 to hold * the final quotient of the division. */ move t4,t2 move v0,zero # set the number of quotient bits calculated # to zero move t2,zero # clear the quotient accumulator1: bltu t4,t6,3f # check if dividend (RS) >= divisor (RT)2: # subtract divisor (RT) from dividend (RS) subu t4,t6 # subtract the fraction words addu t2,1 # add one to the quotient accumulator bne t4,zero,3f # see if division is done (remainder of zero) move t8,zero # clear the sticky register (no remainder) negu v0 # shift the quotient accumulator into it's addu v0,31 # final possition and goto norm_s: sll t2,v0 b norm_s3: sll t4,1 # shift the dividend (RS) left one bit addu v0,1 # add one to the number of quotient bits # calculated sll t2,1 # shift the quotient accumulator left one bit # see if enough quotient bits have been calculated if not continue blt v0,SFRAC_BITS+3,1b negu v0 # shift the quoient accumulator into it's addu v0,31 # final possition sll t2,v0 move t8,t4 # set the sticky register with all the bits of # remainder b norm_s/* * Division double RD = RS / RT */.globl div_ddiv_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 division of infinities, and produce the correct * action if so. */ bne t1,DEXP_INF,3f # is RS an infinity? bne t5,DEXP_INF,2f # is RT also an infinity? /* * The operation is infinity / infinity which is an invalid operation. * 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,1f /* * 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(). */1: li t2,DQUIETNAN_LESS li t3,DQUIETNAN_LEAST move v0,zero b rd_2w /* * RS is an infinity and RT is NOT an infinity so the result is just a * a properly signed infinity (even if RT is zero). */2: 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 */3: bne t5,DEXP_INF,4f # is RT an infinity? /* * RT is an infinity and RS is NOT an infinity so the result is just a * a properly signed zero. */ move t2,t0 move t3,zero move v0,zero b rd_2w4: /* * Check for the division with zeros and produce the correct action * if so. */ 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 /* * Now RT is known to be zero, if RS is zero it is an invalid operation * if not it is a divide by zero. */ bne t1,zero,2f # check RS for a zero value (first the exp) bne t2,zero,2f # then the high part of the fraction bne t3,zero,2f # then the low part of the fraction /* * The operation is 0 / 0 which is an invalid operation. * 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,1f /* * 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(). */1: li t2,DQUIETNAN_LESS li t3,DQUIETNAN_LEAST move v0,zero b rd_2w /* * The operation is x / 0 which is a divide by zero excrption. So set * the divide by zero exception in the fpc_csr (a3) and setup the * result depending if the enable for the divide by zero exception * is set. */2: or a3,DIVIDE0_EXC and v0,a3,DIVIDE0_ENABLE beq v0,zero,3f /* * The divide by zero 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 divide by zero trap was NOT enabled so the result is a properly * signed infinity. */3: or t2,t0,DEXP_INF<<DEXP_SHIFT move t3,zero move v0,zero b rd_2w /* * Now RT is known NOT to be zero, if RS is zero the result is just * a properly signed zero. */4: bne t1,zero,5f # check RS for a zero value (first the exp) bne t2,zero,5f # then the high part of the fraction bne t3,zero,5f # then the low part of the fraction move t2,t0 move v0,zero b rd_2w5: /* * Now that all the NaN, infinity and zero c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -