Test commit
[oota-llvm.git] / lib / Target / Mips / MipsConstantIslandPass.cpp
index 3c62baeec156f0d0f8184ae41ac807fc6480aefa..8f607b057d209fb7bb8f0f5728db957bc1000726 100644 (file)
@@ -17,7 +17,7 @@
 //
 // The constants can be not just numbers but addresses of functions and labels.
 // This can be particularly helpful in static relocation mode for embedded
-// non linux targets.
+// non-linux targets.
 //
 //
 
 #include "llvm/IR/Function.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Support/Format.h"
 #include "llvm/Support/InstIterator.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetInstrInfo.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Support/Format.h"
 #include <algorithm>
 
 using namespace llvm;
@@ -85,7 +85,7 @@ static unsigned int branchTargetOperand(MachineInstr *MI) {
   case Mips::BteqzX16:
   case Mips::Btnez16:
   case Mips::BtnezX16:
-  case Mips::Jal16:
+  case Mips::JalB16:
     return 0;
   case Mips::BeqzRxImm16:
   case Mips::BeqzRxImmX16:
@@ -96,6 +96,16 @@ static unsigned int branchTargetOperand(MachineInstr *MI) {
   llvm_unreachable("Unknown branch type");
 }
 
+static bool isUnconditionalBranch(unsigned int Opcode) {
+  switch (Opcode) {
+  default: return false;
+  case Mips::Bimm16:
+  case Mips::BimmX16:
+  case Mips::JalB16:
+    return true;
+  }
+}
+
 static unsigned int longformBranchOpcode(unsigned int Opcode) {
   switch (Opcode) {
   case Mips::Bimm16:
@@ -107,8 +117,8 @@ static unsigned int longformBranchOpcode(unsigned int Opcode) {
   case Mips::Btnez16:
   case Mips::BtnezX16:
     return Mips::BtnezX16;
-  case Mips::Jal16:
-    return Mips::Jal16;
+  case Mips::JalB16:
+    return Mips::JalB16;
   case Mips::BeqzRxImm16:
   case Mips::BeqzRxImmX16:
     return Mips::BeqzRxImmX16;
@@ -702,41 +712,49 @@ initializeFunctionInfo(const std::vector<MachineInstr*> &CPEMIs) {
           isCond = false;
           break;
         case Mips::BeqzRxImm16:
+          UOpc=Mips::Bimm16;
           Bits = 8;
           Scale = 2;
           isCond = true;
           break;
         case Mips::BeqzRxImmX16:
+          UOpc=Mips::Bimm16;
           Bits = 16;
           Scale = 2;
           isCond = true;
           break;
         case Mips::BnezRxImm16:
+          UOpc=Mips::Bimm16;
           Bits = 8;
           Scale = 2;
           isCond = true;
           break;
         case Mips::BnezRxImmX16:
+          UOpc=Mips::Bimm16;
           Bits = 16;
           Scale = 2;
           isCond = true;
           break;
         case Mips::Bteqz16:
+          UOpc=Mips::Bimm16;
           Bits = 8;
           Scale = 2;
           isCond = true;
           break;
         case Mips::BteqzX16:
+          UOpc=Mips::Bimm16;
           Bits = 16;
           Scale = 2;
           isCond = true;
           break;
         case Mips::Btnez16:
+          UOpc=Mips::Bimm16;
           Bits = 8;
           Scale = 2;
           isCond = true;
           break;
         case Mips::BtnezX16:
+          UOpc=Mips::Bimm16;
           Bits = 16;
           Scale = 2;
           isCond = true;
@@ -772,11 +790,11 @@ initializeFunctionInfo(const std::vector<MachineInstr*> &CPEMIs) {
             Bits = 8;
             Scale = 4;
             LongFormOpcode = Mips::LwRxPcTcpX16;
-            LongFormBits = 16;
+            LongFormBits = 14;
             LongFormScale = 1;
             break;
           case Mips::LwRxPcTcpX16:
-            Bits = 16;
+            Bits = 14;
             Scale = 1;
             NegOk = true;
             break;
@@ -1561,7 +1579,7 @@ MipsConstantIslands::fixupUnconditionalBr(ImmBranch &Br) {
     //
     DestBB->setAlignment(2);
     Br.MaxDisp = ((1<<24)-1) * 2;
-    MI->setDesc(TII->get(Mips::Jal16));
+    MI->setDesc(TII->get(Mips::JalB16));
   }
   BBInfo[MBB->getNumber()].Size += 2;
   adjustBBOffsetsAfter(MBB);
@@ -1592,17 +1610,14 @@ MipsConstantIslands::fixupConditionalBr(ImmBranch &Br) {
     MI->setDesc(TII->get(LongFormOpcode));
     return true;
   }
-  llvm_unreachable("Fixup of very long conditional branch not working yet.");
 
   // Add an unconditional branch to the destination and invert the branch
   // condition to jump over it:
-  // blt L1
+  // bteqz L1
   // =>
-  // bge L2
+  // bnez L2
   // b   L1
   // L2:
-  unsigned CCReg = 0;  // FIXME
-  unsigned CC=0; //FIXME
 
   // If the branch is at the end of its MBB and that has a fall-through block,
   // direct the updated conditional branch to the fall-through block. Otherwise,
@@ -1610,29 +1625,34 @@ MipsConstantIslands::fixupConditionalBr(ImmBranch &Br) {
   MachineBasicBlock *MBB = MI->getParent();
   MachineInstr *BMI = &MBB->back();
   bool NeedSplit = (BMI != MI) || !BBHasFallthrough(MBB);
-
+  unsigned OppositeBranchOpcode = TII->getOppositeBranchOpc(Opcode);
   ++NumCBrFixed;
   if (BMI != MI) {
     if (llvm::next(MachineBasicBlock::iterator(MI)) == prior(MBB->end()) &&
-        BMI->getOpcode() == Br.UncondBr) {
+        isUnconditionalBranch(BMI->getOpcode())) {
       // Last MI in the BB is an unconditional branch. Can we simply invert the
       // condition and swap destinations:
-      // beq L1
+      // beqz L1
       // b   L2
       // =>
-      // bne L2
+      // bnez L2
       // b   L1
-      MachineBasicBlock *NewDest = BMI->getOperand(0).getMBB();
+      unsigned BMITargetOperand = branchTargetOperand(BMI);
+      MachineBasicBlock *NewDest = 
+        BMI->getOperand(BMITargetOperand).getMBB();
       if (isBBInRange(MI, NewDest, Br.MaxDisp)) {
         DEBUG(dbgs() << "  Invert Bcc condition and swap its destination with "
                      << *BMI);
-        BMI->getOperand(0).setMBB(DestBB);
-        MI->getOperand(0).setMBB(NewDest);
+        MI->setDesc(TII->get(OppositeBranchOpcode));
+        BMI->getOperand(BMITargetOperand).setMBB(DestBB);
+        MI->getOperand(TargetOperand).setMBB(NewDest);
         return true;
       }
     }
   }
 
+
   if (NeedSplit) {
     splitBlockBeforeInstr(MI);
     // No need for the branch to the next block. We're adding an unconditional
@@ -1650,8 +1670,14 @@ MipsConstantIslands::fixupConditionalBr(ImmBranch &Br) {
 
   // Insert a new conditional branch and a new unconditional branch.
   // Also update the ImmBranch as well as adding a new entry for the new branch.
-  BuildMI(MBB, DebugLoc(), TII->get(MI->getOpcode()))
-    .addMBB(NextBB).addImm(CC).addReg(CCReg);
+  if (MI->getNumExplicitOperands() == 2) {
+    BuildMI(MBB, DebugLoc(), TII->get(OppositeBranchOpcode))
+           .addReg(MI->getOperand(0).getReg())
+           .addMBB(NextBB);
+  } else {
+    BuildMI(MBB, DebugLoc(), TII->get(OppositeBranchOpcode))
+           .addMBB(NextBB);
+  }
   Br.MI = &MBB->back();
   BBInfo[MBB->getNumber()].Size += TII->GetInstSizeInBytes(&MBB->back());
   BuildMI(MBB, DebugLoc(), TII->get(Br.UncondBr)).addMBB(DestBB);