correct table-matching
[openpower-isa.git] / src / openpower / decoder / power_table.py
1 import pathlib
2 from openpower.decoder.power_enums import find_wiki_dir
3 from openpower.decoder.power_insn import (Database, MarkdownDatabase,
4 FieldsDatabase, PPCDatabase,
5 IntegerOpcode, PatternOpcode,
6 parse, Section, BitSel,
7 FieldsOpcode)
8 root = find_wiki_dir()
9 root = pathlib.Path(root)
10 mdwndb = MarkdownDatabase()
11 fieldsdb = FieldsDatabase()
12
13 # create by-sections first. these will be the markdown tables
14 sections = {}
15 insns = {}
16 path = (root / "insndb.csv")
17 with open(path, "r", encoding="UTF-8") as stream:
18 for section in parse(stream, Section.CSV):
19 sections[str(section.path)] = section
20 insns[str(section.path)] = []
21 for (name, section) in sections.items():
22 print (name, section)
23
24 # enumerate all instructions and drop them into sections
25 db = Database(root)
26 for insn in db:
27 insns[str(insn.section.path)].append(insn)
28 print (insn)
29
30 # create one table
31 def do_table(fname, insns, section):
32 insns = insns[fname]
33 section = sections[fname]
34 start, end = section.bitsel.start, section.bitsel.end
35 print ("start-end", start, end)
36 bitlen = end-start+1
37 half = bitlen // 2
38 lowermask = (1<<half)-1
39 uppermask = (1<<(bitlen-half))-1
40 table_entries = {}
41 # debug-print all opcodes first
42 opcode_per_insn = {}
43 for insn in insns:
44 fields = []
45 fields += [(insn.ppc.opcode.value, insn.section.bitsel)]
46 opcode = FieldsOpcode(fields)
47 if not isinstance(opcode, list):
48 opcode = [opcode]
49 for op in opcode:
50 print ("op", insn.name, op)
51 opcode_per_insn[insn.name] = opcode
52
53 for i in range(1<<bitlen):
54 # calculate row, column
55 lower = i & lowermask
56 upper = (i>>half) & uppermask
57 print (i, bin(lower), bin(upper))
58 if lower not in table_entries:
59 table_entries[lower] = {}
60 table_entries[lower][upper] = None
61 # create an XO
62 key = i << (31-end) # MSB0-order shift up by *end*
63 print ("search", i, hex(key))
64 # start hunting
65 for insn in insns:
66 opcode = opcode_per_insn[insn.name]
67 for op in opcode:
68 #print (" search", i, hex(key), insn.name,
69 # hex(op.value), hex(op.mask))
70 if ((op.value & op.mask) == (key & op.mask)):
71 print (" match", i, hex(key), insn.name)
72 assert (table_entries[lower][upper] is None,
73 "entry %d %d should be empty "
74 "contains %s conflicting %s" % \
75 (lower, upper, str(table_entries[lower][upper]),
76 insn.name))
77 table_entries[lower][upper] = insn.name
78 continue
79
80 do_table('minor_30.csv', insns, sections)
81