Modifies test slightly because now RAM is relocated to 0x10000

This commit is contained in:
2025-11-15 01:26:49 +01:00
32 changed files with 974 additions and 274 deletions

View File

@@ -50,7 +50,7 @@ OBJCOPY := $(PREFIX)objcopy
OBTOMEM := common/objtomem.awk OBTOMEM := common/objtomem.awk
## Flags ## Flags
ASFLAGS :=-march=rv64i -mabi=lp64 -ffreestanding -nostdlib -T $(BENCH_DIR)/link.ld ASFLAGS :=-march=rv64im -mabi=lp64 -ffreestanding -nostdlib -T $(BENCH_DIR)/link.ld
CFLAGS :=$(ASFLAGS) CFLAGS :=$(ASFLAGS)
ELFFLAGS :=$(ASFLAGS) $(MEM_DIR)/crt.o -Os -fno-unroll-loops ELFFLAGS :=$(ASFLAGS) $(MEM_DIR)/crt.o -Os -fno-unroll-loops
ODFLAGS :=-j .text -j .rodata -j .data -s ODFLAGS :=-j .text -j .rodata -j .data -s

View File

@@ -1,4 +1,4 @@
# expected: 0000a000,0000b004,0000c008 # expected: 0001a000,0001b004,0001c008
.text .text
_start: _start:
auipc x31, 0xa auipc x31, 0xa

View File

@@ -1,25 +1,60 @@
# expected: ffffffffffffffff, ffffffffffffffff, dead0, 1, 8000000000000000, 7
.text .text
_start: _start:
li x2, 0xdead0 li x2, 0xdead0 # 912080
li x3, 0x0 li x3, 0x1234 # 4660
li x4, 0x1 li x4, 1 # 1
li x5, (-1) li x5, -123456 # -123456
li x6, 0xdead0 li x6, 0xdead0 # duplicate of x2
li x7, (-2355) li x7, -765432 # -765432
li x8, (-324) li x8, 123456 # 123456
li x9, 0x8000000000000000 li x9, -234567 # -234567
li x10, 0x7fffffffffffffff # max positive 64b
li x11, 0x8000000000000000 # min negative 64b
# Div by 0 # 1. DIV : a / 1
div x31, x2, x3
div x31, x5, x3
# Basic divisions
div x31, x2, x4 div x31, x2, x4
# expected: 00000000000dead0
# 2. DIV : a / a
div x31, x2, x6 div x31, x2, x6
# expected: 0000000000000001
# Overflow # 3. DIV : negative / positive
div x31, x9, x5 div x31, x5, x8
# expected: ffffffffffffffff
# Signed / signed # 4. DIV : negative / positive
div x31, x7, x8 div x31, x7, x8
# expected: fffffffffffffffa
# 5. DIV : positive / negative
div x31, x8, x7
# expected: 0000000000000000
# 6. DIV : negative / negative
div x31, x7, x9
# expected: 0000000000000003
# 7. DIV : max / 2
li x12, 2
div x31, x10, x12
# expected: 3fffffffffffffff
# 8. DIV : min / -1
li x12, -1 # -1
div x31, x11, x12
# expected: 8000000000000000
# 9. DIV : min / 1
div x31, x11, x4
# expected: 8000000000000000
# 10. DIV : 0 / any
div x31, x3, x2
# expected: 0000000000000000
# 11. DIV : any / 0
div x31, x2, x0
# expected: ffffffffffffffff
div x31, x7, x0
# expected: ffffffffffffffff

View File

@@ -1,14 +1,55 @@
# expected: ffffffffffffffff, dead0, 1
.text .text
_start: _start:
li x2, 0xdead0 li x2, 0xdead0 # 912080
li x3, 0x0 li x3, 0x1234 # 4660
li x4, 0x1 li x4, 1 # 1
li x6, 0xdead0 li x5, 123456 # 123456
li x6, 0xdead0 # duplicate of x2
li x7, 765432 # 765432
li x8, 123456 # 123456
li x9, 234567 # 234567
li x10, 0x7fffffffffffffff # max positive 64b
li x11, 0x8000000000000000 # min negative 64b (treated as unsigned = 0x8000...)
# Div by 0 # 1. DIVU : a / 1
divu x31, x2, x3
# Basic divisions
divu x31, x2, x4 divu x31, x2, x4
# expected: 00000000000dead0
# 2. DIVU : a / a
divu x31, x2, x6 divu x31, x2, x6
# expected: 0000000000000001
# 3. DIVU : smaller / larger
divu x31, x5, x8
# expected: 0000000000000001
# 4. DIVU : larger / smaller
divu x31, x7, x8
# expected: 0000000000000006
# 5. DIVU : any / any
divu x31, x8, x7
# expected: 0000000000000000
# 6. DIVU : larger / larger
divu x31, x7, x9
# expected: 0000000000000003
# 7. DIVU : max / 2
li x12, 2
divu x31, x10, x12
# expected: 3fffffffffffffff
# 8. DIVU : min / 1
divu x31, x11, x4
# expected: 8000000000000000
# 9. DIVU : 0 / any
divu x31, x3, x2
# expected: 0000000000000000
# 10. DIVU : any / 0
divu x31, x2, x0
# expected: ffffffffffffffff
divu x31, x7, x0
# expected: ffffffffffffffff

View File

@@ -1,14 +1,55 @@
# expected: ffffffffffffffff, dead0, 1
.text .text
_start: _start:
li x2, 0xdead0 li x2, 0xdead0 # 912080
li x3, 0x0 li x3, 0x1234 # 4660
li x4, 0x1 li x4, 1 # 1
li x6, 0xdead0 li x5, -123456 # 0xfffe1dc0 (4294843840)
li x6, 0xdead0 # duplicate of x2
li x7, -765432 # 0xffed32b8 (4294201864)
li x8, 123456 # 123456
li x9, -234567 # 0xfffc7239 (4294732729)
li x10, 0xffffffff # max unsigned 32b (4294967295)
li x11, 0x80000000 # 2147483648
# Div by 0 # 1. DIVUW : a / 1
divuw x31, x2, x3
# Basic divisions
divuw x31, x2, x4 divuw x31, x2, x4
# expected: 000000000000dead0
# 2. DIVUW : a / a
divuw x31, x2, x6 divuw x31, x2, x6
# expected: 0000000000000001
# 3. DIVUW : unsigned(0xfffe1dc0) / 123456
divuw x31, x5, x8
# expected: 00000000000087e4
# 4. DIVUW : unsigned(0xffed32b8) / 123456
divuw x31, x7, x8
# expected: 00000000000087df
# 5. DIVUW : unsigned(123456) / unsigned(0xffed32b8)
divuw x31, x8, x7
# expected: 0000000000000000
# 6. DIVUW : unsigned(x7) / unsigned(x9)
divuw x31, x7, x9
# expected: 0000000000000000
# 7. DIVUW : max32 / 2
li x12, 2
divuw x31, x10, x12
# expected: 000000007fffffff
# 8. DIVUW : min32 / 1
divuw x31, x11, x4
# expected: ffffffff80000000
# 9. DIVUW : 0 / any
divuw x31, x0, x2
# expected: 0000000000000000
# 10. DIVUW : any / 0
divuw x31, x2, x0
# expected: ffffffffffffffff
divuw x31, x7, x0
# expected: ffffffffffffffff

View File

@@ -1,25 +1,60 @@
# expected: ffffffffffffffff, ffffffffffffffff, dead0, 1, ffffffff80000000, 7
.text .text
_start: _start:
li x2, 0xdead0 li x2, 0xdead0 # 912080
li x3, 0x0 li x3, 0x1234 # 4660
li x4, 0x1 li x4, 1 # 1
li x5, (-1) li x5, -123456 # -123456
li x6, 0xdead0 li x6, 0xdead0 # duplicate of x2
li x7, (-2355) li x7, -765432 # -765432
li x8, (-324) li x8, 123456 # 123456
li x9, 0x80000000 li x9, -234567 # -234567
li x10, 0x7fffffff # max positive 32b
li x11, 0x80000000 # min negative 32b
# Div by 0 # 1. DIVW : a / 1
divw x31, x2, x3
divw x31, x5, x3
# Basic divisions
divw x31, x2, x4 divw x31, x2, x4
# expected: 000000000000dead0
# 2. DIVW : a / a
divw x31, x2, x6 divw x31, x2, x6
# expected: 0000000000000001
# Overflow # 3. DIVW : negative / positive
divw x31, x9, x5 divw x31, x5, x8
# expected: ffffffffffffffff
# Signed / signed # 4. DIVW : negative / positive
divw x31, x7, x8 divw x31, x7, x8
# expected: fffffffffffffffa
# 5. DIVW : positive / negative
divw x31, x8, x7
# expected: 0000000000000000
# 6. DIVW : negative / negative
divw x31, x7, x9
# expected: 0000000000000003
# 7. DIVW : max / 2
li x12, 2
divw x31, x10, x12
# expected: 000000003fffffff
# 8. DIVW : min / -1
li x12, -1 # -1
divw x31, x11, x12
# expected: ffffffff80000000
# 9. DIVW : min / 1
divw x31, x11, x4
# expected: ffffffff80000000
# 10. DIVW : 0 / any
divw x31, x0, x2
# expected: 0000000000000000
# 11. DIVW : any / 0
divw x31, x2, x0
# expected: ffffffffffffffff
divw x31, x7, x0
# expected: ffffffffffffffff

View File

@@ -1,10 +1,12 @@
# expected: FFFFFFFFFFFFFFFB, FFFFFFFFFFFFFFFB # expected: FFFFFFFFFFFFFFFB, FFFFFFFFFFFFFFFB
.text .text
_start: _start:
addi x1, x0, 0x0FB li x2, 0x11000
sb x1, 100(x0)
lb x31, 100(x0)
addi x1, x0, 0x0FB addi x1, x0, 0x0FB
sb x1, 106(x0) sb x1, 100(x2)
lb x31, 106(x0) lb x31, 100(x2)
addi x1, x0, 0x0FB
sb x1, 106(x2)
lb x31, 106(x2)

View File

@@ -1,10 +1,12 @@
# expected: 000000FB, 000000FB # expected: 000000FB, 000000FB
.text .text
_start: _start:
addi x1, x0, 0x0FB li x2, 0x11000
sb x1, 100(x0)
lbu x31, 100(x0)
addi x1, x0, 0x0FB addi x1, x0, 0x0FB
sb x1, 106(x0) sb x1, 100(x2)
lbu x31, 106(x0) lbu x31, 100(x2)
addi x1, x0, 0x0FB
sb x1, 106(x2)
lbu x31, 106(x2)

View File

@@ -1,7 +1,9 @@
# expected: 1023456789ABCDEF # expected: 1023456789ABCDEF
.text .text
_start: _start:
li x1, 0x1023456789ABCDEF li x2, 0x11000
sd x1, 100(x0)
ld x31, 100(x0) li x1, 0x1023456789ABCDEF
sd x1, 100(x2)
ld x31, 100(x2)

View File

@@ -1,12 +1,14 @@
# expected: 0000F1BC, 0000F1BC # expected: 0000F1BC, 0000F1BC
.text .text
_start: _start:
lui x1, 0xF li x2, 0x11000
ori x1, x1, 0x1BC
sh x1, 100(x0)
lhu x31, 100(x0)
lui x1, 0xF lui x1, 0xF
ori x1, x1, 0x1BC ori x1, x1, 0x1BC
sh x1, 106(x0) sh x1, 100(x2)
lhu x31, 106(x0) lhu x31, 100(x2)
lui x1, 0xF
ori x1, x1, 0x1BC
sh x1, 106(x2)
lhu x31, 106(x2)

View File

@@ -1,6 +1,8 @@
# expected: 00000000FFFFFFFF # expected: 00000000FFFFFFFF
.text .text
_start: _start:
li x2, 0x11000
li x1, 0xFFFFFFFFFFFFFFFF li x1, 0xFFFFFFFFFFFFFFFF
sw x1, 100(x0) sw x1, 100(x2)
lwu x31, 100(x0) lwu x31, 100(x2)

View File

