1 from collections
import OrderedDict
, namedtuple
2 from soc
.decoder
.power_enums
import download_wiki_file
5 class BitRange(OrderedDict
):
6 """BitRange: remaps from straight indices (0,1,2..) to bit numbers
8 def __getitem__(self
, subscript
):
9 if isinstance(subscript
, slice):
10 return list(self
)[subscript
]
12 return self
[subscript
]
14 def decode_instructions(form
):
18 if l
.strip().startswith("Formats"):
19 l
= l
.strip().split(":")[-1]
20 l
= l
.replace(" ", "")
26 res
[fmt
].append(accum
[0])
29 accum
.append(l
.strip())
32 def decode_form_header(hdr
):
36 for f
in hdr
.split("|"):
40 idx
= int(f
.strip().split(' ')[0])
45 def find_unique(d
, key
):
49 while "%s_%d" % (key
, idx
) in d
:
51 return "%s_%d" % (key
, idx
)
54 def decode_line(header
, line
):
59 for f
in line
.split("|"):
62 end
= count
+ len(f
) + 1
64 if not fieldname
or fieldname
.startswith('/'):
65 if prev_fieldname
is not None:
66 res
[prev_fieldname
] = (res
[prev_fieldname
], header
[count
])
70 bitstart
= header
[count
]
71 if prev_fieldname
is not None:
72 res
[prev_fieldname
] = (res
[prev_fieldname
], bitstart
)
73 res
[fieldname
] = bitstart
75 prev_fieldname
= fieldname
76 res
[prev_fieldname
] = (bitstart
, 32)
80 def decode_form(form
):
81 header
= decode_form_header(form
[0])
84 dec
= decode_line(header
, line
)
90 for k
, (start
,end
) in l
.items():
92 if (start
, end
) == fields
[k
]:
93 continue # already in and matching for this Form
95 alternate
= "%s_%d" % (k
, falternate
[k
])
96 if (start
, end
) == fields
[alternate
]:
98 falternate
[k
] = fidx
= falternate
.get(k
, 0) + 1
99 fields
["%s_%d" % (k
, fidx
)] = (start
, end
)
101 fields
[k
] = (start
, end
)
107 def __init__(self
, bitkls
=BitRange
, bitargs
=(), fname
="fields.text"):
109 self
.bitargs
= bitargs
110 self
.fname
= download_wiki_file(fname
)
112 def create_specs(self
):
113 self
.forms
, self
.instrs
= self
.decode_fields()
114 self
.form_names
= forms
= self
.instrs
.keys()
115 #print ("specs", self.forms, forms)
117 fields
= self
.instrs
[form
]
119 Fields
= namedtuple("Fields", fk
)
120 instr
= Fields(**fields
)
121 setattr(self
, "Form%s" % form
, instr
)
122 # now add in some commonly-used fields (should be done automatically)
123 # note that these should only be ones which are the same on all Forms
124 # note: these are from microwatt insn_helpers.vhdl
125 self
.common_fields
= {
133 "SH32": self
.FormM
.SH
,
134 "sh": self
.FormMD
.sh
,
135 "MB32": self
.FormM
.MB
,
136 "ME32": self
.FormM
.ME
,
141 "OE": self
.FormXO
.Rc
,
144 "CR": self
.FormXL
.XO
,
145 "BB": self
.FormXL
.BB
,
146 "BA": self
.FormXL
.BA
,
147 "BT": self
.FormXL
.BT
,
148 "FXM": self
.FormXFX
.FXM
,
149 "BO": self
.FormXL
.BO
,
150 "BI": self
.FormXL
.BI
,
151 "BH": self
.FormXL
.BH
,
153 "DS": self
.FormDS
.DS
,
159 "SPR": self
.FormXFX
.SPR
}
160 for k
, v
in self
.common_fields
.items():
163 def decode_fields(self
):
164 with
open(self
.fname
) as f
:
166 #print ("decode", txt)
177 forms
[heading
].append(l
)
180 heading
= l
[1:].strip()
181 #if heading.startswith('1.6.28'): # skip instr fields for now
183 heading
= heading
.split(' ')[-1]
190 for hdr
, form
in forms
.items():
191 if heading
== 'Fields':
192 i
= decode_instructions(form
)
193 for form
, field
in i
.items():
194 inst
[form
] = self
.decode_instruction_fields(field
)
196 # res[hdr] = decode_form(form)
199 def decode_instruction_fields(self
, fields
):
202 f
, spec
= field
.strip().split(" ")
203 d
= self
.bitkls(*self
.bitargs
)
205 for s
in spec
[1:-1].split(","):
217 f
= f
.replace(",", "_")
218 unique
= find_unique(res
, f
)
223 if __name__
== '__main__':
226 forms
, instrs
= dec
.forms
, dec
.instrs