Add multiplication implementation
This commit is contained in:
parent
9494848392
commit
10bafd8485
3 changed files with 49 additions and 3 deletions
5
Makefile
5
Makefile
|
@ -20,11 +20,14 @@ hello.elf: hello.o
|
||||||
calc.elf: mem.o hex.o debug.o math.o calc.o
|
calc.elf: mem.o hex.o debug.o math.o calc.o
|
||||||
$(LD) -m elf32lriscv -T link.ld $^ -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
|
tests/math_add64.elf: hex.o math.o tests/math_add64.o
|
||||||
$(LD) -m elf32lriscv -T link.ld $^ -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
|
tests/btohex.elf: mem.o hex.o debug.o tests/btohex.o
|
||||||
$(LD) -m elf32lriscv -T link.ld $^ -o $@
|
$(LD) -m elf32lriscv -T link.ld $^ -o $@
|
||||||
|
|
||||||
|
|
26
math.s
26
math.s
|
@ -1,4 +1,5 @@
|
||||||
.globl add64
|
.globl add64
|
||||||
|
.globl mul
|
||||||
|
|
||||||
.text
|
.text
|
||||||
|
|
||||||
|
@ -24,3 +25,28 @@ add64:
|
||||||
add a1, t0, t1 # upper 32 bits of answer (upper sum + carry bit)
|
add a1, t0, t1 # upper 32 bits of answer (upper sum + carry bit)
|
||||||
ret
|
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
|
||||||
|
|
|
@ -2,8 +2,10 @@
|
||||||
|
|
||||||
test_add64() {
|
test_add64() {
|
||||||
result=$("${QEMU}" -B 0x80000000 -s 2k tests/math_add64.elf)
|
result=$("${QEMU}" -B 0x80000000 -s 2k tests/math_add64.elf)
|
||||||
# 3.5
|
# 3.5
|
||||||
# 3.75
|
# 3.75
|
||||||
|
# 1.25
|
||||||
|
# -1.25
|
||||||
expected=$(cat << END
|
expected=$(cat << END
|
||||||
00000003.80000000
|
00000003.80000000
|
||||||
00000003.C0000000
|
00000003.C0000000
|
||||||
|
@ -14,3 +16,18 @@ END
|
||||||
# different inputs.
|
# different inputs.
|
||||||
test $? -eq 0 && test "$result" = "$expected"
|
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"
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue