You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
riscemu/test/test_isa.py

82 lines
2.3 KiB
Python

from riscemu.colors import FMT_ERROR, FMT_NONE, FMT_BOLD, FMT_GREEN
from riscemu.instructions import InstructionSet
from riscemu.types import Instruction, CPU
from riscemu.decoder import RISCV_REGS
FMT_SUCCESS = FMT_GREEN + FMT_BOLD
def assert_equals(ins: Instruction, cpu: CPU):
a, b = (get_arg_from_ins(ins, i, cpu) for i in (0, 2))
return a == b
def assert_equals_mem(ins: Instruction, cpu: CPU):
a, b = (get_arg_from_ins(ins, i, cpu) for i in (0, 2))
a = cpu.mmu.read_int(a)
return a == b
def assert_in(ins: Instruction, cpu: CPU):
a = get_arg_from_ins(ins, 0, cpu)
others = [get_arg_from_ins(ins, i, cpu) for i in range(2, len(ins.args))]
return a in others
def _not(func):
def test(ins: Instruction, cpu: CPU):
return not func(ins, cpu)
return test
def get_arg_from_ins(ins: Instruction, num: int, cpu: CPU):
a = ins.args[num]
if a in RISCV_REGS:
return cpu.regs.get(a)
return ins.get_imm(num)
assert_ops = {
"==": assert_equals,
"!=": _not(assert_equals),
"in": assert_in,
"not_in": _not(assert_in),
}
class Z_test(InstructionSet):
def __init__(self, cpu: "CPU"):
print(
"[Test] loading testing ISA, this is only meant for running testcases and is not part of the RISC-V ISA!"
)
self.failed = False
super().__init__(cpu)
def instruction_assert(self, ins: Instruction):
if len(ins.args) < 3:
print(
FMT_ERROR + "[Test] Unknown assert statement: {}".format(ins) + FMT_NONE
)
return
op = ins.args[1]
if op not in assert_ops:
print(
FMT_ERROR
+ "[Test] Unknown operation statement: {} in {}".format(op, ins)
+ FMT_NONE
)
return
if assert_ops[op](ins, self.cpu):
print(FMT_SUCCESS + "[TestCase] 🟢 passed assertion {}".format(ins))
else:
print(FMT_ERROR + "[TestCase] 🔴 failed assertion {}".format(ins))
self.cpu.halted = True
self.failed = True
def instruction_fail(self, ins: Instruction):
print(FMT_ERROR + "[TestCase] 🔴 reached fail instruction! {}".format(ins))
self.cpu.halted = True
self.failed = True