forked from OSchip/llvm-project
There are a few places where subtarget features are still
represented by uint64_t, this patch replaces these usages with the FeatureBitset (std::bitset) type. Differential Revision: http://reviews.llvm.org/D10542 llvm-svn: 241058
This commit is contained in:
parent
f256184693
commit
5b119091a1
|
@ -13,6 +13,7 @@
|
|||
#include "llvm/MC/MCExpr.h"
|
||||
#include "llvm/MC/MCParser/MCAsmParserExtension.h"
|
||||
#include "llvm/MC/MCTargetOptions.h"
|
||||
#include "llvm/MC/SubtargetFeature.h"
|
||||
#include <memory>
|
||||
|
||||
namespace llvm {
|
||||
|
@ -95,7 +96,7 @@ protected: // Can only create subclasses.
|
|||
MCTargetAsmParser();
|
||||
|
||||
/// AvailableFeatures - The current set of available features.
|
||||
uint64_t AvailableFeatures;
|
||||
FeatureBitset AvailableFeatures;
|
||||
|
||||
/// ParsingInlineAsm - Are we parsing ms-style inline assembly?
|
||||
bool ParsingInlineAsm;
|
||||
|
@ -110,8 +111,8 @@ protected: // Can only create subclasses.
|
|||
public:
|
||||
~MCTargetAsmParser() override;
|
||||
|
||||
uint64_t getAvailableFeatures() const { return AvailableFeatures; }
|
||||
void setAvailableFeatures(uint64_t Value) { AvailableFeatures = Value; }
|
||||
FeatureBitset getAvailableFeatures() const { return AvailableFeatures; }
|
||||
void setAvailableFeatures(FeatureBitset Value) { AvailableFeatures = Value; }
|
||||
|
||||
bool isParsingInlineAsm () { return ParsingInlineAsm; }
|
||||
void setParsingInlineAsm (bool Value) { ParsingInlineAsm = Value; }
|
||||
|
@ -169,6 +170,7 @@ public:
|
|||
virtual bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
OperandVector &Operands, MCStreamer &Out,
|
||||
uint64_t &ErrorInfo,
|
||||
FeatureBitset &ErrorMissingFeature,
|
||||
bool MatchingInlineAsm) = 0;
|
||||
|
||||
/// Allows targets to let registers opt out of clobber lists.
|
||||
|
|
|
@ -1681,9 +1681,11 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
|
|||
// If parsing succeeded, match the instruction.
|
||||
if (!HadError) {
|
||||
uint64_t ErrorInfo;
|
||||
FeatureBitset ErrorMissingFeature;
|
||||
getTargetParser().MatchAndEmitInstruction(IDLoc, Info.Opcode,
|
||||
Info.ParsedOperands, Out,
|
||||
ErrorInfo, ParsingInlineAsm);
|
||||
ErrorInfo, ErrorMissingFeature,
|
||||
ParsingInlineAsm);
|
||||
}
|
||||
|
||||
// Don't skip the rest of the line, the instruction parser is responsible for
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "llvm/Support/SourceMgr.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/MC/SubtargetFeature.h"
|
||||
#include <cstdio>
|
||||
using namespace llvm;
|
||||
|
||||
|
@ -86,6 +87,7 @@ private:
|
|||
bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
OperandVector &Operands, MCStreamer &Out,
|
||||
uint64_t &ErrorInfo,
|
||||
FeatureBitset &ErrorMissingFeature,
|
||||
bool MatchingInlineAsm) override;
|
||||
/// @name Auto-generated Match Functions
|
||||
/// {
|
||||
|
@ -3613,12 +3615,13 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode) {
|
|||
}
|
||||
}
|
||||
|
||||
static const char *getSubtargetFeatureName(uint64_t Val);
|
||||
static const char *getSubtargetFeatureName(uint64_t Feature);
|
||||
|
||||
bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
OperandVector &Operands,
|
||||
MCStreamer &Out,
|
||||
uint64_t &ErrorInfo,
|
||||
FeatureBitset &ErrorMissingFeature,
|
||||
bool MatchingInlineAsm) {
|
||||
assert(!Operands.empty() && "Unexpect empty operand list!");
|
||||
AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[0]);
|
||||
|
@ -3894,13 +3897,13 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||
// First try to match against the secondary set of tables containing the
|
||||
// short-form NEON instructions (e.g. "fadd.2s v0, v1, v2").
|
||||
unsigned MatchResult =
|
||||
MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 1);
|
||||
MatchInstructionImpl(Operands, Inst, ErrorInfo, ErrorMissingFeature, MatchingInlineAsm, 1);
|
||||
|
||||
// If that fails, try against the alternate table containing long-form NEON:
|
||||
// "fadd v0.2s, v1.2s, v2.2s"
|
||||
if (MatchResult != Match_Success)
|
||||
MatchResult =
|
||||
MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 0);
|
||||
MatchInstructionImpl(Operands, Inst, ErrorInfo, ErrorMissingFeature, MatchingInlineAsm, 0);
|
||||
|
||||
switch (MatchResult) {
|
||||
case Match_Success: {
|
||||
|
@ -3917,17 +3920,15 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||
return false;
|
||||
}
|
||||
case Match_MissingFeature: {
|
||||
assert(ErrorInfo && "Unknown missing feature!");
|
||||
assert(ErrorMissingFeature.any() && "Unknown missing feature!");
|
||||
// Special case the error message for the very common case where only
|
||||
// a single subtarget feature is missing (neon, e.g.).
|
||||
std::string Msg = "instruction requires:";
|
||||
uint64_t Mask = 1;
|
||||
for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
|
||||
if (ErrorInfo & Mask) {
|
||||
for (unsigned i = 0; i < ErrorMissingFeature.size(); ++i) {
|
||||
if (ErrorMissingFeature[i]) {
|
||||
Msg += " ";
|
||||
Msg += getSubtargetFeatureName(ErrorInfo & Mask);
|
||||
Msg += getSubtargetFeatureName(i);
|
||||
}
|
||||
Mask <<= 1;
|
||||
}
|
||||
return Error(IDLoc, Msg);
|
||||
}
|
||||
|
|
|
@ -361,6 +361,7 @@ public:
|
|||
bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
OperandVector &Operands, MCStreamer &Out,
|
||||
uint64_t &ErrorInfo,
|
||||
FeatureBitset &ErrorMissingFeature,
|
||||
bool MatchingInlineAsm) override;
|
||||
bool ParseDirective(AsmToken DirectiveID) override;
|
||||
OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Mnemonic);
|
||||
|
@ -542,10 +543,11 @@ bool AMDGPUAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||
OperandVector &Operands,
|
||||
MCStreamer &Out,
|
||||
uint64_t &ErrorInfo,
|
||||
FeatureBitset &ErrorMissingFeature,
|
||||
bool MatchingInlineAsm) {
|
||||
MCInst Inst;
|
||||
|
||||
switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
|
||||
switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, ErrorMissingFeature, MatchingInlineAsm)) {
|
||||
default: break;
|
||||
case Match_Success:
|
||||
Inst.setLoc(IDLoc);
|
||||
|
@ -577,6 +579,7 @@ bool AMDGPUAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||
AMDGPUOperand::ImmTyOMod));
|
||||
bool Res = MatchAndEmitInstruction(IDLoc, Opcode, Operands,
|
||||
Out, ErrorInfo,
|
||||
ErrorMissingFeature,
|
||||
MatchingInlineAsm);
|
||||
if (!Res)
|
||||
return Res;
|
||||
|
|
|
@ -281,7 +281,7 @@ class ARMAsmParser : public MCTargetAsmParser {
|
|||
}
|
||||
|
||||
void SwitchMode() {
|
||||
uint64_t FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
|
||||
FeatureBitset FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
|
||||
setAvailableFeatures(FB);
|
||||
}
|
||||
bool isMClass() const {
|
||||
|
@ -375,6 +375,7 @@ public:
|
|||
bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
OperandVector &Operands, MCStreamer &Out,
|
||||
uint64_t &ErrorInfo,
|
||||
FeatureBitset &ErrorMissingFeature,
|
||||
bool MatchingInlineAsm) override;
|
||||
void onLabelParsed(MCSymbol *Symbol) override;
|
||||
};
|
||||
|
@ -5623,7 +5624,7 @@ static bool isDataTypeToken(StringRef Tok) {
|
|||
static bool doesIgnoreDataTypeSuffix(StringRef Mnemonic, StringRef DT) {
|
||||
return Mnemonic.startswith("vldm") || Mnemonic.startswith("vstm");
|
||||
}
|
||||
static void applyMnemonicAliases(StringRef &Mnemonic, uint64_t Features,
|
||||
static void applyMnemonicAliases(StringRef &Mnemonic, FeatureBitset Features,
|
||||
unsigned VariantID);
|
||||
|
||||
static bool RequiresVFPRegListValidation(StringRef Inst,
|
||||
|
@ -5662,7 +5663,7 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
|
|||
// The generic tblgen'erated code does this later, at the start of
|
||||
// MatchInstructionImpl(), but that's too late for aliases that include
|
||||
// any sort of suffix.
|
||||
uint64_t AvailableFeatures = getAvailableFeatures();
|
||||
FeatureBitset AvailableFeatures = getAvailableFeatures();
|
||||
unsigned AssemblerDialect = getParser().getAssemblerDialect();
|
||||
applyMnemonicAliases(Name, AvailableFeatures, AssemblerDialect);
|
||||
|
||||
|
@ -8573,16 +8574,17 @@ template <> inline bool IsCPSRDead<MCInst>(MCInst *Instr) {
|
|||
}
|
||||
}
|
||||
|
||||
static const char *getSubtargetFeatureName(uint64_t Val);
|
||||
static const char *getSubtargetFeatureName(uint64_t Feature);
|
||||
bool ARMAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
OperandVector &Operands,
|
||||
MCStreamer &Out, uint64_t &ErrorInfo,
|
||||
FeatureBitset &ErrorMissingFeature,
|
||||
bool MatchingInlineAsm) {
|
||||
MCInst Inst;
|
||||
unsigned MatchResult;
|
||||
|
||||
MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
|
||||
MatchingInlineAsm);
|
||||
ErrorMissingFeature, MatchingInlineAsm);
|
||||
switch (MatchResult) {
|
||||
case Match_Success:
|
||||
// Context sensitive operand constraints aren't handled by the matcher,
|
||||
|
@ -8625,17 +8627,15 @@ bool ARMAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||
Out.EmitInstruction(Inst, STI);
|
||||
return false;
|
||||
case Match_MissingFeature: {
|
||||
assert(ErrorInfo && "Unknown missing feature!");
|
||||
assert(ErrorMissingFeature.any() && "Unknown missing feature!");
|
||||
// Special case the error message for the very common case where only
|
||||
// a single subtarget feature is missing (Thumb vs. ARM, e.g.).
|
||||
std::string Msg = "instruction requires:";
|
||||
uint64_t Mask = 1;
|
||||
for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
|
||||
if (ErrorInfo & Mask) {
|
||||
for (unsigned i = 0; i < ErrorMissingFeature.size(); ++i) {
|
||||
if (ErrorMissingFeature[i]) {
|
||||
Msg += " ";
|
||||
Msg += getSubtargetFeatureName(ErrorInfo & Mask);
|
||||
Msg += getSubtargetFeatureName(i);
|
||||
}
|
||||
Mask <<= 1;
|
||||
}
|
||||
return Error(IDLoc, Msg);
|
||||
}
|
||||
|
@ -9916,27 +9916,27 @@ extern "C" void LLVMInitializeARMAsmParser() {
|
|||
// flags below, that were generated by table-gen.
|
||||
static const struct {
|
||||
const ARM::ArchExtKind Kind;
|
||||
const unsigned ArchCheck;
|
||||
const FeatureBitset ArchCheck;
|
||||
const FeatureBitset Features;
|
||||
} Extensions[] = {
|
||||
{ ARM::AEK_CRC, Feature_HasV8, {ARM::FeatureCRC} },
|
||||
{ ARM::AEK_CRYPTO, Feature_HasV8,
|
||||
{ ARM::AEK_CRC, {Feature_HasV8}, {ARM::FeatureCRC} },
|
||||
{ ARM::AEK_CRYPTO, {Feature_HasV8},
|
||||
{ARM::FeatureCrypto, ARM::FeatureNEON, ARM::FeatureFPARMv8} },
|
||||
{ ARM::AEK_FP, Feature_HasV8, {ARM::FeatureFPARMv8} },
|
||||
{ ARM::AEK_HWDIV, Feature_HasV7 | Feature_IsNotMClass,
|
||||
{ ARM::AEK_FP, {Feature_HasV8}, {ARM::FeatureFPARMv8} },
|
||||
{ ARM::AEK_HWDIV, {Feature_HasV7, Feature_IsNotMClass},
|
||||
{ARM::FeatureHWDiv, ARM::FeatureHWDivARM} },
|
||||
{ ARM::AEK_MP, Feature_HasV7 | Feature_IsNotMClass, {ARM::FeatureMP} },
|
||||
{ ARM::AEK_SIMD, Feature_HasV8, {ARM::FeatureNEON, ARM::FeatureFPARMv8} },
|
||||
{ ARM::AEK_MP, {Feature_HasV7 , Feature_IsNotMClass}, {ARM::FeatureMP} },
|
||||
{ ARM::AEK_SIMD, {Feature_HasV8}, {ARM::FeatureNEON, ARM::FeatureFPARMv8} },
|
||||
// FIXME: Also available in ARMv6-K
|
||||
{ ARM::AEK_SEC, Feature_HasV7, {ARM::FeatureTrustZone} },
|
||||
{ ARM::AEK_SEC, {Feature_HasV7}, {ARM::FeatureTrustZone} },
|
||||
// FIXME: Only available in A-class, isel not predicated
|
||||
{ ARM::AEK_VIRT, Feature_HasV7, {ARM::FeatureVirtualization} },
|
||||
{ ARM::AEK_VIRT, {Feature_HasV7}, {ARM::FeatureVirtualization} },
|
||||
// FIXME: Unsupported extensions.
|
||||
{ ARM::AEK_OS, Feature_None, {} },
|
||||
{ ARM::AEK_IWMMXT, Feature_None, {} },
|
||||
{ ARM::AEK_IWMMXT2, Feature_None, {} },
|
||||
{ ARM::AEK_MAVERICK, Feature_None, {} },
|
||||
{ ARM::AEK_XSCALE, Feature_None, {} },
|
||||
{ ARM::AEK_OS, {Feature_None}, {} },
|
||||
{ ARM::AEK_IWMMXT, {Feature_None}, {} },
|
||||
{ ARM::AEK_IWMMXT2, {Feature_None}, {} },
|
||||
{ ARM::AEK_MAVERICK, {Feature_None}, {} },
|
||||
{ ARM::AEK_XSCALE, {Feature_None}, {} },
|
||||
};
|
||||
|
||||
/// parseDirectiveArchExtension
|
||||
|
@ -9980,7 +9980,7 @@ bool ARMAsmParser::parseDirectiveArchExtension(SMLoc L) {
|
|||
? (~STI.getFeatureBits() & Extension.Features)
|
||||
: ( STI.getFeatureBits() & Extension.Features);
|
||||
|
||||
uint64_t Features =
|
||||
FeatureBitset Features =
|
||||
ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures));
|
||||
setAvailableFeatures(Features);
|
||||
return false;
|
||||
|
|
|
@ -127,6 +127,7 @@ class MipsAsmParser : public MCTargetAsmParser {
|
|||
bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
OperandVector &Operands, MCStreamer &Out,
|
||||
uint64_t &ErrorInfo,
|
||||
FeatureBitset &ErrorMissingFeature,
|
||||
bool MatchingInlineAsm) override;
|
||||
|
||||
/// Parse a register as used in CFI directives
|
||||
|
@ -2722,12 +2723,13 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||
OperandVector &Operands,
|
||||
MCStreamer &Out,
|
||||
uint64_t &ErrorInfo,
|
||||
FeatureBitset &ErrorMissingFeature,
|
||||
bool MatchingInlineAsm) {
|
||||
|
||||
MCInst Inst;
|
||||
SmallVector<MCInst, 8> Instructions;
|
||||
unsigned MatchResult =
|
||||
MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
|
||||
MatchInstructionImpl(Operands, Inst, ErrorInfo, ErrorMissingFeature, MatchingInlineAsm);
|
||||
|
||||
switch (MatchResult) {
|
||||
case Match_Success: {
|
||||
|
|
|
@ -277,6 +277,7 @@ class PPCAsmParser : public MCTargetAsmParser {
|
|||
bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
OperandVector &Operands, MCStreamer &Out,
|
||||
uint64_t &ErrorInfo,
|
||||
FeatureBitset &ErrorMissingFeature,
|
||||
bool MatchingInlineAsm) override;
|
||||
|
||||
void ProcessInstruction(MCInst &Inst, const OperandVector &Ops);
|
||||
|
@ -1197,10 +1198,11 @@ void PPCAsmParser::ProcessInstruction(MCInst &Inst,
|
|||
bool PPCAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
OperandVector &Operands,
|
||||
MCStreamer &Out, uint64_t &ErrorInfo,
|
||||
FeatureBitset &ErrorMissingFeature,
|
||||
bool MatchingInlineAsm) {
|
||||
MCInst Inst;
|
||||
|
||||
switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
|
||||
switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, ErrorMissingFeature, MatchingInlineAsm)) {
|
||||
case Match_Success:
|
||||
// Post-process instructions (typically extended mnemonics)
|
||||
ProcessInstruction(Inst, Operands);
|
||||
|
|
|
@ -49,6 +49,7 @@ class SparcAsmParser : public MCTargetAsmParser {
|
|||
bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
OperandVector &Operands, MCStreamer &Out,
|
||||
uint64_t &ErrorInfo,
|
||||
FeatureBitset &ErrorMissingFeature,
|
||||
bool MatchingInlineAsm) override;
|
||||
bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
|
||||
bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
|
||||
|
@ -445,10 +446,12 @@ bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||
OperandVector &Operands,
|
||||
MCStreamer &Out,
|
||||
uint64_t &ErrorInfo,
|
||||
FeatureBitset &ErrorMissingFeature,
|
||||
bool MatchingInlineAsm) {
|
||||
MCInst Inst;
|
||||
SmallVector<MCInst, 8> Instructions;
|
||||
unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
|
||||
ErrorMissingFeature,
|
||||
MatchingInlineAsm);
|
||||
switch (MatchResult) {
|
||||
case Match_Success: {
|
||||
|
@ -510,7 +513,7 @@ ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc)
|
|||
return Error(StartLoc, "invalid register name");
|
||||
}
|
||||
|
||||
static void applyMnemonicAliases(StringRef &Mnemonic, uint64_t Features,
|
||||
static void applyMnemonicAliases(StringRef &Mnemonic, FeatureBitset Features,
|
||||
unsigned VariantID);
|
||||
|
||||
bool SparcAsmParser::ParseInstruction(ParseInstructionInfo &Info,
|
||||
|
|
|
@ -404,6 +404,7 @@ public:
|
|||
bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
OperandVector &Operands, MCStreamer &Out,
|
||||
uint64_t &ErrorInfo,
|
||||
FeatureBitset &ErrorMissingFeature,
|
||||
bool MatchingInlineAsm) override;
|
||||
|
||||
// Used by the TableGen code to parse particular operand types.
|
||||
|
@ -782,12 +783,13 @@ bool SystemZAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||
OperandVector &Operands,
|
||||
MCStreamer &Out,
|
||||
uint64_t &ErrorInfo,
|
||||
FeatureBitset &ErrorMissingFeature,
|
||||
bool MatchingInlineAsm) {
|
||||
MCInst Inst;
|
||||
unsigned MatchResult;
|
||||
|
||||
MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
|
||||
MatchingInlineAsm);
|
||||
ErrorMissingFeature, MatchingInlineAsm);
|
||||
switch (MatchResult) {
|
||||
case Match_Success:
|
||||
Inst.setLoc(IDLoc);
|
||||
|
@ -795,17 +797,15 @@ bool SystemZAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||
return false;
|
||||
|
||||
case Match_MissingFeature: {
|
||||
assert(ErrorInfo && "Unknown missing feature!");
|
||||
assert(ErrorMissingFeature.any() && "Unknown missing feature!");
|
||||
// Special case the error message for the very common case where only
|
||||
// a single subtarget feature is missing
|
||||
std::string Msg = "instruction requires:";
|
||||
uint64_t Mask = 1;
|
||||
for (unsigned I = 0; I < sizeof(ErrorInfo) * 8 - 1; ++I) {
|
||||
if (ErrorInfo & Mask) {
|
||||
for (unsigned I = 0; I < ErrorMissingFeature.size(); ++I) {
|
||||
if (ErrorMissingFeature[I]) {
|
||||
Msg += " ";
|
||||
Msg += getSubtargetFeatureName(ErrorInfo & Mask);
|
||||
Msg += getSubtargetFeatureName(I);
|
||||
}
|
||||
Mask <<= 1;
|
||||
}
|
||||
return Error(IDLoc, Msg);
|
||||
}
|
||||
|
|
|
@ -722,22 +722,25 @@ private:
|
|||
bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
OperandVector &Operands, MCStreamer &Out,
|
||||
uint64_t &ErrorInfo,
|
||||
FeatureBitset &ErrorMissingFeature,
|
||||
bool MatchingInlineAsm) override;
|
||||
|
||||
void MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op, OperandVector &Operands,
|
||||
MCStreamer &Out, bool MatchingInlineAsm);
|
||||
|
||||
bool ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
|
||||
bool ErrorMissingFeature(SMLoc IDLoc, FeatureBitset MissingFeature,
|
||||
bool MatchingInlineAsm);
|
||||
|
||||
bool MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
OperandVector &Operands, MCStreamer &Out,
|
||||
uint64_t &ErrorInfo,
|
||||
FeatureBitset &ErrorMissingFeature,
|
||||
bool MatchingInlineAsm);
|
||||
|
||||
bool MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
OperandVector &Operands, MCStreamer &Out,
|
||||
uint64_t &ErrorInfo,
|
||||
FeatureBitset &ErrorMissingFeature,
|
||||
bool MatchingInlineAsm);
|
||||
|
||||
bool OmitRegisterFromClobberLists(unsigned RegNo) override;
|
||||
|
@ -768,7 +771,7 @@ private:
|
|||
void SwitchMode(unsigned mode) {
|
||||
FeatureBitset AllModes({X86::Mode64Bit, X86::Mode32Bit, X86::Mode16Bit});
|
||||
FeatureBitset OldMode = STI.getFeatureBits() & AllModes;
|
||||
unsigned FB = ComputeAvailableFeatures(
|
||||
FeatureBitset FB = ComputeAvailableFeatures(
|
||||
STI.ToggleFeature(OldMode.flip(mode)));
|
||||
setAvailableFeatures(FB);
|
||||
|
||||
|
@ -2490,7 +2493,7 @@ bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
|
|||
}
|
||||
}
|
||||
|
||||
static const char *getSubtargetFeatureName(uint64_t Val);
|
||||
static const char *getSubtargetFeatureName(uint64_t Feature);
|
||||
|
||||
void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
|
||||
MCStreamer &Out) {
|
||||
|
@ -2501,12 +2504,13 @@ void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
|
|||
bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
OperandVector &Operands,
|
||||
MCStreamer &Out, uint64_t &ErrorInfo,
|
||||
FeatureBitset &ErrorMissingFeature,
|
||||
bool MatchingInlineAsm) {
|
||||
if (isParsingIntelSyntax())
|
||||
return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
|
||||
MatchingInlineAsm);
|
||||
ErrorMissingFeature, MatchingInlineAsm);
|
||||
return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
|
||||
MatchingInlineAsm);
|
||||
ErrorMissingFeature, MatchingInlineAsm);
|
||||
}
|
||||
|
||||
void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
|
||||
|
@ -2535,18 +2539,16 @@ void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
|
|||
}
|
||||
}
|
||||
|
||||
bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
|
||||
bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, FeatureBitset MissingFeature,
|
||||
bool MatchingInlineAsm) {
|
||||
assert(ErrorInfo && "Unknown missing feature!");
|
||||
assert(MissingFeature.any() && "Unknown missing feature!");
|
||||
ArrayRef<SMRange> EmptyRanges = None;
|
||||
SmallString<126> Msg;
|
||||
raw_svector_ostream OS(Msg);
|
||||
OS << "instruction requires:";
|
||||
uint64_t Mask = 1;
|
||||
for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
|
||||
if (ErrorInfo & Mask)
|
||||
OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask);
|
||||
Mask <<= 1;
|
||||
for (unsigned i = 0; i < MissingFeature.size(); ++i) {
|
||||
if (MissingFeature[i])
|
||||
OS << ' ' << getSubtargetFeatureName(i);
|
||||
}
|
||||
return Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
|
||||
}
|
||||
|
@ -2555,6 +2557,7 @@ bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||
OperandVector &Operands,
|
||||
MCStreamer &Out,
|
||||
uint64_t &ErrorInfo,
|
||||
FeatureBitset &ErrMissingFeature,
|
||||
bool MatchingInlineAsm) {
|
||||
assert(!Operands.empty() && "Unexpect empty operand list!");
|
||||
X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
|
||||
|
@ -2569,7 +2572,8 @@ bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||
|
||||
// First, try a direct match.
|
||||
switch (MatchInstructionImpl(Operands, Inst,
|
||||
ErrorInfo, MatchingInlineAsm,
|
||||
ErrorInfo, ErrMissingFeature,
|
||||
MatchingInlineAsm,
|
||||
isParsingIntelSyntax())) {
|
||||
default: llvm_unreachable("Unexpected match result!");
|
||||
case Match_Success:
|
||||
|
@ -2589,7 +2593,7 @@ bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||
Opcode = Inst.getOpcode();
|
||||
return false;
|
||||
case Match_MissingFeature:
|
||||
return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm);
|
||||
return ErrorMissingFeature(IDLoc, ErrMissingFeature, MatchingInlineAsm);
|
||||
case Match_InvalidOperand:
|
||||
WasOriginallyInvalidOperand = true;
|
||||
break;
|
||||
|
@ -2619,16 +2623,16 @@ bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||
|
||||
// Check for the various suffix matches.
|
||||
uint64_t ErrorInfoIgnore;
|
||||
uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
|
||||
FeatureBitset ErrorInfoMissingFeature;
|
||||
unsigned Match[4];
|
||||
|
||||
for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) {
|
||||
Tmp.back() = Suffixes[I];
|
||||
Match[I] = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
|
||||
MatchingInlineAsm, isParsingIntelSyntax());
|
||||
Match[I] = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore, ErrMissingFeature,
|
||||
MatchingInlineAsm, isParsingIntelSyntax());
|
||||
// If this returned as a missing feature failure, remember that.
|
||||
if (Match[I] == Match_MissingFeature)
|
||||
ErrorInfoMissingFeature = ErrorInfoIgnore;
|
||||
ErrorInfoMissingFeature = ErrMissingFeature;
|
||||
}
|
||||
|
||||
// Restore the old token.
|
||||
|
@ -2707,8 +2711,8 @@ bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||
// missing feature.
|
||||
if (std::count(std::begin(Match), std::end(Match),
|
||||
Match_MissingFeature) == 1) {
|
||||
ErrorInfo = ErrorInfoMissingFeature;
|
||||
return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
|
||||
ErrMissingFeature = ErrorInfoMissingFeature;
|
||||
return ErrorMissingFeature(IDLoc, ErrMissingFeature,
|
||||
MatchingInlineAsm);
|
||||
}
|
||||
|
||||
|
@ -2730,6 +2734,7 @@ bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||
OperandVector &Operands,
|
||||
MCStreamer &Out,
|
||||
uint64_t &ErrorInfo,
|
||||
FeatureBitset& ErrMissingFeature,
|
||||
bool MatchingInlineAsm) {
|
||||
assert(!Operands.empty() && "Unexpect empty operand list!");
|
||||
X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
|
||||
|
@ -2766,22 +2771,23 @@ bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||
// operand size. In Intel assembly, the size is not part of the instruction
|
||||
// mnemonic.
|
||||
SmallVector<unsigned, 8> Match;
|
||||
uint64_t ErrorInfoMissingFeature = 0;
|
||||
FeatureBitset ErrorInfoMissingFeature;
|
||||
if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {
|
||||
static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
|
||||
for (unsigned Size : MopSizes) {
|
||||
UnsizedMemOp->Mem.Size = Size;
|
||||
uint64_t ErrorInfoIgnore;
|
||||
FeatureBitset MissingFeature;
|
||||
unsigned LastOpcode = Inst.getOpcode();
|
||||
unsigned M =
|
||||
MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
|
||||
MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore, MissingFeature,
|
||||
MatchingInlineAsm, isParsingIntelSyntax());
|
||||
if (Match.empty() || LastOpcode != Inst.getOpcode())
|
||||
Match.push_back(M);
|
||||
|
||||
// If this returned as a missing feature failure, remember that.
|
||||
if (Match.back() == Match_MissingFeature)
|
||||
ErrorInfoMissingFeature = ErrorInfoIgnore;
|
||||
ErrorInfoMissingFeature = MissingFeature;
|
||||
}
|
||||
|
||||
// Restore the size of the unsized memory operand if we modified it.
|
||||
|
@ -2794,11 +2800,12 @@ bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||
// matching with the unsized operand.
|
||||
if (Match.empty()) {
|
||||
Match.push_back(MatchInstructionImpl(Operands, Inst, ErrorInfo,
|
||||
ErrMissingFeature,
|
||||
MatchingInlineAsm,
|
||||
isParsingIntelSyntax()));
|
||||
// If this returned as a missing feature failure, remember that.
|
||||
if (Match.back() == Match_MissingFeature)
|
||||
ErrorInfoMissingFeature = ErrorInfo;
|
||||
ErrorInfoMissingFeature = ErrMissingFeature;
|
||||
}
|
||||
|
||||
// Restore the size of the unsized memory operand if we modified it.
|
||||
|
@ -2847,7 +2854,7 @@ bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||
// missing feature.
|
||||
if (std::count(std::begin(Match), std::end(Match),
|
||||
Match_MissingFeature) == 1) {
|
||||
ErrorInfo = ErrorInfoMissingFeature;
|
||||
ErrMissingFeature = ErrorInfoMissingFeature;
|
||||
return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
|
||||
MatchingInlineAsm);
|
||||
}
|
||||
|
|
|
@ -2223,7 +2223,7 @@ static void emitSubtargetFeatureFlagEnumeration(AsmMatcherInfo &Info,
|
|||
<< " {\n";
|
||||
for (const auto &SF : Info.SubtargetFeatures) {
|
||||
const SubtargetFeatureInfo &SFI = SF.second;
|
||||
OS << " " << SFI.getEnumName() << " = (1ULL << " << SFI.Index << "),\n";
|
||||
OS << " " << SFI.getEnumName() << " = " << SFI.Index << ",\n";
|
||||
}
|
||||
OS << " Feature_None = 0\n";
|
||||
OS << "};\n\n";
|
||||
|
@ -2254,9 +2254,9 @@ static void emitOperandDiagnosticTypes(AsmMatcherInfo &Info, raw_ostream &OS) {
|
|||
static void emitGetSubtargetFeatureName(AsmMatcherInfo &Info, raw_ostream &OS) {
|
||||
OS << "// User-level names for subtarget features that participate in\n"
|
||||
<< "// instruction matching.\n"
|
||||
<< "static const char *getSubtargetFeatureName(uint64_t Val) {\n";
|
||||
<< "static const char *getSubtargetFeatureName(uint64_t Feature) {\n";
|
||||
if (!Info.SubtargetFeatures.empty()) {
|
||||
OS << " switch(Val) {\n";
|
||||
OS << " switch(Feature) {\n";
|
||||
for (const auto &SF : Info.SubtargetFeatures) {
|
||||
const SubtargetFeatureInfo &SFI = SF.second;
|
||||
// FIXME: Totally just a placeholder name to get the algorithm working.
|
||||
|
@ -2279,9 +2279,9 @@ static void emitComputeAvailableFeatures(AsmMatcherInfo &Info,
|
|||
std::string ClassName =
|
||||
Info.AsmParser->getValueAsString("AsmParserClassName");
|
||||
|
||||
OS << "uint64_t " << Info.Target.getName() << ClassName << "::\n"
|
||||
OS << "FeatureBitset " << Info.Target.getName() << ClassName << "::\n"
|
||||
<< "ComputeAvailableFeatures(const FeatureBitset& FB) const {\n";
|
||||
OS << " uint64_t Features = 0;\n";
|
||||
OS << " FeatureBitset Features;\n";
|
||||
for (const auto &SF : Info.SubtargetFeatures) {
|
||||
const SubtargetFeatureInfo &SFI = SF.second;
|
||||
|
||||
|
@ -2315,7 +2315,7 @@ static void emitComputeAvailableFeatures(AsmMatcherInfo &Info,
|
|||
} while (true);
|
||||
|
||||
OS << ")\n";
|
||||
OS << " Features |= " << SFI.getEnumName() << ";\n";
|
||||
OS << " Features.set(" << SFI.getEnumName() << ", 1);\n";
|
||||
}
|
||||
OS << " return Features;\n";
|
||||
OS << "}\n\n";
|
||||
|
@ -2400,7 +2400,7 @@ static void emitMnemonicAliasVariant(raw_ostream &OS,const AsmMatcherInfo &Info,
|
|||
|
||||
if (!MatchCode.empty())
|
||||
MatchCode += "else ";
|
||||
MatchCode += "if ((Features & " + FeatureMask + ") == "+FeatureMask+")\n";
|
||||
MatchCode += "if ((Features & FeatureBitset({"+FeatureMask+"})) == FeatureBitset({"+FeatureMask+"}))\n";
|
||||
MatchCode += " Mnemonic = \"" +R->getValueAsString("ToMnemonic")+"\";\n";
|
||||
}
|
||||
|
||||
|
@ -2431,7 +2431,7 @@ static bool emitMnemonicAliases(raw_ostream &OS, const AsmMatcherInfo &Info,
|
|||
if (Aliases.empty()) return false;
|
||||
|
||||
OS << "static void applyMnemonicAliases(StringRef &Mnemonic, "
|
||||
"uint64_t Features, unsigned VariantID) {\n";
|
||||
"FeatureBitset Features, unsigned VariantID) {\n";
|
||||
OS << " switch (VariantID) {\n";
|
||||
unsigned VariantCount = Target.getAsmParserVariantCount();
|
||||
for (unsigned VC = 0; VC != VariantCount; ++VC) {
|
||||
|
@ -2467,8 +2467,7 @@ static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target,
|
|||
// Emit the static custom operand parsing table;
|
||||
OS << "namespace {\n";
|
||||
OS << " struct OperandMatchEntry {\n";
|
||||
OS << " " << getMinimalRequiredFeaturesType(Info)
|
||||
<< " RequiredFeatures;\n";
|
||||
OS << " FeatureBitset RequiredFeatures;\n";
|
||||
OS << " " << getMinimalTypeForRange(MaxMnemonicIndex)
|
||||
<< " Mnemonic;\n";
|
||||
OS << " " << getMinimalTypeForRange(std::distance(
|
||||
|
@ -2511,12 +2510,14 @@ static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target,
|
|||
|
||||
// Write the required features mask.
|
||||
if (!II.RequiredFeatures.empty()) {
|
||||
OS << "{";
|
||||
for (unsigned i = 0, e = II.RequiredFeatures.size(); i != e; ++i) {
|
||||
if (i) OS << "|";
|
||||
if (i) OS << ",";
|
||||
OS << II.RequiredFeatures[i]->getEnumName();
|
||||
}
|
||||
OS << "}";
|
||||
} else
|
||||
OS << "0";
|
||||
OS << "{}";
|
||||
|
||||
// Store a pascal-style length byte in the mnemonic.
|
||||
std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.str();
|
||||
|
@ -2572,7 +2573,7 @@ static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target,
|
|||
|
||||
// Emit code to get the available features.
|
||||
OS << " // Get the current feature set.\n";
|
||||
OS << " uint64_t AvailableFeatures = getAvailableFeatures();\n\n";
|
||||
OS << " FeatureBitset AvailableFeatures = getAvailableFeatures();\n\n";
|
||||
|
||||
OS << " // Get the next operand index.\n";
|
||||
OS << " unsigned NextOpNum = Operands.size()-1;\n";
|
||||
|
@ -2675,7 +2676,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
|||
OS << "#undef GET_ASSEMBLER_HEADER\n";
|
||||
OS << " // This should be included into the middle of the declaration of\n";
|
||||
OS << " // your subclasses implementation of MCTargetAsmParser.\n";
|
||||
OS << " uint64_t ComputeAvailableFeatures(const FeatureBitset& FB) const;\n";
|
||||
OS << " FeatureBitset ComputeAvailableFeatures(const FeatureBitset& FB) const;\n";
|
||||
OS << " void convertToMCInst(unsigned Kind, MCInst &Inst, "
|
||||
<< "unsigned Opcode,\n"
|
||||
<< " const OperandVector "
|
||||
|
@ -2685,8 +2686,9 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
|||
OS << " bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) override;\n";
|
||||
OS << " unsigned MatchInstructionImpl(const OperandVector &Operands,\n"
|
||||
<< " MCInst &Inst,\n"
|
||||
<< " uint64_t &ErrorInfo,"
|
||||
<< " bool matchingInlineAsm,\n"
|
||||
<< " uint64_t &ErrorInfo,\n"
|
||||
<< " FeatureBitset &ErrorMissingFeature,\n"
|
||||
<< " bool matchingInlineAsm,\n"
|
||||
<< " unsigned VariantID = 0);\n";
|
||||
|
||||
if (!Info.OperandMatchInfo.empty()) {
|
||||
|
@ -2797,8 +2799,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
|||
OS << " uint16_t Opcode;\n";
|
||||
OS << " " << getMinimalTypeForRange(Info.Matchables.size())
|
||||
<< " ConvertFn;\n";
|
||||
OS << " " << getMinimalRequiredFeaturesType(Info)
|
||||
<< " RequiredFeatures;\n";
|
||||
OS << " FeatureBitset RequiredFeatures;\n";
|
||||
OS << " " << getMinimalTypeForRange(
|
||||
std::distance(Info.Classes.begin(), Info.Classes.end()))
|
||||
<< " Classes[" << MaxNumOperands << "];\n";
|
||||
|
@ -2844,12 +2845,14 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
|||
|
||||
// Write the required features mask.
|
||||
if (!MI->RequiredFeatures.empty()) {
|
||||
OS << "{";
|
||||
for (unsigned i = 0, e = MI->RequiredFeatures.size(); i != e; ++i) {
|
||||
if (i) OS << "|";
|
||||
if (i) OS << ",";
|
||||
OS << MI->RequiredFeatures[i]->getEnumName();
|
||||
}
|
||||
OS << "}";
|
||||
} else
|
||||
OS << "0";
|
||||
OS << "{}";
|
||||
|
||||
OS << ", { ";
|
||||
for (unsigned i = 0, e = MI->AsmOperands.size(); i != e; ++i) {
|
||||
|
@ -2888,6 +2891,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
|||
OS << "unsigned " << Target.getName() << ClassName << "::\n"
|
||||
<< "MatchInstructionImpl(const OperandVector &Operands,\n";
|
||||
OS << " MCInst &Inst, uint64_t &ErrorInfo,\n"
|
||||
<< " FeatureBitset &ErrorMissingFeature,\n"
|
||||
<< " bool matchingInlineAsm, unsigned VariantID) {\n";
|
||||
|
||||
OS << " // Eliminate obvious mismatches.\n";
|
||||
|
@ -2898,7 +2902,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
|||
|
||||
// Emit code to get the available features.
|
||||
OS << " // Get the current feature set.\n";
|
||||
OS << " uint64_t AvailableFeatures = getAvailableFeatures();\n\n";
|
||||
OS << " FeatureBitset AvailableFeatures = getAvailableFeatures();\n\n";
|
||||
|
||||
OS << " // Get the instruction mnemonic, which is the first token.\n";
|
||||
OS << " StringRef Mnemonic = ((" << Target.getName()
|
||||
|
@ -2914,7 +2918,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
|||
OS << " bool HadMatchOtherThanFeatures = false;\n";
|
||||
OS << " bool HadMatchOtherThanPredicate = false;\n";
|
||||
OS << " unsigned RetCode = Match_InvalidOperand;\n";
|
||||
OS << " uint64_t MissingFeatures = ~0ULL;\n";
|
||||
OS << " FeatureBitset MissingFeatures(~0ULL);\n";
|
||||
OS << " // Set ErrorInfo to the operand that mismatches if it is\n";
|
||||
OS << " // wrong for all instances of the instruction.\n";
|
||||
OS << " ErrorInfo = ~0ULL;\n";
|
||||
|
@ -2990,10 +2994,10 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
|||
OS << " if ((AvailableFeatures & it->RequiredFeatures) "
|
||||
<< "!= it->RequiredFeatures) {\n";
|
||||
OS << " HadMatchOtherThanFeatures = true;\n";
|
||||
OS << " uint64_t NewMissingFeatures = it->RequiredFeatures & "
|
||||
OS << " FeatureBitset NewMissingFeatures = it->RequiredFeatures & "
|
||||
"~AvailableFeatures;\n";
|
||||
OS << " if (countPopulation(NewMissingFeatures) <=\n"
|
||||
" countPopulation(MissingFeatures))\n";
|
||||
OS << " if (NewMissingFeatures.count() <=\n"
|
||||
" MissingFeatures.count())\n";
|
||||
OS << " MissingFeatures = NewMissingFeatures;\n";
|
||||
OS << " continue;\n";
|
||||
OS << " }\n";
|
||||
|
@ -3043,7 +3047,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
|||
OS << " if (HadMatchOtherThanPredicate || !HadMatchOtherThanFeatures)\n";
|
||||
OS << " return RetCode;\n\n";
|
||||
OS << " // Missing feature matches return which features were missing\n";
|
||||
OS << " ErrorInfo = MissingFeatures;\n";
|
||||
OS << " ErrorMissingFeature = MissingFeatures;\n";
|
||||
OS << " return Match_MissingFeature;\n";
|
||||
OS << "}\n\n";
|
||||
|
||||
|
|
Loading…
Reference in New Issue