getting sim instruction decoder to reproduce asm instruction disassembly
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 17 Jun 2020 19:20:35 +0000 (20:20 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 17 Jun 2020 19:20:35 +0000 (20:20 +0100)
libreriscv
src/soc/decoder/decode2execute1.py
src/soc/decoder/isa/caller.py
src/soc/decoder/power_decoder.py
src/soc/decoder/power_enums.py

index c732d3ea7f5f50c646f35a6de9ce629ee1450876..b4a37081cfd2985ffa7678597f2dd459c39c72ff 160000 (submodule)
@@ -1 +1 @@
-Subproject commit c732d3ea7f5f50c646f35a6de9ce629ee1450876
+Subproject commit b4a37081cfd2985ffa7678597f2dd459c39c72ff
index 7f3709095dccb340c065888ec204a583ec0dd9c1..966def93ae580fe48ee9a9ad4851dc7845fa4dd8 100644 (file)
@@ -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
index 1dd5a9bc4955d011037f85e071a8f219faaa0538..5de6de592708bdbd7de139bfefb610d73c52ef32 100644 (file)
@@ -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)
 
index 0b9ffc5bcdb9012d765574b0a4ce3909bf4c98db..ea714632803ada2d90b3d000d1b98c6f1456711c 100644 (file)
@@ -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
index 5d0b8eb08924db7c37d0f90520d8cd2882a7a681..415d9e0657f0bee471ca39e84967237d487a6498 100644 (file)
@@ -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",