@@ -1,22 +1,54 @@
# expected: 0000000000000000, 00000000000dead0, c1b080e900, -dead0, 54a029
.text .text
_start: _start:
li x2, 0xdead0 li x2, 0xdead0 # +912080
li x3, 0x0 li x3, 0 # zero
li x4, 0x1 li x4, 1 # one
li x5, (-1) li x5, -1 # -1
li x6, 0xdead0 li x6, 0xdead0 # duplicate of x2
li x7, (-2355) li x7, -2355 # negative
li x8, 123456 # positive
li x9, -765432 # negative
li x10, 0x7fffffffffffffff # max positive 64b
li x11, 0x8000000000000000 # min negative 64b
# Mul 0 # --------------------------------------------------------------
# 1. MUL : a * 0
mul x31, x2, x3 mul x31, x2, x3
# expected: 0000000000000000
# Basic multiplications # 2. MUL : a * 1
mul x31, x2, x4 mul x31, x2, x4
# expected: 00000000000dead0
# 3. MUL : a * a
mul x31, x2, x6 mul x31, x2, x6
# expected: 0000000c1b080e900
# Overflow # 4. MUL : -1 * a
mul x31, x5, x2 mul x31, x5, x2
# expected: -00000000000dead0
# Signed * signed # 5. MUL : negative * negative
mul x31, x7, x7 mul x31, x7, x7
# expected: 000000000054a029
# 6. MUL : negative * positive
mul x31, x7, x8
# expected: -00000000115452c0
# 7. MUL : positive * negative
mul x31, x8, x9
# expected: -0000001600786e00
# 8. MUL : overflow example (max * 2)
li x12, 2
mul x31, x10, x12
# expected: fffffffffffffffe
# 9. MUL : max * max
mul x31, x10, x10
# expected: 0000000000000001
# 10. MUL : min * min
mul x31, x11, x11
# expected: 0000000000000000

View File

@@ -1,19 +1,54 @@
# expected: 0000000000000000, 0000000000000000, c1b080e9, ffffffffffffffff
.text .text
_start: _start:
li x2, 0xdead0 li x2, 0xdead00000 # +59774074880
li x3, 0x0 li x3, 0 # zero
li x4, 0x1 li x4, 1 # one
li x5, (-1) li x5, -1 # -1
li x6, 0xdead0 li x6, 0xdead00000 # duplicate of x2
li x7, 0xdead00000000 li x7, -235555555555 # negative
li x8, 123456789 # positive
li x9, -765432000000 # negative
li x10, 0x7fffffffffffffff # max positive 64b
li x11, 0x8000000000000000 # min negative 64b
# Mul 0 # --------------------------------------------------------------
# 1. MULH : a * 0
mulh x31, x2, x3 mulh x31, x2, x3
# expected: 0000000000000000
# Basic multiplications # 2. MULH : a * 1
mulh x31, x2, x4 mulh x31, x2, x4
mulh x31, x7, x7 # expected: 0000000000000000
# Overflow # 3. MULH : a * a
mulh x31, x2, x6
# expected: 00000000000000c1
# 4. MULH : -1 * a
mulh x31, x5, x2 mulh x31, x5, x2
# expected: ffffffffffffffff
# 5. MULH : negative * negative
mulh x31, x7, x7
# expected: 0000000000000bbf
# 6. MULH : negative * positive
mulh x31, x7, x8
# expected: fffffffffffffffe
# 7. MULH : positive * negative
mulh x31, x8, x9
# expected: fffffffffffffffa
# 8. MULH : overflow example (max * 2)
li x12, 2
mulh x31, x10, x12
# expected: 0000000000000000
# 9. MULH : max * max
mulh x31, x10, x10
# expected: 3fffffffffffffff
# 10. MULH : min * min
mulh x31, x11, x11
# expected: 4000000000000000

View File

@@ -1,20 +1,54 @@
# expected: 0000000000000000, 0000000000000000, c1b080e9, ffffffffffffffff, deacf
.text .text
_start: _start:
li x2, 0xdead0 li x2, 0xdead00000 # +59774074880
li x3, 0x0 li x3, 0 # zero
li x4, 0x1 li x4, 1 # one
li x5, (-1) li x5, -1 # -1
li x6, 0xdead0 li x6, 0xdead00000 # duplicate of x2
li x7, 0xdead00000000 li x7, -235555555555 # negative
li x8, 123456789 # positive
li x9, 765432000000 # positive
li x10, 0x7fffffffffffffff # max positive 64b
li x11, 0x8000000000000000 # min negative 64b
# Mul 0 # --------------------------------------------------------------
# 1. MULHSU : a * 0
mulhsu x31, x2, x3 mulhsu x31, x2, x3
# expected: 0000000000000000
# Basic multiplications # 2. MULHSU : a * 1
mulhsu x31, x2, x4 mulhsu x31, x2, x4
mulhsu x31, x7, x7 # expected: 0000000000000000
# Overflow # 3. MULHSU : a * a
mulhsu x31, x2, x6
# expected: 00000000000000c1
# 4. MULHSU : -1 * a
mulhsu x31, x5, x2 mulhsu x31, x5, x2
mulhsu x31, x2, x5 # expected: ffffffffffffffff
# 5. MULHSU : negative * positive
mulhsu x31, x7, x8
# expected: fffffffffffffffe
# 6. MULHSU : negative * positive large
mulhsu x31, x7, x9
# expected: ffffffffffffd9d1
# 7. MULHSU : positive * positive
mulhsu x31, x8, x9
# expected: 0000000000000005
# 8. MULHSU : overflow example (max * 2)
li x12, 2
mulhsu x31, x10, x12
# expected: 0000000000000000
# 9. MULHSU : max * max
mulhsu x31, x10, x10
# expected: 3fffffffffffffff
# 10. MULHSU : min * max
mulhsu x31, x11, x10
# expected: c000000000000000

View File

