divpoint 2 to match v3.1
[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.section.bitsel)]
52 opcode = FieldsOpcode(fields)
53 if not isinstance(opcode, list):
54 opcode = [opcode]
55 for op in opcode:
56 print ("op", insn.name, op)
57 opcode_per_insn[insn.name] = opcode
58
59 maxnamelen = 0
60 for i in range(1<<bitlen):
61 # calculate row, column
62 lower = i & lowermask
63 upper = (i>>half) & uppermask
64 print (i, bin(lower), bin(upper))
65 if upper not in table_entries:
66 table_entries[upper] = {}
67 table_entries[upper][lower] = None
68 # create an XO
69 key = i << (31-end) # MSB0-order shift up by *end*
70 print ("search", i, hex(key))
71 # start hunting
72 for insn in insns:
73 opcode = opcode_per_insn[insn.name]
74 for op in opcode:
75 #print (" search", i, hex(key), insn.name,
76 # hex(op.value), hex(op.mask))
77 if ((op.value & op.mask) == (key & op.mask)):
78 print (" match", i, hex(key), insn.name)
79 assert (table_entries[upper][lower] is None,
80 "entry %d %d should be empty "
81 "contains %s conflicting %s" % \
82 (lower, upper, str(table_entries[upper][lower]),
83 insn.name))
84 table_entries[upper][lower] = insn.name
85 maxnamelen = max(maxnamelen, len(insn.name))
86 continue
87
88 print (table_entries)
89 # now got the table: print it out
90
91 table = []
92 line = [" "*half]
93 for j in range(1<<(half)):
94 hdr = binmaxed(half, j)
95 line.append(maxme(maxnamelen, hdr))
96 line.append(" "*half)
97 table.append("|" + "|".join(line) + "|")
98 line = ["-"*half] + ["-"*maxnamelen] * (1<<(bitlen-half)) + ["-"*half]
99 table.append("|" + "|".join(line) + "|")
100
101 for i in range(1<<(bitlen-half)):
102 hdr = binmaxed(half, i)
103 line = [hdr]
104 for j in range(1<<(half)):
105 line.append(maxme(maxnamelen, table_entries[i][j] or " "))
106 line.append(hdr)
107 table.append("|" + "|".join(line) + "|")
108
109 print ("\n".join(table))
110
111 do_table('minor_30.csv', insns, sections, divpoint=2)
112