def _EmitCodeC(fout): print( "// Indexed by OPC which in turn are organize to help with disassembly", file=fout) print("const Opcode OpcodeTable[] = {", file=fout) print("\n".join(_RenderOpcodeTable()), file=fout) print("};\n", file=fout) print("const int16_t OpcodeTableJumper[] = {", file=fout) print(",\n".join(_RenderOpcodeTableJumper()), file=fout) print("};\n", file=fout) print("// Indexed by FieldKind", file=fout) print("static const Field FieldTable[] = {", file=fout) print("\n".join(_RenderFieldTable()), file=fout) print("};\n", file=fout) print( "// Indexed by djb2 hash of mnemonic. Collisions are resolved via linear probing", file=fout) print("static const OPC MnemonicHashTable[512] = {", file=fout) print("\n".join(_RenderMnemonicHashLookup()), file=fout) print("};\n", file=fout) # what about REG/SREG/DREG cgen.RenderEnumToStringMap(cgen.NameValues(PRED), "PRED", fout) cgen.RenderEnumToStringFun("PRED", fout) cgen.RenderEnumToStringMap(cgen.NameValues(ADDR_MODE), "ADDR_MODE", fout) cgen.RenderEnumToStringFun("ADDR_MODE", fout) cgen.RenderEnumToStringMap(cgen.NameValues(SHIFT), "SHIFT", fout) cgen.RenderEnumToStringFun("SHIFT", fout)
def render(cls, both_ways=True): cgen.RenderEnumToStringMap(cgen.NameValues(cls), cls.__name__, fout) cgen.RenderEnumToStringFun(cls.__name__, fout) if both_ways: cgen.RenderStringToEnumMap(cgen.NameValues(cls), cls.__name__ + "FromStringMap", cls.__name__ + "Jumper", fout)
def EmitEnumsC(fout): for cls, info in CLASSES.items(): if info[0] is UNSUPPORTED: continue if info[0] is FLAG: cgen.RenderEnumToStringMapFlag(cgen.NameValues(cls), cls.__name__, fout) cgen.RenderEnumToStringFun(cls.__name__, fout) elif info[1] in {8, 16}: cgen.RenderEnumToStringMap(cgen.NameValues(cls), cls.__name__, fout) cgen.RenderEnumToStringFun(cls.__name__, fout) elif info[1] == 32: for n, first in enumerate(info[2]): if first == -1: continue last = info[2][n + 1] cgen.RenderEnumToStringMap(_EnumGenerator(cls, first, last), f"{cls.__name__ }_{first:x}", fout, first)
def _EmitCodeC(fout): print( "// Indexed by OPC which in turn are organize to help with disassembly", file=fout) print("const Opcode OpcodeTable[] = {", file=fout) print("\n".join(_RenderOpcodeTable()), file=fout) print("};\n", file=fout) print("const OPC ClusteredOpcodeTable[] = {", file=fout) print(",\n".join(_RenderClusteredOpcodeTable()), file=fout) print("};\n", file=fout) print("const int16_t OpcodeTableJumper[] = {", file=fout) print(",\n".join(_RenderOpcodeTableJumper()), file=fout) print("};\n", file=fout) print( f"constexpr const unsigned MNEMONIC_HASH_TABLE_SIZE = {_MNEMONIC_HASH_TABLE_SIZE};", file=fout) print( "// Indexed by djb2 hash of mnemonic. Collisions are resolved via linear probing", file=fout) print(f"static const OPC MnemonicHashTable[MNEMONIC_HASH_TABLE_SIZE] = {{", file=fout) print("\n".join(_RenderMnemonicHashLookup()), file=fout) print("};\n", file=fout) cgen.RenderEnumToStringMap(cgen.NameValues(REG), "REG", fout) cgen.RenderEnumToStringFun("REG", fout) cgen.RenderEnumToStringMap(cgen.NameValues(DREG), "DREG", fout) cgen.RenderEnumToStringFun("DREG", fout) cgen.RenderEnumToStringMap(cgen.NameValues(SREG), "SREG", fout) cgen.RenderEnumToStringFun("SREG", fout) cgen.RenderEnumToStringMap(cgen.NameValues(PRED), "PRED", fout) cgen.RenderEnumToStringFun("PRED", fout) cgen.RenderEnumToStringMap(cgen.NameValues(SHIFT), "SHIFT", fout) cgen.RenderEnumToStringFun("SHIFT", fout) # Note this also uses the string tables from the enums above print("// Indexed by OK", file=fout) print("const FieldInfo FieldInfoTable[] = {", file=fout) print("\n".join(_RenderFieldInfoTable()), file=fout) print("};\n", file=fout)
def _EmitCodeC(fout): print(f"\nconst InsTmpl kInsTemplates[] = {{", file=fout) print(" { /*used first entry*/ },", file=fout) num_ins = 1 for i in range(256): patterns = Pattern.Table.get(i) if patterns is None: continue opcode = o.Opcode.TableByNo.get(i) for pat in patterns: for tmpl in pat.emit: mask, ops = _RenderOperands(tmpl.args) num_ins += 1 print(f" {{ {{{', '.join(ops)}}},", file=fout) print( f" a32::OPC::{tmpl.opcode.NameForEnum()}, 0x{mask:x} }}, // {opcode.name} [{num_ins}]", file=fout) print(f"}};", file=fout) print(f"\nconst uint16_t kPatternJumper[256] = {{") n = 0 for i in range(256): opcode = o.Opcode.TableByNo.get(i) name = opcode.name if opcode else "---" print(f" {n} /* {name} */, ", end="", file=fout) n += len(Pattern.Table.get(i, [])) if i % 4 == 3: print("", file=fout) print(f"}};", file=fout) print(f"\nconst Pattern kPatterns[] = {{", file=fout) num_ins = 1 # we want the first entry in the kInsTemplate to be unused num_pattern = 0 for i in range(256): patterns = Pattern.Table.get(i) if patterns is None: continue opcode = o.Opcode.TableByNo.get(i) for pat in patterns: reg_constraints = [f"DK::{c.name}" for c in pat.type_constraints] imm_constraints = [f"IK::{c.name}" for c in pat.imm_constraints] print(f" {{ {{{', '.join(reg_constraints)}}},") print(f" {{{', '.join(imm_constraints)}}},") print( f" &kInsTemplates[{num_ins}], {len(pat.emit)} }}, // {opcode.name} [{num_pattern}]" ) num_ins += len(pat.emit) num_pattern += 1 print(f"}};", file=fout) print("} // namspace", file=fout) cgen.RenderEnumToStringMap(cgen.NameValues(IMM_KIND), "IMM_KIND", fout) cgen.RenderEnumToStringFun("IMM_KIND", fout)
def _EmitCodeC(fout): cgen.RenderEnumToStringMap(cgen.NameValues(OK), "OK", fout) cgen.RenderEnumToStringFun("OK", fout)