@@ -1,20 +1,54 @@
# expected: 0000000000000000, 0000000000000000, c1b080e9, deacf, deacf
.text .text
_start: _start:
li x2, 0xdead0 li x2, 0xdead00000 # +59774074880
li x3, 0x0 li x3, 0 # zero
li x4, 0x1 li x4, 1 # one
li x5, (-1) li x5, 123456789 # small positive
li x6, 0xdead0 li x6, 0xdead00000 # duplicate of x2
li x7, 0xdead00000000 li x7, 765432000000 # large positive
li x8, 123456789 # small positive
li x9, 234567890000 # large positive
li x10, 0xffffffffffffffff # max positive 64b
li x11, 0x8000000000000000 # min unsigned = 2^63
# Mul 0 # --------------------------------------------------------------
# 1. MULHU : a * 0
mulhu x31, x2, x3 mulhu x31, x2, x3
# expected: 0000000000000000
# Basic multiplications # 2. MULHU : a * 1
mulhu x31, x2, x4 mulhu x31, x2, x4
mulhu x31, x7, x7 # expected: 0000000000000000
# Overflow # 3. MULHU : a * a
mulhu x31, x5, x2 mulhu x31, x2, x6
mulhu x31, x2, x5 # expected: 00000000000000c1
# 4. MULHU : small * small
mulhu x31, x5, x8
# expected: 0000000000000000
# 5. MULHU : small * large
mulhu x31, x5, x7
# expected: 0000000000000005
# 6. MULHU : large * small
mulhu x31, x7, x8
# expected: 0000000000000005
# 7. MULHU : large * large
mulhu x31, x7, x9
# expected: 0000000000002605
# 8. MULHU : max * 2
li x12, 2
mulhu x31, x10, x12
# expected: 0000000000000001
# 9. MULHU : max * max
mulhu x31, x10, x10
# expected: fffffffffffffffe
# 10. MULHU : min * max
mulhu x31, x11, x10
# expected: 7fffffffffffffff

View File

@@ -1,22 +1,54 @@
# expected: 0000000000000000, 00000000000dead0, ffffffffb080e900, -dead0, 54a029
.text .text
_start: _start:
li x2, 0xdead0 li x2, 0xdead0 # +912080
li x3, 0x0 li x3, 0 # zero
li x4, 0x1 li x4, 1 # one
li x5, (-1) li x5, -1 # -1
li x6, 0xdead0 li x6, 0xdead0 # duplicate of x2
li x7, (-2355) li x7, -2355 # negative
li x8, 123456 # positive
li x9, -765432 # negative
li x10, 0x7fffffff # max positive 32b
li x11, 0x80000000 # min negative 32b
# Mul 0 # --------------------------------------------------------------
# 1. MULW : a * 0
mulw x31, x2, x3 mulw x31, x2, x3
# expected: 0000000000000000
# Basic multiplications # 2. MULW : a * 1
mulw x31, x2, x4 mulw x31, x2, x4
# expected: 000000000000dead0
# 3. MULW : a * a
mulw x31, x2, x6 mulw x31, x2, x6
# expected: FFFFFFFFB080E900
# Overflow # 4. MULW : -1 * a
mulw x31, x5, x2 mulw x31, x5, x2
# expected: -dead0
# Signed * signed # 5. MULW : negative * negative
mulw x31, x7, x7 mulw x31, x7, x7
# expected: 000000000054A029
# 6. MULW : negative * positive
mulw x31, x7, x8
# expected: FFFFFFFFEEABAD40
# 7. MULW : positive * negative
mulw x31, x8, x9
# expected: FFFFFFFFFF879200
# 8. MULW : overflow example (max * 2)
li x12, 2
mulw x31, x10, x12
# expected: fffffffffffffffe
# 9. MULW : max * max
mulw x31, x10, x10
# expected: 0000000000000001
# 10. MULW : min * min
mulw x31, x11, x11
# expected: 0000000000000000

View File

@@ -1,27 +1,60 @@
# expected: dead0, ffffffffffffffff, 0, 0, 18, 0, -57
.text .text
_start: _start:
li x1, 0x0293 li x2, 0xdead0 # 912080
li x2, 0xdead0 li x3, 0x1234 # 4660
li x3, 0x0 li x4, 1 # 1
li x4, 0x1 li x5, -123456 # -123456
li x5, (-1) li x6, 0xdead0 # duplicate of x2
li x6, 0xdead0 li x7, -765432 # -765432
li x7, (-2355) li x8, 123456 # 123456
li x8, (-324) li x9, -234567 # -234567
li x9, 0x8000000000000000 li x10, 0x7fffffffffffffff # max positive 64b
li x11, 0x8000000000000000 # min negative 64b
# Remainder by 0 # 1. REM : a % 1
rem x31, x2, x3
rem x31, x5, x3
# Basic remainders
rem x31, x2, x4 rem x31, x2, x4
# expected: 0000000000000000
# 2. REM : a % a
rem x31, x2, x6 rem x31, x2, x6
rem x31, x6, x1 # expected: 0000000000000000
# Overflow # 3. REM : negative % positive
rem x31, x9, x5 rem x31, x5, x8
# expected: 0000000000000000
# Signed / signed # 4. REM : negative % positive
rem x31, x7, x8 rem x31, x7, x8
# expected: 00000000000181c8
# 5. REM : positive % negative
rem x31, x8, x7
# expected: -9cbb8
# 6. REM : negative % negative
rem x31, x7, x9
# expected: -f123
# 7. REM : max % 2
li x12, 2
rem x31, x10, x12
# expected: 0000000000000001
# 8. REM : min % -1
li x12, -1
rem x31, x11, x12
# expected: 0000000000000000
# 9. REM : min % 1
rem x31, x11, x4
# expected: 0000000000000000
# 10. REM : 0 % any
rem x31, x3, x2
# expected: 0000000000001234
# 11. REM : any % 0
rem x31, x2, x0
# expected: 00000000000dead0
rem x31, x7, x0
# expected: -badf8

View File

