summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--utils/TableGen/CodeEmitterGen.cpp38
-rw-r--r--utils/TableGen/CodeGenTarget.cpp40
-rw-r--r--utils/TableGen/CodeGenTarget.h4
-rw-r--r--utils/TableGen/FixedLenDecoderEmitter.cpp2
4 files changed, 47 insertions, 37 deletions
diff --git a/utils/TableGen/CodeEmitterGen.cpp b/utils/TableGen/CodeEmitterGen.cpp
index c94d384901..b7dea1046b 100644
--- a/utils/TableGen/CodeEmitterGen.cpp
+++ b/utils/TableGen/CodeEmitterGen.cpp
@@ -43,7 +43,6 @@ public:
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,
@@ -53,40 +52,6 @@ private:
};
-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,
@@ -238,8 +203,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();
diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp
index dd17059558..4b8efff600 100644
--- a/utils/TableGen/CodeGenTarget.cpp
+++ b/utils/TableGen/CodeGenTarget.cpp
@@ -357,6 +357,46 @@ bool CodeGenTarget::isLittleEndianEncoding() const {
return getInstructionSet()->getValueAsBit("isLittleEndianEncoding");
}
+/// reverseBitsForLittleEndianEncoding - For little-endian instruction bit
+/// encodings, reverse the bit order of all instructions.
+void CodeGenTarget::reverseBitsForLittleEndianEncoding() {
+ if (!isLittleEndianEncoding())
+ return;
+
+ std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
+ 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);
+ }
+}
+
/// guessInstructionProperties - Return true if it's OK to guess instruction
/// properties instead of raising an error.
///
diff --git a/utils/TableGen/CodeGenTarget.h b/utils/TableGen/CodeGenTarget.h
index 6271443029..d6458f41cf 100644
--- a/utils/TableGen/CodeGenTarget.h
+++ b/utils/TableGen/CodeGenTarget.h
@@ -177,6 +177,10 @@ public:
///
bool isLittleEndianEncoding() const;
+ /// reverseBitsForLittleEndianEncoding - For little-endian instruction bit
+ /// encodings, reverse the bit order of all instructions.
+ void reverseBitsForLittleEndianEncoding();
+
/// guessInstructionProperties - should we just guess unset instruction
/// properties?
bool guessInstructionProperties() const;
diff --git a/utils/TableGen/FixedLenDecoderEmitter.cpp b/utils/TableGen/FixedLenDecoderEmitter.cpp
index 87d18cdb9d..d2d3f3dd07 100644
--- a/utils/TableGen/FixedLenDecoderEmitter.cpp
+++ b/utils/TableGen/FixedLenDecoderEmitter.cpp
@@ -2012,6 +2012,8 @@ void FixedLenDecoderEmitter::run(raw_ostream &o) {
emitFieldFromInstruction(OS);
+ Target.reverseBitsForLittleEndianEncoding();
+
// Parameterize the decoders based on namespace and instruction width.
NumberedInstructions = &Target.getInstructionsByEnumValue();
std::map<std::pair<std::string, unsigned>,