1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

Add an instruction deprecation feature to TableGen.

The 'Deprecated' class allows you to specify a SubtargetFeature that the
instruction is deprecated on.

The 'ComplexDeprecationPredicate' class allows you to define a custom
predicate that is called to check for deprecation.
For example:
  ComplexDeprecationPredicate<"MCR">

would mean you would have to define the following function:
  bool getMCRDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI,
                             std::string &Info)

Which returns 'false' for not deprecated, and 'true' for deprecated
and store the warning message in 'Info'.

The MCTargetAsmParser constructor was chaned to take an extra argument of
the MCInstrInfo class, so out-of-tree targets will need to be changed.

llvm-svn: 190598
This commit is contained in:
Joey Gouly 2013-09-12 10:28:05 +00:00
parent 139f25ed2c
commit fccb3bcae3
20 changed files with 144 additions and 51 deletions

View File

@ -41,6 +41,7 @@ namespace llvm {
class MCAsmInfo; class MCAsmInfo;
class MCCFIInstruction; class MCCFIInstruction;
class MCContext; class MCContext;
class MCInstrInfo;
class MCSection; class MCSection;
class MCStreamer; class MCStreamer;
class MCSymbol; class MCSymbol;
@ -64,6 +65,7 @@ namespace llvm {
/// ///
const MCAsmInfo *MAI; const MCAsmInfo *MAI;
const MCInstrInfo *MII;
/// OutContext - This is the context for the output file that we are /// OutContext - This is the context for the output file that we are
/// streaming. This owns all of the global MC-related objects for the /// streaming. This owns all of the global MC-related objects for the
/// generated translation unit. /// generated translation unit.

View File

@ -17,6 +17,7 @@
#include "llvm/MC/MCInst.h" #include "llvm/MC/MCInst.h"
#include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/DataTypes.h" #include "llvm/Support/DataTypes.h"
namespace llvm { namespace llvm {
@ -145,6 +146,10 @@ public:
const uint16_t *ImplicitUses; // Registers implicitly read by this instr const uint16_t *ImplicitUses; // Registers implicitly read by this instr
const uint16_t *ImplicitDefs; // Registers implicitly defined by this instr const uint16_t *ImplicitDefs; // Registers implicitly defined by this instr
const MCOperandInfo *OpInfo; // 'NumOperands' entries about operands 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 /// \brief Returns the value of the specific constraint if
/// it is set. Returns -1 if it is not set. /// it is set. Returns -1 if it is not set.
@ -158,6 +163,20 @@ public:
return -1; 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. /// \brief Return the opcode number for this descriptor.
unsigned getOpcode() const { unsigned getOpcode() const {
return Opcode; return Opcode;

View File

@ -108,7 +108,8 @@ namespace llvm {
StringRef TT, StringRef TT,
StringRef CPU); StringRef CPU);
typedef MCTargetAsmParser *(*MCAsmParserCtorTy)(MCSubtargetInfo &STI, typedef MCTargetAsmParser *(*MCAsmParserCtorTy)(MCSubtargetInfo &STI,
MCAsmParser &P); MCAsmParser &P,
const MCInstrInfo &MII);
typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T, typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T,
const MCSubtargetInfo &STI); const MCSubtargetInfo &STI);
typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T, typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T,
@ -386,10 +387,11 @@ namespace llvm {
/// \param Parser The target independent parser implementation to use for /// \param Parser The target independent parser implementation to use for
/// parsing and lexing. /// parsing and lexing.
MCTargetAsmParser *createMCAsmParser(MCSubtargetInfo &STI, MCTargetAsmParser *createMCAsmParser(MCSubtargetInfo &STI,
MCAsmParser &Parser) const { MCAsmParser &Parser,
const MCInstrInfo &MII) const {
if (!MCAsmParserCtorFn) if (!MCAsmParserCtorFn)
return 0; return 0;
return MCAsmParserCtorFn(STI, Parser); return MCAsmParserCtorFn(STI, Parser, MII);
} }
/// createAsmPrinter - Create a target specific assembly printer pass. This /// createAsmPrinter - Create a target specific assembly printer pass. This
@ -1142,8 +1144,9 @@ namespace llvm {
} }
private: private:
static MCTargetAsmParser *Allocator(MCSubtargetInfo &STI, MCAsmParser &P) { static MCTargetAsmParser *Allocator(MCSubtargetInfo &STI, MCAsmParser &P,
return new MCAsmParserImpl(STI, P); const MCInstrInfo &MII) {
return new MCAsmParserImpl(STI, P, MII);
} }
}; };

View File

@ -1010,6 +1010,17 @@ class SubtargetFeature<string n, string a, string v, string d,
list<SubtargetFeature> Implies = i; 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 // Processor chip sets - These values represent each of the chip sets supported
// by the scheduler. Each Processor definition requires corresponding // by the scheduler. Each Processor definition requires corresponding

View File

@ -94,7 +94,7 @@ static unsigned getGVAlignmentLog2(const GlobalValue *GV, const DataLayout &TD,
AsmPrinter::AsmPrinter(TargetMachine &tm, MCStreamer &Streamer) AsmPrinter::AsmPrinter(TargetMachine &tm, MCStreamer &Streamer)
: MachineFunctionPass(ID), : MachineFunctionPass(ID),
TM(tm), MAI(tm.getMCAsmInfo()), TM(tm), MAI(tm.getMCAsmInfo()), MII(tm.getInstrInfo()),
OutContext(Streamer.getContext()), OutContext(Streamer.getContext()),
OutStreamer(Streamer), OutStreamer(Streamer),
LastMI(0), LastFn(0), Counter(~0U), SetCounter(0) { LastMI(0), LastFn(0), Counter(~0U), SetCounter(0) {

View File

@ -123,7 +123,7 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, const MDNode *LocMDNode,
TM.getTargetCPU(), TM.getTargetCPU(),
TM.getTargetFeatureString())); TM.getTargetFeatureString()));
OwningPtr<MCTargetAsmParser> OwningPtr<MCTargetAsmParser>
TAP(TM.getTarget().createMCAsmParser(*STI, *Parser)); TAP(TM.getTarget().createMCAsmParser(*STI, *Parser, *MII));
if (!TAP) if (!TAP)
report_fatal_error("Inline asm not supported by this streamer because" report_fatal_error("Inline asm not supported by this streamer because"
" we don't have an asm parser for this target\n"); " we don't have an asm parser for this target\n");

