Refactor.

Store AsmParser info locally. A small step towards emitting match entries for multiple asm variants.

llvm-svn: 147710
This commit is contained in:
Devang Patel 2012-01-07 01:33:34 +00:00
parent f730f39f3f
commit 6d676e45df
1 changed files with 45 additions and 38 deletions

View File

@ -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;
}
StringRef RegName = Tok.substr(Info.RegisterPrefix.size());
if (!Tok.startswith(RegisterPrefix))
return;
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");