summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorHal Finkel <hfinkel@anl.gov>2013-12-17 22:37:50 +0000
committerHal Finkel <hfinkel@anl.gov>2013-12-17 22:37:50 +0000
commit81e6fccbd72ac4be2be9ad014d78cf0c09e5a1bb (patch)
tree043e26fc56125a61305244263113e5ef5955b62d /llvm
parent98e79a06048d877169b5a0587df0ff6473aa4e8d (diff)
downloadbcm5719-llvm-81e6fccbd72ac4be2be9ad014d78cf0c09e5a1bb.tar.gz
bcm5719-llvm-81e6fccbd72ac4be2be9ad014d78cf0c09e5a1bb.zip
Support little-endian encodings in the FixedLenDecoderEmitter
The convention used to specify the PowerPC ISA is that bits are numbered in reverse order (0 is the index of the high bit). To support this "little endian" encoding convention, CodeEmitterGen will reverse the bit numberings prior to generating the encoding tables. In order to generate a disassembler, FixedLenDecoderEmitter needs to do the same. This moves the bit reversal logic out of CodeEmitterGen and into CodeGenTarget (where it can be used by both CodeEmitterGen and FixedLenDecoderEmitter). This is prep work for disassembly support in the PPC backend (which is the only in-tree user of this little-endian encoding support). llvm-svn: 197532
Diffstat (limited to 'llvm')
-rw-r--r--llvm/utils/TableGen/CodeEmitterGen.cpp38
-rw-r--r--llvm/utils/TableGen/CodeGenTarget.cpp40
-rw-r--r--llvm/utils/TableGen/CodeGenTarget.h4
-rw-r--r--llvm/utils/TableGen/FixedLenDecoderEmitter.cpp2
4 files changed, 47 insertions, 37 deletions
diff --git a/llvm/utils/TableGen/CodeEmitterGen.cpp b/llvm/utils/TableGen/CodeEmitterGen.cpp
index c94d384901f..b7dea1046ba 100644
--- a/llvm/utils/TableGen/CodeEmitterGen.cpp
+++ b/llvm/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/llvm/utils/TableGen/CodeGenTarget.cpp b/llvm/utils/TableGen/CodeGenTarget.cpp
index dd170595582..4b8efff600c 100644
--- a/llvm/utils/TableGen/CodeGenTarget.cpp
+++ b/llvm/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/llvm/utils/TableGen/CodeGenTarget.h b/llvm/utils/TableGen/CodeGenTarget.h
index 62714430293..d6458f41cf2 100644
--- a/llvm/utils/TableGen/CodeGenTarget.h
+++ b/llvm/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/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp
index 87d18cdb9d4..d2d3f3dd076 100644
--- a/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp
+++ b/llvm/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>,
OpenPOWER on IntegriCloud