4 ## Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
6 ## This program is free software; you can redistribute it and/or modify
7 ## it under the terms of the GNU General Public License as published by
8 ## the Free Software Foundation; either version 2 of the License, or
9 ## (at your option) any later version.
11 ## This program is distributed in the hope that it will be useful,
12 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ## GNU General Public License for more details.
16 ## You should have received a copy of the GNU General Public License
17 ## along with this program; if not, see <http://www.gnu.org/licenses/>.
27 tag
: "".join(reversed(iset
.iset
[tag
]["enc"].replace(" ", "")))
29 if iset
.iset
[tag
]["enc"] != "MISSING ENCODING"
32 enc_classes
= set([iset
.iset
[tag
]["enc_class"] for tag
in encs
.keys()])
33 subinsn_enc_classes
= set(
34 [enc_class
for enc_class
in enc_classes
if enc_class
.startswith("SUBINSN_")]
36 ext_enc_classes
= set(
39 for enc_class
in enc_classes
40 if enc_class
not in ("NORMAL", "16BIT") and not enc_class
.startswith("SUBINSN_")
45 subinsn_groupings
= iset
.subinsn_groupings
46 except AttributeError:
47 subinsn_groupings
= {}
49 for tag
, subinsn_grouping
in subinsn_groupings
.items():
50 encs
[tag
] = "".join(reversed(subinsn_grouping
["enc"].replace(" ", "")))
52 dectree_normal
= {"leaves": set()}
53 dectree_16bit
= {"leaves": set()}
54 dectree_subinsn_groupings
= {"leaves": set()}
55 dectree_subinsns
= {name
: {"leaves": set()} for name
in subinsn_enc_classes
}
56 dectree_extensions
= {name
: {"leaves": set()} for name
in ext_enc_classes
}
58 for tag
in encs
.keys():
59 if tag
in subinsn_groupings
:
60 dectree_subinsn_groupings
["leaves"].add(tag
)
62 enc_class
= iset
.iset
[tag
]["enc_class"]
63 if enc_class
.startswith("SUBINSN_"):
64 if len(encs
[tag
]) != 32:
65 encs
[tag
] = encs
[tag
] + "0" * (32 - len(encs
[tag
]))
66 dectree_subinsns
[enc_class
]["leaves"].add(tag
)
67 elif enc_class
== "16BIT":
68 if len(encs
[tag
]) != 16:
70 'Tag "{}" has enc_class "{}" and not an encoding '
71 + "width of 16 bits!".format(tag
, enc_class
)
73 dectree_16bit
["leaves"].add(tag
)
75 if len(encs
[tag
]) != 32:
77 'Tag "{}" has enc_class "{}" and not an encoding '
78 + "width of 32 bits!".format(tag
, enc_class
)
80 if enc_class
== "NORMAL":
81 dectree_normal
["leaves"].add(tag
)
83 dectree_extensions
[enc_class
]["leaves"].add(tag
)
86 for tag
, enc
in iset
.enc_ext_spaces
.items():
88 encs
[tag
] = "".join(reversed(enc
.replace(" ", "")))
89 dectree_normal
["leaves"].add(tag
)
91 faketags |
= set(subinsn_groupings
.keys())
94 def every_bit_counts(bitset
):
95 for i
in range(1, len(next(iter(bitset
)))):
96 if len(set([bits
[:i
] + bits
[i
+ 1 :] for bits
in bitset
])) == len(bitset
):
101 def auto_separate(node
):
102 tags
= node
["leaves"]
105 enc_width
= len(encs
[next(iter(tags
))])
106 opcode_bit_for_all
= [
107 all([encs
[tag
][i
] in "01" for tag
in tags
]) for i
in range(enc_width
)
109 opcode_bit_is_0_for_all
= [
110 opcode_bit_for_all
[i
] and all([encs
[tag
][i
] == "0" for tag
in tags
])
111 for i
in range(enc_width
)
113 opcode_bit_is_1_for_all
= [
114 opcode_bit_for_all
[i
] and all([encs
[tag
][i
] == "1" for tag
in tags
])
115 for i
in range(enc_width
)
117 differentiator_opcode_bit
= [
118 opcode_bit_for_all
[i
]
119 and not (opcode_bit_is_0_for_all
[i
] or opcode_bit_is_1_for_all
[i
])
120 for i
in range(enc_width
)
123 for width
in range(4, 0, -1):
124 for lsb
in range(enc_width
- width
, -1, -1):
125 bitset
= set([encs
[tag
][lsb
: lsb
+ width
] for tag
in tags
])
126 if all(differentiator_opcode_bit
[lsb
: lsb
+ width
]) and (
127 len(bitset
) == len(tags
) or every_bit_counts(bitset
)
131 caught_all_tags
= len(bitset
) == len(tags
)
137 "Could not find a way to differentiate the encodings "
138 + "of the following tags:\n{}".format("\n".join(tags
))
141 for width
in range(1, best_width
):
142 for lsb
in range(enc_width
- width
, -1, -1):
143 bitset
= set([encs
[tag
][lsb
: lsb
+ width
] for tag
in tags
])
144 if all(differentiator_opcode_bit
[lsb
: lsb
+ width
]) and len(
153 node
["separator_lsb"] = best_lsb
154 node
["separator_width"] = best_width
155 node
["children"] = []
156 for value
in range(2**best_width
):
158 bits
= "".join(reversed("{:0{}b}".format(value
, best_width
)))
159 child
["leaves"] = set(
160 [tag
for tag
in tags
if encs
[tag
][best_lsb
: best_lsb
+ best_width
] == bits
]
162 node
["children"].append(child
)
163 for child
in node
["children"]:
167 auto_separate(dectree_normal
)
168 auto_separate(dectree_16bit
)
169 if subinsn_groupings
:
170 auto_separate(dectree_subinsn_groupings
)
171 for dectree_subinsn
in dectree_subinsns
.values():
172 auto_separate(dectree_subinsn
)
173 for dectree_ext
in dectree_extensions
.values():
174 auto_separate(dectree_ext
)
180 def table_name(parents
, node
):
181 path
= parents
+ [node
]
183 tag
= next(iter(node
["leaves"]))
184 if tag
in subinsn_groupings
:
185 enc_width
= len(subinsn_groupings
[tag
]["enc"].replace(" ", ""))
187 tag
= next(iter(node
["leaves"] - faketags
))
188 enc_width
= len(encs
[tag
])
189 determining_bits
= ["_"] * enc_width
190 for parent
, child
in zip(path
[:-1], path
[1:]):
191 lsb
= parent
["separator_lsb"]
192 width
= parent
["separator_width"]
193 value
= parent
["children"].index(child
)
194 determining_bits
[lsb
: lsb
+ width
] = list(
195 reversed("{:0{}b}".format(value
, width
))
197 if tag
in subinsn_groupings
:
198 name
= "DECODE_ROOT_EE"
200 enc_class
= iset
.iset
[tag
]["enc_class"]
201 if enc_class
in ext_enc_classes
:
202 name
= "DECODE_EXT_{}".format(enc_class
)
203 elif enc_class
in subinsn_enc_classes
:
204 name
= "DECODE_SUBINSN_{}".format(enc_class
)
206 name
= "DECODE_ROOT_{}".format(enc_width
)
208 name
+= "_" + "".join(reversed(determining_bits
))
212 def print_node(f
, node
, parents
):
213 if len(node
["leaves"]) <= 1:
215 name
= table_name(parents
, node
)
216 lsb
= node
["separator_lsb"]
217 width
= node
["separator_width"]
219 "DECODE_NEW_TABLE({},{},DECODE_SEPARATOR_BITS({},{}))".format(
220 name
, 2**width
, lsb
, width
224 for child
in node
["children"]:
225 if len(child
["leaves"]) == 0:
226 print("INVALID()", file=f
)
227 elif len(child
["leaves"]) == 1:
228 (tag
,) = child
["leaves"]
229 if tag
in subinsn_groupings
:
230 class_a
= subinsn_groupings
[tag
]["class_a"]
231 class_b
= subinsn_groupings
[tag
]["class_b"]
232 enc
= subinsn_groupings
[tag
]["enc"].replace(" ", "")
233 if "RESERVED" in tag
:
234 print("INVALID()", file=f
)
237 'SUBINSNS({},{},{},"{}")'.format(tag
, class_a
, class_b
, enc
),
240 elif tag
in iset
.enc_ext_spaces
:
241 enc
= iset
.enc_ext_spaces
[tag
].replace(" ", "")
242 print('EXTSPACE({},"{}")'.format(tag
, enc
), file=f
)
244 enc
= "".join(reversed(encs
[tag
]))
245 print('TERMINAL({},"{}")'.format(tag
, enc
), file=f
)
247 print("TABLE_LINK({})".format(table_name(parents
+ [node
], child
)), file=f
)
249 "DECODE_END_TABLE({},{},DECODE_SEPARATOR_BITS({},{}))".format(
250 name
, 2**width
, lsb
, width
256 for child
in node
["children"]:
257 print_node(f
, child
, parents
)
261 def print_tree(f
, tree
):
262 print_node(f
, tree
, [])
265 def print_match_info(f
):
266 for tag
in sorted(encs
.keys(), key
=iset
.tags
.index
):
267 enc
= "".join(reversed(encs
[tag
]))
268 mask
= int(re
.sub(r
"[^1]", r
"0", enc
.replace("0", "1")), 2)
269 match
= int(re
.sub(r
"[^01]", r
"0", enc
), 2)
272 "DECODE{}_MATCH_INFO({},0x{:x}U,0x{:x}U)".format(suffix
, tag
, mask
, match
),
277 regre
= re
.compile(r
"((?<!DUP)[MNORCPQXSGVZA])([stuvwxyzdefg]+)([.]?[LlHh]?)(\d+S?)")
278 immre
= re
.compile(r
"[#]([rRsSuUm])(\d+)(?:[:](\d+))?")
281 def ordered_unique(l
):
282 return sorted(set(l
), key
=l
.index
)
285 implicit_registers
= {"SP": 29, "FP": 30, "LR": 31}
287 num_registers
= {"R": 32, "V": 32}
290 def print_op_info(f
):
291 for tag
in sorted(encs
.keys(), key
=iset
.tags
.index
):
294 print("DECODE_OPINFO({},".format(tag
), file=f
)
295 regs
= ordered_unique(regre
.findall(iset
.iset
[tag
]["syntax"]))
296 imms
= ordered_unique(immre
.findall(iset
.iset
[tag
]["syntax"]))
300 reg_letter
= reg
[1][0]
301 reg_num_choices
= int(reg
[3].rstrip("S"))
302 reg_mapping
= reg
[0] + "".join(["_" for letter
in reg
[1]]) + reg
[3]
303 reg_enc_fields
= re
.findall(reg_letter
+ "+", enc
)
304 if len(reg_enc_fields
) == 0:
305 raise Exception('Tag "{}" missing register field!'.format(tag
))
306 if len(reg_enc_fields
) > 1:
307 raise Exception('Tag "{}" has split register field!'.format(tag
))
308 reg_enc_field
= reg_enc_fields
[0]
309 if 2 ** len(reg_enc_field
) != reg_num_choices
:
311 'Tag "{}" has incorrect register field width!'.format(tag
)
314 " DECODE_REG({},{},{})".format(
315 regno
, len(reg_enc_field
), enc
.index(reg_enc_field
)
319 if reg_type
in num_registers
and reg_num_choices
!= num_registers
[reg_type
]:
321 " DECODE_MAPPED_REG({},{})".format(regno
, reg_mapping
),
326 def implicit_register_key(reg
):
327 return implicit_registers
[reg
]
334 iset
.iset
[tag
]["rregs"].split(",")
335 + iset
.iset
[tag
]["wregs"].split(",")
337 if r
in implicit_registers
340 key
=implicit_register_key
,
343 " DECODE_IMPL_REG({},{})".format(regno
, implicit_registers
[reg
]),
347 if imms
and imms
[0][0].isupper():
348 imms
= reversed(imms
)
355 imm_width
= int(imm
[1])
358 imm_shift
= int(imm_shift
)
361 if imm_type
.islower():
365 remainder
= imm_width
366 for m
in reversed(list(re
.finditer(imm_letter
+ "+", enc
))):
367 remainder
-= m
.end() - m
.start()
369 " DECODE_IMM({},{},{},{})".format(
370 immno
, m
.end() - m
.start(), m
.start(), remainder
376 imm
[2] = ":" + imm
[2]
378 'Tag "{}" has an incorrect number of '
379 + 'encoding bits for immediate "{}"'.format(tag
, "".join(imm
))
381 if imm_type
.lower() in "sr":
382 print(" DECODE_IMM_SXT({},{})".format(immno
, imm_width
), file=f
)
383 if imm_type
.lower() == "n":
384 print(" DECODE_IMM_NEG({},{})".format(immno
, imm_width
), file=f
)
387 " DECODE_IMM_SHIFT({},{})".format(immno
, imm_shift
), file=f
392 if __name__
== "__main__":
393 with
open(sys
.argv
[1], "w") as f
:
394 print_tree(f
, dectree_normal
)
395 print_tree(f
, dectree_16bit
)
396 if subinsn_groupings
:
397 print_tree(f
, dectree_subinsn_groupings
)
398 for name
, dectree_subinsn
in sorted(dectree_subinsns
.items()):
399 print_tree(f
, dectree_subinsn
)
400 for name
, dectree_ext
in sorted(dectree_extensions
.items()):
401 print_tree(f
, dectree_ext
)