mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-10 02:29:32 +00:00
TblGen/AsmMatcher: Add support for honoring instruction Requires<[]> attributes as part of the matcher.
- Currently includes a hack to limit ourselves to "In32BitMode" and "In64BitMode", because we don't have the other infrastructure to properly deal with setting SSE, etc. features on X86. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@108677 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
24fdd27683
commit
54074b5f04
@ -28,14 +28,20 @@ class TargetAsmParser : public MCAsmParserExtension {
|
|||||||
protected: // Can only create subclasses.
|
protected: // Can only create subclasses.
|
||||||
TargetAsmParser(const Target &);
|
TargetAsmParser(const Target &);
|
||||||
|
|
||||||
/// TheTarget - The Target that this machine was created for.
|
/// The Target that this machine was created for.
|
||||||
const Target &TheTarget;
|
const Target &TheTarget;
|
||||||
|
|
||||||
|
/// The current set of available features.
|
||||||
|
unsigned AvailableFeatures;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~TargetAsmParser();
|
virtual ~TargetAsmParser();
|
||||||
|
|
||||||
const Target &getTarget() const { return TheTarget; }
|
const Target &getTarget() const { return TheTarget; }
|
||||||
|
|
||||||
|
unsigned getAvailableFeatures() const { return AvailableFeatures; }
|
||||||
|
void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; }
|
||||||
|
|
||||||
/// ParseInstruction - Parse one assembly instruction.
|
/// ParseInstruction - Parse one assembly instruction.
|
||||||
///
|
///
|
||||||
/// The parser is positioned following the instruction name. The target
|
/// The parser is positioned following the instruction name. The target
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
TargetAsmParser::TargetAsmParser(const Target &T)
|
TargetAsmParser::TargetAsmParser(const Target &T)
|
||||||
: TheTarget(T)
|
: TheTarget(T), AvailableFeatures(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "llvm/Target/TargetAsmParser.h"
|
#include "llvm/Target/TargetAsmParser.h"
|
||||||
#include "X86.h"
|
#include "X86.h"
|
||||||
|
#include "X86Subtarget.h"
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/ADT/StringSwitch.h"
|
#include "llvm/ADT/StringSwitch.h"
|
||||||
#include "llvm/ADT/Twine.h"
|
#include "llvm/ADT/Twine.h"
|
||||||
@ -51,12 +52,14 @@ private:
|
|||||||
|
|
||||||
void InstructionCleanup(MCInst &Inst);
|
void InstructionCleanup(MCInst &Inst);
|
||||||
|
|
||||||
/// @name Auto-generated Match Functions
|
|
||||||
/// {
|
|
||||||
|
|
||||||
bool MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
bool MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||||
MCInst &Inst);
|
MCInst &Inst);
|
||||||
|
|
||||||
|
/// @name Auto-generated Matcher Functions
|
||||||
|
/// {
|
||||||
|
|
||||||
|
unsigned ComputeAvailableFeatures(const X86Subtarget *Subtarget) const;
|
||||||
|
|
||||||
bool MatchInstructionImpl(
|
bool MatchInstructionImpl(
|
||||||
const SmallVectorImpl<MCParsedAsmOperand*> &Operands, MCInst &Inst);
|
const SmallVectorImpl<MCParsedAsmOperand*> &Operands, MCInst &Inst);
|
||||||
|
|
||||||
@ -64,7 +67,12 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
X86ATTAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &TM)
|
X86ATTAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &TM)
|
||||||
: TargetAsmParser(T), Parser(_Parser), TM(TM) {}
|
: TargetAsmParser(T), Parser(_Parser), TM(TM) {
|
||||||
|
|
||||||
|
// Initialize the set of available features.
|
||||||
|
setAvailableFeatures(ComputeAvailableFeatures(
|
||||||
|
&TM.getSubtarget<X86Subtarget>()));
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc,
|
virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc,
|
||||||
SmallVectorImpl<MCParsedAsmOperand*> &Operands);
|
SmallVectorImpl<MCParsedAsmOperand*> &Operands);
|
||||||
|
@ -271,6 +271,8 @@ static bool IsAssemblerInstruction(StringRef Name,
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
struct SubtargetFeatureInfo;
|
||||||
|
|
||||||
/// ClassInfo - Helper class for storing the information about a particular
|
/// ClassInfo - Helper class for storing the information about a particular
|
||||||
/// class of operands which can be matched.
|
/// class of operands which can be matched.
|
||||||
struct ClassInfo {
|
struct ClassInfo {
|
||||||
@ -444,6 +446,9 @@ struct InstructionInfo {
|
|||||||
/// Operands - The operands that this instruction matches.
|
/// Operands - The operands that this instruction matches.
|
||||||
SmallVector<Operand, 4> Operands;
|
SmallVector<Operand, 4> Operands;
|
||||||
|
|
||||||
|
/// Predicates - The required subtarget features to match this instruction.
|
||||||
|
SmallVector<SubtargetFeatureInfo*, 4> RequiredFeatures;
|
||||||
|
|
||||||
/// ConversionFnKind - The enum value which is passed to the generated
|
/// ConversionFnKind - The enum value which is passed to the generated
|
||||||
/// ConvertToMCInst to convert parsed operands into an MCInst for this
|
/// ConvertToMCInst to convert parsed operands into an MCInst for this
|
||||||
/// function.
|
/// function.
|
||||||
@ -505,6 +510,19 @@ public:
|
|||||||
void dump();
|
void dump();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// SubtargetFeatureInfo - Helper class for storing information on a subtarget
|
||||||
|
/// feature which participates in instruction matching.
|
||||||
|
struct SubtargetFeatureInfo {
|
||||||
|
/// \brief The predicate record for this feature.
|
||||||
|
Record *TheDef;
|
||||||
|
|
||||||
|
/// \brief An unique index assigned to represent this feature.
|
||||||
|
unsigned Index;
|
||||||
|
|
||||||
|
/// \brief The name of the enumerated constant identifying this feature.
|
||||||
|
std::string EnumName;
|
||||||
|
};
|
||||||
|
|
||||||
class AsmMatcherInfo {
|
class AsmMatcherInfo {
|
||||||
public:
|
public:
|
||||||
/// The tablegen AsmParser record.
|
/// The tablegen AsmParser record.
|
||||||
@ -525,6 +543,9 @@ public:
|
|||||||
/// Map of Register records to their class information.
|
/// Map of Register records to their class information.
|
||||||
std::map<Record*, ClassInfo*> RegisterClasses;
|
std::map<Record*, ClassInfo*> RegisterClasses;
|
||||||
|
|
||||||
|
/// Map of Predicate records to their subtarget information.
|
||||||
|
std::map<Record*, SubtargetFeatureInfo*> SubtargetFeatures;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Map of token to class information which has already been constructed.
|
/// Map of token to class information which has already been constructed.
|
||||||
std::map<std::string, ClassInfo*> TokenClasses;
|
std::map<std::string, ClassInfo*> TokenClasses;
|
||||||
@ -543,6 +564,23 @@ private:
|
|||||||
ClassInfo *getOperandClass(StringRef Token,
|
ClassInfo *getOperandClass(StringRef Token,
|
||||||
const CodeGenInstruction::OperandInfo &OI);
|
const CodeGenInstruction::OperandInfo &OI);
|
||||||
|
|
||||||
|
/// getSubtargetFeature - Lookup or create the subtarget feature info for the
|
||||||
|
/// given operand.
|
||||||
|
SubtargetFeatureInfo *getSubtargetFeature(Record *Def) {
|
||||||
|
assert(Def->isSubClassOf("Predicate") && "Invalid predicate type!");
|
||||||
|
|
||||||
|
SubtargetFeatureInfo *&Entry = SubtargetFeatures[Def];
|
||||||
|
if (!Entry) {
|
||||||
|
Entry = new SubtargetFeatureInfo;
|
||||||
|
Entry->TheDef = Def;
|
||||||
|
Entry->Index = SubtargetFeatures.size() - 1;
|
||||||
|
Entry->EnumName = "Feature_" + Def->getName();
|
||||||
|
assert(Entry->Index < 32 && "Too many subtarget features!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Entry;
|
||||||
|
}
|
||||||
|
|
||||||
/// BuildRegisterClasses - Build the ClassInfo* instances for register
|
/// BuildRegisterClasses - Build the ClassInfo* instances for register
|
||||||
/// classes.
|
/// classes.
|
||||||
void BuildRegisterClasses(CodeGenTarget &Target,
|
void BuildRegisterClasses(CodeGenTarget &Target,
|
||||||
@ -903,7 +941,31 @@ void AsmMatcherInfo::BuildInfo(CodeGenTarget &Target) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compute the require features.
|
||||||
|
ListInit *Predicates = CGI.TheDef->getValueAsListInit("Predicates");
|
||||||
|
for (unsigned i = 0, e = Predicates->getSize(); i != e; ++i) {
|
||||||
|
if (DefInit *Pred = dynamic_cast<DefInit*>(Predicates->getElement(i))) {
|
||||||
|
// Ignore OptForSize and OptForSpeed, they aren't really requirements,
|
||||||
|
// rather they are hints to isel.
|
||||||
|
//
|
||||||
|
// FIXME: Find better way to model this.
|
||||||
|
if (Pred->getDef()->getName() == "OptForSize" ||
|
||||||
|
Pred->getDef()->getName() == "OptForSpeed")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// FIXME: Total hack; for now, we just limit ourselves to In32BitMode
|
||||||
|
// and In64BitMode, because we aren't going to have the right feature
|
||||||
|
// masks for SSE and friends. We need to decide what we are going to do
|
||||||
|
// about CPU subtypes to implement this the right way.
|
||||||
|
if (Pred->getDef()->getName() != "In32BitMode" &&
|
||||||
|
Pred->getDef()->getName() != "In64BitMode")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
II->RequiredFeatures.push_back(getSubtargetFeature(Pred->getDef()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Instructions.push_back(II.take());
|
Instructions.push_back(II.take());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1499,6 +1561,48 @@ static void EmitMatchRegisterName(CodeGenTarget &Target, Record *AsmParser,
|
|||||||
OS << "}\n\n";
|
OS << "}\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// EmitSubtargetFeatureFlagEnumeration - Emit the subtarget feature flag
|
||||||
|
/// definitions.
|
||||||
|
static void EmitSubtargetFeatureFlagEnumeration(CodeGenTarget &Target,
|
||||||
|
AsmMatcherInfo &Info,
|
||||||
|
raw_ostream &OS) {
|
||||||
|
OS << "// Flags for subtarget features that participate in "
|
||||||
|
<< "instruction matching.\n";
|
||||||
|
OS << "enum SubtargetFeatureFlag {\n";
|
||||||
|
for (std::map<Record*, SubtargetFeatureInfo*>::const_iterator
|
||||||
|
it = Info.SubtargetFeatures.begin(),
|
||||||
|
ie = Info.SubtargetFeatures.end(); it != ie; ++it) {
|
||||||
|
SubtargetFeatureInfo &SFI = *it->second;
|
||||||
|
OS << " " << SFI.EnumName << " = (1 << " << SFI.Index << "),\n";
|
||||||
|
}
|
||||||
|
OS << " Feature_None = 0\n";
|
||||||
|
OS << "};\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// EmitComputeAvailableFeatures - Emit the function to compute the list of
|
||||||
|
/// available features given a subtarget.
|
||||||
|
static void EmitComputeAvailableFeatures(CodeGenTarget &Target,
|
||||||
|
AsmMatcherInfo &Info,
|
||||||
|
raw_ostream &OS) {
|
||||||
|
std::string ClassName =
|
||||||
|
Info.AsmParser->getValueAsString("AsmParserClassName");
|
||||||
|
|
||||||
|
OS << "unsigned " << Target.getName() << ClassName << "::\n"
|
||||||
|
<< "ComputeAvailableFeatures(const " << Target.getName()
|
||||||
|
<< "Subtarget *Subtarget) const {\n";
|
||||||
|
OS << " unsigned Features = 0;\n";
|
||||||
|
for (std::map<Record*, SubtargetFeatureInfo*>::const_iterator
|
||||||
|
it = Info.SubtargetFeatures.begin(),
|
||||||
|
ie = Info.SubtargetFeatures.end(); it != ie; ++it) {
|
||||||
|
SubtargetFeatureInfo &SFI = *it->second;
|
||||||
|
OS << " if (" << SFI.TheDef->getValueAsString("CondString")
|
||||||
|
<< ")\n";
|
||||||
|
OS << " Features |= " << SFI.EnumName << ";\n";
|
||||||
|
}
|
||||||
|
OS << " return Features;\n";
|
||||||
|
OS << "}\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
void AsmMatcherEmitter::run(raw_ostream &OS) {
|
void AsmMatcherEmitter::run(raw_ostream &OS) {
|
||||||
CodeGenTarget Target;
|
CodeGenTarget Target;
|
||||||
Record *AsmParser = Target.getAsmParser();
|
Record *AsmParser = Target.getAsmParser();
|
||||||
@ -1550,6 +1654,9 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
|||||||
|
|
||||||
EmitSourceFileHeader("Assembly Matcher Source Fragment", OS);
|
EmitSourceFileHeader("Assembly Matcher Source Fragment", OS);
|
||||||
|
|
||||||
|
// Emit the subtarget feature enumeration.
|
||||||
|
EmitSubtargetFeatureFlagEnumeration(Target, Info, OS);
|
||||||
|
|
||||||
// Emit the function to match a register name to number.
|
// Emit the function to match a register name to number.
|
||||||
EmitMatchRegisterName(Target, AsmParser, OS);
|
EmitMatchRegisterName(Target, AsmParser, OS);
|
||||||
|
|
||||||
@ -1570,6 +1677,9 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
|||||||
// Emit the subclass predicate routine.
|
// Emit the subclass predicate routine.
|
||||||
EmitIsSubclass(Target, Info.Classes, OS);
|
EmitIsSubclass(Target, Info.Classes, OS);
|
||||||
|
|
||||||
|
// Emit the available features compute function.
|
||||||
|
EmitComputeAvailableFeatures(Target, Info, OS);
|
||||||
|
|
||||||
// Finally, build the match function.
|
// Finally, build the match function.
|
||||||
|
|
||||||
size_t MaxNumOperands = 0;
|
size_t MaxNumOperands = 0;
|
||||||
@ -1600,6 +1710,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
|||||||
OS << " unsigned Opcode;\n";
|
OS << " unsigned Opcode;\n";
|
||||||
OS << " ConversionKind ConvertFn;\n";
|
OS << " ConversionKind ConvertFn;\n";
|
||||||
OS << " MatchClassKind Classes[" << MaxNumOperands << "];\n";
|
OS << " MatchClassKind Classes[" << MaxNumOperands << "];\n";
|
||||||
|
OS << " unsigned RequiredFeatures;\n";
|
||||||
OS << " } MatchTable[" << Info.Instructions.size() << "] = {\n";
|
OS << " } MatchTable[" << Info.Instructions.size() << "] = {\n";
|
||||||
|
|
||||||
for (std::vector<InstructionInfo*>::const_iterator it =
|
for (std::vector<InstructionInfo*>::const_iterator it =
|
||||||
@ -1615,11 +1726,27 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
|||||||
if (i) OS << ", ";
|
if (i) OS << ", ";
|
||||||
OS << Op.Class->Name;
|
OS << Op.Class->Name;
|
||||||
}
|
}
|
||||||
OS << " } },\n";
|
OS << " }, ";
|
||||||
|
|
||||||
|
// Write the required features mask.
|
||||||
|
if (!II.RequiredFeatures.empty()) {
|
||||||
|
for (unsigned i = 0, e = II.RequiredFeatures.size(); i != e; ++i) {
|
||||||
|
if (i) OS << "|";
|
||||||
|
OS << II.RequiredFeatures[i]->EnumName;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
OS << "0";
|
||||||
|
|
||||||
|
OS << "},\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
OS << " };\n\n";
|
OS << " };\n\n";
|
||||||
|
|
||||||
|
|
||||||
|
// Emit code to get the available features.
|
||||||
|
OS << " // Get the current feature set.\n";
|
||||||
|
OS << " unsigned AvailableFeatures = getAvailableFeatures();\n\n";
|
||||||
|
|
||||||
// Emit code to compute the class list for this operand vector.
|
// Emit code to compute the class list for this operand vector.
|
||||||
OS << " // Eliminate obvious mismatches.\n";
|
OS << " // Eliminate obvious mismatches.\n";
|
||||||
OS << " if (Operands.size() > " << MaxNumOperands << ")\n";
|
OS << " if (Operands.size() > " << MaxNumOperands << ")\n";
|
||||||
@ -1645,6 +1772,13 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
|||||||
OS << " for (const MatchEntry *it = MatchTable, "
|
OS << " for (const MatchEntry *it = MatchTable, "
|
||||||
<< "*ie = MatchTable + " << Info.Instructions.size()
|
<< "*ie = MatchTable + " << Info.Instructions.size()
|
||||||
<< "; it != ie; ++it) {\n";
|
<< "; it != ie; ++it) {\n";
|
||||||
|
|
||||||
|
// Emit check that the required features are available.
|
||||||
|
OS << " if ((AvailableFeatures & it->RequiredFeatures) "
|
||||||
|
<< "!= it->RequiredFeatures)\n";
|
||||||
|
OS << " continue;\n";
|
||||||
|
|
||||||
|
// Emit check that the subclasses match.
|
||||||
for (unsigned i = 0; i != MaxNumOperands; ++i) {
|
for (unsigned i = 0; i != MaxNumOperands; ++i) {
|
||||||
OS << " if (!IsSubclass(Classes["
|
OS << " if (!IsSubclass(Classes["
|
||||||
<< i << "], it->Classes[" << i << "]))\n";
|
<< i << "], it->Classes[" << i << "]))\n";
|
||||||
|
Loading…
Reference in New Issue
Block a user