@@ -1,27 +1,55 @@
# expected: dead0, ffffffffffffffff, 0, 0, 18, 8000000000000000, fffffffffffff6cd
.text .text
_start: _start:
li x1, 0x0293 li x2, 0xdead0 # 912080
li x2, 0xdead0 li x3, 0x1234 # 4660
li x3, 0x0 li x4, 1 # 1
li x4, 0x1 li x5, 123456 # 123456
li x5, (-1) li x6, 0xdead0 # duplicate of x2
li x6, 0xdead0 li x7, 765432 # 765432
li x7, (-2355) li x8, 123456 # 123456
li x8, (-324) li x9, 234567 # 234567
li x9, 0x8000000000000000 li x10, 0x7fffffffffffffff # max positive 64b
li x11, 0x8000000000000000 # min negative 64b
# Remainder by 0 # 1. REMU : a % 1
remu x31, x2, x3
remu x31, x5, x3
# Basic remainders
remu x31, x2, x4 remu x31, x2, x4
# expected: 0000000000000000
# 2. REMU : a % a
remu x31, x2, x6 remu x31, x2, x6
remu x31, x6, x1 # expected: 0000000000000000
# Overflow # 3. REMU : smaller % larger
remu x31, x9, x5 remu x31, x5, x7
# expected: 000000000001e240
# Signed / signed # 4. REMU : larger % smaller
remu x31, x7, x8 remu x31, x7, x8
# expected: 0000000000006078
# 5. REMU : any % any
remu x31, x8, x7
# expected: 000000000001e240
# 6. REMU : larger % larger
remu x31, x7, x9
# expected: 000000000000f123
# 7. REMU : max % 2
li x12, 2
remu x31, x10, x12
# expected: 0000000000000001
# 8. REMU : min % 1
remu x31, x11, x4
# expected: 0000000000000000
# 9. REMU : 0 % any
remu x31, x3, x2
# expected: 0000000000001234
# 10. REMU : any % 0
remu x31, x2, x0
# expected: 00000000000dead0
remu x31, x7, x0
# expected: 00000000000badf8

View File

@@ -1,27 +1,60 @@
# expected: dead0, ffffffffffffffff, 0, 0, 18, ffffffff80000000, fffffffffffff6cd
.text .text
_start: _start:
li x1, 0x0293 li x2, 0xdead0 # 912080
li x2, 0xdead0 li x3, 0x1234 # 4660
li x3, 0x0 li x4, 1 # 1
li x4, 0x1 li x5, -123456 # 0xfffe1dc0 (4294843840)
li x5, (-1) li x6, 0xdead0 # duplicate of x2
li x6, 0xdead0 li x7, -765432 # 0xffed32b8 (4294201864)
li x7, (-2355) li x8, 123456 # 123456
li x8, (-324) li x9, -234567 # 0xfffc7239 (4294732729)
li x9, 0x80000000 li x10, 0xffffffff # max unsigned 32b
li x11, 0x80000000 # 2147483648
# Remainder by 0 # 1. REMUW : a % 1
remuw x31, x2, x3
remuw x31, x5, x3
# Basic remainders
remuw x31, x2, x4 remuw x31, x2, x4
# expected: 0000000000000000
# 2. REMUW : a % a
remuw x31, x2, x6 remuw x31, x2, x6
remuw x31, x6, x1 # expected: 0000000000000000
# Overflow # 3. REMUW : unsigned(x5) % x8
remuw x31, x9, x5 remuw x31, x5, x8
# expected: 000000000000dcc0
# Signed / signed # 4. REMUW : unsigned(x7) % x8
remuw x31, x7, x8 remuw x31, x7, x8
# expected: 0000000000007c48
# 5. REMUW : x8 % unsigned(x7)
remuw x31, x8, x7
# expected: 000000000001e240
# 6. REMUW : unsigned(x7) % unsigned(x9)
remuw x31, x7, x9
# expected: fffffffffff45208
# 7. REMUW : max32 % 2
li x12, 2
remuw x31, x10, x12
# expected: 0000000000000001
# 8. REMUW : min32 % -1
remuw x31, x11, x12
# expected: 0000000000000000
# 9. REMUW : min32 % 1
remuw x31, x11, x4
# expected: 0000000000000000
# 10. REMUW : 0 % any
remuw x31, x3, x2
# expected: 0000000000001234
# 11. REMUW : any % 0
remuw x31, x2, x0
# expected: 00000000000dead0
remuw x31, x7, x0
# expected: FFFFFFFFFFF45208

View File

@@ -1,27 +1,60 @@
# expected: dead0, ffffffffffffffff, 0, 0, 18, 0, -57
.text .text
_start: _start:
li x1, 0x0293 li x2, 0xdead0 # 912080
li x2, 0xdead0 li x3, 0x1234 # 4660
li x3, 0x0 li x4, 1 # 1
li x4, 0x1 li x5, -123456 # -123456
li x5, (-1) li x6, 0xdead0 # duplicate of x2
li x6, 0xdead0 li x7, -765432 # -765432
li x7, (-2355) li x8, 123456 # 123456
li x8, (-324) li x9, -234567 # -234567
li x9, 0x80000000 li x10, 0x7fffffff # max positive 32b
li x11, 0x80000000 # min negative 32b
# Remainder by 0 # 1. REMW : a % 1
remw x31, x2, x3
remw x31, x5, x3
# Basic remainders
remw x31, x2, x4 remw x31, x2, x4
# expected: 0000000000000000
# 2. REMW : a % a
remw x31, x2, x6 remw x31, x2, x6
remw x31, x6, x1 # expected: 0000000000000000
# Overflow # 3. REMW : negative % positive
remw x31, x9, x5 remw x31, x5, x8
# expected: 0
# Signed / signed # 4. REMW : negative % positive
remw x31, x7, x8 remw x31, x7, x8
# expected: 181c8
# 5. REMW : positive % negative
remw x31, x8, x7
# expected: fffffffffff63448
# 6. REMW : negative % negative
remw x31, x7, x9
# expected: ffffffffffff0edd
# 7. REMW : max % 2
li x12, 2
remw x31, x10, x12
# expected: 00000001
# 8. REMW : min % -1
li x12, -1
remw x31, x11, x12
# expected: 00000000
# 9. REMW : min % 1
remw x31, x11, x4
# expected: 00000000
# 10. REMW : 0 % any
remw x31, x3, x2
# expected: 00001234
# 11. REMW : any % 0
remw x31, x2, x0
# expected: 000dead0
remw x31, x7, x0
# expected: -badf8

View File

