// 2. The operand matcher will try every possible entry with the same
// mnemonic and will check if the target feature for this mnemonic also
// matches. After that, if the operand to be matched has its index
-// present in the mask, a successfull match occurs. Otherwise, fallback
+// present in the mask, a successful match occurs. Otherwise, fallback
// to the regular operand parsing.
//
// 3. For a match success, each operand class that has a 'ParserMethod'
#include "AsmMatcherEmitter.h"
#include "CodeGenTarget.h"
+#include "Error.h"
#include "Record.h"
#include "StringMatcher.h"
#include "llvm/ADT/OwningPtr.h"
return ValueName < RHS.ValueName;
default:
- // This class preceeds the RHS if it is a proper subset of the RHS.
+ // This class precedes the RHS if it is a proper subset of the RHS.
if (isSubsetOf(RHS))
return true;
if (RHS.isSubsetOf(*this))
if (SubOpIdx != -1)
Rec = dynamic_cast<DefInit*>(OI.MIOperandInfo->getArg(SubOpIdx))->getDef();
+ if (Rec->isSubClassOf("RegisterOperand")) {
+ // RegisterOperand may have an associated ParserMatchClass. If it does,
+ // use it, else just fall back to the underlying register class.
+ const RecordVal *R = Rec->getValue("ParserMatchClass");
+ if (R == 0 || R->getValue() == 0)
+ throw "Record `" + Rec->getName() +
+ "' does not have a ParserMatchClass!\n";
+
+ if (DefInit *DI= dynamic_cast<DefInit*>(R->getValue())) {
+ Record *MatchClass = DI->getDef();
+ if (ClassInfo *CI = AsmOperandClasses[MatchClass])
+ return CI;
+ }
+
+ // No custom match class. Just use the register class.
+ Record *ClassRec = Rec->getValueAsDef("RegClass");
+ if (!ClassRec)
+ throw TGError(Rec->getLoc(), "RegisterOperand `" + Rec->getName() +
+ "' has no associated register class!\n");
+ if (ClassInfo *CI = RegisterClassClasses[ClassRec])
+ return CI;
+ throw TGError(Rec->getLoc(), "register class has no class info!");
+ }
+
+
if (Rec->isSubClassOf("RegisterClass")) {
if (ClassInfo *CI = RegisterClassClasses[Rec])
return CI;
void AsmMatcherInfo::
BuildRegisterClasses(SmallPtrSet<Record*, 16> &SingletonRegisters) {
- const std::vector<CodeGenRegister> &Registers = Target.getRegisters();
+ const std::vector<CodeGenRegister*> &Registers =
+ Target.getRegBank().getRegisters();
const std::vector<CodeGenRegisterClass> &RegClassList =
Target.getRegisterClasses();
// Gather the defined sets.
for (std::vector<CodeGenRegisterClass>::const_iterator it =
RegClassList.begin(), ie = RegClassList.end(); it != ie; ++it)
- RegisterSets.insert(std::set<Record*>(it->Elements.begin(),
- it->Elements.end()));
+ RegisterSets.insert(std::set<Record*>(it->getOrder().begin(),
+ it->getOrder().end()));
// Add any required singleton sets.
for (SmallPtrSet<Record*, 16>::iterator it = SingletonRegisters.begin(),
// a unique register set class), and build the mapping of registers to the set
// they should classify to.
std::map<Record*, std::set<Record*> > RegisterMap;
- for (std::vector<CodeGenRegister>::const_iterator it = Registers.begin(),
+ for (std::vector<CodeGenRegister*>::const_iterator it = Registers.begin(),
ie = Registers.end(); it != ie; ++it) {
- const CodeGenRegister &CGR = *it;
+ const CodeGenRegister &CGR = **it;
// Compute the intersection of all sets containing this register.
std::set<Record*> ContainingSet;
// Name the register classes which correspond to a user defined RegisterClass.
for (std::vector<CodeGenRegisterClass>::const_iterator
it = RegClassList.begin(), ie = RegClassList.end(); it != ie; ++it) {
- ClassInfo *CI = RegisterSetClasses[std::set<Record*>(it->Elements.begin(),
- it->Elements.end())];
+ ClassInfo *CI = RegisterSetClasses[std::set<Record*>(it->getOrder().begin(),
+ it->getOrder().end())];
if (CI->ValueName.empty()) {
CI->ClassName = it->getName();
CI->Name = "MCK_" + it->getName();
II->BuildAliasResultOperands();
}
- // Reorder classes so that classes preceed super classes.
+ // Reorder classes so that classes precede super classes.
std::sort(Classes.begin(), Classes.end(), less_ptr<ClassInfo>());
}
MatchableInfo &II = **it;
// Check if we have a custom match function.
- StringRef AsmMatchConverter = II.getResultInst()->TheDef->getValueAsString(
- "AsmMatchConverter");
+ std::string AsmMatchConverter =
+ II.getResultInst()->TheDef->getValueAsString("AsmMatchConverter");
if (!AsmMatchConverter.empty()) {
- std::string Signature = "ConvertCustom_" + AsmMatchConverter.str();
+ std::string Signature = "ConvertCustom_" + AsmMatchConverter;
II.ConversionFnKind = Signature;
// Check if we have already generated this signature.
// operand from the earlier one.We can only tie single MCOperand values.
//assert(OpInfo.MINumOperands == 1 && "Not a singular MCOperand");
unsigned TiedOp = OpInfo.TiedOperandNum;
- assert(i > TiedOp && "Tied operand preceeds its target!");
+ assert(i > TiedOp && "Tied operand precedes its target!");
CaseOS << " Inst.addOperand(Inst.getOperand(" << TiedOp << "));\n";
Signature += "__Tie" + utostr(TiedOp);
break;
raw_ostream &OS) {
// Construct the match list.
std::vector<StringMatcher::StringPair> Matches;
- for (unsigned i = 0, e = Target.getRegisters().size(); i != e; ++i) {
- const CodeGenRegister &Reg = Target.getRegisters()[i];
- if (Reg.TheDef->getValueAsString("AsmName").empty())
+ const std::vector<CodeGenRegister*> &Regs =
+ Target.getRegBank().getRegisters();
+ for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
+ const CodeGenRegister *Reg = Regs[i];
+ if (Reg->TheDef->getValueAsString("AsmName").empty())
continue;
Matches.push_back(StringMatcher::StringPair(
- Reg.TheDef->getValueAsString("AsmName"),
- "return " + utostr(i + 1) + ";"));
+ Reg->TheDef->getValueAsString("AsmName"),
+ "return " + utostr(Reg->EnumValue) + ";"));
}
OS << "static unsigned MatchRegisterName(StringRef Name) {\n";
AliasWithNoPredicate = i;
continue;
}
+ if (R->getValueAsString("ToMnemonic") == I->first)
+ throw TGError(R->getLoc(), "MnemonicAlias to the same string");
if (!MatchCode.empty())
MatchCode += "else ";
OS << " for (unsigned i = 0; i != " << MaxNumOperands << "; ++i) {\n";
OS << " if (i + 1 >= Operands.size()) {\n";
OS << " OperandsValid = (it->Classes[i] == " <<"InvalidMatchClass);\n";
- OS << " break;";
+ OS << " break;\n";
OS << " }\n";
OS << " if (ValidateOperandClass(Operands[i+1], it->Classes[i]))\n";
OS << " continue;\n";