Files
kaizen/external/capstone/contrib/riscv_update/0002-update-TableGen-for-generate-RISCV-port-inc-for-CAPS.patch
T
iris 00cc9309cb Squashed 'external/ircolib/' changes from ce3cd726c..de6e324bd
de6e324bd separate emu thread
10d3daf86 Roms List improvements
95d202f37 Let's make the rom list process on a separate thread so the emulator doesnt take ages to load.
fc306967f Wow the ROM Header was just completely busted. Game list view works now
bad1691ee fuck this shit
2b59e5f46 game list in progress
d26417b83 remappable inputs in progress
ac4af8106 input
e72abc240 update readme
430139dc9 Qt6 frontend
3080d4d45 Fix this small bug too
08cd13b85 Cop0 unused functions do not actually pose a threat (as per manual). They don't do anything, so shall we.
61bb4fb44 make idle loop detection a little more specific with where the load goes
b037de4c3 SAZDFsdff
12e81e73e need to figure out why n64-systemtest loops indefinitely at some address that appears to be valid (i think it's me not invalidating the cache properly)
204f0e13b idle skipping seems to work!
cb8bb634a sdkfjlasdf
58e5c89c1 Fix compilation issue on my machine (no idea)
24fb2898e attempting more serious idle skipping
214719577 Place rsp.Step inside cached interpreter. Gains about 3 more fps
bb97dcc23 mmmmm
920b77d38 wjkhasdfjhkasdf
430ccdab4 it's a start...
4f42a673a Cached interpreter plays Mario 64. Start looking into RSP as well
c9a030787 idle skipping works!
5fbda03ce new idea
366637aba Idle skipping... maybe?
609fa2fb0 Cache instructions implemented but broken lmao. Commented out for now
e140a6d12 - Stop using inheritance for CPU, instead use composition. - Introduce KAIZEN_JIT_ENABLED optional define instead of relying on __aarch64__ and the like. - More cache work
68e613057 prep cache impl
811b4d809 fix clang format
fda755f7d idk
d5024ebbf small MI refactor in preparation of (eventually) implementing the RDRAM interface properly
694b45341 Merge commit '206dcdedf195fb320913584180edb12c7731e396' as 'external/SDL'
206dcdedf Squashed 'external/SDL/' content from commit 4d17b99d0a
4d16e1cb4 need to update sdl
848b19920 Fix compilation error
db61b5299 Merge commit 'e94a94559f28e49678fbcf72199a5258137b0fe9' as 'external/imgui'
e94a94559 Squashed 'external/imgui/' content from commit 02e9b8cac
52edb3757 need to update imgui
c1a705e86 Emulate weird JALR behaviour
4b4c32f4b Fix exception for "unusable COP1" in 4 instructions i missed accidentally (again)
df5828142 Bug putting 0s in the log everywhere
f8b580048 Make isviewer a sink to file
8241e9735 Fix exception for "unusable COP1" in 4 instructions i missed accidentally
b29715f20 small changes
d9a620bc1 make use of my new small utility library
0d1aa938e Add 'external/ircolib/' from commit 'ce3cd726c8df8388d554abf8bb55d55020eb4450'
e64eb40b3 Fuck git

git-subtree-dir: external/ircolib
git-subtree-split: de6e324bde
2026-06-15 11:56:38 +02:00

906 lines
34 KiB
Diff

From 40ac7444e7f3679fad852564acca4f30f47fb52d Mon Sep 17 00:00:00 2001
From: fanfuqiang <feqin1023@gmail.com>
Date: Thu, 28 Feb 2019 01:37:55 +0800
Subject: [PATCH] update TableGen for generate RISCV port inc for CAPSTONE
---
llvm/lib/Target/RISCV/CMakeLists.txt | 2 +-
llvm/utils/TableGen/AsmWriterEmitter.cpp | 175 ++++++++++++++++--
.../utils/TableGen/FixedLenDecoderEmitter.cpp | 122 ++++++------
llvm/utils/TableGen/InstrInfoEmitter.cpp | 14 +-
llvm/utils/TableGen/RegisterInfoEmitter.cpp | 20 +-
llvm/utils/TableGen/TableGen.cpp | 6 +
6 files changed, 249 insertions(+), 90 deletions(-)
diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt
index 1821f4b01..603aa3f54 100644
--- a/llvm/lib/Target/RISCV/CMakeLists.txt
+++ b/llvm/lib/Target/RISCV/CMakeLists.txt
@@ -6,7 +6,7 @@ tablegen(LLVM RISCVGenCompressInstEmitter.inc -gen-compress-inst-emitter)
tablegen(LLVM RISCVGenDAGISel.inc -gen-dag-isel)
tablegen(LLVM RISCVGenDisassemblerTables.inc -gen-disassembler)
tablegen(LLVM RISCVGenInstrInfo.inc -gen-instr-info)
-tablegen(LLVM RISCVGenMappingInsn.inc -gen-mapping-insn)
+tablegen(LLVM RISCVMappingInsn.inc -gen-mapping-insn)
tablegen(LLVM RISCVGenInsnNameMaps.inc -gen-insn-name-maps)
tablegen(LLVM RISCVGenMCCodeEmitter.inc -gen-emitter)
tablegen(LLVM RISCVGenMCPseudoLowering.inc -gen-pseudo-lowering)
diff --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp
index c24dc6052..ac82573fe 100644
--- a/llvm/utils/TableGen/AsmWriterEmitter.cpp
+++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp
@@ -270,12 +270,13 @@ static void UnescapeString(std::string &Str) {
/// implementation. Destroys all instances of AsmWriterInst information, by
/// clearing the Instructions vector.
void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
+#ifdef CAPSTONE
+ bool PassSubtarget = false;
+#else
Record *AsmWriter = Target.getAsmWriter();
-#ifndef CAPSTONE
StringRef ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
-#endif
bool PassSubtarget = AsmWriter->getValueAsInt("PassSubtarget");
-
+#endif
O <<
"/// printInstruction - This method is automatically generated by tablegen\n"
"/// from the instruction set description.\n"
@@ -434,7 +435,11 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
}
// Emit the initial tab character.
-#ifndef CAPSTONE
+#ifdef CAPSTONE
+ O << "#ifndef CAPSTONE_DIET\n"
+ << " SStream_concat0(O, \"\\t\");\n"
+ << "#endif\n\n";
+#else
O << " O << \"\\t\";\n\n";
#endif
@@ -493,10 +498,10 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
<< ((1 << NumBits)-1) << ") {\n"
<< " default: "
#ifdef CAPSTONE
- << "assert(0);\n"
-#endif
+ << "assert(0 && \"Invalid command number.\");\n";
+#else
<< "llvm_unreachable(\"Invalid command number.\");\n";
-
+#endif
// Print out all the cases.
for (unsigned j = 0, e = Commands.size(); j != e; ++j) {
O << " case " << j << ":\n";
@@ -576,9 +581,7 @@ emitRegisterNameString(raw_ostream &O, StringRef AltName,
}
StringTable.layout();
-#ifdef CAPSTONE
- O << "#ifndef CAPSTONE_DIET\n";
-#endif
+
O << " static const char AsmStrs" << AltName << "[] = {\n";
StringTable.emit(O, printChar);
O << " };\n\n";
@@ -625,7 +628,8 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) {
O << " "
<< "assert(RegNo && RegNo < " << (Registers.size()+1)
<< " && \"Invalid register number!\");\n"
- << "\n";
+ << "\n"
+ << "#ifndef CAPSTONE_DIET\n";
if (hasAltNames) {
for (const Record *R : AltNameIndices)
@@ -636,7 +640,7 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) {
if (hasAltNames) {
O << " switch(AltIdx) {\n"
#ifdef CAPSTONE
- << " default: assert(0);\n";
+ << " default: assert(0 && \"Invalid register alt name index!\");\n";
#else
<< " default: llvm_unreachable(\"Invalid register alt name index!\");\n";
#endif
@@ -886,7 +890,9 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
IAPrinter IAP(CGA.Result->getAsString(), FlatAliasAsmString);
+#ifndef CAPSTONE // Silence the compiler waring.
StringRef Namespace = Target.getName();
+#endif
std::vector<Record *> ReqFeatures;
if (PassSubtarget) {
// We only consider ReqFeatures predicates if PassSubtarget
@@ -902,7 +908,11 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
NumMIOps += ResultInstOpnd.MINumOperands;
std::string Cond;
+#ifdef CAPSTONE
+ Cond = std::string("MCInst_getNumOperands(MI) == ") + utostr(NumMIOps);
+#else
Cond = std::string("MI->getNumOperands() == ") + utostr(NumMIOps);
+#endif
IAP.addCond(Cond);
bool CantHandle = false;
@@ -926,9 +936,11 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
}
break;
}
-
+#ifdef CAPSTONE
+ std::string Op = "MCInst_getOperand(MI, " + utostr(MIOpNum) + ")";
+#else
std::string Op = "MI->getOperand(" + utostr(MIOpNum) + ")";
-
+#endif
const CodeGenInstAlias::ResultOperand &RO = CGA.ResultOperands[i];
switch (RO.Kind) {
@@ -954,19 +966,39 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
if (Rec->isSubClassOf("RegisterOperand"))
Rec = Rec->getValueAsDef("RegClass");
if (Rec->isSubClassOf("RegisterClass")) {
+#ifdef CAPSTONE
+ IAP.addCond("MCOperand_isReg(" + Op + ")");
+#else
IAP.addCond(Op + ".isReg()");
+#endif
if (!IAP.isOpMapped(ROName)) {
IAP.addOperand(ROName, MIOpNum, PrintMethodIdx);
Record *R = CGA.ResultOperands[i].getRecord();
if (R->isSubClassOf("RegisterOperand"))
R = R->getValueAsDef("RegClass");
+
+#ifdef CAPSTONE
+ Cond = std::string("MCRegisterClass_contains(") +
+ "MCRegisterInfo_getRegClass(" + "MRI, " +
+ Target.getName().str() + "_" + R->getName().str() + "RegClassID)" +
+ ", " +
+ "MCOperand_getReg(" + Op + "))";
+#else
Cond = std::string("MRI.getRegClass(") + Target.getName().str() +
"::" + R->getName().str() + "RegClassID).contains(" + Op +
".getReg())";
+#endif
+
} else {
+#ifdef CAPSTONE
+ Cond = std::string("MCOperand_getReg(") + Op + ") == " +
+ "MCOperand_getReg(MCInst_getOperand(MI, " +
+ utostr(IAP.getOpIndex(ROName)) + "))";
+#else
Cond = Op + ".getReg() == MI->getOperand(" +
utostr(IAP.getOpIndex(ROName)) + ").getReg()";
+#endif
}
} else {
// Assume all printable operands are desired for now. This can be
@@ -984,8 +1016,12 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
break; // No conditions on this operand at all
}
Cond = (Target.getName() + ClassName + "ValidateMCOperand(" + Op +
+ #ifdef CAPSTONE
+ ", " + utostr(Entry) + ")").str();
+ #else
", STI, " + utostr(Entry) + ")")
.str();
+ #endif
}
// for all subcases of ResultOperand::K_Record:
IAP.addCond(Cond);
@@ -994,9 +1030,15 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
case CodeGenInstAlias::ResultOperand::K_Imm: {
// Just because the alias has an immediate result, doesn't mean the
// MCInst will. An MCExpr could be present, for example.
+#ifdef CAPSTONE
+ IAP.addCond("MCOperand_isImm(" + Op + ")");
+ Cond = "MCOperand_getImm(" + Op + ") == " +
+ itostr(CGA.ResultOperands[i].getImm());
+#else
IAP.addCond(Op + ".isImm()");
-
Cond = Op + ".getImm() == " + itostr(CGA.ResultOperands[i].getImm());
+#endif
+
IAP.addCond(Cond);
break;
}
@@ -1008,8 +1050,14 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
break;
}
+#ifdef CAPSTONE
+ Cond = "MCOperand_getReg(" + Op + ") == " + Target.getName().str() +
+ "_" + CGA.ResultOperands[i].getRegister()->getName().str();
+#else
Cond = Op + ".getReg() == " + Target.getName().str() + "::" +
CGA.ResultOperands[i].getRegister()->getName().str();
+#endif
+
IAP.addCond(Cond);
break;
}
@@ -1019,6 +1067,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
if (CantHandle) continue;
+#ifndef CAPSTONE
for (auto I = ReqFeatures.cbegin(); I != ReqFeatures.cend(); I++) {
Record *R = *I;
StringRef AsmCondString = R->getValueAsString("AssemblerCondString");
@@ -1040,6 +1089,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
IAP.addCond(Cond);
}
}
+#endif
IAPrinterMap[Aliases.first].push_back(std::move(IAP));
}
@@ -1052,10 +1102,17 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
std::string Header;
raw_string_ostream HeaderO(Header);
+#ifdef CAPSTONE
+ HeaderO << "\nstatic bool printAliasInstr(MCInst *MI, SStream * OS, void *info)"
+ << "\n"
+ << "{\n"
+ << " MCRegisterInfo *MRI = (MCRegisterInfo *) info;\n";
+#else
HeaderO << "bool " << Target.getName() << ClassName
<< "::printAliasInstr(const MCInst"
<< " *MI, " << (PassSubtarget ? "const MCSubtargetInfo &STI, " : "")
<< "raw_ostream &OS) {\n";
+#endif
std::string Cases;
raw_string_ostream CasesO(Cases);
@@ -1079,7 +1136,16 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
if (UniqueIAPs.empty()) continue;
+#ifdef CAPSTONE
+ // TODO: tricky.
+ const char* tmpCase = Entry.first.c_str();
+ assert (Entry.first.size() > 7);
+ CasesO.indent(2) << "case "
+ << "RISCV_" << std::string(tmpCase + 7) // strlen("RISCV::) == 7
+ << ":\n";
+#else
CasesO.indent(2) << "case " << Entry.first << ":\n";
+#endif
for (IAPrinter *IAP : UniqueIAPs) {
CasesO.indent(4);
@@ -1100,13 +1166,21 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
if (!MCOpPredicates.empty())
O << "static bool " << Target.getName() << ClassName
+#ifdef CAPSTONE
+ << "ValidateMCOperand(MCOperand *MCOp,\n"
+#else
<< "ValidateMCOperand(const MCOperand &MCOp,\n"
<< " const MCSubtargetInfo &STI,\n"
+#endif
<< " unsigned PredicateIndex);\n";
O << HeaderO.str();
O.indent(2) << "const char *AsmString;\n";
+#ifdef CAPSTONE
+ O.indent(2) << "switch (MCInst_getOpcode(MI)) {\n";
+#else
O.indent(2) << "switch (MI->getOpcode()) {\n";
+#endif
O.indent(2) << "default: return false;\n";
O << CasesO.str();
O.indent(2) << "}\n\n";
@@ -1114,14 +1188,27 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
// Code that prints the alias, replacing the operands with the ones from the
// MCInst.
O << " unsigned I = 0;\n";
+#ifdef CAPSTONE
+ O << " char *tmpString = cs_strdup(AsmString);\n";
+#endif
O << " while (AsmString[I] != ' ' && AsmString[I] != '\\t' &&\n";
O << " AsmString[I] != '$' && AsmString[I] != '\\0')\n";
O << " ++I;\n";
+#ifdef CAPSTONE
+ O << " tmpString[I] = 0;\n";
+ O << " SStream_concat0(OS, \"\\t\");\n";
+ O << " SStream_concat0(OS, tmpString);\n";
+ O << " SStream_concat0(OS, \"\\n\");\n";
+#else
O << " OS << '\\t' << StringRef(AsmString, I);\n";
-
+#endif
O << " if (AsmString[I] != '\\0') {\n";
O << " if (AsmString[I] == ' ' || AsmString[I] == '\\t') {\n";
+#ifdef CAPSTONE
+ O << " SStream_concat0(OS, \"\\t\");\n";
+#else
O << " OS << '\\t';\n";
+#endif
O << " ++I;\n";
O << " }\n";
O << " do {\n";
@@ -1131,15 +1218,28 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
O << " ++I;\n";
O << " int OpIdx = AsmString[I++] - 1;\n";
O << " int PrintMethodIdx = AsmString[I++] - 1;\n";
+#ifdef CAPSTONE
+ O << " printCustomAliasOperand(MI, OpIdx, PrintMethodIdx, OS);\n";
+#else
O << " printCustomAliasOperand(MI, OpIdx, PrintMethodIdx, ";
O << (PassSubtarget ? "STI, " : "");
O << "OS);\n";
+#endif
O << " } else\n";
+
+#ifdef CAPSTONE
+ O << " printOperand(MI, (unsigned)(AsmString[I++]) - 1, OS);\n";
+#else
O << " printOperand(MI, unsigned(AsmString[I++]) - 1, ";
O << (PassSubtarget ? "STI, " : "");
O << "OS);\n";
+#endif
O << " } else {\n";
+#ifdef CAPSTONE
+ O << " SStream_concat0(OS, &AsmString[I++]);\n";
+#else
O << " OS << AsmString[I++];\n";
+#endif
O << " }\n";
O << " } while (AsmString[I] != '\\0');\n";
O << " }\n\n";
@@ -1150,25 +1250,48 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
//////////////////////////////
// Write out the printCustomAliasOperand function
//////////////////////////////
-
+#ifdef CAPSTONE
+ O << "static void "
+#else
O << "void " << Target.getName() << ClassName << "::"
+#endif
<< "printCustomAliasOperand(\n"
+#ifdef CAPSTONE
+ << " MCInst *MI, unsigned OpIdx,\n"
+#else
<< " const MCInst *MI, unsigned OpIdx,\n"
+#endif
<< " unsigned PrintMethodIdx,\n"
+#ifdef CAPSTONE
+ << " SStream *OS) {\n";
+#else
<< (PassSubtarget ? " const MCSubtargetInfo &STI,\n" : "")
<< " raw_ostream &OS) {\n";
+#endif
if (PrintMethods.empty())
+#ifdef CAPSTONE
+ O << " assert(0 && \"Unknown PrintMethod kind\");\n";
+#else
O << " llvm_unreachable(\"Unknown PrintMethod kind\");\n";
+#endif
else {
O << " switch (PrintMethodIdx) {\n"
<< " default:\n"
+#ifdef CAPSTONE
+ << " assert(0 && \"Unknown PrintMethod kind\");\n"
+#else
<< " llvm_unreachable(\"Unknown PrintMethod kind\");\n"
+#endif
<< " break;\n";
for (unsigned i = 0; i < PrintMethods.size(); ++i) {
O << " case " << i << ":\n"
<< " " << PrintMethods[i] << "(MI, OpIdx, "
+#ifdef CAPSTONE
+ << "OS);\n"
+#else
<< (PassSubtarget ? "STI, " : "") << "OS);\n"
+#endif
<< " break;\n";
}
O << " }\n";
@@ -1177,9 +1300,20 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
if (!MCOpPredicates.empty()) {
O << "static bool " << Target.getName() << ClassName
+#ifdef CAPSTONE
+ << "ValidateMCOperand(MCOperand *MCOp,\n"
+#else
<< "ValidateMCOperand(const MCOperand &MCOp,\n"
<< " const MCSubtargetInfo &STI,\n"
- << " unsigned PredicateIndex) {\n"
+#endif
+ << " unsigned PredicateIndex) {\n"
+#ifdef CAPSTONE
+ << " // TODO: need some constant untils operate the MCOperand,\n"
+ << " // but current CAPSTONE does't have.\n"
+ << " // So, We just return true\n"
+ << " return true;\n\n"
+ << "#if 0\n"
+#endif
<< " switch (PredicateIndex) {\n"
<< " default:\n"
<< " llvm_unreachable(\"Unknown MCOperandPredicate kind\");\n"
@@ -1195,6 +1329,9 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
llvm_unreachable("Unexpected MCOperandPredicate field!");
}
O << " }\n"
+#ifdef CAPSTONE
+ << "#endif\n"
+#endif
<< "}\n\n";
}
@@ -1228,7 +1365,7 @@ void AsmWriterEmitter::run(raw_ostream &O) {
#endif
EmitPrintInstruction(O);
EmitGetRegisterName(O);
-#ifndef CAPSTONE
+#ifdef CAPSTONE
EmitPrintAliasInstruction(O);
#endif
}
diff --git a/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp
index 3db428dfa..e1bfaa934 100644
--- a/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp
+++ b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp
@@ -946,13 +946,6 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS,
void FixedLenDecoderEmitter::
emitPredicateFunction(formatted_raw_ostream &OS, PredicateSet &Predicates,
unsigned Indentation) const {
-#ifdef CAPSTONE
- OS.indent(Indentation) << "static bool getbool(uint64_t b)\n";
- OS.indent(Indentation) << "{\n";
- OS.indent(Indentation) << "\treturn b != 0;\n";
- OS.indent(Indentation) << "}\n\n";
-#endif
-
// The predicate function is just a big switch statement based on the
// input predicate index.
OS.indent(Indentation) << "static bool checkDecoderPredicate(unsigned Idx, "
@@ -966,26 +959,25 @@ emitPredicateFunction(formatted_raw_ostream &OS, PredicateSet &Predicates,
OS.indent(Indentation) << "switch (Idx) {\n";
OS.indent(Indentation) << "default: "
#ifdef CAPSTONE
- << "assert(0);\n"
-#endif
+ << "assert(0 && \"Invalid index!\");\n";
+#else
<< "llvm_unreachable(\"Invalid index!\");\n";
+#endif
unsigned Index = 0;
for (const auto &Predicate : Predicates) {
OS.indent(Indentation) << "case " << Index++ << ":\n";
OS.indent(Indentation+2) << "return "
-#ifdef CAPSTONE
- << "getbool"
-#endif
- << "(" << Predicate << ");\n";
+ << Predicate << ";\n";
}
OS.indent(Indentation) << "}\n";
} else {
// No case statement to emit
OS.indent(Indentation)
#ifdef CAPSTONE
- << "assert(0);\n"
-#endif
+ << "assert(0 && \"Invalid index!\");\n";
+#else
<< "llvm_unreachable(\"Invalid index!\");\n";
+#endif
}
Indentation -= 2;
OS.indent(Indentation) << "}\n\n";
@@ -998,10 +990,11 @@ emitDecoderFunction(formatted_raw_ostream &OS, DecoderSet &Decoders,
// input decoder index.
#ifdef CAPSTONE
#define EDF_EOL " \\\n"
- OS.indent(Indentation) << "#define DecodeToMCInst(fname,fieldname, InsnType) \\\n";
- OS.indent(Indentation) << "static DecodeStatus fname(DecodeStatus S, unsigned Idx, InsnType insn, MCInst *MI, \\\n";
- OS.indent(Indentation) << " uint64_t Address, const void *Decoder) \\\n";
- OS.indent(Indentation) << "{ \\\n";
+ OS.indent(Indentation) << "#define DecodeToMCInst(fname, fieldname, InsnType) \\\n";
+ OS.indent(Indentation) << "static DecodeStatus fname(DecodeStatus S, unsigned Idx,"
+ << " InsnType insn, MCInst *MI, \\\n";
+ OS.indent(Indentation) << " uint64_t Address, const void *Decoder,\\\n";
+ OS.indent(Indentation) << " bool *DecodeComplete) {\\\n";
#else
#define EDF_EOL "\n"
OS.indent(Indentation) << "template<typename InsnType>\n";
@@ -1011,16 +1004,18 @@ emitDecoderFunction(formatted_raw_ostream &OS, DecoderSet &Decoders,
<< "Address, const void *Decoder, bool &DecodeComplete) {\n";
#endif
Indentation += 2;
-#ifndef CAPSTONE
+#ifdef CAPSTONE
+ OS.indent(Indentation) << "*DecodeComplete = true;\\\n";
+#else
OS.indent(Indentation) << "DecodeComplete = true;\n";
#endif
OS.indent(Indentation) << "InsnType tmp;" EDF_EOL;
OS.indent(Indentation) << "switch (Idx) {" EDF_EOL;
OS.indent(Indentation) << "default:"
-#ifndef CAPSTONE
- << " llvm_unreachable(\"Invalid index!\");\n";
+#ifdef CAPSTONE
+ << " assert(0 && \"Invalid index!\");\\\n";
#else
- << " assert(0);\\\n";
+ << " llvm_unreachable(\"Invalid index!\");\n";
#endif
unsigned Index = 0;
for (const auto &Decoder : Decoders) {
@@ -1174,8 +1169,27 @@ void FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation,
if (Decoder != "") {
OpHasCompleteDecoder = OpInfo.HasCompleteDecoder;
+#ifdef CAPSTONE
+ std::string::size_type posOfLeftAngle = 0, posOfRightAngle = 0;
+ posOfLeftAngle = Decoder.find("<");
+ posOfRightAngle = Decoder.find(">");
+ std::string printDecoder = Decoder;
+ if (posOfLeftAngle != std::string::npos &&
+ posOfRightAngle != std::string::npos) {
+ printDecoder = Decoder.substr(0, posOfLeftAngle);
+ o.indent(Indentation) << Emitter->GuardPrefix
+ << printDecoder
+ << "(MI, tmp, Address, Decoder, "
+ << Decoder.substr(posOfLeftAngle+1, posOfRightAngle-posOfLeftAngle-1);
+ } else
+ o.indent(Indentation) << Emitter->GuardPrefix << Decoder
+ << "(MI, tmp, Address, Decoder";
+ // trick.
+ o << ")"
+#else
o.indent(Indentation) << Emitter->GuardPrefix << Decoder
<< "(MI, tmp, Address, Decoder)"
+#endif
<< Emitter->GuardPostfix
#ifdef CAPSTONE
<< " return MCDisassembler_Fail; \\\n";
@@ -1246,7 +1260,7 @@ static void emitSinglePredicateMatch(raw_ostream &o, StringRef str,
const std::string &PredicateNamespace) {
if (str[0] == '!')
#ifdef CAPSTONE
- o << "~(Bits & " << PredicateNamespace << "_"
+ o << "!(Bits & " << PredicateNamespace << "_"
<< str.slice(1,str.size()) << ")";
#else
o << "!Bits[" << PredicateNamespace << "::"
@@ -2331,15 +2345,13 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) {
#endif
#ifdef CAPSTONE
- OS << "static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], "
-
+ OS << "#define DecodeInstruction(fname, fieldname, decoder, InsnType) \\\n"
+ << "static DecodeStatus fname(const uint8_t DecodeTable[], "
"MCInst *MI,\\\n"
- << " InsnType insn, uint64_t "
+ << " InsnType insn, uint64_t "
"Address,\\\n"
- << " const void *DisAsm,\\\n"
- << " int feature) {\\\n"
- << " uint64_t Bits = getFeatureBits(feature); \\\n"
- //<< " const FeatureBitset& Bits = STI.getFeatureBits();\n"
+ << " const void *DisAsm, int feature) {\\\n"
+ << " uint64_t Bits = getFeatureBits(feature);\\\n"
<< "\\\n"
<< " const uint8_t *Ptr = DecodeTable;\\\n"
<< " uint32_t CurFieldValue = 0;\\\n"
@@ -2353,52 +2365,42 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) {
<< " unsigned Start = *++Ptr;\\\n"
<< " unsigned Len = *++Ptr;\\\n"
<< " ++Ptr;\\\n"
- << " CurFieldValue = fieldFromInstruction(insn, Start, Len);\\\n"
+ << " CurFieldValue = fieldname(insn, Start, Len);\\\n"
<< " break;\\\n"
<< " }\\\n"
<< " case MCD_OPC_FilterValue: {\\\n"
- << " // Decode the field value.\\\n"
<< " unsigned Len;\\\n"
<< " InsnType Val = decodeULEB128(++Ptr, &Len);\\\n"
<< " Ptr += Len;\\\n"
- << " // NumToSkip is a plain 24-bit integer.\\\n"
<< " unsigned NumToSkip = *Ptr++;\\\n"
<< " NumToSkip |= (*Ptr++) << 8;\\\n"
<< " NumToSkip |= (*Ptr++) << 16;\\\n"
<< "\\\n"
- << " // Perform the filter operation.\\\n"
<< " if (Val != CurFieldValue)\\\n"
<< " Ptr += NumToSkip;\\\n"
- << "\\\n"
<< " break;\\\n"
<< " }\\\n"
<< " case MCD_OPC_CheckField: {\\\n"
<< " unsigned Start = *++Ptr;\\\n"
<< " unsigned Len = *++Ptr;\\\n"
- << " InsnType FieldValue = fieldFromInstruction(insn, Start, Len);\\\n"
- << " // Decode the field value.\\\n"
+ << " InsnType FieldValue = fieldname(insn, Start, Len);\\\n"
<< " uint32_t ExpectedValue = decodeULEB128(++Ptr, &Len);\\\n"
<< " Ptr += Len;\\\n"
- << " // NumToSkip is a plain 24-bit integer.\\\n"
<< " unsigned NumToSkip = *Ptr++;\\\n"
<< " NumToSkip |= (*Ptr++) << 8;\\\n"
<< " NumToSkip |= (*Ptr++) << 16;\\\n"
<< "\\\n"
- << " // If the actual and expected values don't match, skip.\\\n"
<< " if (ExpectedValue != FieldValue)\\\n"
<< " Ptr += NumToSkip;\\\n"
<< " break;\\\n"
<< " }\\\n"
<< " case MCD_OPC_CheckPredicate: {\\\n"
<< " unsigned Len;\\\n"
- << " // Decode the Predicate Index value.\\\n"
<< " unsigned PIdx = decodeULEB128(++Ptr, &Len);\\\n"
<< " Ptr += Len;\\\n"
- << " // NumToSkip is a plain 24-bit integer.\\\n"
<< " unsigned NumToSkip = *Ptr++;\\\n"
<< " NumToSkip |= (*Ptr++) << 8;\\\n"
<< " NumToSkip |= (*Ptr++) << 16;\\\n"
- << " // Check the predicate.\\\n"
<< " bool Pred;\\\n"
<< " if (!(Pred = checkDecoderPredicate(PIdx, Bits)))\\\n"
<< " Ptr += NumToSkip;\\\n"
@@ -2407,7 +2409,6 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) {
<< " }\\\n"
<< " case MCD_OPC_Decode: {\\\n"
<< " unsigned Len;\\\n"
- << " // Decode the Opcode value.\\\n"
<< " unsigned Opc = decodeULEB128(++Ptr, &Len);\\\n"
<< " Ptr += Len;\\\n"
<< " unsigned DecodeIdx = decodeULEB128(Ptr, &Len);\\\n"
@@ -2416,47 +2417,39 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) {
<< " MCInst_clear(MI);\\\n"
<< " MCInst_setOpcode(MI, Opc);\\\n"
<< " bool DecodeComplete;\\\n"
- << " S = decodeToMCInst(S, DecodeIdx, insn, MI, Address, DisAsm, "
- "DecodeComplete);\\\n"
+ << " S = decoder(S, DecodeIdx, insn, MI, Address, DisAsm, "
+ "&DecodeComplete);\\\n"
<< " assert(DecodeComplete);\\\n"
<< "\\\n"
<< " return S;\\\n"
<< " }\\\n"
<< " case MCD_OPC_TryDecode: {\\\n"
<< " unsigned Len;\\\n"
- << " // Decode the Opcode value.\\\n"
<< " unsigned Opc = decodeULEB128(++Ptr, &Len);\\\n"
<< " Ptr += Len;\\\n"
<< " unsigned DecodeIdx = decodeULEB128(Ptr, &Len);\\\n"
<< " Ptr += Len;\\\n"
- << " // NumToSkip is a plain 24-bit integer.\\\n"
<< " unsigned NumToSkip = *Ptr++;\\\n"
<< " NumToSkip |= (*Ptr++) << 8;\\\n"
<< " NumToSkip |= (*Ptr++) << 16;\\\n"
<< "\\\n"
- << " // Perform the decode operation.\\\n"
<< " MCInst TmpMI;\\\n"
<< " MCInst_setOpcode(&TmpMI, Opc);\\\n"
- << " bool DecodeComplete;\n"
- << " S = decodeToMCInst(S, DecodeIdx, insn, &TmpMI, Address, DisAsm, "
- "DecodeComplete);\\\n"
+ << " bool DecodeComplete;\\\n"
+ << " S = decoder(S, DecodeIdx, insn, &TmpMI, Address, DisAsm, "
+ "&DecodeComplete);\\\n"
+ << "\\\n"
<< " if (DecodeComplete) {\\\n"
- << " // Decoding complete.\\\n"
- << " MI = &TmpMI;\\\n"
+ << " *MI = TmpMI;\\\n"
<< " return S;\\\n"
<< " } else {\\\n"
<< " assert(S == MCDisassembler_Fail);\\\n"
- << " // If the decoding was incomplete, skip.\\\n"
<< " Ptr += NumToSkip;\\\n"
- << " // Reset decode status. This also drops a SoftFail status "
- "that could be\\\n"
- << " // set before the decode attempt.\\\n"
<< " S = MCDisassembler_Success;\\\n"
<< " }\\\n"
<< " break;\\\n"
<< " }\\\n"
<< " case MCD_OPC_SoftFail: {\\\n"
- << " // Decode the mask values.\\\n"
<< " unsigned Len;\\\n"
<< " InsnType PositiveMask = decodeULEB128(++Ptr, &Len);\\\n"
<< " Ptr += Len;\\\n"
@@ -2472,8 +2465,8 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) {
<< " }\\\n"
<< " }\\\n"
<< " }\\\n"
- << " assert(0);\\\n"
-
+ << " assert(0 && \"bogosity detected in disassembler state "
+ "machine!\");\\\n"
#else
OS << "template<typename InsnType>\n"
<< "static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], "
@@ -2752,9 +2745,10 @@ void FixedLenDecoderEmitter::run(raw_ostream &o) {
emitDecodeInstruction(OS);
#ifdef CAPSTONE
- OS << "FieldFromInstruction(fieldFromInstruction, uint64_t)\n";
- OS << "DecodeToMCInst(decodeToMCInst, fieldFromInstruction, uint64_t)\n";
- OS << "DecodeInstruction(decodeInstruction, fieldFromInstruction, decodeToMCInst, uint64_t)\n";
+ OS << "// For RISCV instruction is 32 bits.\n";
+ OS << "FieldFromInstruction(fieldFromInstruction, uint32_t)\n";
+ OS << "DecodeToMCInst(decodeToMCInst, fieldFromInstruction, uint32_t)\n";
+ OS << "DecodeInstruction(decodeInstruction, fieldFromInstruction, decodeToMCInst, uint32_t)\n";
#else
OS << "\n} // End llvm namespace\n";
#endif
diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp
index 01605184f..e59dace24 100644
--- a/llvm/utils/TableGen/InstrInfoEmitter.cpp
+++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp
@@ -769,6 +769,7 @@ void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) {
#ifdef CAPSTONE
std::string GetPublicName(const CodeGenInstruction *Inst) {
std::string Name = Inst->TheDef->getName();
+#if 0
// Apply backward compatibility fixups.
// BRNLE -> BNLER.
if (Name.length() >= 5 && Name.substr(0, 5) == "BRAsm") {
@@ -785,7 +786,7 @@ std::string GetPublicName(const CodeGenInstruction *Inst) {
break;
}
Name = Name.substr(0, pos) + Name.substr(pos + 3);
- }
+ }f 0
// CPSDRxx -> CPSDR.
if (Name.length() >= 2) {
std::string Suffix2 = Name.substr(Name.length() - 2, 2);
@@ -794,7 +795,8 @@ std::string GetPublicName(const CodeGenInstruction *Inst) {
Name = Name.substr(0, Name.length() - 2);
}
}
- return "SYSZ_INS_" + Name;
+#endif
+ return "RISCV_INS_" + Name;
}
std::string GetRegisterName(Record *Reg) {
@@ -802,6 +804,7 @@ std::string GetRegisterName(Record *Reg) {
for (char& c : Name) {
c = toupper(c);
}
+#if 0
// R0L, R0D -> R0.
if (Name.length() >= 3 &&
Name[Name.length() - 3] == 'R' &&
@@ -809,7 +812,8 @@ std::string GetRegisterName(Record *Reg) {
Name[Name.length() - 1] == 'D')) {
Name = Name.substr(0, Name.length() - 3) + Name[Name.length() - 2];
}
- return "SYSZ_REG_" + Name;
+#endif
+ return "RISCV_REG_" + Name;
}
std::string GetGroupName(Record *Pred) {
@@ -817,10 +821,12 @@ std::string GetGroupName(Record *Pred) {
for (char& c : Name) {
c = toupper(c);
}
+#if 0
if (Name.length() >= 7 && Name.substr(0, 7) == "FEATURE") {
Name = Name.substr(7);
}
- return "SYSZ_GRP_" + Name;
+#endif
+ return "RISCV_GRP_" + Name;
}
void EmitMappingInsn(RecordKeeper &RK, raw_ostream &OS) {
diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
index 0df306680..cf9c352d7 100644
--- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
@@ -180,12 +180,20 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS,
#endif
}
-#ifndef CAPSTONE
const std::vector<Record*> &RegAltNameIndices = Target.getRegAltNameIndices();
// If the only definition is the default NoRegAltName, we don't need to
// emit anything.
if (RegAltNameIndices.size() > 1) {
OS << "\n// Register alternate name indices\n\n";
+#ifdef CAPSTONE
+ OS << "enum {\n";
+ for (unsigned i = 0, e = RegAltNameIndices.size(); i != e; ++i)
+ OS << " " << NAME_PREFIX RegAltNameIndices[i]->getName()
+ << ",\t// " << i << "\n";
+ OS << " " << NAME_PREFIX "NUM_TARGET_REG_ALT_NAMES = "
+ << RegAltNameIndices.size() << "\n";
+ OS << "};\n";
+#else
if (!Namespace.empty())
OS << "namespace " << Namespace << " {\n";
OS << "enum {\n";
@@ -195,11 +203,19 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS,
OS << "};\n";
if (!Namespace.empty())
OS << "} // end namespace " << Namespace << "\n\n";
+#endif
}
auto &SubRegIndices = Bank.getSubRegIndices();
if (!SubRegIndices.empty()) {
OS << "\n// Subregister indices\n\n";
+#ifdef CAPSTONE
+ OS << "enum {\n" << " " << NAME_PREFIX "NoSubRegister,\n";
+ unsigned i = 0;
+ for (const auto &Idx : SubRegIndices)
+ OS << " " << NAME_PREFIX Idx.getName() << ",\t// " << ++i << "\n";
+ OS << " " << NAME_PREFIX "NUM_TARGET_SUBREGS\n};\n";
+#else
std::string Namespace = SubRegIndices.front().getNamespace();
if (!Namespace.empty())
OS << "namespace " << Namespace << " {\n";
@@ -210,8 +226,8 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS,
OS << " NUM_TARGET_SUBREGS\n};\n";
if (!Namespace.empty())
OS << "} // end namespace " << Namespace << "\n\n";
- }
#endif
+ }
#ifndef CAPSTONE
OS << "} // end namespace llvm\n\n";
diff --git a/llvm/utils/TableGen/TableGen.cpp b/llvm/utils/TableGen/TableGen.cpp
index 9e2a868be..7ec93c0e0 100644
--- a/llvm/utils/TableGen/TableGen.cpp
+++ b/llvm/utils/TableGen/TableGen.cpp
@@ -27,8 +27,10 @@ enum ActionType {
GenEmitter,
GenRegisterInfo,
GenInstrInfo,
+#ifdef CAPSTONE
GenMappingInsn,
GenInsnNameMaps,
+#endif
GenInstrDocs,
GenAsmWriter,
GenAsmMatcher,
@@ -76,10 +78,12 @@ namespace {
"Generate registers and register classes info"),
clEnumValN(GenInstrInfo, "gen-instr-info",
"Generate instruction descriptions"),
+#ifdef CAPSTONE
clEnumValN(GenMappingInsn, "gen-mapping-insn",
""),
clEnumValN(GenInsnNameMaps, "gen-insn-name-maps",
""),
+#endif
clEnumValN(GenInstrDocs, "gen-instr-docs",
"Generate instruction documentation"),
clEnumValN(GenCallingConv, "gen-callingconv",
@@ -160,12 +164,14 @@ bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
case GenInstrInfo:
EmitInstrInfo(Records, OS);
break;
+#ifdef CAPSTONE
case GenMappingInsn:
EmitMappingInsn(Records, OS);
break;
case GenInsnNameMaps:
EmitInsnNameMaps(Records, OS);
break;
+#endif
case GenInstrDocs:
EmitInstrDocs(Records, OS);
break;
--
2.20.1