[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp PowerPCInstrInfo.td

Nate Begeman natebegeman at mac.com
Sat Apr 9 13:09:23 PDT 2005



Changes in directory llvm/lib/Target/PowerPC:

PPC32ISelPattern.cpp updated: 1.55 -> 1.56
PowerPCInstrInfo.td updated: 1.55 -> 1.56
---
Log message:

Add rlwnm instruction for variable rotate
Generate rotate left/right immediate
Generate code for brcondtwoway
Use new livein/liveout functionality


---
Diffs of the changes:  (+79 -29)

 PPC32ISelPattern.cpp |  104 +++++++++++++++++++++++++++++++++++++--------------
 PowerPCInstrInfo.td  |    4 +
 2 files changed, 79 insertions(+), 29 deletions(-)


Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp
diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.55 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.56
--- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.55	Sat Apr  9 04:33:07 2005
+++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp	Sat Apr  9 15:09:12 2005
@@ -16,7 +16,7 @@
 #include "PowerPC.h"
 #include "PowerPCInstrBuilder.h"
 #include "PowerPCInstrInfo.h"
-#include "PPC32RegisterInfo.h"
+#include "PPC32TargetMachine.h"
 #include "llvm/Constants.h"                   // FIXME: REMOVE
 #include "llvm/Function.h"
 #include "llvm/CodeGen/MachineConstantPool.h" // FIXME: REMOVE
@@ -49,7 +49,6 @@
       addRegisterClass(MVT::f64, PPC32::FPRCRegisterClass);
       
       // PowerPC has no intrinsics for these particular operations
-      setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand);
       setOperationAction(ISD::MEMMOVE, MVT::Other, Expand);
       setOperationAction(ISD::MEMSET, MVT::Other, Expand);
       setOperationAction(ISD::MEMCPY, MVT::Other, Expand);
@@ -129,6 +128,7 @@
     SDOperand newroot, argt;
     unsigned ObjSize;
     bool needsLoad = false;
+    bool ArgLive = !I->use_empty();
     MVT::ValueType ObjectVT = getValueType(I->getType());
     
     switch (ObjectVT) {
@@ -138,8 +138,9 @@
     case MVT::i16:
     case MVT::i32: 
       ObjSize = 4;
+      if (!ArgLive) break;
       if (GPR_remaining > 0) {
-        BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx]);
+        MF.addLiveIn(GPR[GPR_idx]);
         argt = newroot = DAG.getCopyFromReg(GPR[GPR_idx], MVT::i32,
                                             DAG.getRoot());
         if (ObjectVT != MVT::i32)
@@ -149,10 +150,11 @@
       }
       break;
       case MVT::i64: ObjSize = 8;
+      if (!ArgLive) break;
       // FIXME: can split 64b load between reg/mem if it is last arg in regs
       if (GPR_remaining > 1) {
-        BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx]);
-        BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx+1]);
+        MF.addLiveIn(GPR[GPR_idx]);
+        MF.addLiveIn(GPR[GPR_idx+1]);
         // Copy the extracted halves into the virtual registers
         SDOperand argHi = DAG.getCopyFromReg(GPR[GPR_idx], MVT::i32, 
                                              DAG.getRoot());
@@ -164,10 +166,12 @@
         needsLoad = true; 
       }
       break;
-      case MVT::f32: ObjSize = 4;
-      case MVT::f64: ObjSize = 8;
+      case MVT::f32:
+      case MVT::f64:
+      ObjSize = (ObjectVT == MVT::f64) ? 8 : 4;
+      if (!ArgLive) break;
       if (FPR_remaining > 0) {
-        BuildMI(&BB, PPC::IMPLICIT_DEF, 0, FPR[FPR_idx]);
+        MF.addLiveIn(FPR[FPR_idx]);
         argt = newroot = DAG.getCopyFromReg(FPR[FPR_idx], ObjectVT, 
                                             DAG.getRoot());
         --FPR_remaining;
@@ -214,7 +218,7 @@
     // result of va_next.
     std::vector<SDOperand> MemOps;
     for (; GPR_remaining > 0; --GPR_remaining, ++GPR_idx) {
-      BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx]);
+      MF.addLiveIn(GPR[GPR_idx]);
       SDOperand Val = DAG.getCopyFromReg(GPR[GPR_idx], MVT::i32, DAG.getRoot());
       SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1), 
                                     Val, FIN);