@@ -1,10 +1,12 @@
# expected: 00000050, 000001AB # expected: 00000050, 000001AB
.text .text
_start: _start:
auipc x12, 0x0
addi x1, x0, 0x5 addi x1, x0, 0x5
# Write x1 in the next addi instruction, position 12+3 bytes # Write x1 in the next addi instruction, position 12+3 bytes
# Due to type I immediate, x31 must contain 0x050 # Due to type I immediate, x31 must contain 0x050
sb x1, 15(x0) sb x1, 19(x12)
nop nop
addi x31, x0, 0x0 addi x31, x0, 0x0
@@ -14,11 +16,13 @@ _start:
addi x2, x0, 0x0F addi x2, x0, 0x0F
addi x3, x0, 0xB0 addi x3, x0, 0xB0
addi x4, x0, 0x1A addi x4, x0, 0x1A
sb x1, 52(x0) sb x1, 56(x12)
sb x2, 53(x0) sb x2, 57(x12)
sb x3, 54(x0) sb x3, 58(x12)
sb x4, 55(x0) sb x4, 59(x12)
nop nop
# Instruction will be written here # Instruction will be written here
nop nop

View File

@@ -1,9 +1,10 @@
# expected: 000000009ABCDEF0, 0000000012345678 # expected: 000000009ABCDEF0, 0000000012345678
.text .text
_start: _start:
auipc x2, 0x01
li x1, 0x123456789ABCDEF0 li x1, 0x123456789ABCDEF0
sd x1, 128(x0) sd x1, 128(x2)
lwu x31, 128(x0) lwu x31, 128(x2)
lwu x31, 132(x0) lwu x31, 132(x2)

View File

@@ -1,10 +1,11 @@
# expected: 00000050, 000001AB # expected: 00000050, 000001AB
.text .text
_start: _start:
auipc x12, 0x0
addi x1, x0, 0x500 addi x1, x0, 0x500
# Write x1 in the next addi instruction, position 12+2 bytes # Write x1 in the next addi instruction, position 12+2 bytes
# Due to type I immediate, x31 must contain 0x050 # Due to type I immediate, x31 must contain 0x050
sh x1, 14(x0) sh x1, 18(x12)
nop nop
addi x31, x0, 0x0 addi x31, x0, 0x0
@@ -14,8 +15,8 @@ _start:
srli x1, x1, 12 srli x1, x1, 12
lui x2, 0x1AB0 lui x2, 0x1AB0
srli x2, x2, 12 srli x2, x2, 12
sh x1, 44(x0) sh x1, 48(x12)
sh x2, 46(x0) sh x2, 50(x12)
nop nop
# Instruction will be written here # Instruction will be written here

View File

@@ -3,12 +3,14 @@
_start: _start:
# Create an instruction bytes per bytes # Create an instruction bytes per bytes
# addi x31, x0, 0x1AB -> 0x1AB00F93 # addi x31, x0, 0x1AB -> 0x1AB00F93
auipc x12, 0x0
lui x1, 0x0F93 lui x1, 0x0F93
srli x1, x1, 12 srli x1, x1, 12
lui x2, 0x1AB0 lui x2, 0x1AB0
slli x2, x2, 4 slli x2, x2, 4
or x1, x1, x2 or x1, x1, x2
sw x1, 28(x0) sw x1, 32(x12)
nop nop
# Instruction will be written here # Instruction will be written here

View File

