450e1cfa75f1f4599e15c441a995f771c4920dfb
1 from collections
import OrderedDict
, namedtuple
2 from openpower
.decoder
.power_enums
import find_wiki_file
5 class BitRange(OrderedDict
):
6 """BitRange: remaps from straight indices (0,1,2..) to bit numbers
9 def __getitem__(self
, subscript
):
10 if isinstance(subscript
, slice):
11 return list(self
.values())[subscript
]
13 return OrderedDict
.__getitem
__(self
, subscript
)
16 def decode_instructions(form
):
20 if l
.strip().startswith("Formats"):
21 l
= l
.strip().split(":")[-1]
22 l
= l
.replace(" ", "")
28 res
[fmt
].append(accum
[0])
31 accum
.append(l
.strip())
35 def decode_form_header(hdr
):
39 for f
in hdr
.split("|"):
43 idx
= int(f
.strip().split(' ')[0])
49 def find_unique(d
, key
):
53 while "%s_%d" % (key
, idx
) in d
:
55 return "%s_%d" % (key
, idx
)
58 def decode_line(header
, line
):
63 for f
in line
.split("|"):
66 end
= count
+ len(f
) + 1
68 if not fieldname
or fieldname
.startswith('/'):
69 if prev_fieldname
is not None:
70 res
[prev_fieldname
] = (res
[prev_fieldname
], header
[count
])
74 bitstart
= header
[count
]
75 if prev_fieldname
is not None:
76 res
[prev_fieldname
] = (res
[prev_fieldname
], bitstart
)
77 res
[fieldname
] = bitstart
79 prev_fieldname
= fieldname
80 res
[prev_fieldname
] = (bitstart
, 32)
84 def decode_form(form
):
85 header
= decode_form_header(form
[0])
88 dec
= decode_line(header
, line
)
94 for k
, (start
, end
) in l
.items():
96 if (start
, end
) == fields
[k
]:
97 continue # already in and matching for this Form
99 alternate
= "%s_%d" % (k
, falternate
[k
])
100 if (start
, end
) == fields
[alternate
]:
102 falternate
[k
] = fidx
= falternate
.get(k
, 0) + 1
103 fields
["%s_%d" % (k
, fidx
)] = (start
, end
)
105 fields
[k
] = (start
, end
)
111 def __init__(self
, bitkls
=BitRange
, bitargs
=(), fname
=None,
114 self
.bitargs
= bitargs
116 assert name_on_wiki
is None
118 name_on_wiki
= "fields.text"
119 self
.fname
= find_wiki_file(name_on_wiki
)
122 def form_names(self
):
123 return self
.instrs
.keys()
125 def create_specs(self
):
126 self
.forms
, self
.instrs
= self
.decode_fields()
127 forms
= self
.form_names
128 #print ("specs", self.forms, forms)
130 fields
= self
.instrs
[form
]
132 Fields
= namedtuple("Fields", fk
)
133 instr
= Fields(**fields
)
134 setattr(self
, "Form%s" % form
, instr
)
135 # now add in some commonly-used fields (should be done automatically)
136 # note that these should only be ones which are the same on all Forms
137 # note: these are from microwatt insn_helpers.vhdl
138 self
.common_fields
= {
139 "PO": self
.Formall
.PO
,
140 "FRS": self
.FormX
.FRS
,
141 "FRT": self
.FormX
.FRT
,
142 "FRA": self
.FormX
.FRA
,
143 "FRB": self
.FormX
.FRB
,
144 "FRC": self
.FormA
.FRC
,
152 "SH32": self
.FormM
.SH
,
153 "sh": self
.FormMD
.sh
,
154 "MB32": self
.FormM
.MB
,
155 "ME32": self
.FormM
.ME
,
160 "OE": self
.FormXO
.OE
,
163 "CR": self
.FormXL
.XO
,
164 "BB": self
.FormXL
.BB
,
165 "BA": self
.FormXL
.BA
,
166 "BT": self
.FormXL
.BT
,
167 "FXM": self
.FormXFX
.FXM
,
168 "BO": self
.FormXL
.BO
,
169 "BI": self
.FormXL
.BI
,
170 "BH": self
.FormXL
.BH
,
172 "DS": self
.FormDS
.DS
,
178 "SPR": self
.FormXFX
.SPR
}
179 for k
, v
in self
.common_fields
.items():
182 def decode_fields(self
):
183 with
open(self
.fname
) as f
:
185 #print ("decode", txt)
196 forms
[heading
].append(l
)
199 heading
= l
[1:].strip()
200 # if heading.startswith('1.6.28'): # skip instr fields for now
202 heading
= heading
.split(' ')[-1]
209 for hdr
, form
in forms
.items():
210 if heading
== 'Fields':
211 i
= decode_instructions(form
)
212 for form
, field
in i
.items():
213 inst
[form
] = self
.decode_instruction_fields(field
)
215 # res[hdr] = decode_form(form)
218 def decode_instruction_fields(self
, fields
):
221 f
, spec
= field
.strip().split(" ")
222 ss
= spec
[1:-1].split(",")
225 individualfields
= []
226 for f0
, s0
in zip(fs
, ss
):
227 txt
= "%s (%s)" % (f0
, s0
)
228 individualfields
.append(txt
)
230 res
.update(self
.decode_instruction_fields(
232 d
= self
.bitkls(*self
.bitargs
)
246 f
= f
.replace(",", "_")
247 unique
= find_unique(res
, f
)
253 if __name__
== '__main__':
256 forms
, instrs
= dec
.forms
, dec
.instrs
257 for form
, fields
in instrs
.items():
259 for field
, bits
in fields
.items():
260 print("\tfield", field
, bits
)