@@ -226,6 +230,26 @@
     DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps));
   }
 
+  // Finally, inform the code generator which regs we return values in.
+  switch (getValueType(F.getReturnType())) {
+  default: assert(0 && "Unknown type!");
+  case MVT::isVoid: break;
+  case MVT::i1:
+  case MVT::i8:
+  case MVT::i16:
+  case MVT::i32:
+    MF.addLiveOut(PPC::R3);
+    break;
+  case MVT::i64:
+    MF.addLiveOut(PPC::R3);
+    MF.addLiveOut(PPC::R4);
+    break;
+  case MVT::f32:
+  case MVT::f64:
+    MF.addLiveOut(PPC::F1);
+    break;
+  }
+
   return ArgValues;
 }
 
@@ -440,7 +464,7 @@
 }
 
 namespace {
-Statistic<>NotLogic("ppc-codegen", "Number of inverted logical ops");
+Statistic<>Rotates("ppc-codegen", "Number of rotates emitted");
 Statistic<>FusedFP("ppc-codegen", "Number of fused fp operations");
 //===--------------------------------------------------------------------===//
 /// ISel - PPC32 specific code to select PPC32 machine instructions for
@@ -837,6 +861,7 @@
 /// 3. or shr, and   7. or shr, shl
 /// 4. or and, shr
 bool ISel::SelectBitfieldInsert(SDOperand OR, unsigned Result) {
+  bool IsRotate = false;
   unsigned TgtMask = 0xFFFFFFFF, InsMask = 0xFFFFFFFF, Amount = 0;
   unsigned Op0Opc = OR.getOperand(0).getOpcode();
   unsigned Op1Opc = OR.getOperand(1).getOpcode();
@@ -865,12 +890,14 @@
     switch(Op1Opc) {
     case ISD::SHL: 
       Amount = CN->getValue(); 
-      InsMask <<= Amount; 
+      InsMask <<= Amount;
+      if (Op0Opc == ISD::SRL) IsRotate = true;
       break;
     case ISD::SRL: 
       Amount = CN->getValue(); 
       InsMask >>= Amount; 
       Amount = 32-Amount;
+      if (Op0Opc == ISD::SHL) IsRotate = true;
       break;
     case ISD::AND: 
       InsMask &= (unsigned)CN->getValue();
@@ -887,6 +914,16 @@
   unsigned MB, ME;
   if (((TgtMask ^ InsMask) == 0xFFFFFFFF) && IsRunOfOnes(InsMask, MB, ME)) {
     unsigned Tmp1, Tmp2;
+    // Check for rotlwi / rotrwi here, a special case of bitfield insert
+    // where both bitfield halves are sourced from the same value.
+    if (IsRotate && 
+        OR.getOperand(0).getOperand(0) == OR.getOperand(1).getOperand(0)) {
+      ++Rotates;  // Statistic
+      Tmp1 = SelectExpr(OR.getOperand(0).getOperand(0));
+      BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm(Amount)
+        .addImm(0).addImm(31);
+      return true;
+    }
     if (Op0Opc == ISD::AND)
       Tmp1 = SelectExpr(OR.getOperand(0).getOperand(0));
     else
@@ -954,26 +991,38 @@
 
 void ISel::SelectBranchCC(SDOperand N)
 {
-  assert(N.getOpcode() == ISD::BRCOND && "Not a BranchCC???");
   MachineBasicBlock *Dest = 
     cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock();
 
-  // Get the MBB we will fall through to so that we can hand it off to the
-  // branch selection pass as an argument to the PPC::COND_BRANCH pseudo op.
-  //ilist<MachineBasicBlock>::iterator It = BB;
-  //MachineBasicBlock *Fallthrough = ++It;
-  
   Select(N.getOperand(0));  //chain
   unsigned Opc = SelectSetCR0(N.getOperand(1));
-  // FIXME: Use this once we have something approximating two-way branches
-  // We cannot currently use this in case the ISel hands us something like
-  // BRcc MBBx
-  // BR MBBy
-  // since the fallthrough basic block for the conditional branch does not start
-  // with the unconditional branch (it is skipped over).
-  //BuildMI(BB, PPC::COND_BRANCH, 4).addReg(PPC::CR0).addImm(Opc)
-  //  .addMBB(Dest).addMBB(Fallthrough);
-  BuildMI(BB, Opc, 2).addReg(PPC::CR0).addMBB(Dest);
+
+  // Iterate to the next basic block, unless we're already at the end of the
+  ilist<MachineBasicBlock>::iterator It = BB, E = BB->getParent()->end();
+  if (It != E) ++It;
+
+  // If this is a two way branch, then grab the fallthrough basic block argument
+  // and build a PowerPC branch pseudo-op, suitable for long branch conversion
+  // if necessary by the branch selection pass.  Otherwise, emit a standard
+  // conditional branch.
+  if (N.getOpcode() == ISD::BRCONDTWOWAY) {
+    MachineBasicBlock *Fallthrough = 
+      cast<BasicBlockSDNode>(N.getOperand(3))->getBasicBlock();
+    if (Dest != It) {
+      BuildMI(BB, PPC::COND_BRANCH, 4).addReg(PPC::CR0).addImm(Opc)
+        .addMBB(Dest).addMBB(Fallthrough);
+      if (Fallthrough != It)
+        BuildMI(BB, PPC::B, 1).addMBB(Fallthrough);
+    } else {
+      if (Fallthrough != It) {
+        Opc = PPC32InstrInfo::invertPPCBranchOpcode(Opc);
+        BuildMI(BB, PPC::COND_BRANCH, 4).addReg(PPC::CR0).addImm(Opc)
+          .addMBB(Fallthrough).addMBB(Dest);
+      }
+    }
+  } else {
+    BuildMI(BB, Opc, 2).addReg(PPC::CR0).addMBB(Dest);
+  }
   return;
 }
 
@@ -1670,7 +1719,6 @@
     if (N.getOperand(0).getOpcode() == ISD::XOR &&
         N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant &&
         cast<ConstantSDNode>(N.getOperand(0).getOperand(1))->isAllOnesValue()) {
-      ++NotLogic;
       Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
       Tmp2 = SelectExpr(N.getOperand(1));
       BuildMI(BB, PPC::EQV, 2, Result).addReg(Tmp1).addReg(Tmp2);
@@ -1679,7 +1727,6 @@
     // Check for NOT, NOR, and NAND: xor (copy, or, and), -1
     if (N.getOperand(1).getOpcode() == ISD::Constant &&
         cast<ConstantSDNode>(N.getOperand(1))->isAllOnesValue()) {
-      ++NotLogic;
       switch(N.getOperand(0).getOpcode()) {
       case ISD::OR:
         Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
@@ -2145,6 +2192,7 @@
     return;
   }
   case ISD::BRCOND: 
+  case ISD::BRCONDTWOWAY:
     SelectBranchCC(N);
     return;
   case ISD::CopyToReg:


Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td
diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.55 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.56
--- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.55	Tue Apr  5 19:25:27 2005
+++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td	Sat Apr  9 15:09:12 2005
@@ -458,7 +458,9 @@
 def RLWINM : MForm_2<21, 0, 0, 0,
                      (ops GPRC:$rA, GPRC:$rS, u5imm:$SH, u5imm:$MB, u5imm:$ME),
                      "rlwinm $rA, $rS, $SH, $MB, $ME">;
-
+def RLWNM  : MForm_2<23, 0, 0, 0,
+                     (ops GPRC:$rA, GPRC:$rS, GPRC:$rB, u5imm:$MB, u5imm:$ME),
+                     "rlwnm $rA, $rS, $rB, $MB, $ME">;
 
 // MD-Form instructions.  64 bit rotate instructions.
 //






More information about the llvm-commits mailing list