parseinstrs: Use tuples/ints for indexing in trie
This avoids useless internal string formatting.
This commit is contained in:
@@ -292,35 +292,12 @@ class Opcode(NamedTuple):
|
|||||||
kinds, values = zip(*opcode)
|
kinds, values = zip(*opcode)
|
||||||
return [tuple(zip(kinds, prod)) for prod in product(*values)]
|
return [tuple(zip(kinds, prod)) for prod in product(*values)]
|
||||||
|
|
||||||
def format_opcode(opcode):
|
|
||||||
opcode_string = ""
|
|
||||||
prefix = ""
|
|
||||||
for kind, byte in opcode:
|
|
||||||
if kind == EntryKind.TABLE_ROOT:
|
|
||||||
opcode_string += ["", "0f", "0f38", "0f3a"][byte & 3]
|
|
||||||
prefix += ["", "VEX."][byte >> 2]
|
|
||||||
elif kind == EntryKind.TABLE256:
|
|
||||||
opcode_string += "{:02x}".format(byte)
|
|
||||||
elif kind == EntryKind.TABLE16:
|
|
||||||
opcode_string += "/{:x}{}".format(byte & 7, "mr"[byte >> 3])
|
|
||||||
elif kind == EntryKind.TABLE8E:
|
|
||||||
opcode_string += "+rm={:x}".format(byte)
|
|
||||||
elif kind == EntryKind.TABLE_PREFIX:
|
|
||||||
if byte & 4:
|
|
||||||
prefix += "VEX."
|
|
||||||
prefix += ["NP.", "66.", "F3.", "F2."][byte&3]
|
|
||||||
elif kind == EntryKind.TABLE_VEX:
|
|
||||||
prefix += "W{}.L{}.".format(byte & 1, byte >> 1)
|
|
||||||
else:
|
|
||||||
raise Exception("unsupported opcode kind {}".format(kind))
|
|
||||||
return prefix + opcode_string
|
|
||||||
|
|
||||||
class Table:
|
class Table:
|
||||||
def __init__(self, root_count=1):
|
def __init__(self, root_count=1):
|
||||||
self.data = OrderedDict()
|
self.data = OrderedDict()
|
||||||
self.roots = ["root%d"%i for i in range(root_count)]
|
self.roots = [(i,) for i in range(root_count)]
|
||||||
for i in range(root_count):
|
for i in range(root_count):
|
||||||
self.data["root%d"%i] = TrieEntry.table(EntryKind.TABLE_ROOT)
|
self.data[i,] = TrieEntry.table(EntryKind.TABLE_ROOT)
|
||||||
self.descs = []
|
self.descs = []
|
||||||
self.descs_map = {}
|
self.descs_map = {}
|
||||||
self.offsets = {}
|
self.offsets = {}
|
||||||
@@ -337,21 +314,19 @@ class Table:
|
|||||||
self.data[name] = TrieEntry(old.kind, new_items, None)
|
self.data[name] = TrieEntry(old.kind, new_items, None)
|
||||||
|
|
||||||
def _walk_opcode(self, opcode, root_idx):
|
def _walk_opcode(self, opcode, root_idx):
|
||||||
name = "t{},{}".format(root_idx, format_opcode(opcode))
|
tn = root_idx,
|
||||||
|
|
||||||
tn = "root%d"%root_idx
|
|
||||||
for i in range(len(opcode) - 1):
|
for i in range(len(opcode) - 1):
|
||||||
# kind is the table kind that we want to point to in the _next_.
|
# kind is the table kind that we want to point to in the _next_.
|
||||||
kind, byte = opcode[i+1][0], opcode[i][1]
|
kind, byte = opcode[i+1][0], opcode[i][1]
|
||||||
# Retain prev_tn name so that we can update it.
|
# Retain prev_tn name so that we can update it.
|
||||||
prev_tn, tn = tn, self.data[tn].items[byte]
|
prev_tn, tn = tn, self.data[tn].items[byte]
|
||||||
if tn is None:
|
if tn is None:
|
||||||
tn = "t{},{}".format(root_idx, format_opcode(opcode[:i+1]))
|
tn = prev_tn + (byte,)
|
||||||
self._update_table(prev_tn, byte, tn, TrieEntry.table(kind))
|
self._update_table(prev_tn, byte, tn, TrieEntry.table(kind))
|
||||||
|
|
||||||
if self.data[tn].kind != kind:
|
if self.data[tn].kind != kind:
|
||||||
raise Exception("{}, have {}, want {}".format(
|
raise Exception("{}, have {}, want {}".format(
|
||||||
name, self.data[tn].kind, kind))
|
opcode, self.data[tn].kind, kind))
|
||||||
return tn
|
return tn
|
||||||
|
|
||||||
def _add_encoding(self, instr_encoding):
|
def _add_encoding(self, instr_encoding):
|
||||||
@@ -362,10 +337,9 @@ class Table:
|
|||||||
return TrieEntry.instr(desc_idx)
|
return TrieEntry.instr(desc_idx)
|
||||||
|
|
||||||
def add_opcode(self, opcode, instr_encoding, root_idx=0):
|
def add_opcode(self, opcode, instr_encoding, root_idx=0):
|
||||||
name = "t{},{}".format(root_idx, format_opcode(opcode))
|
|
||||||
tn = self._walk_opcode(opcode, root_idx)
|
tn = self._walk_opcode(opcode, root_idx)
|
||||||
desc_entry = self._add_encoding(instr_encoding)
|
desc_entry = self._add_encoding(instr_encoding)
|
||||||
self._update_table(tn, opcode[-1][1], name, desc_entry)
|
self._update_table(tn, opcode[-1][1], desc_entry.descidx, desc_entry)
|
||||||
|
|
||||||
def fill_free(self, opcode, instr_encoding, root_idx=0):
|
def fill_free(self, opcode, instr_encoding, root_idx=0):
|
||||||
desc_entry = self._add_encoding(instr_encoding)
|
desc_entry = self._add_encoding(instr_encoding)
|
||||||
@@ -375,7 +349,7 @@ class Table:
|
|||||||
tn, idx = queue.pop()
|
tn, idx = queue.pop()
|
||||||
entry = self.data[tn].items[idx]
|
entry = self.data[tn].items[idx]
|
||||||
if not entry:
|
if not entry:
|
||||||
self._update_table(tn, idx, f"tn,*{idx:x}", desc_entry)
|
self._update_table(tn, idx, desc_entry.descidx, desc_entry)
|
||||||
else:
|
else:
|
||||||
for i in range(len(self.data[entry].items)):
|
for i in range(len(self.data[entry].items)):
|
||||||
queue.append((entry, i))
|
queue.append((entry, i))
|
||||||
|
|||||||
Reference in New Issue
Block a user