radix: reading first page table entry
[soc.git] / src / soc / decoder / power_fields.py
index aabf591af34a0eee7a6aa697fd89b6ffe998dcb5..58df625b94e4faa5eaafc4eef78ae3a287a09d5c 100644 (file)
@@ -1,15 +1,17 @@
 from collections import OrderedDict, namedtuple
-from soc.decoder.power_enums import download_wiki_file
+from soc.decoder.power_enums import find_wiki_file
 
 
 class BitRange(OrderedDict):
     """BitRange: remaps from straight indices (0,1,2..) to bit numbers
     """
+
     def __getitem__(self, subscript):
         if isinstance(subscript, slice):
-            return list(self)[subscript]
+            return list(self.values())[subscript]
         else:
-            return self[subscript]
+            return OrderedDict.__getitem__(self, subscript)
+
 
 def decode_instructions(form):
     res = {}
@@ -29,11 +31,11 @@ def decode_instructions(form):
             accum.append(l.strip())
     return res
 
+
 def decode_form_header(hdr):
     res = {}
     count = 0
     hdr = hdr.strip()
-    print (hdr.split('|'))
     for f in hdr.split("|"):
         if not f:
             continue
@@ -43,6 +45,7 @@ def decode_form_header(hdr):
         count += len(f) + 1
     return res
 
+
 def find_unique(d, key):
     if key not in d:
         return key
@@ -56,7 +59,6 @@ def decode_line(header, line):
     line = line.strip()
     res = {}
     count = 0
-    print ("line", line)
     prev_fieldname = None
     for f in line.split("|"):
         if not f:
@@ -82,7 +84,6 @@ def decode_line(header, line):
 def decode_form(form):
     header = decode_form_header(form[0])
     res = []
-    print ("header", header)
     for line in form[1:]:
         dec = decode_line(header, line)
         if dec:
@@ -90,10 +91,10 @@ def decode_form(form):
     fields = {}
     falternate = {}
     for l in res:
-        for k, (start,end) in l.items():
+        for k, (start, end) in l.items():
             if k in fields:
                 if (start, end) == fields[k]:
-                    continue # already in and matching for this Form
+                    continue  # already in and matching for this Form
                 if k in falternate:
                     alternate = "%s_%d" % (k, falternate[k])
                     if (start, end) == fields[alternate]:
@@ -107,14 +108,24 @@ def decode_form(form):
 
 class DecodeFields:
 
-    def __init__(self, bitkls=BitRange, bitargs=(), fname="fields.text"):
+    def __init__(self, bitkls=BitRange, bitargs=(), fname=None,
+                 name_on_wiki=None):
         self.bitkls = bitkls
         self.bitargs = bitargs
-        self.fname = download_wiki_file(fname)
+        if fname is None:
+            assert name_on_wiki is None
+            fname = "fields.txt"
+            name_on_wiki = "fields.text"
+        self.fname = find_wiki_file(name_on_wiki)
+
+    @property
+    def form_names(self):
+        return self.instrs.keys()
 
     def create_specs(self):
         self.forms, self.instrs = self.decode_fields()
-        self.form_names = forms = self.instrs.keys()
+        forms = self.form_names
+        #print ("specs", self.forms, forms)
         for form in forms:
             fields = self.instrs[form]
             fk = fields.keys()
@@ -124,48 +135,51 @@ class DecodeFields:
         # now add in some commonly-used fields (should be done automatically)
         # note that these should only be ones which are the same on all Forms
         # note: these are from microwatt insn_helpers.vhdl
