Some instructions are passed to the assembler to be
authorJack Carter <jcarter@mips.com>
Tue, 28 Aug 2012 19:07:39 +0000 (19:07 +0000)
committerJack Carter <jcarter@mips.com>
Tue, 28 Aug 2012 19:07:39 +0000 (19:07 +0000)
transformed to the final instruction variant. An
example would be dsrll which is transformed into
dsll32 if the shift value is greater than 32.

For direct object output we need to do this transformation
in the codegen. If the instruction was inside branch
delay slot, it was being missed. This patch corrects this
oversight.

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

lib/Target/Mips/MipsAsmPrinter.cpp
test/MC/Mips/mips64shift.ll

index 00ff7545c14a089222ff74adcdda3152ddc3e997..3b1509d46bb350c4466810db3bb87354916d5b5e 100644 (file)
@@ -58,33 +58,37 @@ void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {
     return;
   }
 
-  // Direct object specific instruction lowering
-  if (!OutStreamer.hasRawTextSupport())
-    switch (MI->getOpcode()) {
-    case Mips::DSLL:
-    case Mips::DSRL:
-    case Mips::DSRA:
-      assert(MI->getNumOperands() == 3 &&
-             "Invalid no. of machine operands for shift!");
-      assert(MI->getOperand(2).isImm());
-      int64_t Shift = MI->getOperand(2).getImm();
-      if (Shift > 31) {
-        MCInst TmpInst0;
-        MCInstLowering.LowerLargeShift(MI, TmpInst0, Shift - 32);
-        OutStreamer.EmitInstruction(TmpInst0);
-        return;
-      }
-      break;
-    }
-
   MachineBasicBlock::const_instr_iterator I = MI;
   MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end();
 
   do {
     MCInst TmpInst0;
+
+    // Direct object specific instruction lowering
+    if (!OutStreamer.hasRawTextSupport())
+      switch (I->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;
+        }
+      }
+      }
+
     MCInstLowering.Lower(I++, TmpInst0);
     OutStreamer.EmitInstruction(TmpInst0);
-  } while ((I != E) && I->isInsideBundle());
+
+  } while ((I != E) && I->isInsideBundle()); // Delay slot check
 }
 
 //===----------------------------------------------------------------------===//
index e1c18576de06a18f0a0de2a8111c7f62fc120700..99cac7b591fac17f3c277b686f54c673300968b8 100644 (file)
@@ -1,5 +1,8 @@
-; RUN: llc -march=mips64el -filetype=obj -mcpu=mips64r2 -disable-mips-delay-filler %s -o - | llvm-objdump -disassemble -triple mips64el - | FileCheck %s
+; RUN: llc -march=mips64el -filetype=obj -mcpu=mips64r2 -disable-mips-delay-filler %s -o - \
+; RUN: | llvm-objdump -disassemble -triple mips64el - | FileCheck %s 
 
+; RUN: llc -march=mips64el -filetype=obj -mcpu=mips64r2 %s -o - \
+; RUN: | llvm-objdump -disassemble -triple mips64el - | FileCheck %s 
 
 define i64 @f3(i64 %a0) nounwind readnone {
 entry: