diff options
-rw-r--r-- | include/llvm/CodeGen/AsmPrinter.h | 2 | ||||
-rw-r--r-- | include/llvm/MC/MCInstrDesc.h | 19 | ||||
-rw-r--r-- | include/llvm/Support/TargetRegistry.h | 13 | ||||
-rw-r--r-- | include/llvm/Target/Target.td | 11 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp | 2 | ||||
-rw-r--r-- | lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp | 5 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 5 | ||||
-rw-r--r-- | lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 35 | ||||
-rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp | 18 | ||||
-rw-r--r-- | lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 10 | ||||
-rw-r--r-- | lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp | 5 | ||||
-rw-r--r-- | lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp | 5 | ||||
-rw-r--r-- | lib/Target/X86/AsmParser/X86AsmParser.cpp | 5 | ||||
-rw-r--r-- | test/MC/ARM/deprecated-v8.s | 2 | ||||
-rw-r--r-- | tools/llvm-mc/llvm-mc.cpp | 6 | ||||
-rw-r--r-- | utils/TableGen/AsmMatcherEmitter.cpp | 20 | ||||
-rw-r--r-- | utils/TableGen/CodeGenInstruction.cpp | 14 | ||||
-rw-r--r-- | utils/TableGen/CodeGenInstruction.h | 3 | ||||
-rw-r--r-- | utils/TableGen/InstrInfoEmitter.cpp | 13 |
20 files changed, 144 insertions, 51 deletions
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index 59d14ccbd5..5462212a78 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -41,6 +41,7 @@ namespace llvm { class MCAsmInfo; class MCCFIInstruction; class MCContext; + class MCInstrInfo; class MCSection; class MCStreamer; class MCSymbol; @@ -64,6 +65,7 @@ namespace llvm { /// const MCAsmInfo *MAI; + const MCInstrInfo *MII; /// OutContext - This is the context for the output file that we are /// streaming. This owns all of the global MC-related objects for the /// generated translation unit. diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h index 310f706877..84d6380476 100644 --- a/include/llvm/MC/MCInstrDesc.h +++ b/include/llvm/MC/MCInstrDesc.h @@ -17,6 +17,7 @@ #include "llvm/MC/MCInst.h" #include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Support/DataTypes.h" namespace llvm { @@ -145,6 +146,10 @@ public: const uint16_t *ImplicitUses; // Registers implicitly read by this instr const uint16_t *ImplicitDefs; // Registers implicitly defined by this instr const MCOperandInfo *OpInfo; // 'NumOperands' entries about operands + uint64_t DeprecatedFeatureMask;// Feature bits that this is deprecated on, if any + // A complex method to determine is a certain is deprecated or not, and return + // the reason for deprecation. + bool (*ComplexDeprecationInfo)(MCInst &, MCSubtargetInfo &, std::string &); /// \brief Returns the value of the specific constraint if /// it is set. Returns -1 if it is not set. @@ -158,6 +163,20 @@ public: return -1; } + /// \brief Returns true if a certain instruction is deprecated and if so + /// returns the reason in \p Info. + bool getDeprecatedInfo(MCInst &MI, MCSubtargetInfo &STI, + std::string &Info) const { + if (ComplexDeprecationInfo) + return ComplexDeprecationInfo(MI, STI, Info); + if (DeprecatedFeatureMask != 0) { + // FIXME: it would be nice to include the subtarget feature here. + Info = "deprecated"; + return true; + } + return false; + } + /// \brief Return the opcode number for this descriptor. unsigned getOpcode() const { return Opcode; diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h index 9282853b88..05f7cf2f6f 100644 --- a/include/llvm/Support/TargetRegistry.h +++ b/include/llvm/Support/TargetRegistry.h @@ -108,7 +108,8 @@ namespace llvm { StringRef TT, StringRef CPU); typedef MCTargetAsmParser *(*MCAsmParserCtorTy)(MCSubtargetInfo &STI, - MCAsmParser &P); + MCAsmParser &P, + const MCInstrInfo &MII); typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T, const MCSubtargetInfo &STI); typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T, @@ -386,10 +387,11 @@ namespace llvm { /// \param Parser The target independent parser implementation to use for /// parsing and lexing. MCTargetAsmParser *createMCAsmParser(MCSubtargetInfo &STI, - MCAsmParser &Parser) const { + MCAsmParser &Parser, + const MCInstrInfo &MII) const { if (!MCAsmParserCtorFn) return 0; - return MCAsmParserCtorFn(STI, Parser); + return MCAsmParserCtorFn(STI, Parser, MII); } /// createAsmPrinter - Create a target specific assembly printer pass. This @@ -1142,8 +1144,9 @@ namespace llvm { } private: - static MCTargetAsmParser *Allocator(MCSubtargetInfo &STI, MCAsmParser &P) { - return new MCAsmParserImpl(STI, P); + static MCTargetAsmParser *Allocator(MCSubtargetInfo &STI, MCAsmParser &P, + const MCInstrInfo &MII) { + return new MCAsmParserImpl(STI, P, MII); } }; diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index b7f369357a..c15a4abf38 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -1010,6 +1010,17 @@ class SubtargetFeature<string n, string a, string v, string d, list<SubtargetFeature> Implies = i; } +/// Specifies a Subtarget feature that this instruction is deprecated on. +class Deprecated<SubtargetFeature dep> { + SubtargetFeature DeprecatedFeatureMask = dep; +} + +/// A custom predicate used to determine if an instruction is +/// deprecated or not. +class ComplexDeprecationPredicate<string dep> { + string ComplexDeprecationPredicate = dep; +} + //===----------------------------------------------------------------------===// // Processor chip sets - These values represent each of the chip sets supported // by the scheduler. Each Processor definition requires corresponding diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index a427c269ce..a4e7808731 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -94,7 +94,7 @@ static unsigned getGVAlignmentLog2(const GlobalValue *GV, const DataLayout &TD, AsmPrinter::AsmPrinter(TargetMachine &tm, MCStreamer &Streamer) : MachineFunctionPass(ID), - TM(tm), MAI(tm.getMCAsmInfo()), + TM(tm), MAI(tm.getMCAsmInfo()), MII(tm.getInstrInfo()), OutContext(Streamer.getContext()), OutStreamer(Streamer), LastMI(0), LastFn(0), Counter(~0U), SetCounter(0) { diff --git a/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp index d8e9c95ad7..4f927f6ba8 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp @@ -123,7 +123,7 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, const MDNode *LocMDNode, TM.getTargetCPU(), TM.getTargetFeatureString())); OwningPtr<MCTargetAsmParser> - TAP(TM.getTarget().createMCAsmParser(*STI, *Parser)); + TAP(TM.getTarget().createMCAsmParser(*STI, *Parser, *MII)); if (!TAP) report_fatal_error("Inline asm not supported by this streamer because" " we don't have an asm parser for this target\n"); diff --git a/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 68d4be472c..f7e9c6fe17 100644 --- a/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -54,8 +54,9 @@ public: #include "AArch64GenAsmMatcher.inc" }; - AArch64AsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) - : MCTargetAsmParser(), STI(_STI), Parser(_Parser) { + AArch64AsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser, + const MCInstrInfo &MII) + : MCTargetAsmParser(), STI(_STI), Parser(_Parser) { MCAsmParserExtension::Initialize(_Parser); // Initialize the set of available features. diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index c9bad1cd35..b488f264fa 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -1840,7 +1840,7 @@ defm PLDW : APreLoad<0, 1, "pldw">, Requires<[IsARM,HasV7,HasMP]>; defm PLI : APreLoad<1, 0, "pli">, Requires<[IsARM,HasV7]>; def SETEND : AXI<(outs), (ins setend_op:$end), MiscFrm, NoItinerary, - "setend\t$end", []>, Requires<[IsARM]> { + "setend\t$end", []>, Requires<[IsARM]>, Deprecated<HasV8Ops> { bits<1> end; let Inst{31-10} = 0b1111000100000001000000; let Inst{9} = end; @@ -4772,7 +4772,8 @@ def MCR : MovRCopro<"mcr", 0 /* from ARM core register to coprocessor */, (ins p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2), [(int_arm_mcr imm:$cop, imm:$opc1, GPR:$Rt, imm:$CRn, - imm:$CRm, imm:$opc2)]>; + imm:$CRm, imm:$opc2)]>, + ComplexDeprecationPredicate<"MCR">; def : ARMInstAlias<"mcr${p} $cop, $opc1, $Rt, $CRn, $CRm", (MCR p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn, c_imm:$CRm, 0, pred:$p)>; diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index cfa24f9f16..032e74438a 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -24,6 +24,7 @@ #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstrDesc.h" +#include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCParser/MCAsmLexer.h" #include "llvm/MC/MCParser/MCAsmParser.h" #include "llvm/MC/MCParser/MCParsedAsmOperand.h" @@ -47,6 +48,7 @@ enum VectorLaneTy { NoLanes, AllLanes, IndexedLane }; class ARMAsmParser : public MCTargetAsmParser { MCSubtargetInfo &STI; MCAsmParser &Parser; + const MCInstrInfo &MII; const MCRegisterInfo *MRI; // Unwind directives state @@ -232,8 +234,6 @@ class ARMAsmParser : public MCTargetAsmParser { SmallVectorImpl<MCParsedAsmOperand*> &Operands); bool shouldOmitPredicateOperand(StringRef Mnemonic, SmallVectorImpl<MCParsedAsmOperand*> &Operands); - bool isDeprecated(MCInst &Inst, StringRef &Info); - public: enum ARMMatchResultTy { Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY, @@ -245,8 +245,9 @@ public: }; - ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) - : MCTargetAsmParser(), STI(_STI), Parser(_Parser), FPReg(-1) { + ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser, + const MCInstrInfo &MII) + : MCTargetAsmParser(), STI(_STI), Parser(_Parser), MII(MII), FPReg(-1) { MCAsmParserExtension::Initialize(_Parser); // Cache the MCRegisterInfo. @@ -4972,14 +4973,6 @@ bool ARMAsmParser::shouldOmitPredicateOperand( return false; } -bool ARMAsmParser::isDeprecated(MCInst &Inst, StringRef &Info) { - if (hasV8Ops() && Inst.getOpcode() == ARM::SETEND) { - Info = "armv8"; - return true; - } - return false; -} - static bool isDataTypeToken(StringRef Tok) { return Tok == ".8" || Tok == ".16" || Tok == ".32" || Tok == ".64" || Tok == ".i8" || Tok == ".i16" || Tok == ".i32" || Tok == ".i64" || @@ -5296,16 +5289,6 @@ static bool listContainsReg(MCInst &Inst, unsigned OpNo, unsigned Reg) { return false; } -// FIXME: We would really prefer to have MCInstrInfo (the wrapper around -// the ARMInsts array) instead. Getting that here requires awkward -// API changes, though. Better way? -namespace llvm { -extern const MCInstrDesc ARMInsts[]; -} -static const MCInstrDesc &getInstDesc(unsigned Opcode) { - return ARMInsts[Opcode]; -} - // Return true if instruction has the interesting property of being // allowed in IT blocks, but not being predicable. static bool instIsBreakpoint(const MCInst &Inst) { @@ -5320,7 +5303,7 @@ static bool instIsBreakpoint(const MCInst &Inst) { bool ARMAsmParser:: validateInstruction(MCInst &Inst, const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { - const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); + const MCInstrDesc &MCID = MII.get(Inst.getOpcode()); SMLoc Loc = Operands[0]->getStartLoc(); // Check the IT block state first. @@ -5513,10 +5496,6 @@ validateInstruction(MCInst &Inst, } } - StringRef DepInfo; - if (isDeprecated(Inst, DepInfo)) - Warning(Loc, "deprecated on " + DepInfo); - return false; } @@ -7553,7 +7532,7 @@ unsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) { // 16-bit thumb arithmetic instructions either require or preclude the 'S' // suffix depending on whether they're in an IT block or not. unsigned Opc = Inst.getOpcode(); - const MCInstrDesc &MCID = getInstDesc(Opc); + const MCInstrDesc &MCID = MII.get(Opc); if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) { assert(MCID.hasOptionalDef() && "optionally flag setting instruction missing optional def operand"); diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp index caa19495bb..ea5d7ba5c5 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp @@ -26,16 +26,32 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/TargetRegistry.h" +using namespace llvm; + #define GET_REGINFO_MC_DESC #include "ARMGenRegisterInfo.inc" +static bool getMCRDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI, + std::string &Info) { + // Checks for the deprecated CP15ISB encoding: + // mcr pX, #0, rX, c7, c5, #4 + if (STI.getFeatureBits() & llvm::ARM::HasV8Ops && + (MI.getOperand(1).isImm() && MI.getOperand(1).getImm() == 0) && + (MI.getOperand(3).isImm() && MI.getOperand(3).getImm() == 7) && + (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 5) && + (MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 4)) { + Info = "deprecated on armv8"; + return true; + } + return false; +} + #define GET_INSTRINFO_MC_DESC #include "ARMGenInstrInfo.inc" #define GET_SUBTARGETINFO_MC_DESC #include "ARMGenSubtargetInfo.inc" -using namespace llvm; std::string ARM_MC::ParseARMTriple(StringRef TT, StringRef CPU) { Triple triple(TT); diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index e547de5121..c4ce4ff5b3 100644 --- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -24,6 +24,10 @@ using namespace llvm; +namespace llvm { +class MCInstrInfo; +} + namespace { class MipsAssemblerOptions { public: @@ -201,8 +205,10 @@ class MipsAsmParser : public MCTargetAsmParser { bool processInstruction(MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions); public: - MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser) - : MCTargetAsmParser(), STI(sti), Parser(parser), hasConsumedDollar(false) { + MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser, + const MCInstrInfo &MII) + : MCTargetAsmParser(), STI(sti), Parser(parser), + hasConsumedDollar(false) { // Initialize the set of available features. setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); } diff --git a/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp b/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp index bfa9bb77dc..4827c8fd91 100644 --- a/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp +++ b/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp @@ -218,8 +218,9 @@ class PPCAsmParser : public MCTargetAsmParser { public: - PPCAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) - : MCTargetAsmParser(), STI(_STI), Parser(_Parser) { + PPCAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser, + const MCInstrInfo &MII) + : MCTargetAsmParser(), STI(_STI), Parser(_Parser) { // Check for 64-bit vs. 32-bit pointer mode. Triple TheTriple(STI.getTargetTriple()); IsPPC64 = (TheTriple.getArch() == Triple::ppc64 || diff --git a/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp b/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp index 58af2c4920..3551b2dfb4 100644 --- a/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp +++ b/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp @@ -327,8 +327,9 @@ private: StringRef Mnemonic); public: - SystemZAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser) - : MCTargetAsmParser(), STI(sti), Parser(parser) { + SystemZAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser, + const MCInstrInfo &MII) + : MCTargetAsmParser(), STI(sti), Parser(parser) { MCAsmParserExtension::Initialize(Parser); // Initialize the set of available features. diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index 3d56acf917..93c2169a40 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -556,8 +556,9 @@ private: /// } public: - X86AsmParser(MCSubtargetInfo &sti, MCAsmParser &parser) - : MCTargetAsmParser(), STI(sti), Parser(parser), InstInfo(0) { + X86AsmParser(MCSubtargetInfo &sti, MCAsmParser &parser, + const MCInstrInfo &MII) + : MCTargetAsmParser(), STI(sti), Parser(parser), InstInfo(0) { // Initialize the set of available features. setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); diff --git a/test/MC/ARM/deprecated-v8.s b/test/MC/ARM/deprecated-v8.s index e509a35a94..b365cd198a 100644 --- a/test/MC/ARM/deprecated-v8.s +++ b/test/MC/ARM/deprecated-v8.s @@ -1,3 +1,5 @@ @ RUN: llvm-mc -triple armv8 -show-encoding < %s 2>&1 | FileCheck %s setend be +@ CHECK: warning: deprecated +mcr p8, #0, r5, c7, c5, #4 @ CHECK: warning: deprecated on armv8 diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp index 482873748a..7ec2bba0f9 100644 --- a/tools/llvm-mc/llvm-mc.cpp +++ b/tools/llvm-mc/llvm-mc.cpp @@ -319,10 +319,10 @@ static int AsLexInput(SourceMgr &SrcMgr, MCAsmInfo &MAI, tool_output_file *Out) static int AssembleInput(const char *ProgName, const Target *TheTarget, SourceMgr &SrcMgr, MCContext &Ctx, MCStreamer &Str, - MCAsmInfo &MAI, MCSubtargetInfo &STI) { + MCAsmInfo &MAI, MCSubtargetInfo &STI, MCInstrInfo &MCII) { OwningPtr<MCAsmParser> Parser(createMCAsmParser(SrcMgr, Ctx, Str, MAI)); - OwningPtr<MCTargetAsmParser> TAP(TheTarget->createMCAsmParser(STI, *Parser)); + OwningPtr<MCTargetAsmParser> TAP(TheTarget->createMCAsmParser(STI, *Parser, MCII)); if (!TAP) { errs() << ProgName << ": error: this target does not support assembly parsing.\n"; @@ -459,7 +459,7 @@ int main(int argc, char **argv) { Res = AsLexInput(SrcMgr, *MAI, Out.get()); break; case AC_Assemble: - Res = AssembleInput(ProgName, TheTarget, SrcMgr, Ctx, *Str, *MAI, *STI); + Res = AssembleInput(ProgName, TheTarget, SrcMgr, Ctx, *Str, *MAI, *STI, *MCII); break; case AC_MDisassemble: assert(IP && "Expected assembly output"); diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index 31c17fb3d6..c82752580e 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -430,6 +430,9 @@ struct MatchableInfo { /// function. std::string ConversionFnKind; + /// If this instruction is deprecated in some form. + bool HasDeprecation; + MatchableInfo(const CodeGenInstruction &CGI) : AsmVariantID(0), TheDef(CGI.TheDef), DefRec(&CGI), AsmString(CGI.AsmString) { @@ -779,6 +782,13 @@ void MatchableInfo::initialize(const AsmMatcherInfo &Info, if (Record *Reg = AsmOperands[i].SingletonReg) SingletonRegisters.insert(Reg); } + + const RecordVal *DepMask = TheDef->getValue("DeprecatedFeatureMask"); + if (!DepMask) + DepMask = TheDef->getValue("ComplexDeprecationPredicate"); + + HasDeprecation = + DepMask ? !DepMask->getValue()->getAsUnquotedString().empty() : false; } /// tokenizeAsmString - Tokenize a simplified assembly string. @@ -2743,11 +2753,13 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { size_t MaxNumOperands = 0; unsigned MaxMnemonicIndex = 0; + bool HasDeprecation = false; for (std::vector<MatchableInfo*>::const_iterator it = Info.Matchables.begin(), ie = Info.Matchables.end(); it != ie; ++it) { MatchableInfo &II = **it; MaxNumOperands = std::max(MaxNumOperands, II.AsmOperands.size()); + HasDeprecation |= II.HasDeprecation; // Store a pascal-style length byte in the mnemonic. std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.str(); @@ -3018,6 +3030,14 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { if (!InsnCleanupFn.empty()) OS << " " << InsnCleanupFn << "(Inst);\n"; + if (HasDeprecation) { + OS << " std::string Info;\n"; + OS << " if (MII.get(Inst.getOpcode()).getDeprecatedInfo(Inst, STI, Info)) {\n"; + OS << " SMLoc Loc = ((" << Target.getName() << "Operand*)Operands[0])->getStartLoc();\n"; + OS << " Parser.Warning(Loc, Info, None);\n"; + OS << " }\n"; + } + OS << " return Match_Success;\n"; OS << " }\n\n"; diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp index bf59d3afb5..576388b2ed 100644 --- a/utils/TableGen/CodeGenInstruction.cpp +++ b/utils/TableGen/CodeGenInstruction.cpp @@ -337,6 +337,20 @@ CodeGenInstruction::CodeGenInstruction(Record *R) // Parse the DisableEncoding field. Operands.ProcessDisableEncoding(R->getValueAsString("DisableEncoding")); + + // First check for a ComplexDeprecationPredicate. + if (R->getValue("ComplexDeprecationPredicate")) { + HasComplexDeprecationPredicate = true; + DeprecatedReason = R->getValueAsString("ComplexDeprecationPredicate"); + } else if (RecordVal *Dep = R->getValue("DeprecatedFeatureMask")) { + // Check if we have a Subtarget feature mask. + HasComplexDeprecationPredicate = false; + DeprecatedReason = Dep->getValue()->getAsString(); + } else { + // This instruction isn't deprecated. + HasComplexDeprecationPredicate = false; + DeprecatedReason = ""; + } } /// HasOneImplicitDefWithKnownVT - If the instruction has at least one diff --git a/utils/TableGen/CodeGenInstruction.h b/utils/TableGen/CodeGenInstruction.h index d1e1153554..6004f66792 100644 --- a/utils/TableGen/CodeGenInstruction.h +++ b/utils/TableGen/CodeGenInstruction.h @@ -248,6 +248,9 @@ namespace llvm { bool isCodeGenOnly; bool isPseudo; + std::string DeprecatedReason; + bool HasComplexDeprecationPredicate; + /// Are there any undefined flags? bool hasUndefFlags() const { return mayLoad_Unset || mayStore_Unset || hasSideEffects_Unset; diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp index 84bd4dee3a..af26353d01 100644 --- a/utils/TableGen/InstrInfoEmitter.cpp +++ b/utils/TableGen/InstrInfoEmitter.cpp @@ -514,6 +514,19 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, else OS << "OperandInfo" << OpInfo.find(OperandInfo)->second; + CodeGenTarget &Target = CDP.getTargetInfo(); + if (Inst.HasComplexDeprecationPredicate) + // Emit a function pointer to the complex predicate method. + OS << ",0" + << ",&get" << Inst.DeprecatedReason << "DeprecationInfo"; + else if (!Inst.DeprecatedReason.empty()) + // Emit the Subtarget feature. + OS << "," << Target.getInstNamespace() << "::" << Inst.DeprecatedReason + << ",0"; + else + // Instruction isn't deprecated. + OS << ",0,0"; + OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n"; } |