add decoder on power fields
[soc.git] / src / decoder / power_fields.py
1 from collections import OrderedDict
2
3
4 def decode_fields():
5 with open("fields.txt") as f:
6 txt = f.readlines()
7 forms = {}
8 reading_data = False
9 for l in txt:
10 print ("line", l)
11 l = l.strip()
12 if len(l) == 0:
13 continue
14 if reading_data:
15 if l[0] == '#':
16 reading_data = False
17 else:
18 forms[heading].append(l)
19 if not reading_data:
20 assert l[0] == '#'
21 heading = l[1:].strip()
22 #if heading.startswith('1.6.28'): # skip instruction fields for now
23 #break
24 heading = heading.split(' ')[-1]
25 print ("heading", heading)
26 reading_data = True
27 forms[heading] = []
28
29 res = {}
30 inst = {}
31
32 for hdr, form in forms.items():
33 print ("heading", hdr)
34 if heading == 'Fields':
35 i = decode_instructions(form)
36 for form, field in i.items():
37 inst[form] = decode_instruction_fields(field)
38 #else:
39 # res[hdr] = decode_form(form)
40 return res, inst
41
42 class BitRange(OrderedDict):
43 """BitRange: remaps from straight indices (0,1,2..) to bit numbers
44 """
45 def __getitem__(self, subscript):
46 if isinstance(subscript, slice):
47 return list(self)[subscript]
48 else:
49 return self[subscript]
50
51
52 def decode_instruction_fields(fields):
53 res = {}
54 for field in fields:
55 f, spec = field.strip().split(" ")
56 d = BitRange()
57 idx = 0
58 for s in spec[1:-1].split(","):
59 s = s.split(':')
60 if len(s) == 1:
61 d[idx] = int(s[0])
62 idx += 1
63 else:
64 start = int(s[0])
65 end = int(s[1])
66 while start <= end:
67 d[idx] = start
68 idx += 1
69 start += 1
70 res[f] = d
71
72 return res
73
74 def decode_instructions(form):
75 res = {}
76 accum = []
77 for l in form:
78 if l.strip().startswith("Formats"):
79 l = l.strip().split(":")[-1]
80 l = l.replace(" ", "")
81 l = l.split(",")
82 for fmt in l:
83 if fmt not in res:
84 res[fmt] = [accum[0]]
85 else:
86 res[fmt].append(accum[0])
87 accum = []
88 else:
89 accum.append(l.strip())
90 return res
91
92 def decode_form_header(hdr):
93 res = {}
94 count = 0
95 hdr = hdr.strip()
96 print (hdr.split('|'))
97 for f in hdr.split("|"):
98 if not f:
99 continue
100 if f[0].isdigit():
101 idx = int(f.strip().split(' ')[0])
102 res[count] = idx
103 count += len(f) + 1
104 return res
105
106 def find_unique(d, key):
107 if key not in d:
108 return key
109 idx = 1
110 while "%s_%d" % (key, idx) in d:
111 idx += 1
112 return "%s_%d" % (key, idx)
113
114
115 def decode_line(header, line):
116 line = line.strip()
117 res = {}
118 count = 0
119 print ("line", line)
120 prev_fieldname = None
121 for f in line.split("|"):
122 if not f:
123 continue
124 end = count + len(f) + 1
125 fieldname = f.strip()
126 if not fieldname or fieldname.startswith('/'):
127 if prev_fieldname is not None:
128 res[prev_fieldname] = (res[prev_fieldname], header[count])
129 prev_fieldname = None
130 count = end
131 continue
132 bitstart = header[count]
133 if prev_fieldname is not None:
134 res[prev_fieldname] = (res[prev_fieldname], bitstart)
135 res[fieldname] = bitstart
136 count = end
137 prev_fieldname = fieldname
138 res[prev_fieldname] = (bitstart, 32)
139 return res
140
141
142 def decode_form(form):
143 header = decode_form_header(form[0])
144 res = []
145 print ("header", header)
146 for line in form[1:]:
147 dec = decode_line(header, line)
148 if dec:
149 res.append(dec)
150 fields = {}
151 falternate = {}
152 for l in res:
153 for k, (start,end) in l.items():
154 if k in fields:
155 if (start, end) == fields[k]:
156 continue # already in and matching for this Form
157 if k in falternate:
158 alternate = "%s_%d" % (k, falternate[k])
159 if (start, end) == fields[alternate]:
160 continue
161 falternate[k] = fidx = falternate.get(k, 0) + 1
162 fields["%s_%d" % (k, fidx)] = (start, end)
163 else:
164 fields[k] = (start, end)
165 return fields
166
167
168 if __name__ == '__main__':
169 forms, instrs = decode_fields()
170 for hdr, form in forms.items():
171 print ()
172 print (hdr)
173 for k, v in form.items():
174 #print ("line", l)
175 #for k, v in l.items():
176 print ("%s: %d-%d" % (k, v[0], v[1]))
177 for form, field in instrs.items():
178 print ()
179 print (form)
180 for f, vals in field.items():
181 print (" ", f, vals)