create list of opcodes by dict entry
[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 def maxme(num, s):
31 return s.ljust(num)
32
33 def binmaxed(num, v):
34 return format(v, "0%db" % num)
35
36 # create one table
37 def do_table(fname, insns, section, divpoint):
38 insns = insns[fname]
39 section = sections[fname]
40 start, end = section.bitsel.start, section.bitsel.end
41 print ("start-end", start, end)
42 bitlen = end-start+1
43 half = divpoint
44 lowermask = (1<<half)-1
45 uppermask = (1<<(bitlen-half))-1
46 table_entries = {}
47 # debug-print all opcodes first
48 opcode_per_insn = {}
49 for insn in insns:
50 #fields = []
51 #fields += [(insn.ppc.opcode.value, insn.ppc.bitsel)]
52 #opcode = FieldsOpcode(fields)
53 opcode = insn.ppc.opcode
54 if not isinstance(opcode, list):
55 opcode = [opcode]
56 for op in opcode:
57 print ("op", insn.name, op)
58 if insn.name not in opcode_per_insn:
59 opcode_per_insn[insn.name] = []
60 opcode_per_insn[insn.name] += opcode
61
62 maxnamelen = 0
63 for i in range(1<<bitlen):
64 # calculate row, column
65 lower = i & lowermask
66 upper = (i>>half) & uppermask
67 print (i, bin(lower), bin(upper))
68 if upper not in table_entries:
69 table_entries[upper] = {}
70 table_entries[upper][lower] = None
71 # create an XO
72 key = i
73 print ("search", i, hex(key))
74 # start hunting
75 for insn in insns:
76 opcode = opcode_per_insn[insn.name]
77 for op in opcode:
78 #print (" search", i, hex(key), insn.name,
79 # hex(op.value), hex(op.mask))
80 if ((op.value & op.mask) == (key & op.mask)):
81 print (" match", i, hex(key), insn.name)
82 assert (table_entries[upper][lower] is None,
83 "entry %d %d should be empty "
84 "contains %s conflicting %s" % \
85 (lower, upper, str(table_entries[upper][lower]),
86 insn.name))
87 table_entries[upper][lower] = insn.name
88 maxnamelen = max(maxnamelen, len(insn.name))
89 continue
90
91 print (table_entries)
92 # now got the table: print it out
93
94 table = []
95 line = [" "*half]
96 for j in range(1<<(half)):
97 hdr = binmaxed(half, j)
98 line.append(maxme(maxnamelen, hdr))
99 line.append(" "*half)
100 table.append("|" + "|".join(line) + "|")
101 line = ["-"*half] + ["-"*maxnamelen] * (1<<(half)) + ["-"*half]
102 table.append("|" + "|".join(line) + "|")
103
104 for i in range(1<<(bitlen-half)):
105 hdr = binmaxed(half, i)
106 line = [hdr]
107 for j in range(1<<(half)):
108 line.append(maxme(maxnamelen, table_entries[i][j] or " "))
109 line.append(hdr)
110 table.append("|" + "|".join(line) + "|")
111
112 print ("\n".join(table))
113
114 do_table('minor_30.csv', insns, sections, divpoint=2)
115