Support to provide exception and selector registers.
[oota-llvm.git] / lib / Target / PowerPC / PPCInstrInfo.cpp
index 63188466bed4b72b43eab7b91d36b25506f65c72..1ba701f6a759875993c5e2c6f827496b819c3d06 100644 (file)
 //===----------------------------------------------------------------------===//
 
 #include "PPCInstrInfo.h"
+#include "PPCPredicates.h"
 #include "PPCGenInstrInfo.inc"
 #include "PPCTargetMachine.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
-#include <iostream>
 using namespace llvm;
 
 PPCInstrInfo::PPCInstrInfo(PPCTargetMachine &tm)
   : TargetInstrInfo(PPCInsts, sizeof(PPCInsts)/sizeof(PPCInsts[0])), TM(tm),
-    RI(*TM.getSubtargetImpl()) {}
+    RI(*TM.getSubtargetImpl(), *this) {}
 
 /// getPointerRegClass - Return the register class to use to hold pointers.
 /// This is used for addressing modes.
@@ -147,8 +147,18 @@ MachineInstr *PPCInstrInfo::commuteInstruction(MachineInstr *MI) const {
   // Swap op1/op2
   unsigned Reg1 = MI->getOperand(1).getReg();
   unsigned Reg2 = MI->getOperand(2).getReg();
+  bool Reg1IsKill = MI->getOperand(1).isKill();
+  bool Reg2IsKill = MI->getOperand(2).isKill();
   MI->getOperand(2).setReg(Reg1);
   MI->getOperand(1).setReg(Reg2);
+  if (Reg1IsKill)
+    MI->getOperand(2).setIsKill();
+  else
+    MI->getOperand(2).unsetIsKill();
+  if (Reg2IsKill)
+    MI->getOperand(1).setIsKill();
+  else
+    MI->getOperand(1).unsetIsKill();
   
   // Swap the mask around.
   unsigned MB = MI->getOperand(4).getImmedValue();
@@ -160,7 +170,7 @@ MachineInstr *PPCInstrInfo::commuteInstruction(MachineInstr *MI) const {
 
 void PPCInstrInfo::insertNoop(MachineBasicBlock &MBB, 
                               MachineBasicBlock::iterator MI) const {
-  BuildMI(MBB, MI, PPC::NOP, 0);
+  BuildMI(MBB, MI, get(PPC::NOP));
 }
 
 
@@ -181,7 +191,7 @@ bool PPCInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
     if (LastInst->getOpcode() == PPC::B) {
       TBB = LastInst->getOperand(0).getMachineBasicBlock();
       return false;
-    } else if (LastInst->getOpcode() == PPC::COND_BRANCH) {
+    } else if (LastInst->getOpcode() == PPC::BCC) {
       // Block ends with fall-through condbranch.
       TBB = LastInst->getOperand(2).getMachineBasicBlock();
       Cond.push_back(LastInst->getOperand(0));
@@ -200,8 +210,8 @@ bool PPCInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
       isTerminatorInstr((--I)->getOpcode()))
     return true;
   
-  // If the block ends with PPC::B and PPC:COND_BRANCH, handle it.
-  if (SecondLastInst->getOpcode() == PPC::COND_BRANCH && 
+  // If the block ends with PPC::B and PPC:BCC, handle it.
+  if (SecondLastInst->getOpcode() == PPC::BCC && 
       LastInst->getOpcode() == PPC::B) {
     TBB =  SecondLastInst->getOperand(2).getMachineBasicBlock();
     Cond.push_back(SecondLastInst->getOperand(0));
@@ -218,7 +228,7 @@ void PPCInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
   MachineBasicBlock::iterator I = MBB.end();
   if (I == MBB.begin()) return;
   --I;
-  if (I->getOpcode() != PPC::B && I->getOpcode() != PPC::COND_BRANCH)
+  if (I->getOpcode() != PPC::B && I->getOpcode() != PPC::BCC)
     return;
   
   // Remove the branch.
@@ -228,7 +238,7 @@ void PPCInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
 
   if (I == MBB.begin()) return;
   --I;
-  if (I->getOpcode() != PPC::COND_BRANCH)
+  if (I->getOpcode() != PPC::BCC)
     return;
   
   // Remove the branch.
@@ -246,23 +256,34 @@ void PPCInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
   // One-way branch.
   if (FBB == 0) {
     if (Cond.empty())   // Unconditional branch
-      BuildMI(&MBB, PPC::B, 1).addMBB(TBB);
+      BuildMI(&MBB, get(PPC::B)).addMBB(TBB);
     else                // Conditional branch
-      BuildMI(&MBB, PPC::COND_BRANCH, 3)
-        .addReg(Cond[0].getReg()).addImm(Cond[1].getImm()).addMBB(TBB);
+      BuildMI(&MBB, get(PPC::BCC))
+        .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB);
     return;
   }
   
   // Two-way Conditional Branch.
-  BuildMI(&MBB, PPC::COND_BRANCH, 3)
-    .addReg(Cond[0].getReg()).addImm(Cond[1].getImm()).addMBB(TBB);
-  BuildMI(&MBB, PPC::B, 1).addMBB(FBB);
+  BuildMI(&MBB, get(PPC::BCC))
+    .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB);
+  BuildMI(&MBB, get(PPC::B)).addMBB(FBB);
+}
+
+bool PPCInstrInfo::BlockHasNoFallThrough(MachineBasicBlock &MBB) const {
+  if (MBB.empty()) return false;
+  
+  switch (MBB.back().getOpcode()) {
+  case PPC::B:     // Uncond branch.
+  case PPC::BCTR:  // Indirect branch.
+    return true;
+  default: return false;
+  }
 }
 
 bool PPCInstrInfo::
 ReverseBranchCondition(std::vector<MachineOperand> &Cond) const {
   assert(Cond.size() == 2 && "Invalid PPC branch opcode!");
   // Leave the CR# the same, but invert the condition.
-  Cond[1].setImm(invertPPCBranchOpcode(Cond[1].getImm()));
+  Cond[0].setImm(PPC::InvertPredicate((PPC::Predicate)Cond[0].getImm()));
   return false;
 }