Add multiplication implementation

This commit is contained in:
Wesley Moore 2025-02-14 21:09:46 +10:00
parent 9494848392
commit 10bafd8485
No known key found for this signature in database
3 changed files with 49 additions and 3 deletions

View file

@ -20,11 +20,14 @@ hello.elf: hello.o
calc.elf: mem.o hex.o debug.o math.o calc.o
$(LD) -m elf32lriscv -T link.ld $^ -o $@
tests: tests/btohex.elf tests/tohex.elf tests/math_add64.elf
tests: tests/btohex.elf tests/tohex.elf tests/math_add64.elf tests/math_mul.elf
tests/math_add64.elf: hex.o math.o tests/math_add64.o
$(LD) -m elf32lriscv -T link.ld $^ -o $@
tests/math_mul.elf: hex.o math.o tests/math_mul.o
$(LD) -m elf32lriscv -T link.ld $^ -o $@
tests/btohex.elf: mem.o hex.o debug.o tests/btohex.o
$(LD) -m elf32lriscv -T link.ld $^ -o $@

26
math.s
View file

@ -1,4 +1,5 @@
.globl add64
.globl mul
.text
@ -24,3 +25,28 @@ add64:
add a1, t0, t1 # upper 32 bits of answer (upper sum + carry bit)
ret
# 32-bit shift-add multiplication
# arguments:
# a0: multiplicand
# a1: multiplier
# return:
# a0 = a0 × a1
#
mul:
mv t0, a1 # Save multiplier in t0
li a1, 0 # Initialize product in a1
multiply_loop:
beqz t0, done # If multiplier is 0, we're done
andi t1, t0, 1 # Check least significant bit
beqz t1, shift # If LSB is 0, skip addition
add a1, a1, a0 # Add multiplicand to product
shift:
slli a0, a0, 1 # Shift multiplicand left
srli t0, t0, 1 # Shift multiplier right
j multiply_loop # Continue loop
done:
mv a0, a1 # Move product to return register
ret

View file

@ -2,8 +2,10 @@
test_add64() {
result=$("${QEMU}" -B 0x80000000 -s 2k tests/math_add64.elf)
# 3.5
# 3.75
# 3.5
# 3.75
# 1.25
# -1.25
expected=$(cat << END
00000003.80000000
00000003.C0000000
@ -14,3 +16,18 @@ END
# different inputs.
test $? -eq 0 && test "$result" = "$expected"
}
test_mul() {
result=$("${QEMU}" -B 0x80000000 -s 2k tests/math_mul.elf)
expected=$(cat << END
0000000F
0000003F
0063FF9C
FFFFFFEB
END
)
# TODO: Ideally this test would allow calling the binary repeatedly with
# different inputs.
test $? -eq 0 && test "$result" = "$expected"
}