diff --git a/riscemu/CPU.py b/riscemu/CPU.py index 063a925..267ebc3 100644 --- a/riscemu/CPU.py +++ b/riscemu/CPU.py @@ -1,5 +1,5 @@ import traceback -from typing import Tuple, List, Dict, Callable +from typing import Tuple, List, Dict, Callable, Type from .Tokenizer import RiscVTokenizer @@ -14,11 +14,11 @@ import typing if typing.TYPE_CHECKING: from . import Executable, LoadedExecutable, LoadedInstruction - from .Instructions.InstructionSet import InstructionSet + from .instructions.InstructionSet import InstructionSet class CPU: - def __init__(self, conf: RunConfig, instruction_sets: List['InstructionSet']): + def __init__(self, conf: RunConfig, instruction_sets: List[Type['InstructionSet']]): # setup CPU states self.pc = 0 self.cycle = 0 @@ -32,10 +32,12 @@ class CPU: self.syscall_int = SyscallInterface() # load all instruction sets - self.sets = instruction_sets + self.instruction_sets: List['InstructionSet'] = list() self.instructions: Dict[str, Callable[[LoadedInstruction], None]] = dict() - for ins_set in instruction_sets: + for set_class in instruction_sets: + ins_set = set_class() self.instructions.update(ins_set.load(self)) + self.instruction_sets.append(ins_set) # provide global syscall symbols if option is set if conf.include_scall_symbols: diff --git a/riscemu/__main__.py b/riscemu/__main__.py index 9babc36..3eac088 100644 --- a/riscemu/__main__.py +++ b/riscemu/__main__.py @@ -1,7 +1,7 @@ if __name__ == '__main__': from . import * from .helpers import * - from .Instructions.RV32I import RV32I + from .instructions import RV32I, RVM import argparse import sys @@ -61,7 +61,7 @@ if __name__ == '__main__': FMT_PRINT = FMT_BOLD + FMT_MAGENTA try: - cpu = CPU(cfg, [RV32I()]) + cpu = CPU(cfg, [RV32I, RVM]) loaded_exe = None for file in args.files: tk = cpu.get_tokenizer(RiscVInput.from_file(file)) diff --git a/riscemu/Instructions/InstructionSet.py b/riscemu/instructions/InstructionSet.py similarity index 92% rename from riscemu/Instructions/InstructionSet.py rename to riscemu/instructions/InstructionSet.py index 2f6bd8d..e4ca7e3 100644 --- a/riscemu/Instructions/InstructionSet.py +++ b/riscemu/instructions/InstructionSet.py @@ -8,8 +8,7 @@ class InstructionSet(ABC): """ Represents a collection of instructions """ - def __init__(self, name): - self.name = name + def __init__(self): self.cpu: typing.Optional['CPU'] = None self.mmu: typing.Optional['MMU'] = None self.regs: typing.Optional['Registers'] = None @@ -41,6 +40,6 @@ class InstructionSet(ABC): def __repr__(self): return "InstructionSet[{}] with {} instructions".format( - self.name, + self.__class__.__name__, len(list(self.get_instructions())) ) \ No newline at end of file diff --git a/riscemu/Instructions/RV32I.py b/riscemu/instructions/RV32I.py similarity index 99% rename from riscemu/Instructions/RV32I.py rename to riscemu/instructions/RV32I.py index 59236f0..1375285 100644 --- a/riscemu/Instructions/RV32I.py +++ b/riscemu/instructions/RV32I.py @@ -2,10 +2,8 @@ from .InstructionSet import * from ..helpers import int_from_bytes, int_to_bytes, to_unsigned, to_signed + class RV32I(InstructionSet): - def __init__(self): - super().__init__('RV32I') - def instruction_lb(self, ins: 'LoadedInstruction'): rd, addr = self.parse_mem_ins(ins) self.regs.set(rd, int_from_bytes(self.mmu.read(addr, 1))) @@ -290,4 +288,4 @@ class RV32I(InstructionSet): launch_debug_session(self.cpu, self.mmu, self.regs, "Debug instruction encountered at 0x{:08X}".format(self.pc)) def instruction_nop(self, ins: 'LoadedInstruction'): - pass \ No newline at end of file + pass diff --git a/riscemu/instructions/RVM.py b/riscemu/instructions/RVM.py new file mode 100644 index 0000000..2a26586 --- /dev/null +++ b/riscemu/instructions/RVM.py @@ -0,0 +1,28 @@ +from .InstructionSet import * +from ..helpers import int_from_bytes, int_to_bytes, to_unsigned, to_signed + + +class RVM(InstructionSet): + def instruction_mul(self, ins: 'LoadedInstruction'): + INS_NOT_IMPLEMENTED(ins) + + def instruction_mulh(self, ins: 'LoadedInstruction'): + INS_NOT_IMPLEMENTED(ins) + + def instruction_mulhsu(self, ins: 'LoadedInstruction'): + INS_NOT_IMPLEMENTED(ins) + + def instruction_mulhu(self, ins: 'LoadedInstruction'): + INS_NOT_IMPLEMENTED(ins) + + def instruction_div(self, ins: 'LoadedInstruction'): + INS_NOT_IMPLEMENTED(ins) + + def instruction_divu(self, ins: 'LoadedInstruction'): + INS_NOT_IMPLEMENTED(ins) + + def instruction_rem(self, ins: 'LoadedInstruction'): + INS_NOT_IMPLEMENTED(ins) + + def instruction_remu(self, ins: 'LoadedInstruction'): + INS_NOT_IMPLEMENTED(ins) diff --git a/riscemu/instructions/__init__.py b/riscemu/instructions/__init__.py new file mode 100644 index 0000000..55b5b97 --- /dev/null +++ b/riscemu/instructions/__init__.py @@ -0,0 +1,3 @@ +from .InstructionSet import InstructionSet +from .RVM import RVM +from .RV32I import RV32I \ No newline at end of file diff --git a/riscemu/Instructions/__init__.py b/test.asm similarity index 100% rename from riscemu/Instructions/__init__.py rename to test.asm