summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/utils/TableGen/CodeEmitterGen.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2014-11-24 17:02:24 +0000
committerdim <dim@FreeBSD.org>2014-11-24 17:02:24 +0000
commit2c8643c6396b0a3db33430cf9380e70bbb9efce0 (patch)
tree4df130b28021d86e13bf4565ef58c1c5a5e093b4 /contrib/llvm/utils/TableGen/CodeEmitterGen.cpp
parent678318cd20f7db4e6c6b85d83fe00fa327b04fca (diff)
parente27feadae0885aa074df58ebfda2e7a7f7a7d590 (diff)
downloadFreeBSD-src-2c8643c6396b0a3db33430cf9380e70bbb9efce0.zip
FreeBSD-src-2c8643c6396b0a3db33430cf9380e70bbb9efce0.tar.gz
Merge llvm 3.5.0 release from ^/vendor/llvm/dist, resolve conflicts, and
preserve our customizations, where necessary.
Diffstat (limited to 'contrib/llvm/utils/TableGen/CodeEmitterGen.cpp')
-rw-r--r--contrib/llvm/utils/TableGen/CodeEmitterGen.cpp90
1 files changed, 44 insertions, 46 deletions
diff --git a/contrib/llvm/utils/TableGen/CodeEmitterGen.cpp b/contrib/llvm/utils/TableGen/CodeEmitterGen.cpp
index c94d384..4d0c0ca 100644
--- a/contrib/llvm/utils/TableGen/CodeEmitterGen.cpp
+++ b/contrib/llvm/utils/TableGen/CodeEmitterGen.cpp
@@ -41,52 +41,16 @@ public:
void run(raw_ostream &o);
private:
- void emitMachineOpEmitter(raw_ostream &o, const std::string &Namespace);
- void emitGetValueBit(raw_ostream &o, const std::string &Namespace);
- void reverseBits(std::vector<Record*> &Insts);
int getVariableBit(const std::string &VarName, BitsInit *BI, int bit);
std::string getInstructionCase(Record *R, CodeGenTarget &Target);
void AddCodeToMergeInOperand(Record *R, BitsInit *BI,
const std::string &VarName,
unsigned &NumberedOp,
+ std::set<unsigned> &NamedOpIndices,
std::string &Case, CodeGenTarget &Target);
};
-void CodeEmitterGen::reverseBits(std::vector<Record*> &Insts) {
- for (std::vector<Record*>::iterator I = Insts.begin(), E = Insts.end();
- I != E; ++I) {
- Record *R = *I;
- if (R->getValueAsString("Namespace") == "TargetOpcode" ||
- R->getValueAsBit("isPseudo"))
- continue;
-
- BitsInit *BI = R->getValueAsBitsInit("Inst");
-
- unsigned numBits = BI->getNumBits();
-
- SmallVector<Init *, 16> NewBits(numBits);
-
- for (unsigned bit = 0, end = numBits / 2; bit != end; ++bit) {
- unsigned bitSwapIdx = numBits - bit - 1;
- Init *OrigBit = BI->getBit(bit);
- Init *BitSwap = BI->getBit(bitSwapIdx);
- NewBits[bit] = BitSwap;
- NewBits[bitSwapIdx] = OrigBit;
- }
- if (numBits % 2) {
- unsigned middle = (numBits + 1) / 2;
- NewBits[middle] = BI->getBit(middle);
- }
-
- BitsInit *NewBI = BitsInit::get(NewBits);
-
- // Update the bits in reversed order so that emitInstrOpBits will get the
- // correct endianness.
- R->getValue("Inst")->setValue(NewBI);
- }
-}
-
// If the VarBitInit at position 'bit' matches the specified variable then
// return the variable bit position. Otherwise return -1.
int CodeEmitterGen::getVariableBit(const std::string &VarName,
@@ -106,6 +70,7 @@ int CodeEmitterGen::getVariableBit(const std::string &VarName,
void CodeEmitterGen::
AddCodeToMergeInOperand(Record *R, BitsInit *BI, const std::string &VarName,
unsigned &NumberedOp,
+ std::set<unsigned> &NamedOpIndices,
std::string &Case, CodeGenTarget &Target) {
CodeGenInstruction &CGI = Target.getInstruction(R);
@@ -138,9 +103,22 @@ AddCodeToMergeInOperand(Record *R, BitsInit *BI, const std::string &VarName,
/// If this operand is not supposed to be emitted by the
/// generated emitter, skip it.
while (NumberedOp < NumberOps &&
- CGI.Operands.isFlatOperandNotEmitted(NumberedOp))
+ (CGI.Operands.isFlatOperandNotEmitted(NumberedOp) ||
+ (NamedOpIndices.size() && NamedOpIndices.count(
+ CGI.Operands.getSubOperandNumber(NumberedOp).first)))) {
++NumberedOp;
+ if (NumberedOp >= CGI.Operands.back().MIOperandNo +
+ CGI.Operands.back().MINumOperands) {
+ errs() << "Too few operands in record " << R->getName() <<
+ " (no match for variable " << VarName << "):\n";
+ errs() << *R;
+ errs() << '\n';
+
+ return;
+ }
+ }
+
OpIdx = NumberedOp++;
}
@@ -157,14 +135,14 @@ AddCodeToMergeInOperand(Record *R, BitsInit *BI, const std::string &VarName,
Case += " // op: " + VarName + "\n" +
" op = " + EncoderMethodName + "(MI, " + utostr(OpIdx);
if (MCEmitter)
- Case += ", Fixups";
+ Case += ", Fixups, STI";
Case += ");\n";
}
} else {
Case += " // op: " + VarName + "\n" +
" op = getMachineOpValue(MI, MI.getOperand(" + utostr(OpIdx) + ")";
if (MCEmitter)
- Case += ", Fixups";
+ Case += ", Fixups, STI";
Case += ");\n";
}
@@ -215,6 +193,21 @@ std::string CodeEmitterGen::getInstructionCase(Record *R,
const std::vector<RecordVal> &Vals = R->getValues();
unsigned NumberedOp = 0;
+ std::set<unsigned> NamedOpIndices;
+ // Collect the set of operand indices that might correspond to named
+ // operand, and skip these when assigning operands based on position.
+ if (Target.getInstructionSet()->
+ getValueAsBit("noNamedPositionallyEncodedOperands")) {
+ CodeGenInstruction &CGI = Target.getInstruction(R);
+ for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
+ unsigned OpIdx;
+ if (!CGI.Operands.hasOperandNamed(Vals[i].getName(), OpIdx))
+ continue;
+
+ NamedOpIndices.insert(OpIdx);
+ }
+ }
+
// Loop over all of the fields in the instruction, determining which are the
// operands to the instruction.
for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
@@ -223,12 +216,17 @@ std::string CodeEmitterGen::getInstructionCase(Record *R,
if (Vals[i].getPrefix() || Vals[i].getValue()->isComplete())
continue;
- AddCodeToMergeInOperand(R, BI, Vals[i].getName(), NumberedOp, Case, Target);
+ AddCodeToMergeInOperand(R, BI, Vals[i].getName(), NumberedOp,
+ NamedOpIndices, Case, Target);
}
std::string PostEmitter = R->getValueAsString("PostEncoderMethod");
- if (!PostEmitter.empty())
- Case += " Value = " + PostEmitter + "(MI, Value);\n";
+ if (!PostEmitter.empty()) {
+ Case += " Value = " + PostEmitter + "(MI, Value";
+ if (MCEmitter)
+ Case += ", STI";
+ Case += ");\n";
+ }
return Case;
}
@@ -238,8 +236,7 @@ void CodeEmitterGen::run(raw_ostream &o) {
std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
// For little-endian instruction bit encodings, reverse the bit order
- if (Target.isLittleEndianEncoding()) reverseBits(Insts);
-
+ Target.reverseBitsForLittleEndianEncoding();
const std::vector<const CodeGenInstruction*> &NumberedInstructions =
Target.getInstructionsByEnumValue();
@@ -248,7 +245,8 @@ void CodeEmitterGen::run(raw_ostream &o) {
o << "uint64_t " << Target.getName();
if (MCEmitter)
o << "MCCodeEmitter::getBinaryCodeForInstr(const MCInst &MI,\n"
- << " SmallVectorImpl<MCFixup> &Fixups) const {\n";
+ << " SmallVectorImpl<MCFixup> &Fixups,\n"
+ << " const MCSubtargetInfo &STI) const {\n";
else
o << "CodeEmitter::getBinaryCodeForInstr(const MachineInstr &MI) const {\n";
OpenPOWER on IntegriCloud