summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorJack Carter <jcarter@mips.com>2012-10-02 23:09:40 +0000
committerJack Carter <jcarter@mips.com>2012-10-02 23:09:40 +0000
commitaa7aeaa0a55ee39536f5a6b02091f46b330dac51 (patch)
tree76084a0bb6c61fb7ffc2d69dd10f1558ae4f25ab /llvm/lib
parente61fc44c3d102c4bad0cd565dd9aaceb5e6a125a (diff)
downloadbcm5719-llvm-aa7aeaa0a55ee39536f5a6b02091f46b330dac51.tar.gz
bcm5719-llvm-aa7aeaa0a55ee39536f5a6b02091f46b330dac51.zip
The mips 64bit instructions DSLL, DSRA, DSRL, DEXT and DINS get transformed by the assembler or through codegen direct object output to other variants based on the value of the immediate values of the operands.
If the code is generated as assembler, this transformation does not occur assuming that it will occur later in the assembler. This code was originally called from MipsAsmPrinter.cpp and we needed to check for OutStreamer.hasRawTextSupport(). This was not a good place for it and has been moved to MCTargetDesc/MipsMCCodeEmitter.cpp where both direct object and the assembler use it it automagically. The test cases have been checked in for a number of weeks now. llvm-svn: 165067
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/Mips/CMakeLists.txt1
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/CMakeLists.txt1
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsDirectObjLower.cpp (renamed from llvm/lib/Target/Mips/MipsDirectObjLower.cpp)63
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsDirectObjLower.h (renamed from llvm/lib/Target/Mips/MipsDirectObjLower.h)0
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp28
-rw-r--r--llvm/lib/Target/Mips/MipsAsmPrinter.cpp17
6 files changed, 54 insertions, 56 deletions
diff --git a/llvm/lib/Target/Mips/CMakeLists.txt b/llvm/lib/Target/Mips/CMakeLists.txt
index 7dec066fb69..3cc2821d474 100644
--- a/llvm/lib/Target/Mips/CMakeLists.txt
+++ b/llvm/lib/Target/Mips/CMakeLists.txt
@@ -22,7 +22,6 @@ add_llvm_target(MipsCodeGen
MipsAsmPrinter.cpp
MipsCodeEmitter.cpp
MipsDelaySlotFiller.cpp
- MipsDirectObjLower.cpp
MipsELFWriterInfo.cpp
MipsJITInfo.cpp
MipsInstrInfo.cpp
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/Mips/MCTargetDesc/CMakeLists.txt
index fa231507a2e..be5d7e42532 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/CMakeLists.txt
+++ b/llvm/lib/Target/Mips/MCTargetDesc/CMakeLists.txt
@@ -1,5 +1,6 @@
add_llvm_library(LLVMMipsDesc
MipsAsmBackend.cpp
+ MipsDirectObjLower.cpp
MipsMCAsmInfo.cpp
MipsMCCodeEmitter.cpp
MipsMCTargetDesc.cpp
diff --git a/llvm/lib/Target/Mips/MipsDirectObjLower.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsDirectObjLower.cpp
index 0d74db808c3..15c4282030d 100644
--- a/llvm/lib/Target/Mips/MipsDirectObjLower.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsDirectObjLower.cpp
@@ -11,8 +11,8 @@
// left to the assembler to lower such as large shifts.
//
//===----------------------------------------------------------------------===//
-#include "MipsDirectObjLower.h"
#include "MipsInstrInfo.h"
+#include "MCTargetDesc/MipsDirectObjLower.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCStreamer.h"
@@ -25,32 +25,28 @@ void Mips::LowerLargeShift(MCInst& Inst) {
assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!");
assert(Inst.getOperand(2).isImm());
- bool isLarge = false;
- int64_t Shift;
- Shift = Inst.getOperand(2).getImm();
- if (Shift > 31) {
- Shift -= 32;
- isLarge = true;
- }
+ int64_t Shift = Inst.getOperand(2).getImm();
+ if (Shift <= 31)
+ return; // Do nothing
+ Shift -= 32;
// saminus32
- (Inst.getOperand(2)).setImm(Shift);
+ Inst.getOperand(2).setImm(Shift);
- if (isLarge)
- switch (Inst.getOpcode()) {
- default:
- // Calling function is not synchronized
- llvm_unreachable("Unexpected shift instruction");
- case Mips::DSLL:
- Inst.setOpcode(Mips::DSLL32);
- return;
- case Mips::DSRL:
- Inst.setOpcode(Mips::DSRL32);
- return;
- case Mips::DSRA:
- Inst.setOpcode(Mips::DSRA32);
- return;
- }
+ switch (Inst.getOpcode()) {
+ default:
+ // Calling function is not synchronized
+ llvm_unreachable("Unexpected shift instruction");
+ case Mips::DSLL:
+ Inst.setOpcode(Mips::DSLL32);
+ return;
+ case Mips::DSRL:
+ Inst.setOpcode(Mips::DSRL32);
+ return;
+ case Mips::DSRA:
+ Inst.setOpcode(Mips::DSRA32);
+ return;
+ }
}
// Pick a DEXT or DINS instruction variant based on the pos and size operands
@@ -70,17 +66,16 @@ void Mips::LowerDextDins(MCInst& InstIn) {
int64_t size = InstIn.getOperand(3).getImm();
if (size <= 32) {
- if ((pos < 32)) { // DEXT/DINS, do nothing
- return;
- } else { // DEXTU/DINSU
- InstIn.getOperand(2).setImm(pos - 32);
- InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTU : Mips::DINSU);
+ if (pos < 32) // DEXT/DINS, do nothing
return;
- }
- } else { // DEXTM/DINSM
- assert(pos < 32 && "DEXT/DINS cannot have both size and pos > 32");
- InstIn.getOperand(3).setImm(size - 32);
- InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTM : Mips::DINSM);
+ // DEXTU/DINSU
+ InstIn.getOperand(2).setImm(pos - 32);
+ InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTU : Mips::DINSU);
return;
}
+ // DEXTM/DINSM
+ assert(pos < 32 && "DEXT/DINS cannot have both size and pos > 32");
+ InstIn.getOperand(3).setImm(size - 32);
+ InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTM : Mips::DINSM);
+ return;
}
diff --git a/llvm/lib/Target/Mips/MipsDirectObjLower.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsDirectObjLower.h
index 8813cc9ac7a..8813cc9ac7a 100644
--- a/llvm/lib/Target/Mips/MipsDirectObjLower.h
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsDirectObjLower.h
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
index f3a8d3fb0d0..06882e138c0 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
@@ -13,6 +13,7 @@
//
#define DEBUG_TYPE "mccodeemitter"
#include "MCTargetDesc/MipsBaseInfo.h"
+#include "MCTargetDesc/MipsDirectObjLower.h"
#include "MCTargetDesc/MipsFixupKinds.h"
#include "MCTargetDesc/MipsMCTargetDesc.h"
#include "llvm/ADT/APFloat.h"
@@ -109,16 +110,35 @@ void MipsMCCodeEmitter::
EncodeInstruction(const MCInst &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups) const
{
- uint32_t Binary = getBinaryCodeForInstr(MI, Fixups);
+
+ // Non-pseudo instructions that get changed for direct object
+ // only based on operand values.
+ // If this list of instructions get much longer we will move
+ // the check to a function call. Until then, this is more efficient.
+ MCInst TmpInst = MI;
+ switch (MI.getOpcode()) {
+ // If shift amount is >= 32 it the inst needs to be lowered further
+ case Mips::DSLL:
+ case Mips::DSRL:
+ case Mips::DSRA:
+ Mips::LowerLargeShift(TmpInst);
+ break;
+ // Double extract instruction is chosen by pos and size operands
+ case Mips::DEXT:
+ case Mips::DINS:
+ Mips::LowerDextDins(TmpInst);
+ }
+
+ uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups);
// Check for unimplemented opcodes.
- // Unfortunately in MIPS both NOT and SLL will come in with Binary == 0
+ // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0
// so we have to special check for them.
- unsigned Opcode = MI.getOpcode();
+ unsigned Opcode = TmpInst.getOpcode();
if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) && !Binary)
llvm_unreachable("unimplemented opcode in EncodeInstruction()");
- const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
+ const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode());
uint64_t TSFlags = Desc.TSFlags;
// Pseudo instructions don't get encoded and shouldn't be here
diff --git a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
index 6ca41624d33..83558c17431 100644
--- a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
+++ b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
@@ -15,7 +15,6 @@
#define DEBUG_TYPE "mips-asm-printer"
#include "Mips.h"
#include "MipsAsmPrinter.h"
-#include "MipsDirectObjLower.h"
#include "MipsInstrInfo.h"
#include "MipsMCInstLower.h"
#include "InstPrinter/MipsInstPrinter.h"
@@ -77,22 +76,6 @@ void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {
MCInst TmpInst0;
MCInstLowering.Lower(I++, TmpInst0);
- // Direct object specific instruction lowering
- if (!OutStreamer.hasRawTextSupport()){
- switch (TmpInst0.getOpcode()) {
- // If shift amount is >= 32 it the inst needs to be lowered further
- case Mips::DSLL:
- case Mips::DSRL:
- case Mips::DSRA:
- Mips::LowerLargeShift(TmpInst0);
- break;
- // Double extract instruction is chosen by pos and size operands
- case Mips::DEXT:
- case Mips::DINS:
- Mips::LowerDextDins(TmpInst0);
- }
- }
-
OutStreamer.EmitInstruction(TmpInst0);
} while ((I != E) && I->isInsideBundle()); // Delay slot check
}
OpenPOWER on IntegriCloud