@@ -5,10 +5,9 @@ import chisel3.util.switch
import chisel3.util.is import chisel3.util.is
object AluOpCode extends ChiselEnum { object AluOpCode extends ChiselEnum {
val Add, Sub, Mul, Mulh, Mulhsu, Mulhu, Div, Divu, Rem, Remu, Mulw, Divw, val Add, Sub, Mul, Mulh, Mulhsu, Mulhu, Div, Divu, Rem, Remu, And, Or, Xor,
Divuw, Remw, Remuw, And, Or, Xor, ShiftLeft, ShiftRight, ShiftLeft, ShiftRight, ShiftArithmeticRight, LessThanSigned,
ShiftArithmeticRight, LessThanSigned, LessThanUnsigned, LessThanUnsigned, GreaterEqualSigned, GreaterEqualUnsigned, Equal =
GreaterEqualSigned, GreaterEqualUnsigned, Equal =
Value Value
} }
@@ -22,12 +21,16 @@ class Alu extends Module {
val opcode = Input(AluOpCode()) val opcode = Input(AluOpCode())
val comp_result = Output(Bool()) val comp_result = Output(Bool())
// Should stop the stall for the current computation (e.g. Division)
val should_stop_stall = Output(Bool())
// ~~ Rv64i ~~ // ~~ Rv64i ~~
// If word_mode is enabled, operations are performed // If word_mode is enabled, operations are performed
// on 32-bit-truncated inputs and then sign extended to 64bits // on 32-bit-truncated inputs and then sign extended to 64bits
val word_mode = Input(Bool()) val word_mode = Input(Bool())
}) })
io.should_stop_stall := false.B
io.out := 0.U; io.out := 0.U;
io.comp_result := false.B; io.comp_result := false.B;
val out = WireInit(0.U(64.W)) val out = WireInit(0.U(64.W))
@@ -37,16 +40,56 @@ class Alu extends Module {
// Defaults // Defaults
op_a := io.a op_a := io.a
op_b := io.b op_b := io.b
val op_a_sign = WireInit(op_a(63))
val op_b_sign = WireInit(op_b(63))
val op_a_unsigned = WireInit(op_a)
val op_b_unsigned = WireInit(op_b)
io.out := out io.out := out
// Truncate operands, sext result // Truncate operands, sext result
when(io.word_mode) { when(io.word_mode) {
op_a := io.a(31, 0) op_a := io.a(31, 0)
op_b := io.b(31, 0) op_b := io.b(31, 0)
op_a_sign := op_a(31)
op_b_sign := op_b(31)
io.out := SignExtend.Sext(out(31, 0), 64) io.out := SignExtend.Sext(out(31, 0), 64)
} }
when(op_a_sign) {
op_a_unsigned := Utils.two_complement(op_a, io.word_mode)
}
when(op_b_sign) {
op_b_unsigned := Utils.two_complement(op_b, io.word_mode)
}
val in_computation = RegInit(false.B)
// Division
val divider = Module(new Divider(64, Constants.DIVISION_CYCLES_COUNT))
divider.io.word_mode := io.word_mode
divider.io.dividend := op_a_unsigned
divider.io.divisor := op_b_unsigned
divider.io.start := false.B
def div_by_zero() = {
when(io.word_mode) {
out := (-1).S(32.W).asUInt
}.otherwise {
out := (-1).S(64.W).asUInt
}
}
// Multiplication
val multiplication_res = op_a * op_b // Mul non signée
val multiplication_low =
Mux(io.word_mode, multiplication_res(31, 0), multiplication_res(63, 0))
val multiplication_high =
Mux(
io.word_mode,
multiplication_res(63, 32),
multiplication_res(127, 64)
)
switch(io.opcode) { switch(io.opcode) {
is(Add) { is(Add) {
out := op_a + op_b; out := op_a + op_b;
@@ -57,56 +100,77 @@ class Alu extends Module {
} }
is(Mul) { is(Mul) {
out := (io.a.asSInt * io.b.asSInt).asUInt; out := multiplication_low;
} }
is(Mulh) { is(Mulh) {
out := ((io.a.asSInt * io.b.asSInt) >> 64.U).asUInt; val correction =
Mux(op_a_sign, op_b, 0.U) + Mux(op_b_sign, op_a, 0.U)
val multiplication_res_with_correction =
multiplication_high - correction
out := multiplication_res_with_correction;
} }
is(Mulhsu) { is(Mulhsu) {
out := ((io.a.asSInt * io.b).asSInt >> 64.U).asUInt; val correction =
Mux(op_a_sign, op_b, 0.U)
val multiplication_res_with_correction =
multiplication_high - correction
out := multiplication_res_with_correction;
} }
is(Mulhu) { is(Mulhu) {
out := (io.a * io.b) >> 64.U; out := multiplication_high;
} }
// is(Div) { is(Div) {
// when(io.b === 0.U) { when(op_b === 0.U) {
// when(io.word_mode) { div_by_zero()
// out := (-1).S(32.W).asUInt }.elsewhen(op_a_sign ^ op_b_sign) {
// }.otherwise { out := Utils.two_complement(divider.io.quotient, io.word_mode)
// out := (-1).S(64.W).asUInt }.otherwise {
// } out := divider.io.quotient
// }.otherwise { }
// out := (io.a.asSInt / io.b.asSInt).asUInt; }
// }
// } is(Divu) {
// divider.io.dividend := op_a
// is(Divu) { divider.io.divisor := op_b
// when(io.b === 0.U) { when(op_b === 0.U) {
// out := "xFFFFFFFFFFFFFFFF".U div_by_zero()
// }.otherwise { }.otherwise { out := divider.io.quotient; }
// out := io.a / io.b; }
// }
// } is(Rem) {
// when(op_b === 0.U) {
// is(Rem) { out := op_a
// when(io.b === 0.U) { }.elsewhen(
// out := io.a op_a_sign && !op_b_sign && divider.io.remainder =/= 0.U
// }.otherwise { ) {
// out := (io.a.asSInt % io.b.asSInt).asUInt; out := op_b - divider.io.remainder
// } }.elsewhen(
// } !op_a_sign && op_b_sign && divider.io.remainder =/= 0.U
// ) {
// is(Remu) { out := Utils.two_complement(
// when(io.b === 0.U) { Utils.two_complement(op_b) - divider.io.remainder,
// out := io.a io.word_mode
// }.otherwise { )
// out := io.a % io.b; }.elsewhen(op_a_sign && op_b_sign) {
// } out := Utils.two_complement(divider.io.remainder, io.word_mode)
// } }.otherwise {
out := divider.io.remainder
}
}
is(Remu) {
divider.io.dividend := op_a
divider.io.divisor := op_b
when(op_b === 0.U) {
out := op_a
}.otherwise {
out := divider.io.remainder
}
}
is(And) { is(And) {
out := op_a & op_b; out := op_a & op_b;
@@ -167,4 +231,44 @@ class Alu extends Module {
} }
} }
switch(io.opcode) {
is(Div, Divu, Rem, Remu) {
when(!in_computation) {
divider.io.start := true.B
in_computation := true.B
}.elsewhen(divider.io.ready) {
io.should_stop_stall := true.B
in_computation := false.B
}
}
}
// Special overflow cases for Div and Rem
when(
io.word_mode &&
op_b === ((BigInt(1) << 32) - 1).U(32.W) &&
op_a === (-1).S(32.W).asUInt
) {
switch(io.opcode) {
is(Div) {
out := (1.U << 31)
}
is(Rem) {
out := 0.U
}
}
}.elsewhen(
!io.word_mode &&
op_b === ((BigInt(1) << 64) - 1).U(64.W) &&
op_a === (-1).S(64.W).asUInt
) {
switch(io.opcode) {
is(Div) {
out := (1.U << 63)
}
is(Rem) {
out := 0.U
}
}
}
} }

View File

@@ -0,0 +1,5 @@
package projet
object Constants {
def DIVISION_CYCLES_COUNT = 8
}

View File

