From 40ac7444e7f3679fad852564acca4f30f47fb52d Mon Sep 17 00:00:00 2001 From: fanfuqiang 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 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\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\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 &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