fix some bugs in the alias support, unblocking changing of "clr" aliases

from c++ hacks to proper .td InstAlias definitions.  Change them!


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118330 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner
2010-11-06 07:31:43 +00:00
parent 662e5a30e8
commit 414098571b
4 changed files with 71 additions and 29 deletions

View File

@@ -372,7 +372,8 @@ struct MatchableInfo {
return -1;
}
void BuildResultOperands();
void BuildInstructionResultOperands();
void BuildAliasResultOperands();
/// operator< - Compare two matchables.
bool operator<(const MatchableInfo &RHS) const {
@@ -1112,7 +1113,10 @@ void AsmMatcherInfo::BuildInfo() {
BuildAliasOperandReference(II, OperandName, Op);
}
II->BuildResultOperands();
if (II->DefRec.is<const CodeGenInstruction*>())
II->BuildInstructionResultOperands();
else
II->BuildAliasResultOperands();
}
// Reorder classes so that classes preceed super classes.
@@ -1182,7 +1186,7 @@ void AsmMatcherInfo::BuildAliasOperandReference(MatchableInfo *II,
OperandName.str() + "'");
}
void MatchableInfo::BuildResultOperands() {
void MatchableInfo::BuildInstructionResultOperands() {
const CodeGenInstruction *ResultInst = getResultInst();
// Loop over all operands of the result instruction, determining how to
@@ -1212,6 +1216,36 @@ void MatchableInfo::BuildResultOperands() {
}
}
void MatchableInfo::BuildAliasResultOperands() {
const CodeGenInstAlias &CGA = *DefRec.get<const CodeGenInstAlias*>();
const CodeGenInstruction *ResultInst = getResultInst();
// Loop over all operands of the result instruction, determining how to
// populate them.
unsigned AliasOpNo = 0;
for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) {
const CGIOperandList::OperandInfo &OpInfo = ResultInst->Operands[i];
// If this is a tied operand, just copy from the previously handled operand.
int TiedOp = OpInfo.getTiedRegister();
if (TiedOp != -1) {
ResOperands.push_back(ResOperand::getTiedOp(TiedOp, &OpInfo));
continue;
}
// Find out what operand from the asmparser that this MCInst operand comes
// from.
int SrcOperand = FindAsmOperandNamed(CGA.ResultOperands[AliasOpNo++].Name);
if (SrcOperand != -1) {
ResOperands.push_back(ResOperand::getRenderedOp(SrcOperand, &OpInfo));
continue;
}
throw TGError(TheDef->getLoc(), "Instruction '" +
TheDef->getName() + "' has operand '" + OpInfo.Name +
"' that doesn't appear in asm string!");
}
}
static void EmitConvertToMCInst(CodeGenTarget &Target,
std::vector<MatchableInfo*> &Infos,

View File

@@ -400,30 +400,35 @@ CodeGenInstAlias::CodeGenInstAlias(Record *R, CodeGenTarget &T) : TheDef(R) {
ResultInst = &T.getInstruction(DI->getDef());
// Check number of arguments in the result.
if (ResultInst->Operands.size() != Result->getNumArgs())
throw TGError(R->getLoc(), "result has " + utostr(Result->getNumArgs()) +
" arguments, but " + ResultInst->TheDef->getName() +
" instruction expects " + utostr(ResultInst->Operands.size())+
" operands!");
// NameClass - If argument names are repeated, we need to verify they have
// the same class.
StringMap<Record*> NameClass;
// Decode and validate the arguments of the result.
for (unsigned i = 0, e = Result->getNumArgs(); i != e; ++i) {
Init *Arg = Result->getArg(i);
unsigned AliasOpNo = 0;
for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) {
// Tied registers don't have an entry in the result dag.
if (ResultInst->Operands[i].getTiedRegister() != -1)
continue;
if (AliasOpNo >= Result->getNumArgs())
throw TGError(R->getLoc(), "result has " + utostr(Result->getNumArgs()) +
" arguments, but " + ResultInst->TheDef->getName() +
" instruction expects " +
utostr(ResultInst->Operands.size()) + " operands!");
Init *Arg = Result->getArg(AliasOpNo);
// If the operand is a record, it must have a name, and the record type must
// match up with the instruction's argument type.
if (DefInit *ADI = dynamic_cast<DefInit*>(Arg)) {
if (Result->getArgName(i).empty())
throw TGError(R->getLoc(), "result argument #" + utostr(i) +
if (Result->getArgName(AliasOpNo).empty())
throw TGError(R->getLoc(), "result argument #" + utostr(AliasOpNo) +
" must have a name!");
if (ADI->getDef() != ResultInst->Operands[i].Rec)
throw TGError(R->getLoc(), "result argument #" + utostr(i) +
throw TGError(R->getLoc(), "result argument #" + utostr(AliasOpNo) +
" declared with class " + ADI->getDef()->getName() +
", instruction operand is class " +
ResultInst->Operands[i].Rec->getName());
@@ -431,18 +436,26 @@ CodeGenInstAlias::CodeGenInstAlias(Record *R, CodeGenTarget &T) : TheDef(R) {
// Verify we don't have something like: (someinst GR16:$foo, GR32:$foo)
// $foo can exist multiple times in the result list, but it must have the
// same type.
Record *&Entry = NameClass[Result->getArgName(i)];
Record *&Entry = NameClass[Result->getArgName(AliasOpNo)];
if (Entry && Entry != ADI->getDef())
throw TGError(R->getLoc(), "result value $" + Result->getArgName(i) +
throw TGError(R->getLoc(), "result value $" +
Result->getArgName(AliasOpNo) +
" is both " + Entry->getName() + " and " +
ADI->getDef()->getName() + "!");
// Now that it is validated, add it.
ResultOperands.push_back(ResultOperand(Result->getArgName(i),
ResultOperands.push_back(ResultOperand(Result->getArgName(AliasOpNo),
ADI->getDef()));
++AliasOpNo;
continue;
}
throw TGError(R->getLoc(), "result of inst alias has unknown operand type");
}
if (AliasOpNo != Result->getNumArgs())
throw TGError(R->getLoc(), "result has " + utostr(Result->getNumArgs()) +
" arguments, but " + ResultInst->TheDef->getName() +
" instruction expects " + utostr(ResultInst->Operands.size())+
" operands!");
}