There are some Mips instructions that are lowered by the
authorJack Carter <jcarter@mips.com>
Thu, 6 Sep 2012 02:31:34 +0000 (02:31 +0000)
committerJack Carter <jcarter@mips.com>
Thu, 6 Sep 2012 02:31:34 +0000 (02:31 +0000)
assembler such as shifts greater than 32. In the case
of direct object, the code gen needs to do this lowering
since the assembler is not involved.

With the advent of the llvm-mc assembler, it also needs
to do the same lowering.

This patch makes that specific lowering code accessible
to both the direct object output and the assembler.

This patch does not affect generated output.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163287 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/CMakeLists.txt
lib/Target/Mips/MipsAsmPrinter.cpp
lib/Target/Mips/MipsDirectObjLower.cpp [new file with mode: 0644]
lib/Target/Mips/MipsDirectObjLower.h [new file with mode: 0644]
lib/Target/Mips/MipsMCInstLower.cpp
lib/Target/Mips/MipsMCInstLower.h

index f535c504dbc0ad83c292c72da1c18631c6897456..0f84358e26a38f9f347e895a85740e5b4f02077a 100644 (file)
@@ -21,6 +21,7 @@ add_llvm_target(MipsCodeGen
   MipsAsmPrinter.cpp
   MipsCodeEmitter.cpp
   MipsDelaySlotFiller.cpp
+  MipsDirectObjLower.cpp
   MipsELFWriterInfo.cpp
   MipsJITInfo.cpp
   MipsInstrInfo.cpp
index e4db9915f0a9f2de20e535009f44e08d8d7c9996..8057f9811e593a5c3ca995b2a9a7000ef4094091 100644 (file)
@@ -15,6 +15,7 @@
 #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"
@@ -63,42 +64,25 @@ void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {
 
   do {
     MCInst TmpInst0;
+    MCInstLowering.Lower(I++, TmpInst0);
 
     // Direct object specific instruction lowering
-    if (!OutStreamer.hasRawTextSupport())
-      switch (I->getOpcode()) {
+    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:
-      {
-        assert(I->getNumOperands() == 3 &&
-            "Invalid no. of machine operands for shift!");
-        assert(I->getOperand(2).isImm());
-        int64_t Shift = I->getOperand(2).getImm();
-        if (Shift > 31) {
-          MCInst TmpInst0;
-          MCInstLowering.LowerLargeShift(I, TmpInst0, Shift - 32);
-          OutStreamer.EmitInstruction(TmpInst0);
-          return;
-        }
-      }
-      break;
-      // Double extract instruction is chosen by pos and size operands
+        Mips::LowerLargeShift(TmpInst0);
+        break;
+        // Double extract instruction is chosen by pos and size operands
       case Mips::DEXT:
       case Mips::DINS:
-        assert(Subtarget->hasMips64() && "DEXT/DINS are MIPS64 instructions");
-        {
-          MCInst TmpInst0;
-          MCInstLowering.LowerDextDins(I, TmpInst0);
-          OutStreamer.EmitInstruction(TmpInst0);
-          return;
-        }
+        Mips::LowerDextDins(TmpInst0);
       }
+    }
 
-    MCInstLowering.Lower(I++, TmpInst0);
     OutStreamer.EmitInstruction(TmpInst0);
-
   } while ((I != E) && I->isInsideBundle()); // Delay slot check
 }
 
diff --git a/lib/Target/Mips/MipsDirectObjLower.cpp b/lib/Target/Mips/MipsDirectObjLower.cpp
new file mode 100644 (file)
index 0000000..0d74db8
--- /dev/null
@@ -0,0 +1,86 @@
+//===-- MipsDirectObjLower.cpp - Mips LLVM direct object lowering -----===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains code to lower Mips MCInst records that are normally
+// left to the assembler to lower such as large shifts.
+//
+//===----------------------------------------------------------------------===//
+#include "MipsDirectObjLower.h"
+#include "MipsInstrInfo.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCStreamer.h"
+
+using namespace llvm;
+
+// If the D<shift> instruction has a shift amount that is greater
+// than 31 (checked in calling routine), lower it to a D<shift>32 instruction
+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;
+  }
+
+  // saminus32
+  (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;
+    }
+}
+
+// Pick a DEXT or DINS instruction variant based on the pos and size operands
+void Mips::LowerDextDins(MCInst& InstIn) {
+  int Opcode = InstIn.getOpcode();
+
+  if (Opcode == Mips::DEXT)
+    assert(InstIn.getNumOperands() == 4 &&
+           "Invalid no. of machine operands for DEXT!");
+  else // Only DEXT and DINS are possible
+    assert(InstIn.getNumOperands() == 5 &&
+           "Invalid no. of machine operands for DINS!");
+
+  assert(InstIn.getOperand(2).isImm());
+  int64_t pos = InstIn.getOperand(2).getImm();
+  assert(InstIn.getOperand(3).isImm());
+  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);
+      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);
+    return;
+  }
+}
diff --git a/lib/Target/Mips/MipsDirectObjLower.h b/lib/Target/Mips/MipsDirectObjLower.h
new file mode 100644 (file)
index 0000000..8813cc9
--- /dev/null
@@ -0,0 +1,28 @@
+//===-- MipsDirectObjLower.h - Mips LLVM direct object lowering *- C++ -*--===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MIPSDIRECTOBJLOWER_H
+#define MIPSDIRECTOBJLOWER_H
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+  class MCInst;
+  class MCStreamer;
+
+  namespace Mips {
+  /// MipsDirectObjLower - This name space is used to lower MCInstr in cases
+  //                       where the assembler usually finishes the lowering
+  //                       such as large shifts.
+    void LowerLargeShift(MCInst &Inst);
+    void LowerDextDins(MCInst &Inst);
+  }
+}
+
+#endif
index 674bce30a5bd3fbe5b56bd4ea1161e2e442db779..5fa6339338386117215167bc65b865fc2c900be9 100644 (file)
@@ -160,71 +160,3 @@ void MipsMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
   }
 }
 
