aboutsummaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-11-06 19:25:43 +0000
committerChris Lattner <sabre@nondot.org>2010-11-06 19:25:43 +0000
commit98c870f87b7f0c996a9ba67003d88d434d6dbcd0 (patch)
tree3f02eb16478f4bae0f26a1164476630369829573 /utils
parentdea546b62339578938a91f05a00a145baf921f6c (diff)
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
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/AsmMatcherEmitter.cpp59
-rw-r--r--utils/TableGen/CodeGenInstruction.cpp15
-rw-r--r--utils/TableGen/CodeGenInstruction.h18
3 files changed, 71 insertions, 21 deletions
diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp
index 23d370c506..46866140eb 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 40d4206b30..924608cbf0 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<IntInit*>(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 f5b2239636..ac593dfb17 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.