From e9c11e9a41ce6ed4f8709adb9565ac4db22bbc63 Mon Sep 17 00:00:00 2001 From: Anton Lydike Date: Tue, 16 Nov 2021 08:02:27 +0100 Subject: [PATCH] added correct instruction printing --- riscemu/decoder/__init__.py | 1 + riscemu/decoder/formatter.py | 39 ++++++++++++++++++++++++++++++++++++ riscemu/priv/ElfLoader.py | 31 +++++++++++++++++----------- 3 files changed, 59 insertions(+), 12 deletions(-) create mode 100644 riscemu/decoder/formatter.py diff --git a/riscemu/decoder/__init__.py b/riscemu/decoder/__init__.py index e68396a..bfb9282 100644 --- a/riscemu/decoder/__init__.py +++ b/riscemu/decoder/__init__.py @@ -1 +1,2 @@ from .decoder import decode, RISCV_REGS +from .formatter import format_ins \ No newline at end of file diff --git a/riscemu/decoder/formatter.py b/riscemu/decoder/formatter.py new file mode 100644 index 0000000..c1c7955 --- /dev/null +++ b/riscemu/decoder/formatter.py @@ -0,0 +1,39 @@ +from .formats import INSTRUCTION_ARGS_DECODER, op, decode_i, decode_r, decode_u, decode_b, decode_j, decode_s, \ + decode_i_shamt, decode_i_unsigned +from .regs import RISCV_REGS + + +def int_to_hex(num: int): + if num < 0: + return f"-0x{-num:x}" + return f"0x{num:x}" + + +def format_ins(ins: int, name: str, fmt: str = 'int'): + opcode = op(ins) + if fmt == 'hex': + fmt = int_to_hex + else: + fmt = str + + if opcode not in INSTRUCTION_ARGS_DECODER: + return f"{name} " + + decoder = INSTRUCTION_ARGS_DECODER[opcode] + if name in ('ecall', 'ebreak'): + return name + if opcode in (0x8, 0x0): + r1, r2, imm = decoder(ins) + return f"{name:<7} {r1}, {imm}({r2})" + elif decoder in (decode_i, decode_i_unsigned, decode_b, decode_i_shamt, decode_s): + r1, r2, imm = decoder(ins) + r1, r2 = RISCV_REGS[r1], RISCV_REGS[r2] + return f"{name:<7} {r1}, {r2}, {fmt(imm)}" + elif decoder in (decode_r,): + rd, rs1, rs2 = [RISCV_REGS[x] for x in decoder(ins)] + return f"{name:<7} {rd}, {rs1}, {rs2}" + elif decoder in (decode_j, decode_u): + r1, imm = decoder(ins) + return f"{name:<7} {RISCV_REGS[r1]}, {fmt(imm)}" + + return f"{name} " diff --git a/riscemu/priv/ElfLoader.py b/riscemu/priv/ElfLoader.py index 9f8a172..886da8a 100644 --- a/riscemu/priv/ElfLoader.py +++ b/riscemu/priv/ElfLoader.py @@ -4,7 +4,7 @@ from typing import List, Dict, Tuple from .Exceptions import * from ..Exceptions import RiscemuBaseException from ..Executable import MemoryFlags, LoadedMemorySection -from ..decoder import decode, RISCV_REGS +from ..decoder import decode, RISCV_REGS, format_ins from ..helpers import FMT_PARSE, FMT_NONE, FMT_GREEN, FMT_BOLD FMT_ELF = FMT_GREEN + FMT_BOLD @@ -118,17 +118,24 @@ class ElfInstruction: def __repr__(self) -> str: if self.name == 'jal' and self.args[0] == 0: - return "j {}".format(self.args[1]) - elif self.name in ('lw', 'lh', 'lb', 'lbu', 'lhu', 'sw', 'sh', 'sb'): - args = "{}, {}({})".format( - RISCV_REGS[self.args[0]], self.args[2], RISCV_REGS[self.args[1]] - ) - else: - args = ", ".join(map(str, self.args)) - return "{:<8} {}".format( - self.name, - args - ) + return "j {}".format(self.args[1]) + if self.name == 'addi' and self.args[2] == 0: + return "mv {}, {}".format(self.get_reg(0), self.get_reg(1)) + if self.name == 'addi' and self.args[1] == 0: + return "li {}, {}".format(self.get_reg(0), self.args[2]) + if self.name == 'ret' and len(self.args) == 0: + return "ret" + return format_ins(self.encoded, self.name) + # if self.name in ('lw', 'lh', 'lb', 'lbu', 'lhu', 'sw', 'sh', 'sb'): + # args = "{}, {}({})".format( + # RISCV_REGS[self.args[0]], self.args[2], RISCV_REGS[self.args[1]] + # ) + # else: + # args = ", ".join(map(str, self.args)) + # return "{:<8} {}".format( + # self.name, + # args + # ) class ElfLoadedMemorySection(LoadedMemorySection):