RV32无MUL移位乘法结果异常求助:0xffffffff×0x19计算错误
无MUL指令的RISC-V 32位无符号乘法进位问题排查
为无硬件乘法器的CH32V003芯片实现无MUL指令的32位无符号乘法,将AVR平台的移位加法代码移植到RISC-V汇编,输出64位结果。多数测试用例(含0xffffffff×0xffffffff)计算正确,但0xffffffff×0x19得到结果0x12ffffffe7,正确结果应为0x18ffffffe7。尝试过ChatGPT、Gemini、DeepSeek等生成的多种代码变体,问题仍存在。目前仅通过重复加法实现的乘法能得到正确结果,怀疑移位加法方案的进位检测存在问题。在RARS中模拟代码,恳请提供解决方案。
移植的RISC-V汇编代码
.data result_lo: .word 0 result_hi: .word 0 modulo: .word 0 .text li a1,0xffffffff # multiplicant li a2,0x19 # multiplier li a3,0x00000000 # result_lo li a4,0x00000000 # result_hi li a5,0 # working register start: call ROR # rotate right multiplier to test lsb is 0 or 1 bnez x3,multiply # if lsb =1 branch to repeated adding of multiplicant to result register finishmul: call RLL2 # shift multiplicand left or multiply by 2 beqz a2,exit_proc J start # repeat loop exit_proc: j exit_proc #ret multiply: add a5,a3,a1 # add multiplicant to low result register and store final result in a5 for processing sltu a0,a5,a3 # set a0 to 1 if result of addition a3:a1 i a5 is greater than a3 sltu x3,a5,a1 # set x3 to 1 if result of addition a3:a1 in a5 is greater than a1 or a0,a0,x3 # or a0 and x3 , if 1 carry if a0 = 0 no carry bnez a0,carryset # if a0 = 1 carry set, branch to label carry set mv a3,a5 # result in working register copied to a3 low result register J finishmul # jump to label finishmul carryset: # reach here only if carryset mv a3,a5 # copy a5 to low result a3 addi a4,a4,1 # add carry to a4 high register result J finishmul # jump to label finishmul ROR: li x3,0 # clear carry mv t0,a2 # copy number in a2 to t0 andi t0,t0,1 # extract lsb is 0 or 1 beqz t0,zzz # if lab is 0 branch to zzz li x3,1 # if lsb is 1 carry occured , load 1 in carry register x3 srli a2,a2,1 # shift right a2 by 1 postion ret # return to caller zzz: # reach here if lsb =0 li x3,0 # load x3 0 indicating carry bit is 0 srli a2,a2,1 # right shift multiplier once. divide multiplier by 2 ret # return to caller ROL: li x3,0 # mv t0,a2 li x3,0x80000000 and t0,t0,x3 beqz t0,zzz1 li x3,1 # carry slli a2,a2,1 ret zzz1: li x3,0 slli a2,a2,1 ret RLL2: # rotate left 2 registers a3:a5 mv a5,a4 # copy contents of a4 to a5 li x3,0 # clear x3 mv t0,a1 # copy multiplicant to t0 li x3 ,0x80000000 # load x3 MSB bitmask and t0,t0,x3 # and with 0x800000000 to extract the MSB bnez t0,OR1 # if MSB = 1 branch to OR1 label slli a1,a1,1 # shift left 1 position a1 register ( multiplicant) slli a5,a5,1 # shift left 1 position working register with value of a4 register ( multiplicant) beqz a2,exit # if multiplier register is 0 exit mv a4,a5 # copy back the shifter multiplicant to a4 ret OR1: mv a5,a4 slli a1,a1,1 slli a5,a5,1 li x3,1 or a5,a5,x3 beqz a2,exit mv a4,a5 ret exit: ret
经测试,上述代码在RARS中计算0xffffffff×0x19得到0x12ffffffe7,而正确结果应为0x18ffffffe7;仅通过重复加法实现的乘法能得到正确结果。
内容的提问来源于stack exchange,提问作者sajeev sankaran
相关产品推荐
相关产品推荐

