From: Luke Kenneth Casson Leighton Date: Wed, 17 Jun 2020 19:20:35 +0000 (+0100) Subject: getting sim instruction decoder to reproduce asm instruction disassembly X-Git-Tag: div_pipeline~334 X-Git-Url: https://git.libre-soc.org/?p=soc.git;a=commitdiff_plain;h=920cd58c14b169164dc8fe4fb36ba1490cb08f74 getting sim instruction decoder to reproduce asm instruction disassembly --- diff --git a/libreriscv b/libreriscv index c732d3ea..b4a37081 160000 --- a/libreriscv +++ b/libreriscv @@ -1 +1 @@ -Subproject commit c732d3ea7f5f50c646f35a6de9ce629ee1450876 +Subproject commit b4a37081cfd2985ffa7678597f2dd459c39c72ff diff --git a/src/soc/decoder/decode2execute1.py b/src/soc/decoder/decode2execute1.py index 7f370909..966def93 100644 --- a/src/soc/decoder/decode2execute1.py +++ b/src/soc/decoder/decode2execute1.py @@ -25,13 +25,15 @@ class Data(Record): class Decode2ToExecute1Type(RecordObject): - def __init__(self, name=None): + def __init__(self, name=None, asmcode=True): RecordObject.__init__(self, name=name) self.valid = Signal(reset_less=True) self.insn_type = Signal(InternalOp, reset_less=True) self.fn_unit = Signal(Function, reset_less=True) + if asmcode: + self.asmcode = Signal(8, reset_less=True) # only for simulator self.nia = Signal(64, reset_less=True) self.write_reg = Data(5, name="rego") self.write_ea = Data(5, name="ea") # for LD/ST in update mode diff --git a/src/soc/decoder/isa/caller.py b/src/soc/decoder/isa/caller.py index 1dd5a9bc..5de6de59 100644 --- a/src/soc/decoder/isa/caller.py +++ b/src/soc/decoder/isa/caller.py @@ -9,10 +9,11 @@ from functools import wraps from soc.decoder.orderedset import OrderedSet from soc.decoder.selectable_int import (FieldSelectableInt, SelectableInt, selectconcat) -from soc.decoder.power_enums import spr_dict, XER_bits +from soc.decoder.power_enums import spr_dict, XER_bits, insns, InternalOp from soc.decoder.helpers import exts from collections import namedtuple import math +import sys instruction_info = namedtuple('instruction_info', 'func read_regs uninit_regs write_regs ' + \ @@ -406,7 +407,7 @@ class ISACaller: ins = self.imem.ld(pc, 4, False, True) if ins is None: raise KeyError("no instruction at 0x%x" % pc) - print("setup: 0x{:X} 0x{:X}".format(pc, ins & 0xffffffff)) + print("setup: 0x%x 0x%x %s" % (pc, ins & 0xffffffff, bin(ins))) print ("NIA, CIA", self.pc.CIA.value, self.pc.NIA.value) yield self.dec2.dec.raw_opcode_in.eq(ins) @@ -428,6 +429,39 @@ class ISACaller: def call(self, name): # TODO, asmregs is from the spec, e.g. add RT,RA,RB # see http://bugs.libre-riscv.org/show_bug.cgi?id=282 + asmcode = yield self.dec2.dec.op.asmcode + asmop = insns.get(asmcode, None) + + # sigh reconstruct the assembly instruction name + ov_en = yield self.dec2.e.oe.oe + ov_ok = yield self.dec2.e.oe.ok + if ov_en & ov_ok: + asmop += "." + lk = yield self.dec2.e.lk + if lk: + asmop += "l" + int_op = yield self.dec2.dec.op.internal_op + print ("int_op", int_op) + if int_op in [InternalOp.OP_B.value, InternalOp.OP_BC.value]: + AA = yield self.dec2.dec.fields.FormI.AA[0:-1] + print ("AA", AA) + if AA: + asmop += "a" + if int_op == InternalOp.OP_MFCR.value: + dec_insn = yield self.dec2.e.insn + if dec_insn & (1<<20): # sigh + asmop = 'mfocrf' + else: + asmop = 'mfcr' + if int_op == InternalOp.OP_MTCRF.value: + dec_insn = yield self.dec2.e.insn + if dec_insn & (1<<20): # sigh + asmop = 'mtocrf' + else: + asmop = 'mtcrf' + print ("call", name, asmcode, asmop) + assert name == asmop, "name %s != %s" % (name, asmop) + info = self.instrs[name] yield from self.prep_namespace(info.form, info.op_fields) diff --git a/src/soc/decoder/power_decoder.py b/src/soc/decoder/power_decoder.py index 0b9ffc5b..ea714632 100644 --- a/src/soc/decoder/power_decoder.py +++ b/src/soc/decoder/power_decoder.py @@ -120,7 +120,7 @@ class PowerOp: self.internal_op = Signal(InternalOp, reset_less=True) self.form = Signal(Form, reset_less=True) if incl_asm: # for simulator only - self.asmcode = Signal(7, reset_less=True) + self.asmcode = Signal(8, reset_less=True) self.in1_sel = Signal(In1Sel, reset_less=True) self.in2_sel = Signal(In2Sel, reset_less=True) self.in3_sel = Signal(In3Sel, reset_less=True) @@ -161,8 +161,9 @@ class PowerOp: self.cry_in.eq(CryIn[row['cry in']]), ] print (row.keys()) - if hasattr(self, "asmcode"): - res.append(self.asmcode.eq(asmidx[row['comment']])) + asmcode = row['comment'] + if hasattr(self, "asmcode") and asmcode in asmidx: + res.append(self.asmcode.eq(asmidx[asmcode])) for bit in single_bit_flags: sig = getattr(self, get_signal_name(bit)) res.append(sig.eq(int(row.get(bit, 0)))) @@ -200,6 +201,8 @@ class PowerOp: self.rc_sel, self.internal_op, self.form] + if hasattr(self, "asmcode"): + regular.append(self.asmcode) single_bit_ports = [getattr(self, get_signal_name(x)) for x in single_bit_flags] return regular + single_bit_ports diff --git a/src/soc/decoder/power_enums.py b/src/soc/decoder/power_enums.py index 5d0b8eb0..415d9e06 100644 --- a/src/soc/decoder/power_enums.py +++ b/src/soc/decoder/power_enums.py @@ -92,10 +92,10 @@ class Form(Enum): # supported instructions: make sure to keep up-to-date with CSV files # just like everything else _insns = [ - "add", "addc", "addco", "adde", "addeo", "addi", "addic", "addic.", + "NONE", "add", "addc", "addco", "adde", "addeo", "addi", "addic", "addic.", "addis", "addme", "addmeo", "addo", "addze", "addzeo", "and", "andc", "andi.", "andis.", "attn", "b", "bc", "bcctr", "bclr", "bctar", - "bperm", "cmp", "cmpb", "cmpeqb", "cmpi", "cmpl", "cmpli", "cmprb", + "bpermd", "cmp", "cmpb", "cmpeqb", "cmpi", "cmpl", "cmpli", "cmprb", "cntlzd", "cntlzw", "cnttzd", "cnttzw", "crand", "crandc", "creqv", "crnand", "crnor", "cror", "crorc", "crxor", "darn", "dcbf", "dcbst", "dcbt", "dcbtst", "dcbz", "divd", "divde", "divdeo", "divdeu",