From 7d09cb209fe82072ae1c13c48f425b320d4c8919 Mon Sep 17 00:00:00 2001 From: Anton Lydike Date: Sun, 18 Apr 2021 00:24:47 +0200 Subject: [PATCH] reworked memory instruction parsing --- riscemu/CPU.py | 62 +++++++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/riscemu/CPU.py b/riscemu/CPU.py index ad752dd..6486d3e 100644 --- a/riscemu/CPU.py +++ b/riscemu/CPU.py @@ -61,50 +61,54 @@ class CPU: else: raise RuntimeError("Unknown instruction: {}".format(ins)) + def parse_mem_ins(self, ins: 'LoadedInstruction') -> Tuple[str, int]: + """ + parses both rd, rs1, imm and rd, imm(rs1) arguments and returns (rd, imm+rs1) + (so a register and address tuple for memory instructions) + """ + if len(ins.args) == 3: + # handle rd, rs1, imm + rs1 = ins.get_reg(1) + imm = ins.get_imm(2) + else: + ASSERT_LEN(ins.args, 2) + ASSERT_IN("(", ins.args[1]) + imm, rs1 = ins.get_imm_reg(1) + # handle rd, imm(rs1) + rd = ins.get_reg(0) + return rd, self.regs.get(rs1) + imm + def instruction_lb(self, ins: 'LoadedInstruction'): - INS_NOT_IMPLEMENTED(ins) + rd, addr = self.parse_mem_ins(ins) + self.regs.set(rd, int_from_bytes(self.mmu.read(addr, 1))) def instruction_lh(self, ins: 'LoadedInstruction'): - INS_NOT_IMPLEMENTED(ins) + rd, addr = self.parse_mem_ins(ins) + self.regs.set(rd, int_from_bytes(self.mmu.read(addr, 2))) def instruction_lw(self, ins: 'LoadedInstruction'): - INS_NOT_IMPLEMENTED(ins) + rd, addr = self.parse_mem_ins(ins) + self.regs.set(rd, int_from_bytes(self.mmu.read(addr, 4))) def instruction_lbu(self, ins: 'LoadedInstruction'): - INS_NOT_IMPLEMENTED(ins) + rd, addr = self.parse_mem_ins(ins) + self.regs.set(rd, int_from_bytes(self.mmu.read(addr, 1), unsigned=True)) def instruction_lhu(self, ins: 'LoadedInstruction'): - INS_NOT_IMPLEMENTED(ins) + rd, addr = self.parse_mem_ins(ins) + self.regs.set(rd, int_from_bytes(self.mmu.read(addr, 2), unsigned=True)) def instruction_sb(self, ins: 'LoadedInstruction'): - src = ins.get_reg(0) - if len(ins.args) == 2: - reg, imm = ins.get_imm_reg(1) - else: - reg = ins.get_reg(1) - imm = ins.get_imm(2) - addr = self.regs.get(reg) + imm - self.mmu.write(addr, 1, int_to_bytes(self.regs.get(reg), 1)) + rd, addr = self.parse_mem_ins(ins) + self.mmu.write(addr, 1, int_to_bytes(self.regs.get(rd), 1)) def instruction_sh(self, ins: 'LoadedInstruction'): - src = ins.get_reg(0) - if len(ins.args) == 2: - reg, imm = ins.get_imm_reg(1) - else: - reg = ins.get_reg(1) - imm = ins.get_imm(2) - addr = self.regs.get(reg) + imm - self.mmu.write(addr, 2, int_to_bytes(self.regs.get(reg), 2)) + rd, addr = self.parse_mem_ins(ins) + self.mmu.write(addr, 2, int_to_bytes(self.regs.get(rd), 2)) def instruction_sw(self, ins: 'LoadedInstruction'): - src = ins.get_reg(0) - if len(ins.args) == 2: - imm, reg = ins.get_imm_reg(1) - else: - reg = ins.get_reg(1) - imm = ins.get_imm(2) - addr = self.regs.get(reg) + imm - self.mmu.write(addr, 4, int_to_bytes(self.regs.get(src), 4)) + rd, addr = self.parse_mem_ins(ins) + self.mmu.write(addr, 4, int_to_bytes(self.regs.get(rd), 4)) def instruction_sll(self, ins: 'LoadedInstruction'): INS_NOT_IMPLEMENTED(ins)