aboutsummaryrefslogtreecommitdiffstats
path: root/utils/TableGen/AsmMatcherEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/TableGen/AsmMatcherEmitter.cpp')
-rw-r--r--utils/TableGen/AsmMatcherEmitter.cpp83
1 files changed, 45 insertions, 38 deletions
diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp
index 3576cc9..1ab2d02 100644
--- a/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/utils/TableGen/AsmMatcherEmitter.cpp
@@ -282,7 +282,11 @@ struct MatchableInfo {
/// The suboperand index within SrcOpName, or -1 for the entire operand.
int SubOpIdx;
- explicit AsmOperand(StringRef T) : Token(T), Class(0), SubOpIdx(-1) {}
+ /// Register record if this token is singleton register.
+ Record *SingletonReg;
+
+ explicit AsmOperand(StringRef T) : Token(T), Class(0), SubOpIdx(-1),
+ SingletonReg(0) {}
};
/// ResOperand - This represents a single operand in the result instruction
@@ -409,16 +413,18 @@ struct MatchableInfo {
}
void Initialize(const AsmMatcherInfo &Info,
- SmallPtrSet<Record*, 16> &SingletonRegisters);
+ SmallPtrSet<Record*, 16> &SingletonRegisters,
+ int AsmVariantNo, std::string &RegisterPrefix);
/// Validate - Return true if this matchable is a valid thing to match against
/// and perform a bunch of validity checking.
bool Validate(StringRef CommentDelimiter, bool Hack) const;
- /// getSingletonRegisterForAsmOperand - If the specified token is a singleton
- /// register, return the Record for it, otherwise return null.
- Record *getSingletonRegisterForAsmOperand(unsigned i,
- const AsmMatcherInfo &Info) const;
+ /// extractSingletonRegisterForAsmOperand - Extract singleton register,
+ /// if present, from specified token.
+ void
+ extractSingletonRegisterForAsmOperand(unsigned i, const AsmMatcherInfo &Info,
+ std::string &RegisterPrefix);
/// FindAsmOperand - Find the AsmOperand with the specified name and
/// suboperand index.
@@ -552,12 +558,6 @@ public:
/// Target - The target information.
CodeGenTarget &Target;
- /// The AsmParser "RegisterPrefix" value.
- std::string RegisterPrefix;
-
- /// The AsmParser variant number.
- int AsmVariantNo;
-
/// The classes which are needed for matching.
std::vector<ClassInfo*> Classes;
@@ -644,10 +644,11 @@ void MatchableInfo::dump() {
}
void MatchableInfo::Initialize(const AsmMatcherInfo &Info,
- SmallPtrSet<Record*, 16> &SingletonRegisters) {
+ SmallPtrSet<Record*, 16> &SingletonRegisters,
+ int AsmVariantNo, std::string &RegisterPrefix) {
// TODO: Eventually support asmparser for Variant != 0.
AsmString =
- CodeGenInstruction::FlattenAsmStringVariants(AsmString, Info.AsmVariantNo);
+ CodeGenInstruction::FlattenAsmStringVariants(AsmString, AsmVariantNo);
TokenizeAsmString(Info);
@@ -660,7 +661,8 @@ void MatchableInfo::Initialize(const AsmMatcherInfo &Info,
// Collect singleton registers, if used.
for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) {
- if (Record *Reg = getSingletonRegisterForAsmOperand(i, Info))
+ extractSingletonRegisterForAsmOperand(i, Info, RegisterPrefix);
+ if (Record *Reg = AsmOperands[i].SingletonReg)
SingletonRegisters.insert(Reg);
}
}
@@ -740,7 +742,7 @@ void MatchableInfo::TokenizeAsmString(const AsmMatcherInfo &Info) {
throw TGError(TheDef->getLoc(),
"Instruction '" + TheDef->getName() + "' has no tokens");
Mnemonic = AsmOperands[0].Token;
- // FIXME : Check and raise an error if it is register.
+ // FIXME : Check and raise an error if it is a register.
if (Mnemonic[0] == '$')
throw TGError(TheDef->getLoc(),
"Invalid instruction mnemonic '" + Mnemonic.str() + "'!");
@@ -804,28 +806,33 @@ bool MatchableInfo::Validate(StringRef CommentDelimiter, bool Hack) const {
return true;
}
-/// getSingletonRegisterForAsmOperand - If the specified token is a singleton
-/// register, return the register name, otherwise return a null StringRef.
-Record *MatchableInfo::
-getSingletonRegisterForAsmOperand(unsigned i, const AsmMatcherInfo &Info) const{
+/// extractSingletonRegisterForAsmOperand - Extract singleton register, if present,
+/// from specified token.
+void MatchableInfo::
+extractSingletonRegisterForAsmOperand(unsigned i, const AsmMatcherInfo &Info,
+ std::string &RegisterPrefix) {
StringRef Tok = AsmOperands[i].Token;
- if (!Tok.startswith(Info.RegisterPrefix))
- return 0;
+ if (RegisterPrefix.empty()) {
+ if (i) {
+ std::string LoweredTok = Tok.lower();
+ if (const CodeGenRegister *Reg = Info.Target.getRegisterByName(LoweredTok))
+ AsmOperands[i].SingletonReg = Reg->TheDef;
+ } else
+ if (const CodeGenRegister *Reg = Info.Target.getRegisterByName(Tok))
+ AsmOperands[i].SingletonReg = Reg->TheDef;
+ return;
+ }
+
+ if (!Tok.startswith(RegisterPrefix))
+ return;
- StringRef RegName = Tok.substr(Info.RegisterPrefix.size());
+ StringRef RegName = Tok.substr(RegisterPrefix.size());
if (const CodeGenRegister *Reg = Info.Target.getRegisterByName(RegName))
- return Reg->TheDef;
+ AsmOperands[i].SingletonReg = Reg->TheDef;
// If there is no register prefix (i.e. "%" in "%eax"), then this may
// be some random non-register token, just ignore it.
- if (Info.RegisterPrefix.empty())
- return 0;
-
- // Otherwise, we have something invalid prefixed with the register prefix,
- // such as %foo.
- std::string Err = "unable to find register for '" + RegName.str() +
- "' (which matches register prefix)";
- throw TGError(TheDef->getLoc(), Err);
+ return;
}
static std::string getEnumNameForToken(StringRef Str) {
@@ -1109,9 +1116,7 @@ void AsmMatcherInfo::BuildOperandClasses() {
AsmMatcherInfo::AsmMatcherInfo(Record *asmParser,
CodeGenTarget &target,
RecordKeeper &records)
- : Records(records), AsmParser(asmParser), Target(target),
- RegisterPrefix(AsmParser->getValueAsString("RegisterPrefix")),
- AsmVariantNo(AsmParser->getValueAsInt("Variant")) {
+ : Records(records), AsmParser(asmParser), Target(target) {
}
/// BuildOperandMatchInfo - Build the necessary information to handle user
@@ -1167,6 +1172,8 @@ void AsmMatcherInfo::BuildInfo() {
}
std::string CommentDelimiter = AsmParser->getValueAsString("CommentDelimiter");
+ std::string RegisterPrefix = AsmParser->getValueAsString("RegisterPrefix");
+ int AsmVariantNo = AsmParser->getValueAsInt("Variant");
// Parse the instructions; we need to do this first so that we can gather the
// singleton register classes.
@@ -1207,7 +1214,7 @@ void AsmMatcherInfo::BuildInfo() {
OwningPtr<MatchableInfo> II(new MatchableInfo(CGI));
- II->Initialize(*this, SingletonRegisters);
+ II->Initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix);
// Ignore instructions which shouldn't be matched and diagnose invalid
// instruction definitions with an error.
@@ -1240,7 +1247,7 @@ void AsmMatcherInfo::BuildInfo() {
OwningPtr<MatchableInfo> II(new MatchableInfo(Alias));
- II->Initialize(*this, SingletonRegisters);
+ II->Initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix);
// Validate the alias definitions.
II->Validate(CommentDelimiter, false);
@@ -1268,7 +1275,7 @@ void AsmMatcherInfo::BuildInfo() {
StringRef Token = Op.Token;
// Check for singleton registers.
- if (Record *RegRecord = II->getSingletonRegisterForAsmOperand(i, *this)) {
+ if (Record *RegRecord = II->AsmOperands[i].SingletonReg) {
Op.Class = RegisterClasses[RegRecord];
assert(Op.Class && Op.Class->Registers.size() == 1 &&
"Unexpected class for singleton register");