Simplify handling of 32-bit and 64-bit encodings

This commit is contained in:
Alexis Engelke
2019-02-23 12:06:04 +01:00
parent 50ba38627b
commit 10e7a41972

View File

@@ -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)