@@ -25,6 +25,10 @@ class CUInterface extends Bundle {
// True if the decoded instruction is a jump // True if the decoded instruction is a jump
val is_jump = Output(Bool()) val is_jump = Output(Bool())
// Stall the pipeline on the current instruction
val should_stall = Output(Bool())
val should_stop_stall = Output(Bool())
// DMem connections // DMem connections
val memory_size = Output(DMemSize()) val memory_size = Output(DMemSize())
val memory_en = Output(Bool()) val memory_en = Output(Bool())
@@ -126,6 +130,8 @@ class ControlUnit() extends Module {
io.alu_word_mode := false.B io.alu_word_mode := false.B
io.optype := OpType.U io.optype := OpType.U
io.is_jump := false.B; io.is_jump := false.B;
io.should_stall := false.B;
io.should_stop_stall := false.B;
io.memory_size := DMemSize.Word io.memory_size := DMemSize.Word
io.memory_en := false.B io.memory_en := false.B
io.memory_we := false.B io.memory_we := false.B

View File

@@ -0,0 +1,82 @@
package projet
import chisel3._
import chisel3.util._
class Divider(width: Int, nCycles: Int) extends Module {
require(
nCycles >= 1 && nCycles <= width,
"nCycles must be between 1 and width"
)
val io = IO(new Bundle {
val dividend = Input(UInt(width.W))
val divisor = Input(UInt(width.W))
val word_mode = Input(Bool())
val start = Input(Bool())
val ready = Output(Bool())
val quotient = Output(UInt(width.W))
val remainder = Output(UInt(width.W))
})
val reg_dividend = Reg(UInt(width.W))
val reg_divisor = Reg(UInt((width * 2).W))
val reg_divisor_start = Reg(UInt(width.W))
val reg_quotient = Reg(UInt(width.W))
val reg_current_shift = Reg(UInt((log2Ceil(width) + 1).W))
val bits_per_cycle = ((width + nCycles - 1) / nCycles)
val cycles_remaining = RegInit(0.U(log2Ceil(nCycles + 1).W))
val busy = RegInit(false.B)
io.ready := !busy
io.quotient := reg_quotient
io.remainder := reg_dividend(width - 1, 0)
when(io.start && !busy) {
reg_dividend := io.dividend
reg_divisor := io.divisor << (width - 1)
reg_divisor_start := io.divisor
reg_quotient := 0.U
reg_current_shift := (width - 1).U
cycles_remaining := nCycles.U
busy := true.B
}
when(busy) {
val stages = Wire(Vec(bits_per_cycle + 1, UInt(width.W)))
val dstages = Wire(Vec(bits_per_cycle + 1, UInt((width * 2).W)))
val qstages = Wire(Vec(bits_per_cycle + 1, UInt(width.W)))
stages(0) := reg_dividend
dstages(0) := reg_divisor
qstages(0) := reg_quotient
for (i <- 0 until bits_per_cycle) {
val cur = stages(i)
val curD = dstages(i)
val curQ = qstages(i)
when(cur >= curD) {
stages(i + 1) := cur - curD
qstages(i + 1) := curQ + (1.U << (reg_current_shift - i.U))
}.otherwise {
stages(i + 1) := cur
qstages(i + 1) := curQ
}
dstages(i + 1) := curD >> 1
}
reg_dividend := stages(bits_per_cycle)
reg_divisor := dstages(bits_per_cycle)
reg_quotient := qstages(bits_per_cycle)
reg_current_shift := reg_current_shift - bits_per_cycle.U
cycles_remaining := cycles_remaining - 1.U
when(cycles_remaining === 1.U) {
busy := false.B
}
}
}

View File

@@ -44,27 +44,44 @@ class Rv64i(sim: Boolean = true) extends Module {
} }
} }
// Insert no-op if jump
val decoded_instruction =
Mux(
is_jump,
"b00000000000000000000000000010011".U,
io.ibus.rdata >> (execute_pc(2) * 32.U)
)
val stalled_instruction = RegInit(0.U)
val should_stop_stall =
control_unit.io.should_stop_stall || alu.io.should_stop_stall
val is_stalled = RegInit(false.B)
val is_immediatly_stalled =
(!should_stop_stall && (is_stalled || control_unit.io.should_stall =/= 0.U))
when(!is_stalled && control_unit.io.should_stall =/= 0.U) {
// Stall the pipeline
is_stalled := true.B
stalled_instruction := decoded_instruction
}
when(is_stalled && should_stop_stall) {
is_stalled := false.B
}
val instruction = Mux(is_stalled, stalled_instruction, decoded_instruction)
// Pipelining registers for mem stage // Pipelining registers for mem stage
val reg_rd_index = RegInit(0.U); val reg_rd_index = RegInit(0.U);
val reg_execute_out = RegInit(0.U); val reg_execute_out = RegInit(0.U);
val reg_mux_executeout_dout = RegInit(true.B); val reg_mux_executeout_dout = RegInit(true.B);
val reg_regile_we = RegInit(false.B); val reg_regile_we = RegInit(false.B);
// Insert no-op if jump
val instruction =
Mux(
is_jump,
"b00000000000000000000000000010011".U,
io.ibus.rdata >> (execute_pc(2) * 32.U)
);
immediate_decoder.io.instruction := instruction immediate_decoder.io.instruction := instruction
immediate_decoder.io.op_type := control_unit.io.optype immediate_decoder.io.op_type := control_unit.io.optype
alu.io.opcode := control_unit.io.alu_opcode; alu.io.opcode := control_unit.io.alu_opcode;
// Reg file write-enable // Reg file write-enable
reg_regile_we := control_unit.io.reg_file_we; reg_regile_we := control_unit.io.reg_file_we;
reg_file.io.we := reg_regile_we; reg_file.io.we := reg_regile_we && !is_stalled;
// Increment PC each clock // Increment PC each clock
val pc_adder_out = Mux( val pc_adder_out = Mux(
@@ -162,4 +179,7 @@ class Rv64i(sim: Boolean = true) extends Module {
false.B false.B
) )
when(is_immediatly_stalled) {
reg_pc := reg_pc
}
} }

View File

@@ -0,0 +1,15 @@
package projet
import chisel3._
object Utils {
def two_complement(x: UInt, word_sized: Bool = false.B): UInt = {
val result = Wire(UInt(64.W))
when(word_sized) {
result := "xFFFFFFFF".U - x + 1.U
}.otherwise {
result := "xFFFFFFFFFFFFFFFF".U - x + 1.U
}
result
}
}

View File

@@ -38,15 +38,19 @@ object OpM {
} }
is(Funct3.DIV) { is(Funct3.DIV) {
io.alu_opcode := AluOpCode.Div io.alu_opcode := AluOpCode.Div
io.should_stall := true.B
} }
is(Funct3.DIVU) { is(Funct3.DIVU) {
io.alu_opcode := AluOpCode.Divu io.alu_opcode := AluOpCode.Divu
io.should_stall := true.B
} }
is(Funct3.REM) { is(Funct3.REM) {
io.alu_opcode := AluOpCode.Rem io.alu_opcode := AluOpCode.Rem
io.should_stall := true.B
} }
is(Funct3.REMU) { is(Funct3.REMU) {
io.alu_opcode := AluOpCode.Remu io.alu_opcode := AluOpCode.Remu
io.should_stall := true.B
} }
} }
} }

View File

@@ -10,9 +10,9 @@ object ZzTopCommon extends AnyFreeSpec with ChiselSim {
Source Source
.fromFile(path) .fromFile(path)
.getLines() .getLines()
.filter(_.startsWith("# expected:")) .filter(_.trim().startsWith("# expected:"))
.map( .map(
_.stripPrefix("# expected:") _.trim().stripPrefix("# expected:")
.split(",") .split(",")
.map(_.trim) .map(_.trim)
.filter(_.nonEmpty) .filter(_.nonEmpty)