View File

@ -54,8 +54,9 @@ public:
#include "AArch64GenAsmMatcher.inc" #include "AArch64GenAsmMatcher.inc"
}; };
AArch64AsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) AArch64AsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser,
: MCTargetAsmParser(), STI(_STI), Parser(_Parser) { const MCInstrInfo &MII)
: MCTargetAsmParser(), STI(_STI), Parser(_Parser) {
MCAsmParserExtension::Initialize(_Parser); MCAsmParserExtension::Initialize(_Parser);
// Initialize the set of available features. // Initialize the set of available features.

View File

@ -1840,7 +1840,7 @@ defm PLDW : APreLoad<0, 1, "pldw">, Requires<[IsARM,HasV7,HasMP]>;
defm PLI : APreLoad<1, 0, "pli">, Requires<[IsARM,HasV7]>; defm PLI : APreLoad<1, 0, "pli">, Requires<[IsARM,HasV7]>;
def SETEND : AXI<(outs), (ins setend_op:$end), MiscFrm, NoItinerary, 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; bits<1> end;
let Inst{31-10} = 0b1111000100000001000000; let Inst{31-10} = 0b1111000100000001000000;
let Inst{9} = end; 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, (ins p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn,
c_imm:$CRm, imm0_7:$opc2), c_imm:$CRm, imm0_7:$opc2),
[(int_arm_mcr imm:$cop, imm:$opc1, GPR:$Rt, imm:$CRn, [(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", def : ARMInstAlias<"mcr${p} $cop, $opc1, $Rt, $CRn, $CRm",
(MCR p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn, (MCR p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn,
c_imm:$CRm, 0, pred:$p)>; c_imm:$CRm, 0, pred:$p)>;

View File

@ -24,6 +24,7 @@
#include "llvm/MC/MCExpr.h" #include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h" #include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrDesc.h" #include "llvm/MC/MCInstrDesc.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCParser/MCAsmLexer.h" #include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCAsmParser.h" #include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h" #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
@ -47,6 +48,7 @@ enum VectorLaneTy { NoLanes, AllLanes, IndexedLane };
class ARMAsmParser : public MCTargetAsmParser { class ARMAsmParser : public MCTargetAsmParser {
MCSubtargetInfo &STI; MCSubtargetInfo &STI;
MCAsmParser &Parser; MCAsmParser &Parser;
const MCInstrInfo &MII;
const MCRegisterInfo *MRI; const MCRegisterInfo *MRI;
// Unwind directives state // Unwind directives state
@ -232,8 +234,6 @@ class ARMAsmParser : public MCTargetAsmParser {
SmallVectorImpl<MCParsedAsmOperand*> &Operands); SmallVectorImpl<MCParsedAsmOperand*> &Operands);
bool shouldOmitPredicateOperand(StringRef Mnemonic, bool shouldOmitPredicateOperand(StringRef Mnemonic,
SmallVectorImpl<MCParsedAsmOperand*> &Operands); SmallVectorImpl<MCParsedAsmOperand*> &Operands);
bool isDeprecated(MCInst &Inst, StringRef &Info);
public: public:
enum ARMMatchResultTy { enum ARMMatchResultTy {
Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY, Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY,
@ -245,8 +245,9 @@ public:
}; };
ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser,
: MCTargetAsmParser(), STI(_STI), Parser(_Parser), FPReg(-1) { const MCInstrInfo &MII)
: MCTargetAsmParser(), STI(_STI), Parser(_Parser), MII(MII), FPReg(-1) {
MCAsmParserExtension::Initialize(_Parser); MCAsmParserExtension::Initialize(_Parser);
// Cache the MCRegisterInfo. // Cache the MCRegisterInfo.
@ -4972,14 +4973,6 @@ bool ARMAsmParser::shouldOmitPredicateOperand(
return false; 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) { static bool isDataTypeToken(StringRef Tok) {
return Tok == ".8" || Tok == ".16" || Tok == ".32" || Tok == ".64" || return Tok == ".8" || Tok == ".16" || Tok == ".32" || Tok == ".64" ||
Tok == ".i8" || Tok == ".i16" || Tok == ".i32" || Tok == ".i64" || Tok == ".i8" || Tok == ".i16" || Tok == ".i32" || Tok == ".i64" ||
@ -5296,16 +5289,6 @@ static bool listContainsReg(MCInst &Inst, unsigned OpNo, unsigned Reg) {
return false; 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 // Return true if instruction has the interesting property of being
// allowed in IT blocks, but not being predicable. // allowed in IT blocks, but not being predicable.
static bool instIsBreakpoint(const MCInst &Inst) { static bool instIsBreakpoint(const MCInst &Inst) {
@ -5320,7 +5303,7 @@ static bool instIsBreakpoint(const MCInst &Inst) {
bool ARMAsmParser:: bool ARMAsmParser::
validateInstruction(MCInst &Inst, validateInstruction(MCInst &Inst,
const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
SMLoc Loc = Operands[0]->getStartLoc(); SMLoc Loc = Operands[0]->getStartLoc();
// Check the IT block state first. // 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; return false;
} }
@ -7553,7 +7532,7 @@ unsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
// 16-bit thumb arithmetic instructions either require or preclude the 'S' // 16-bit thumb arithmetic instructions either require or preclude the 'S'
// suffix depending on whether they're in an IT block or not. // suffix depending on whether they're in an IT block or not.
unsigned Opc = Inst.getOpcode(); unsigned Opc = Inst.getOpcode();
const MCInstrDesc &MCID = getInstDesc(Opc); const MCInstrDesc &MCID = MII.get(Opc);
if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) { if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) {
assert(MCID.hasOptionalDef() && assert(MCID.hasOptionalDef() &&
"optionally flag setting instruction missing optional def operand"); "optionally flag setting instruction missing optional def operand");

View File

@ -26,16 +26,32 @@
#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetRegistry.h"
using namespace llvm;
#define GET_REGINFO_MC_DESC #define GET_REGINFO_MC_DESC
#include "ARMGenRegisterInfo.inc" #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 #define GET_INSTRINFO_MC_DESC
#include "ARMGenInstrInfo.inc" #include "ARMGenInstrInfo.inc"
#define GET_SUBTARGETINFO_MC_DESC #define GET_SUBTARGETINFO_MC_DESC
#include "ARMGenSubtargetInfo.inc" #include "ARMGenSubtargetInfo.inc"
using namespace llvm;
std::string ARM_MC::ParseARMTriple(StringRef TT, StringRef CPU) { std::string ARM_MC::ParseARMTriple(StringRef TT, StringRef CPU) {
Triple triple(TT); Triple triple(TT);

View File

@ -24,6 +24,10 @@
using namespace llvm; using namespace llvm;
namespace llvm {
class MCInstrInfo;
}
namespace { namespace {
class MipsAssemblerOptions { class MipsAssemblerOptions {
public: public:
@ -201,8 +205,10 @@ class MipsAsmParser : public MCTargetAsmParser {
bool processInstruction(MCInst &Inst, SMLoc IDLoc, bool processInstruction(MCInst &Inst, SMLoc IDLoc,
SmallVectorImpl<MCInst> &Instructions); SmallVectorImpl<MCInst> &Instructions);
public: public:
MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser) MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
: MCTargetAsmParser(), STI(sti), Parser(parser), hasConsumedDollar(false) { const MCInstrInfo &MII)
: MCTargetAsmParser(), STI(sti), Parser(parser),
hasConsumedDollar(false) {
// Initialize the set of available features. // Initialize the set of available features.
setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
} }

View File

@ -218,8 +218,9 @@ class PPCAsmParser : public MCTargetAsmParser {
public: public:
PPCAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) PPCAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser,
: MCTargetAsmParser(), STI(_STI), Parser(_Parser) { const MCInstrInfo &MII)
: MCTargetAsmParser(), STI(_STI), Parser(_Parser) {
// Check for 64-bit vs. 32-bit pointer mode. // Check for 64-bit vs. 32-bit pointer mode.
Triple TheTriple(STI.getTargetTriple()); Triple TheTriple(STI.getTargetTriple());
IsPPC64 = (TheTriple.getArch() == Triple::ppc64 || IsPPC64 = (TheTriple.getArch() == Triple::ppc64 ||

View File

@ -327,8 +327,9 @@ private:
StringRef Mnemonic); StringRef Mnemonic);
public: public:
SystemZAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser) SystemZAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
: MCTargetAsmParser(), STI(sti), Parser(parser) { const MCInstrInfo &MII)
: MCTargetAsmParser(), STI(sti), Parser(parser) {
MCAsmParserExtension::Initialize(Parser); MCAsmParserExtension::Initialize(Parser);
// Initialize the set of available features. // Initialize the set of available features.

View File

@ -556,8 +556,9 @@ private:
/// } /// }
public: public:
X86AsmParser(MCSubtargetInfo &sti, MCAsmParser &parser) X86AsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
: MCTargetAsmParser(), STI(sti), Parser(parser), InstInfo(0) { const MCInstrInfo &MII)
: MCTargetAsmParser(), STI(sti), Parser(parser), InstInfo(0) {
// Initialize the set of available features. // Initialize the set of available features.
setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));

View File

@ -1,3 +1,5 @@
@ RUN: llvm-mc -triple armv8 -show-encoding < %s 2>&1 | FileCheck %s @ RUN: llvm-mc -triple armv8 -show-encoding < %s 2>&1 | FileCheck %s
setend be setend be
@ CHECK: warning: deprecated
mcr p8, #0, r5, c7, c5, #4
@ CHECK: warning: deprecated on armv8 @ CHECK: warning: deprecated on armv8

View File

@ -319,10 +319,10 @@ static int AsLexInput(SourceMgr &SrcMgr, MCAsmInfo &MAI, tool_output_file *Out)
static int AssembleInput(const char *ProgName, const Target *TheTarget, static int AssembleInput(const char *ProgName, const Target *TheTarget,
SourceMgr &SrcMgr, MCContext &Ctx, MCStreamer &Str, SourceMgr &SrcMgr, MCContext &Ctx, MCStreamer &Str,
MCAsmInfo &MAI, MCSubtargetInfo &STI) { MCAsmInfo &MAI, MCSubtargetInfo &STI, MCInstrInfo &MCII) {
OwningPtr<MCAsmParser> Parser(createMCAsmParser(SrcMgr, Ctx, OwningPtr<MCAsmParser> Parser(createMCAsmParser(SrcMgr, Ctx,
Str, MAI)); Str, MAI));
OwningPtr<MCTargetAsmParser> TAP(TheTarget->createMCAsmParser(STI, *Parser)); OwningPtr<MCTargetAsmParser> TAP(TheTarget->createMCAsmParser(STI, *Parser, MCII));
if (!TAP) { if (!TAP) {
errs() << ProgName errs() << ProgName
<< ": error: this target does not support assembly parsing.\n"; << ": 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()); Res = AsLexInput(SrcMgr, *MAI, Out.get());
break; break;
case AC_Assemble: case AC_Assemble:
Res = AssembleInput(ProgName, TheTarget, SrcMgr, Ctx, *Str, *MAI, *STI); Res = AssembleInput(ProgName, TheTarget, SrcMgr, Ctx, *Str, *MAI, *STI, *MCII);
break; break;
case AC_MDisassemble: case AC_MDisassemble:
assert(IP && "Expected assembly output"); assert(IP && "Expected assembly output");

View File

@ -430,6 +430,9 @@ struct MatchableInfo {
/// function. /// function.
std::string ConversionFnKind; std::string ConversionFnKind;
/// If this instruction is deprecated in some form.
bool HasDeprecation;
MatchableInfo(const CodeGenInstruction &CGI) MatchableInfo(const CodeGenInstruction &CGI)
: AsmVariantID(0), TheDef(CGI.TheDef), DefRec(&CGI), : AsmVariantID(0), TheDef(CGI.TheDef), DefRec(&CGI),
AsmString(CGI.AsmString) { AsmString(CGI.AsmString) {
@ -779,6 +782,13 @@ void MatchableInfo::initialize(const AsmMatcherInfo &Info,
if (Record *Reg = AsmOperands[i].SingletonReg) if (Record *Reg = AsmOperands[i].SingletonReg)
SingletonRegisters.insert(Reg); 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. /// tokenizeAsmString - Tokenize a simplified assembly string.
@ -2743,11 +2753,13 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
size_t MaxNumOperands = 0; size_t MaxNumOperands = 0;
unsigned MaxMnemonicIndex = 0; unsigned MaxMnemonicIndex = 0;
bool HasDeprecation = false;
for (std::vector<MatchableInfo*>::const_iterator it = for (std::vector<MatchableInfo*>::const_iterator it =
Info.Matchables.begin(), ie = Info.Matchables.end(); Info.Matchables.begin(), ie = Info.Matchables.end();
it != ie; ++it) { it != ie; ++it) {
MatchableInfo &II = **it; MatchableInfo &II = **it;
MaxNumOperands = std::max(MaxNumOperands, II.AsmOperands.size()); MaxNumOperands = std::max(MaxNumOperands, II.AsmOperands.size());
HasDeprecation |= II.HasDeprecation;
// Store a pascal-style length byte in the mnemonic. // Store a pascal-style length byte in the mnemonic.
std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.str(); std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.str();
@ -3018,6 +3030,14 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
if (!InsnCleanupFn.empty()) if (!InsnCleanupFn.empty())
OS << " " << InsnCleanupFn << "(Inst);\n"; 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 << " return Match_Success;\n";
OS << " }\n\n"; OS << " }\n\n";

View File

@ -337,6 +337,20 @@ CodeGenInstruction::CodeGenInstruction(Record *R)
// Parse the DisableEncoding field. // Parse the DisableEncoding field.
Operands.ProcessDisableEncoding(R->getValueAsString("DisableEncoding")); 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 /// HasOneImplicitDefWithKnownVT - If the instruction has at least one

View File

@ -248,6 +248,9 @@ namespace llvm {
bool isCodeGenOnly; bool isCodeGenOnly;
bool isPseudo; bool isPseudo;
std::string DeprecatedReason;
bool HasComplexDeprecationPredicate;
/// Are there any undefined flags? /// Are there any undefined flags?
bool hasUndefFlags() const { bool hasUndefFlags() const {
return mayLoad_Unset || mayStore_Unset || hasSideEffects_Unset; return mayLoad_Unset || mayStore_Unset || hasSideEffects_Unset;

View File

@ -514,6 +514,19 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
else else
OS << "OperandInfo" << OpInfo.find(OperandInfo)->second; 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"; OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n";
} }