I managed to write a new routine that implements 32x32=64 bit multiplication using the shift and add with double register method. If multiplier lsb is 1 add multiplicand to high 32bit register then shift right high result & low result register 1 bit. If multiplier lsb is 0 shift the result high & low result register right 1 bit. Also shift right 1 bit the multiplier. This above process repeated 32 times. When multiplicand is added to the high result if carry occurs 1 is ORed to the MSB of the carry register. During shifting carry register, result_hi register, result_lo is shifted as a block towards right by 1 bit each time. This is the final code and works for the previous value 0xffffffff X 0x19 = 0x18ffffffe7. Thanks to everybody for the support
.data
result_lo: .word 0
result_hi: .word 0
modulo: .word 0
.text
li a1,0xffffffff # multiplicand
li a2,0x19 # multiplier
li a3,0x00000000 # result_lo
li a4,0x00000000 # result_hi
li a5,0 # working register
li x5,32 # number of bits to be tested/counter
loop:
mv x3,a2 # copy multiplier to test lsb 1 or 0
andi x3,x3,1 # extract lsb in x3
bnez x3,addnshift1 # if x3 is 1 branch to add and shift
call shift # if x3 is 0 call routine to shift result hi and lo + carry register right
addi x5,x5,-1 # decrease counter
bnez x5,loop # if counter is not 0 go to label loop
slli t6,t6,1 # if counter is 0, shift carry register left 1 time ( i dont know why but corrects answer)
j exit # exit multiplication procedure
addnshift1:
call addnshift # call addnshift routine to add multiplicand to result_hi and shift both result_hi & result_lo
addi x5,x5,-1 # decrease counter
bnez x5,loop # if counter is more than 0 branch to label loop
slli t6,t6,1 # if counter is 0, shift carry register left 1 time ( i dont know why but corrects answer)
j exit # exit multiplication procedure
shift:
srli a2,a2,1 # multiplier right shift, 1 lsb lost
srli a3,a3,1 # 2n low register(a3) right shift and 0 in msb (a4:a3)
mv x4,a4 # a copy of high 2n register(a4) to x4 (a4:a3)
andi x4,x4,1 # copy lsb of a4 high 2n register
beqz x4,lsb0 # if lsb extracted is 0 , branch to lsb0 label
li x4,0x80000000 # if lsb of a4 was 1
or a3,a3,x4 # lsb of a4 now in msb of a3. (a4:a3 >> 1)
lsb0:
srli a4,a4,1 # 2n high register right shift ,same as 0 shifted between a4 to a3 >>
srli t6,t6,1 # shift right carry register together with a4:a3
ret # return to main program
addnshift:
add a4,a4,a1 # add multiplicand to high 2n register
sltu x8 a4,a1 # set x8 to 1 if result of addition (a4 + a1) answer_hi and multiplicand
bnez x8,setcarry # if x8 is not 0 , branch to setcarry label
return:
srli a2,a2,1 # multiplier right shift
srli a3,a3,1 # 2n low register right shift and 0 in msb
mv x4,a4 # a copy of lw 2n
andi x4,x4,1 # copy lsb of a4 high 2n register
beqz x4,addlsb0 # if lsb extracted is 0 , branch to addlsb0 label
li x4,0x80000000 # if lsb of a4 was 1
or a3,a3,x4 # lsb of a4 now in msb of a3. (a4:a3 >> 1)
addlsb0:
srli a4,a4,1 # 2n high register right shift
srli t6,t6,1 # shift right carry register together with a4:a3
ret # return to main program
setcarry:
li x7,0x80000000 # set msb of x7 with 0x80000000
or t6,t6,x7 # set msb of x7 by oring t6 with x7
j return # jump to shifting routine
exit:
beqz t6,nocarry # if t6 is not set , 0 , no overflow occurred, branch to nocarry
mv a4,t6 # if carry set , copy t6 to answer hi register
nocarry:
la a0,result_hi #
sw a4,0(a0) # save to data section
la a0,result_lo
sw a3,0(a0) # save to data section
end:
j end
–