Simplify handling of 32-bit and 64-bit encodings
This commit is contained in:
@@ -115,6 +115,8 @@ class InstrDesc(namedtuple("InstrDesc", "mnemonic,flags,encoding")):
|
|||||||
if "IMM_8" in desc[6:]: flags.imm_byte = 1
|
if "IMM_8" in desc[6:]: flags.imm_byte = 1
|
||||||
|
|
||||||
return cls(desc[5], frozenset(desc[6:]), flags._encode())
|
return cls(desc[5], frozenset(desc[6:]), flags._encode())
|
||||||
|
def encode(self, mnemonics_lut):
|
||||||
|
return struct.pack("<HL", mnemonics_lut[self.mnemonic], self.encoding)
|
||||||
|
|
||||||
class EntryKind(Enum):
|
class EntryKind(Enum):
|
||||||
NONE = 0
|
NONE = 0
|
||||||
@@ -215,8 +217,7 @@ class Table:
|
|||||||
data += b"\0" * (offsets[name] - len(data))
|
data += b"\0" * (offsets[name] - len(data))
|
||||||
assert len(data) == offsets[name]
|
assert len(data) == offsets[name]
|
||||||
if kind == EntryKind.INSTR:
|
if kind == EntryKind.INSTR:
|
||||||
mnemonicIdx = mnemonics_lut[value[0]]
|
data += value
|
||||||
data += struct.pack("<HL", mnemonicIdx, value[1])
|
|
||||||
else: # Table
|
else: # Table
|
||||||
# count = sum(1 for x in value if x is not None)
|
# count = sum(1 for x in value if x is not None)
|
||||||
# print("Table of kind", kind, "with %d/%d entries"%(count, kind.table_length))
|
# print("Table of kind", kind, "with %d/%d entries"%(count, kind.table_length))
|
||||||
@@ -234,7 +235,7 @@ class Table:
|
|||||||
def deduplicate(self):
|
def deduplicate(self):
|
||||||
# Make values hashable
|
# Make values hashable
|
||||||
for n, (k, v) in self.data.items():
|
for n, (k, v) in self.data.items():
|
||||||
self.data[n] = k, tuple(v)
|
self.data[n] = k, (v if k == EntryKind.INSTR else tuple(v))
|
||||||
synonyms = True
|
synonyms = True
|
||||||
while synonyms:
|
while synonyms:
|
||||||
entries = {} # Mapping from entry to name
|
entries = {} # Mapping from entry to name
|
||||||
@@ -250,7 +251,7 @@ class Table:
|
|||||||
for key in synonyms:
|
for key in synonyms:
|
||||||
del self.data[key]
|
del self.data[key]
|
||||||
|
|
||||||
def add_opcode(self, opcode, instrData, root_idx=0):
|
def add_opcode(self, opcode, instr_encoding, root_idx=0):
|
||||||
opcode = list(opcode) + [(None, None)]
|
opcode = list(opcode) + [(None, None)]
|
||||||
opcode = [(opcode[i+1][0], opcode[i][1]) for i in range(len(opcode)-1)]
|
opcode = [(opcode[i+1][0], opcode[i][1]) for i in range(len(opcode)-1)]
|
||||||
|
|
||||||
@@ -268,9 +269,9 @@ class Table:
|
|||||||
# An opcode can occur once only.
|
# An opcode can occur once only.
|
||||||
assert table[1][opcode[-1][1]] is None
|
assert table[1][opcode[-1][1]] is None
|
||||||
|
|
||||||
name += "{:02x}/{}".format(opcode[-1][1], instrData[0])
|
name += "{:02x}/{}".format(opcode[-1][1], "??")
|
||||||
table[1][opcode[-1][1]] = name
|
table[1][opcode[-1][1]] = name
|
||||||
self.data[name] = EntryKind.INSTR, instrData
|
self.data[name] = EntryKind.INSTR, instr_encoding
|
||||||
|
|
||||||
def wrap(string):
|
def wrap(string):
|
||||||
return "\n".join(string[i:i+80] for i in range(0, len(string), 80))
|
return "\n".join(string[i:i+80] for i in range(0, len(string), 80))
|
||||||
@@ -306,24 +307,21 @@ if __name__ == "__main__":
|
|||||||
for opcode in parse_opcode(opcode_string):
|
for opcode in parse_opcode(opcode_string):
|
||||||
entries[opcode].append(InstrDesc.parse(desc))
|
entries[opcode].append(InstrDesc.parse(desc))
|
||||||
|
|
||||||
mnemonics = set()
|
mnemonics = sorted({desc.mnemonic for descs in entries.values() for desc in descs})
|
||||||
|
mnemonics_lut = {name: mnemonics.index(name) for name in mnemonics}
|
||||||
table32 = Table()
|
table32 = Table()
|
||||||
table64 = Table()
|
table64 = Table()
|
||||||
masks = "ONLY64", "ONLY32"
|
masks = "ONLY64", "ONLY32"
|
||||||
for opcode, descs in entries.items():
|
for opcode, descs in entries.items():
|
||||||
for table, ignore_mask in zip((table32, table64), masks):
|
for desc in descs:
|
||||||
parsed = [desc for desc in descs if ignore_mask not in desc.flags]
|
if "ONLY64" not in desc.flags:
|
||||||
assert len(parsed) <= 1
|
table32.add_opcode(opcode, desc.encode(mnemonics_lut))
|
||||||
if parsed:
|
if "ONLY32" not in desc.flags:
|
||||||
mnemonics.add(parsed[0].mnemonic)
|
table64.add_opcode(opcode, desc.encode(mnemonics_lut))
|
||||||
table.add_opcode(opcode, (parsed[0].mnemonic, parsed[0].encoding))
|
|
||||||
|
|
||||||
table32.deduplicate()
|
table32.deduplicate()
|
||||||
table64.deduplicate()
|
table64.deduplicate()
|
||||||
|
|
||||||
mnemonics = sorted(mnemonics)
|
|
||||||
mnemonics_lut = {name: mnemonics.index(name) for name in mnemonics}
|
|
||||||
|
|
||||||
mnemonic_tab = [0]
|
mnemonic_tab = [0]
|
||||||
for name in mnemonics:
|
for name in mnemonics:
|
||||||
mnemonic_tab.append(mnemonic_tab[-1] + len(name) + 1)
|
mnemonic_tab.append(mnemonic_tab[-1] + len(name) + 1)
|
||||||
|
|||||||
Reference in New Issue
Block a user