X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fopenpower%2Fdecoder%2Fpower_table.py;h=985c6e5248483ee83de157aa3570d07c56bda832;hb=dc4a23240f8b72bb00ee1b2ce16aace7914d8c77;hp=03feb165bafc0c0c4f17f2d14124b95842fa5be6;hpb=0b9e456fb2b9fda4a5cdd4cf0f1f6a7ab60208ea;p=openpower-isa.git diff --git a/src/openpower/decoder/power_table.py b/src/openpower/decoder/power_table.py index 03feb165..985c6e52 100644 --- a/src/openpower/decoder/power_table.py +++ b/src/openpower/decoder/power_table.py @@ -1,81 +1,106 @@ -import pathlib +import collections from openpower.decoder.power_enums import find_wiki_dir -from openpower.decoder.power_insn import (Database, MarkdownDatabase, - FieldsDatabase, PPCDatabase, - IntegerOpcode, PatternOpcode, - parse, Section, BitSel, - FieldsOpcode) -root = find_wiki_dir() -root = pathlib.Path(root) -mdwndb = MarkdownDatabase() -fieldsdb = FieldsDatabase() +from openpower.decoder.power_insn import Database +from openpower.util import log -# create by-sections first. these will be the markdown tables sections = {} -insns = {} -path = (root / "insndb.csv") -with open(path, "r", encoding="UTF-8") as stream: - for section in parse(stream, Section.CSV): - sections[str(section.path)] = section - insns[str(section.path)] = [] -for (name, section) in sections.items(): - print (name, section) +insns = collections.defaultdict(list) + +# create by-sections first. these will be the markdown tables +# then enumerate all instructions and drop them into sections +for insn in Database(find_wiki_dir()): + key = insn.section.path.name + sections[key] = insn.section + insns[key].append(insn) -# enumerate all instructions and drop them into sections -db = Database(root) -for insn in db: - insns[str(insn.section.path)].append(insn) - print (insn) +def maxme(num, s): + return s.ljust(num) + +def binmaxed(num, v): + return format(v, "0%db" % num) # create one table -def do_table(fname, insns, section): +def do_table(fname, insns, section, divpoint): insns = insns[fname] section = sections[fname] start, end = section.bitsel.start, section.bitsel.end - print ("start-end", start, end) + log("start-end", start, end) bitlen = end-start+1 - half = bitlen // 2 + half = divpoint lowermask = (1<>half) & uppermask - print (i, bin(lower), bin(upper)) - if lower not in table_entries: - table_entries[lower] = {} - 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 + lower = XO & lowermask + upper = (XO>>half) & uppermask + log("search", XO, bin(XO), bin(lower), bin(upper)) + if upper not in table_entries: # really should use defaultdict here + table_entries[upper] = {} + table_entries[upper][lower] = None + # hunt through all instructions, check XO against value/mask for insn in insns: opcode = opcode_per_insn[insn.name] for op in opcode: - #print (" search", i, hex(key), insn.name, + #log(" search", XO, 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) - assert (table_entries[lower][upper] is None, - "entry %d %d should be empty " + if ((op.value & op.mask) == (XO & op.mask)): + log(" match", bin(XO), insn.name) + assert table_entries[upper][lower] is None, \ + "entry %d %d (XO %s) should be empty " \ "contains %s conflicting %s" % \ - (lower, upper, str(table_entries[lower][upper]), - insn.name)) - table_entries[lower][upper] = insn.name + (lower, upper, bin(XO), + str(table_entries[upper][lower]), + insn.name) + table_entries[upper][lower] = insn.name + maxnamelen = max(maxnamelen, len(insn.name)) continue -do_table('minor_30.csv', insns, sections) + log(table_entries) + # now got the table: print it out + + # create the markdown header. first line: | |00|01|10|11| | + table = [] + line = [" "*6] + for j in range(1<<(half)): + hdr = binmaxed(half, j) + line.append(maxme(maxnamelen, hdr)) + line.append(" "*6) + table.append("|" + "|".join(line) + "|") + # second line: |--|--|--|--|--|--| + line = ["-"*6] + ["-"*maxnamelen] * (1<<(half)) + ["-"*6] + table.append("|" + "|".join(line) + "|") + + # now the rows, the row number goes into first and last column + for i in range(1<<(bitlen-half)): + hdr = binmaxed(6, i) + line = [hdr] + for j in range(1<<(half)): + line.append(maxme(maxnamelen, table_entries[i][j] or " ")) + line.append(hdr) + table.append("|" + "|".join(line) + "|") + + print("\n".join(table)) +do_table('minor_30.csv', insns, sections, divpoint=2) +#do_table('minor_22.csv', insns, sections, divpoint=5)