XenonRecomp/thirdparty/capstone/contrib/riscv_update/0002-update-TableGen-for-generate-RISCV-port-inc-for-CAPS.patch
2024-09-07 18:15:29 +06: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