-// If the D<shift> instruction has a shift amount that is greater
-// than 31 (checked in calling routine), lower it to a D<shift>32 instruction
-void MipsMCInstLower::LowerLargeShift(const MachineInstr *MI,
-                                      MCInst& Inst,
-                                      int64_t Shift) {
-  // rt
-  Inst.addOperand(LowerOperand(MI->getOperand(0)));
-  // rd
-  Inst.addOperand(LowerOperand(MI->getOperand(1)));
-  // saminus32
-  Inst.addOperand(MCOperand::CreateImm(Shift));
-
-  switch (MI->getOpcode()) {
-  default:
-    // Calling function is not synchronized
-    llvm_unreachable("Unexpected shift instruction");
-    break;
-  case Mips::DSLL:
-    Inst.setOpcode(Mips::DSLL32);
-    break;
-  case Mips::DSRL:
-    Inst.setOpcode(Mips::DSRL32);
-    break;
-  case Mips::DSRA:
-    Inst.setOpcode(Mips::DSRA32);
-    break;
-  }
-}
-
-// Pick a DEXT or DINS instruction variant based on the pos and size operands
-void MipsMCInstLower::LowerDextDins(const MachineInstr *MI,  MCInst& Inst) {
-  int Opcode = MI->getOpcode();
-
-  if (Opcode == Mips::DEXT)
-    assert(MI->getNumOperands() == 4 &&
-           "Invalid no. of machine operands for DEXT!");
-  else // Only DEXT and DINS are possible
-    assert(MI->getNumOperands() == 5 &&
-           "Invalid no. of machine operands for DINS!");
-
-  assert(MI->getOperand(2).isImm());
-  int64_t pos = MI->getOperand(2).getImm();
-  assert(MI->getOperand(3).isImm());
-  int64_t size = MI->getOperand(3).getImm();
-
-  // rt
-  Inst.addOperand(LowerOperand(MI->getOperand(0)));
-  // rs
-  Inst.addOperand(LowerOperand(MI->getOperand(1)));
-
-  if (size <= 32) {
-    if ((pos < 32)) { // DEXT/DINS
-      Inst.addOperand(MCOperand::CreateImm(pos));
-      Inst.addOperand(MCOperand::CreateImm(size));
-      Inst.setOpcode(Opcode);
-    } else { // DEXTU/DINSU
-      Inst.addOperand(MCOperand::CreateImm(pos - 32));
-      Inst.addOperand(MCOperand::CreateImm(size));
-      Inst.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTU : Mips::DINSU);
-    }
-  } else { // DEXTM/DINSM
-    assert(pos < 32 && "DEXT/DINS cannot have both size and pos > 32");
-    Inst.addOperand(MCOperand::CreateImm(pos));
-    Inst.addOperand(MCOperand::CreateImm(size - 32));
-    Inst.setOpcode(Mips::DEXTM);
-    Inst.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTM : Mips::DINSM);
-  }
-}
index c1fe697a20a568fdd7e0ac57c91d2e081fb44786..3eab5a452e33d16c6dbc8d8806ece80edb2ed836 100644 (file)
@@ -33,8 +33,6 @@ public:
   MipsMCInstLower(MipsAsmPrinter &asmprinter);
   void Initialize(Mangler *mang, MCContext *C);
   void Lower(const MachineInstr *MI, MCInst &OutMI) const;
-  void LowerLargeShift(const MachineInstr *MI, MCInst &Inst, int64_t Shift);
-  void LowerDextDins(const MachineInstr *MI, MCInst &Inst);
 
 private:
   MCOperand LowerSymbolOperand(const MachineOperand &MO,