18 Oct 2025
Computer Architecture
cs2600
Multiprecision Arithmetic in RISCV
Multiprecision addition
.data
# data goes here
iter: .word 0x2 # number of chunks
chunksize: .word 0x4 # bytes of the chunk, in this case word
var1: .word 0xffffffff
.word 0x53535353
var2: .word 0x1
.word 0x01010101
var3: .word 0x0
.word 0x0
.section .text
.global main
main:
lw a1, iter
lw a2, chunksize
mul s1, a1, a2
xor s2, s2, s2 #i = 0
xor s3, s3, s3 #carry = 0
loop:
bgeu s2, s1, return # i < k or exit
la t1, var1 #t1 = &var1
add t1, t1, s2 #t1 = &var1 + i
lw t1, 0(t1) #t1 = var1[i]
la t2, var2 #t2 = &var2
add t2, t2, s2 #t2 = &var2 + i
lw t2, 0(t2) #t2 = var2[i]
add t3, t1, t2 #sum = var1[i] + var2[i]
sltu s4, t3, t1 #first carry
add t4, t3, s3 #sum = sum + carry
sltu s5, t4, s3 #second carry
add s3, s4, s5 #final carry
la t3, var3
add t3, t3, s2
sw t4, 0(t3)
add s2, s2, a2
j loop
return:
ret
Multiprecision subtraction
.data
# data goes here
iter: .dword 0x2 # number of chunks
chunksize: .dword 0x8 # bytes of the chunk, in this case word
var1: .dword 0x2222222222222222
.dword 0x0000000000003333
var2: .dword 0x10
.dword 0x3
var3: .dword 0x0
.dword 0x0
.dword 0x0
.dword 0x0
.section .text
.global main
main:
ld a1, iter
ld a2, chunksize
mul s1, a1, a2 #adjusting max iterations to account for chunk size
xor s2, s2, s2 #i = 0
xor s4, s4, s4 #carry = 0
outer_loop:
bgeu s2, s1, return #i < k or exit
la t1, var1 #t1 = &var1
add t1, t1, s2 #t1 = &var1 + i
ld t1, 0(t1) #t1 = var1[i]
xor s3, s3, s3 #j = 0
inner_loop:
bgeu s3, s1, inner_end # j < k or exit
la t2, var2 #t2 = &var2
add t2, t2, s3 #t2 = &var2 + j
ld t2, 0(t2) #t2 = var2[j]
mul t3, t1, t2 #lower bits of var1[i] * var2[j]
add t3, t3, s4 #add the previous carry here
mulh s4, t1, t2 #upper bits of var1[i] * var2[j] set as the new carry
la t4, var3 #t4 = &var3
add t4, t4, s2 #t4 = &var3 + i
add t4, t4, s3 #t4 = &var3 + i + j
ld t5, 0(t4) #fetch whatever the previous value in that block was
add t5, t5, t3 #add the current multiplication to that value
sd t5, 0(t4) #store the final result
add s3, s3, a2 #j = j + 1
j inner_loop
inner_end:
add s2, s2, a2 #i = i + 1
j outer_loop
return:
ret
Function call examples in RISCV
Recursive fibonacci
.data
# data goes here
fib_in: .dword 0xa #the 3rd fibonacci number
fib_out: .dword 0 #output is stored here
.section .text
.global main
main:
addi sp, sp, -0x8 #create stack frame
sd ra, 0(sp) #store return address of main
ld a0, fib_in #load the argument in the a0 reg
jal ra, fib #call the function with a0 = fib_in
la t1, fib_out #take the return value from the a1 reg
sd a1, 0(t1) #store the return value in the required place
ld ra, 0(sp) #load the return address
addi sp, sp, 0x8 #restore stack frame
ret
fib: #fib(k)
addi sp, sp, -0x20 #make the stack frame
sd ra, 0(sp) #store the return address
sd a0, 0x8(sp) #store the argument
li t0, 2 #if a0 == 1 || a0 == 2
bleu a0, t0, fib_done #leave
addi a0, a0, -0x1 #a0 = a0 - 1
jal ra, fib #fib(k - 1)
sd a1, 0x10(sp) #t1 = fib(k-1)
addi a0, a0, -0x1 #store fib(k - 1)
jal ra, fib #fib(k - 2)
sd a1, 0x18(sp) #store fib(k - 2)
ld t1, 0x10(sp)
ld t2, 0x18(sp)
add a1, t2, t1 #a1 = fib(k - 1) + fib(k - 2)
ld ra, 0(sp) #restore return address
ld a0, 0x8(sp) #restore a0
addi sp, sp ,0x20 #restore stack frame
ret
fib_done:
ld ra, 0(sp) #restore return address
ld a0, 0x8(sp) #restore
li a1, 0x1 #send value
addi sp, sp, 0x20 #restore stack frame
ret
