correct table-matching
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 3 Sep 2022 17:00:54 +0000 (18:00 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 3 Sep 2022 17:00:54 +0000 (18:00 +0100)
src/openpower/decoder/power_table.py

index 286cb8e3024c28225d1da4a8309b38e829c25e10..03feb165bafc0c0c4f17f2d14124b95842fa5be6 100644 (file)
@@ -3,7 +3,8 @@ from openpower.decoder.power_enums import find_wiki_dir
 from openpower.decoder.power_insn import (Database, MarkdownDatabase,
                                           FieldsDatabase, PPCDatabase,
                                           IntegerOpcode, PatternOpcode,
-                                          parse, Section)
+                                          parse, Section, BitSel,
+                                          FieldsOpcode)
 root = find_wiki_dir()
 root = pathlib.Path(root)
 mdwndb = MarkdownDatabase()
@@ -26,7 +27,10 @@ for insn in db:
     insns[str(insn.section.path)].append(insn)
     print (insn)
 
-def do_table(insns, section):
+# create one table
+def do_table(fname, insns, section):
+    insns = insns[fname]
+    section = sections[fname]
     start, end = section.bitsel.start, section.bitsel.end
     print ("start-end", start, end)
     bitlen = end-start+1
@@ -35,12 +39,16 @@ def do_table(insns, section):
     uppermask = (1<<(bitlen-half))-1
     table_entries = {}
     # debug-print all opcodes first
+    opcode_per_insn = {}
     for insn in insns:
-        opcode = insn.section.opcode
+        fields = []
+        fields += [(insn.ppc.opcode.value, insn.section.bitsel)]
+        opcode = FieldsOpcode(fields)
         if not isinstance(opcode, list):
             opcode = [opcode]
         for op in opcode:
             print ("op", insn.name, op)
+        opcode_per_insn[insn.name] = opcode
 
     for i in range(1<<bitlen):
         # calculate row, column
@@ -49,17 +57,25 @@ def do_table(insns, section):
         print (i, bin(lower), bin(upper))
         if lower not in table_entries:
             table_entries[lower] = {}
-        table_entries[lower][upper] = i
+        table_entries[lower][upper] = None
         # create an XO
         key = i << (31-end) # MSB0-order shift up by *end*
         print ("search", i, hex(key))
         # start hunting
         for insn in insns:
-            opcode = insn.opcode
-            if not isinstance(opcode, list):
-                opcode = [opcode]
+            opcode = opcode_per_insn[insn.name]
             for op in opcode:
+                #print ("    search", i, hex(key), insn.name,
+                #                       hex(op.value), hex(op.mask))
                 if ((op.value & op.mask) == (key & op.mask)):
-                    print ("match", i, hex(key), insn.name)
+                    print ("    match", i, hex(key), insn.name)
+                    assert (table_entries[lower][upper] is None,
+                            "entry %d %d should be empty "
+                            "contains %s conflicting %s" % \
+                            (lower, upper, str(table_entries[lower][upper]),
+                             insn.name))
+                    table_entries[lower][upper] = insn.name
+                    continue
+
+do_table('minor_30.csv', insns, sections)
 
-do_table(insns['minor_30.csv'], sections['minor_30.csv'])