From 98c870f87b7f0c996a9ba67003d88d434d6dbcd0 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 6 Nov 2010 19:25:43 +0000 Subject: generalize alias support to allow the result of an alias to add fixed immediate values. Move the aad and aam aliases to use this, and document it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118350 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/AsmMatcherEmitter.cpp | 59 +++++++++++++++++++++++------------ utils/TableGen/CodeGenInstruction.cpp | 15 +++++++++ utils/TableGen/CodeGenInstruction.h | 18 ++++++++++- 3 files changed, 71 insertions(+), 21 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index 23d370c..4686614 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -270,7 +270,11 @@ struct MatchableInfo { /// TiedOperand - This represents a result operand that is a duplicate of /// a previous result operand. - TiedOperand + TiedOperand, + + /// ImmOperand - This represents an immediate value that is dumped into + /// the operand. + ImmOperand } Kind; union { @@ -281,6 +285,9 @@ struct MatchableInfo { /// TiedOperandNum - This is the (earlier) result operand that should be /// copied from. unsigned TiedOperandNum; + + /// ImmVal - This is the immediate value added to the instruction. + int64_t ImmVal; }; /// OpInfo - This is the information about the instruction operand that is @@ -304,6 +311,15 @@ struct MatchableInfo { X.OpInfo = Op; return X; } + + static ResOperand getImmOp(int64_t Val, + const CGIOperandList::OperandInfo *Op) { + ResOperand X; + X.Kind = ImmOperand; + X.ImmVal = Val; + X.OpInfo = Op; + return X; + } }; /// TheDef - This is the definition of the instruction or InstAlias that this @@ -538,16 +554,6 @@ void MatchableInfo::dump() { AsmOperand &Op = AsmOperands[i]; errs() << " op[" << i << "] = " << Op.Class->ClassName << " - "; errs() << '\"' << Op.Token << "\"\n"; -#if 0 - if (!Op.OperandInfo) { - errs() << "(singleton register)\n"; - continue; - } - - const CGIOperandList::OperandInfo &OI = *Op.OperandInfo; - errs() << OI.Name << " " << OI.Rec->getName() - << " (" << OI.MIOperandNo << ", " << OI.MINumOperands << ")\n"; -#endif } } @@ -1174,7 +1180,8 @@ void AsmMatcherInfo::BuildAliasOperandReference(MatchableInfo *II, // Set up the operand class. for (unsigned i = 0, e = CGA.ResultOperands.size(); i != e; ++i) - if (CGA.ResultOperands[i].Name == OperandName) { + if (CGA.ResultOperands[i].isRecord() && + CGA.ResultOperands[i].getName() == OperandName) { // It's safe to go with the first one we find, because CodeGenInstAlias // validates that all operands with the same name have the same record. unsigned ResultIdx =CGA.getResultInstOperandIndexForResultOperandIndex(i); @@ -1236,15 +1243,22 @@ void MatchableInfo::BuildAliasResultOperands() { // 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; + if (CGA.ResultOperands[AliasOpNo].isRecord()) { + StringRef Name = CGA.ResultOperands[AliasOpNo++].getName(); + int SrcOperand = FindAsmOperandNamed(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!"); } - throw TGError(TheDef->getLoc(), "Instruction '" + - TheDef->getName() + "' has operand '" + OpInfo.Name + - "' that doesn't appear in asm string!"); + int64_t ImmVal = CGA.ResultOperands[AliasOpNo++].getImm(); + ResOperands.push_back(ResOperand::getImmOp(ImmVal, &OpInfo)); + continue; } } @@ -1291,7 +1305,6 @@ static void EmitConvertToMCInst(CodeGenTarget &Target, // Generate code to populate each result operand. switch (OpInfo.Kind) { - default: assert(0 && "Unknown result operand kind"); case MatchableInfo::ResOperand::RenderAsmOperand: { // This comes from something we parsed. MatchableInfo::AsmOperand &Op = II.AsmOperands[OpInfo.AsmOperandNum]; @@ -1322,6 +1335,12 @@ static void EmitConvertToMCInst(CodeGenTarget &Target, Signature += "__Tie" + utostr(TiedOp); break; } + case MatchableInfo::ResOperand::ImmOperand: { + int64_t Val = OpInfo.ImmVal; + CaseOS << " Inst.addOperand(MCOperand::CreateImm(" << Val << "));\n"; + Signature += "__imm" + itostr(Val); + break; + } } } diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp index 40d4206..924608c 100644 --- a/utils/TableGen/CodeGenInstruction.cpp +++ b/utils/TableGen/CodeGenInstruction.cpp @@ -449,6 +449,21 @@ CodeGenInstAlias::CodeGenInstAlias(Record *R, CodeGenTarget &T) : TheDef(R) { ++AliasOpNo; continue; } + + if (IntInit *II = dynamic_cast(Arg)) { + // Integer arguments can't have names. + if (!Result->getArgName(AliasOpNo).empty()) + throw TGError(R->getLoc(), "result argument #" + utostr(AliasOpNo) + + " must not have a name!"); + if (ResultInst->Operands[i].MINumOperands != 1 || + !ResultInst->Operands[i].Rec->isSubClassOf("Operand")) + throw TGError(R->getLoc(), "invalid argument class " + + ResultInst->Operands[i].Rec->getName() + + " for integer result operand!"); + ResultOperands.push_back(ResultOperand(II->getValue())); + ++AliasOpNo; + continue; + } throw TGError(R->getLoc(), "result of inst alias has unknown operand type"); } diff --git a/utils/TableGen/CodeGenInstruction.h b/utils/TableGen/CodeGenInstruction.h index f5b2239..ac593df 100644 --- a/utils/TableGen/CodeGenInstruction.h +++ b/utils/TableGen/CodeGenInstruction.h @@ -267,10 +267,26 @@ namespace llvm { struct ResultOperand { + private: StringRef Name; Record *R; - ResultOperand(StringRef N, Record *r) : Name(N), R(r) {} + int64_t Imm; + public: + enum { + K_Record, + K_Imm + } Kind; + + ResultOperand(StringRef N, Record *r) : Name(N), R(r), Kind(K_Record) {} + ResultOperand(int64_t I) : Imm(I), Kind(K_Imm) {} + + bool isRecord() const { return Kind == K_Record; } + bool isImm() const { return Kind == K_Imm; } + + StringRef getName() const { assert(isRecord()); return Name; } + Record *getRecord() const { assert(isRecord()); return R; } + int64_t getImm() const { assert(isImm()); return Imm; } }; /// ResultOperands - The decoded operands for the result instruction. -- cgit v1.1