aboutsummaryrefslogtreecommitdiffstats
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)
downloadexternal_llvm-98c870f87b7f0c996a9ba67003d88d434d6dbcd0.zip
external_llvm-98c870f87b7f0c996a9ba67003d88d434d6dbcd0.tar.gz
external_llvm-98c870f87b7f0c996a9ba67003d88d434d6dbcd0.tar.bz2
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 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<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 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.