mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-26 13:10:34 +00:00
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:
parent
662e5a30e8
commit
414098571b
@ -983,17 +983,6 @@ ParseInstruction(StringRef Name, SMLoc NameLoc,
|
||||
Operands[0] = X86Operand::CreateToken("fstps", NameLoc);
|
||||
}
|
||||
|
||||
|
||||
// "clr <reg>" -> "xor <reg>, <reg>".
|
||||
if ((Name == "clrb" || Name == "clrw" || Name == "clrl" || Name == "clrq" ||
|
||||
Name == "clr") && Operands.size() == 2 &&
|
||||
static_cast<X86Operand*>(Operands[1])->isReg()) {
|
||||
unsigned RegNo = static_cast<X86Operand*>(Operands[1])->getReg();
|
||||
Operands.push_back(X86Operand::CreateReg(RegNo, NameLoc, NameLoc));
|
||||
delete Operands[0];
|
||||
Operands[0] = X86Operand::CreateToken("xor", NameLoc);
|
||||
}
|
||||
|
||||
// FIXME: Hack to handle recognize "aa[dm]" -> "aa[dm] $0xA".
|
||||
if ((Name.startswith("aad") || Name.startswith("aam")) &&
|
||||
Operands.size() == 1) {
|
||||
|
@ -1370,6 +1370,12 @@ defm : IntegerCondCodeMnemonicAlias<"cmov", "q">;
|
||||
// Assembler Instruction Aliases
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// clr aliases.
|
||||
def : InstAlias<"clrb $reg", (XOR8rr GR8 :$reg, GR8 :$reg)>;
|
||||
def : InstAlias<"clrw $reg", (XOR16rr GR16:$reg, GR16:$reg)>;
|
||||
def : InstAlias<"clrl $reg", (XOR32rr GR32:$reg, GR32:$reg)>;
|
||||
def : InstAlias<"clrq $reg", (XOR64rr GR64:$reg, GR64:$reg)>;
|
||||
|
||||
// movsx aliases
|
||||
def : InstAlias<"movsx $src, $dst",
|
||||
(MOVSX16rr8W GR16:$dst, GR8:$src)>;
|
||||
|
@ -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,
|
||||
|
@ -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!");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user