Ok for vector_shuffle mask to contain undef elements.
[oota-llvm.git] / lib / Target / PowerPC / PPCInstrInfo.cpp
index d8f008a1fea7b2554bcfcc81b58d5abb67d4ebad..037928fb315a8e2ddbcbaef55e6c8551cf2abb20 100644 (file)
@@ -1,31 +1,32 @@
-//===- PPC32InstrInfo.cpp - PowerPC32 Instruction Information ---*- C++ -*-===//
-// 
+//===- PPCInstrInfo.cpp - PowerPC32 Instruction Information -----*- C++ -*-===//
+//
 //                     The LLVM Compiler Infrastructure
 //
 // This file was developed by the LLVM research group and is distributed under
 // the University of Illinois Open Source License. See LICENSE.TXT for details.
-// 
+//
 //===----------------------------------------------------------------------===//
 //
 // This file contains the PowerPC implementation of the TargetInstrInfo class.
 //
 //===----------------------------------------------------------------------===//
 
-#include "PPC32InstrInfo.h"
-#include "PPC32GenInstrInfo.inc"
-#include "PowerPC.h"
+#include "PPCInstrInfo.h"
+#include "PPCGenInstrInfo.inc"
+#include "PPC.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include <iostream>
 using namespace llvm;
 
-PPC32InstrInfo::PPC32InstrInfo()
-  : TargetInstrInfo(PPC32Insts, sizeof(PPC32Insts)/sizeof(PPC32Insts[0])) {}
+PPCInstrInfo::PPCInstrInfo()
+  : TargetInstrInfo(PPCInsts, sizeof(PPCInsts)/sizeof(PPCInsts[0])) {}
 
-bool PPC32InstrInfo::isMoveInstr(const MachineInstr& MI,
-                                 unsigned& sourceReg,
-                                 unsigned& destReg) const {
+bool PPCInstrInfo::isMoveInstr(const MachineInstr& MI,
+                               unsigned& sourceReg,
+                               unsigned& destReg) const {
   MachineOpCode oc = MI.getOpcode();
-  if (oc == PPC::OR) {                      // or r1, r2, r2
+  if (oc == PPC::OR4 || oc == PPC::OR8 || oc == PPC::VOR ||
+      oc == PPC::OR4To8 || oc == PPC::OR8To4) {                // or r1, r2, r2
     assert(MI.getNumOperands() == 3 &&
            MI.getOperand(0).isRegister() &&
            MI.getOperand(1).isRegister() &&
@@ -57,7 +58,8 @@ bool PPC32InstrInfo::isMoveInstr(const MachineInstr& MI,
       destReg = MI.getOperand(0).getReg();
       return true;
     }
-  } else if (oc == PPC::FMR) {              // fmr r1, r2
+  } else if (oc == PPC::FMRS || oc == PPC::FMRD ||
+             oc == PPC::FMRSD) {      // fmr r1, r2
     assert(MI.getNumOperands() == 2 &&
            MI.getOperand(0).isRegister() &&
            MI.getOperand(1).isRegister() &&
@@ -76,3 +78,76 @@ bool PPC32InstrInfo::isMoveInstr(const MachineInstr& MI,
   }
   return false;
 }
+
+unsigned PPCInstrInfo::isLoadFromStackSlot(MachineInstr *MI, 
+                                           int &FrameIndex) const {
+  switch (MI->getOpcode()) {
+  default: break;
+  case PPC::LD:
+  case PPC::LWZ:
+  case PPC::LFS:
+  case PPC::LFD:
+    if (MI->getOperand(1).isImmediate() && !MI->getOperand(1).getImmedValue() &&
+        MI->getOperand(2).isFrameIndex()) {
+      FrameIndex = MI->getOperand(2).getFrameIndex();
+      return MI->getOperand(0).getReg();
+    }
+    break;
+  }
+  return 0;
+}
+
+unsigned PPCInstrInfo::isStoreToStackSlot(MachineInstr *MI, 
+                                          int &FrameIndex) const {
+  switch (MI->getOpcode()) {
+  default: break;
+  case PPC::STD:
+  case PPC::STW:
+  case PPC::STFS:
+  case PPC::STFD:
+    if (MI->getOperand(1).isImmediate() && !MI->getOperand(1).getImmedValue() &&
+        MI->getOperand(2).isFrameIndex()) {
+      FrameIndex = MI->getOperand(2).getFrameIndex();
+      return MI->getOperand(0).getReg();
+    }
+    break;
+  }
+  return 0;
+}
+
+// commuteInstruction - We can commute rlwimi instructions, but only if the
+// rotate amt is zero.  We also have to munge the immediates a bit.
+MachineInstr *PPCInstrInfo::commuteInstruction(MachineInstr *MI) const {
+  // Normal instructions can be commuted the obvious way.
+  if (MI->getOpcode() != PPC::RLWIMI)
+    return TargetInstrInfo::commuteInstruction(MI);
+  
+  // Cannot commute if it has a non-zero rotate count.
+  if (MI->getOperand(3).getImmedValue() != 0)
+    return 0;
+  
+  // If we have a zero rotate count, we have:
+  //   M = mask(MB,ME)
+  //   Op0 = (Op1 & ~M) | (Op2 & M)
+  // Change this to:
+  //   M = mask((ME+1)&31, (MB-1)&31)
+  //   Op0 = (Op2 & ~M) | (Op1 & M)
+
+  // Swap op1/op2
+  unsigned Reg1 = MI->getOperand(1).getReg();
+  unsigned Reg2 = MI->getOperand(2).getReg();
+  MI->SetMachineOperandReg(2, Reg1);
+  MI->SetMachineOperandReg(1, Reg2);
+  
+  // Swap the mask around.
+  unsigned MB = MI->getOperand(4).getImmedValue();
+  unsigned ME = MI->getOperand(5).getImmedValue();
+  MI->getOperand(4).setImmedValue((ME+1) & 31);
+  MI->getOperand(5).setImmedValue((MB-1) & 31);
+  return MI;
+}
+
+void PPCInstrInfo::insertNoop(MachineBasicBlock &MBB, 
+                              MachineBasicBlock::iterator MI) const {
+  BuildMI(MBB, MI, PPC::NOP, 0);
+}