from collections import OrderedDict, namedtuple
+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 = {}
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
count += len(f) + 1
return res
+
def find_unique(d, key):
if key not in d:
return key
line = line.strip()
res = {}
count = 0
- print ("line", line)
prev_fieldname = None
for f in line.split("|"):
if not f:
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:
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]:
class DecodeFields:
- def __init__(self, bitkls=BitRange, bitargs=(), fname="fields.txt"):
+ def __init__(self, bitkls=BitRange, bitargs=(), fname=None, name_on_wiki=None):
self.bitkls = bitkls
self.bitargs = bitargs
- self.fname = 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)
def create_specs(self):
self.forms, self.instrs = self.decode_fields()
self.form_names = forms = self.instrs.keys()
+ #print ("specs", self.forms, forms)
for form in forms:
fields = self.instrs[form]
fk = fields.keys()
# 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.Rc,
+ "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
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] = []
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])
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)