-        self.RS = self.FormX.RS
-        self.RT = self.FormX.RT
-        self.RA = self.FormX.RA
-        self.RB = self.FormX.RB
-        self.SI = self.FormD.SI
-        self.UI = self.FormD.UI
-        self.L = self.FormD.L
-        self.SH32 = self.FormM.SH
-        self.sh = self.FormMD.sh
-        self.MB32 = self.FormM.MB
-        self.ME32 = self.FormM.ME
-        self.LI = self.FormI.LI
-        self.LK = self.FormI.LK
-        self.AA = self.FormB.AA
-        self.Rc = self.FormX.Rc
-        self.OE = self.FormXO.Rc
-        self.BD = self.FormB.BD
-        self.BF = self.FormX.BF
-        self.CR = self.FormXL.XO # used by further mcrf decoding
-        self.BB = self.FormXL.BB
-        self.BA = self.FormXL.BA
-        self.BT = self.FormXL.BT
-        self.FXM = self.FormXFX.FXM
-        self.BO = self.FormXL.BO
-        self.BI = self.FormXL.BI
-        self.BH = self.FormXL.BH
-        self.D = self.FormD.D
-        self.DS = self.FormDS.DS
-        self.TO = self.FormX.TO
-        self.BC = self.FormA.BC
-        self.SH = self.FormX.SH
-        self.ME = self.FormM.ME
-        self.MB = self.FormM.MB
-        self.SPR = self.FormXFX.SPR
+        self.common_fields = {
+            "RS": self.FormX.RS,
+            "RT": self.FormX.RT,
+            "RA": self.FormX.RA,
+            "RB": self.FormX.RB,
+            "SI": self.FormD.SI,
+            "UI": self.FormD.UI,
+            "L": self.FormD.L,
+            "SH32": self.FormM.SH,
+            "sh": self.FormMD.sh,
+            "MB32": self.FormM.MB,
+            "ME32": self.FormM.ME,
+            "LI": self.FormI.LI,
+            "LK": self.FormI.LK,
+            "AA": self.FormB.AA,
+            "Rc": self.FormX.Rc,
+            "OE": self.FormXO.OE,
+            "BD": self.FormB.BD,
+            "BF": self.FormX.BF,
+            "CR": self.FormXL.XO,
+            "BB": self.FormXL.BB,
+            "BA": self.FormXL.BA,
+            "BT": self.FormXL.BT,
+            "FXM": self.FormXFX.FXM,
+            "BO": self.FormXL.BO,
+            "BI": self.FormXL.BI,
+            "BH": self.FormXL.BH,
+            "D": self.FormD.D,
+            "DS": self.FormDS.DS,
+            "TO": self.FormX.TO,
+            "BC": self.FormA.BC,
+            "SH": self.FormX.SH,
+            "ME": self.FormM.ME,
+            "MB": self.FormM.MB,
+            "SPR": self.FormXFX.SPR}
+        for k, v in self.common_fields.items():
+            setattr(self, k, v)
 
     def decode_fields(self):
         with open(self.fname) as f:
             txt = f.readlines()
+        #print ("decode", txt)
         forms = {}
         reading_data = False
         for l in txt:
-            print ("line", l)
             l = l.strip()
             if len(l) == 0:
                 continue
@@ -177,10 +191,9 @@ class DecodeFields:
             if not reading_data:
                 assert l[0] == '#'
                 heading = l[1:].strip()
-                #if heading.startswith('1.6.28'): # skip instr fields for now
-                    #break
+                # if heading.startswith('1.6.28'): # skip instr fields for now
+                #     break
                 heading = heading.split(' ')[-1]
-                print ("heading", heading)
                 reading_data = True
                 forms[heading] = []
 
@@ -188,22 +201,31 @@ class DecodeFields:
         inst = {}
 
         for hdr, form in forms.items():
-            print ("heading", hdr)
             if heading == 'Fields':
                 i = decode_instructions(form)
                 for form, field in i.items():
                     inst[form] = self.decode_instruction_fields(field)
-            #else:
-            #    res[hdr] = decode_form(form)
+            # else:
+            #     res[hdr] = decode_form(form)
         return res, inst
 
     def decode_instruction_fields(self, fields):
         res = {}
         for field in fields:
             f, spec = field.strip().split(" ")
+            ss = spec[1:-1].split(",")
+            fs = f.split(",")
+            if len(fs) > 1:
+                individualfields = []
+                for f0, s0 in zip(fs, ss):
+                    txt = "%s (%s)" % (f0, s0)
+                    individualfields.append(txt)
+                if len(fs) > 1:
+                    res.update(self.decode_instruction_fields(
+                        individualfields))
             d = self.bitkls(*self.bitargs)
             idx = 0
-            for s in spec[1:-1].split(","):
+            for s in ss:
                 s = s.split(':')
                 if len(s) == 1:
                     d[idx] = int(s[0])
@@ -221,23 +243,12 @@ class DecodeFields:
 
         return res
 
+
 if __name__ == '__main__':
     dec = DecodeFields()
     dec.create_specs()
     forms, instrs = dec.forms, dec.instrs
-    for hdr, form in forms.items():
-        print ()
-        print (hdr)
-        for k, v in form.items():
-            #print ("line", l)
-            #for k, v in l.items():
-            print ("%s: %d-%d" % (k, v[0], v[1]))
-    for form, field in instrs.items():
-        print ()
-        print (form)
-        for f, vals in field.items():
-            print ("    ", f, vals)
-    print (dec.FormX)
-    print (dec.FormX.A)
-    print (dir(dec.FormX))
-    print (dec.FormX._fields)
+    for form, fields in instrs.items():
+        print("Form", form)
+        for field, bits in fields.items():
+            print("\tfield", field, bits)