[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC.td PPCHazardRecognizers.cpp PPCHazardRecognizers.h PPCISelDAGToDAG.cpp PPCInstrFormats.td PPCInstrInfo.h PPCInstrInfo.td

Chris Lattner lattner at cs.uiuc.edu
Sun Mar 12 01:14:04 PST 2006



Changes in directory llvm/lib/Target/PowerPC:

PPC.td updated: 1.12 -> 1.13
PPCHazardRecognizers.cpp updated: 1.8 -> 1.9
PPCHazardRecognizers.h updated: 1.4 -> 1.5
PPCISelDAGToDAG.cpp updated: 1.163 -> 1.164
PPCInstrFormats.td updated: 1.64 -> 1.65
PPCInstrInfo.h updated: 1.12 -> 1.13
PPCInstrInfo.td updated: 1.179 -> 1.180
---
Log message:

Several big changes:
1. Use flags on the instructions in the .td file to indicate the PPC970 unit
   type instead of a table in the .cpp file.  Much cleaner.
2. Change the hazard recognizer to build d-groups according to the actual
   algorithm used, not my flawed understanding of it.
3. Model "must be in the first slot" and "must be the only instr in a group"
   accurately.



---
Diffs of the changes:  (+317 -213)

 PPC.td                   |   21 +++
 PPCHazardRecognizers.cpp |  282 ++++++++++++++++++++++++-----------------------
 PPCHazardRecognizers.h   |   32 ++---
 PPCISelDAGToDAG.cpp      |    4 
 PPCInstrFormats.td       |   22 +++
 PPCInstrInfo.h           |   37 ++++++
 PPCInstrInfo.td          |  132 +++++++++++++---------
 7 files changed, 317 insertions(+), 213 deletions(-)


Index: llvm/lib/Target/PowerPC/PPC.td
diff -u llvm/lib/Target/PowerPC/PPC.td:1.12 llvm/lib/Target/PowerPC/PPC.td:1.13
--- llvm/lib/Target/PowerPC/PPC.td:1.12	Tue Feb 28 01:08:22 2006
+++ llvm/lib/Target/PowerPC/PPC.td	Sun Mar 12 03:13:49 2006
@@ -67,17 +67,32 @@
                    Feature64Bit /*, Feature64BitRegs */]>;
 
 
+def PPCInstrInfo : InstrInfo {
+  // Define how we want to layout our TargetSpecific information field... This
+  // should be kept up-to-date with the fields in the PPCInstrInfo.h file.
+  let TSFlagsFields = ["PPC970_First",
+                       "PPC970_Single",
+                       "PPC970_Unit"];
+  let TSFlagsShifts = [0,
+                       1,
+                       2];
+
+  let isLittleEndianEncoding = 1;
+}
+
+
 def PPC : Target {
   // Pointers on PPC are 32-bits in size.
   let PointerType = i32;
 
+  // Information about the instructions.
+  let InstructionSet = PPCInstrInfo;
+
+
   // According to the Mach-O Runtime ABI, these regs are nonvolatile across
   // calls
   let CalleeSavedRegisters = [R1, R13, R14, R15, R16, R17, R18, R19,
     R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31, F14, F15,
     F16, F17, F18, F19, F20, F21, F22, F23, F24, F25, F26, F27, F28, F29,
     F30, F31, CR2, CR3, CR4, LR];
-
-  // Pull in Instruction Info:
-  let InstructionSet = PowerPCInstrInfo;
 }


Index: llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp
diff -u llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.8 llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.9
--- llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.8	Sat Mar 11 15:49:49 2006
+++ llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp	Sun Mar 12 03:13:49 2006
@@ -14,6 +14,7 @@
 #define DEBUG_TYPE "sched"
 #include "PPCHazardRecognizers.h"
 #include "PPC.h"
+#include "PPCInstrInfo.h"
 #include "llvm/Support/Debug.h"
 #include <iostream>
 using namespace llvm;
@@ -23,15 +24,14 @@
 // PowerPC 970 Hazard Recognizer
 //
 // This models the dispatch group formation of the PPC970 processor.  Dispatch
-// groups are bundles of up to five instructions that can contain up to two ALU
-// (aka FXU) ops, two FPU ops, two Load/Store ops, one CR op, one VALU op, one
-// VPERM op, and one BRANCH op.  If the code contains more instructions in a
-// sequence than the dispatch group can contain (e.g. three loads in a row) the
-// processor terminates the dispatch group early, wasting execution resources.
+// groups are bundles of up to five instructions that can contain various mixes
+// of instructions.  The PPC970 can dispatch a peak of 4 non-branch and one 
+// branch instruction per-cycle.
 //
-// In addition to these restrictions, there are a number of other restrictions:
-// some instructions, e.g. branches, are required to be the last instruction in
-// a group.  Additionally, only branches can issue in the 5th (last) slot.
+// There are a number of restrictions to dispatch group formation: some
+// instructions can only be issued in the first slot of a dispatch group, & some
+// instructions fill an entire dispatch group.  Additionally, only branches can
+// issue in the 5th (last) slot.
 //
 // Finally, there are a number of "structural" hazards on the PPC970.  These
 // conditions cause large performance penalties due to misprediction, recovery,
@@ -41,8 +41,6 @@
 // conditions, we insert no-op instructions when appropriate.
 //
 // FIXME: This is missing some significant cases:
-//  -1. Handle all of the instruction types in GetInstrType.
-//   0. Handling of instructions that must be the first/last in a group.
 //   1. Modeling of microcoded instructions.
 //   2. Handling of cracked instructions.
 //   3. Handling of serialized operations.
@@ -50,103 +48,70 @@
 //      e.g. integer divides that only execute in the second slot.
 //
 
-PPCHazardRecognizer970::PPCHazardRecognizer970() {
+PPCHazardRecognizer970::PPCHazardRecognizer970(const TargetInstrInfo &tii)
+  : TII(tii) {
   EndDispatchGroup();
 }
 
 void PPCHazardRecognizer970::EndDispatchGroup() {
   DEBUG(std::cerr << "=== Start of dispatch group\n");
-  // Pipeline units.
-  NumFXU = NumLSU = NumFPU = 0;
-  HasCR = HasSPR = HasVALU = HasVPERM = false;
   NumIssued = 0;
   
   // Structural hazard info.
   HasCTRSet = false;
-  StorePtr1 = StorePtr2 = SDOperand();
-  StoreSize = 0;
+  NumStores = 0;
 }
 
 
-PPCHazardRecognizer970::PPC970InstrType
-PPCHazardRecognizer970::GetInstrType(unsigned Opcode) {
-  if (Opcode < ISD::BUILTIN_OP_END)
-    return PseudoInst;
+PPCII::PPC970_Unit 
+PPCHazardRecognizer970::GetInstrType(unsigned Opcode,
+                                     bool &isFirst, bool &isSingle,
+                                     bool &isLoad, bool &isStore){
+  if (Opcode < ISD::BUILTIN_OP_END) {
+    isFirst = isSingle = isLoad = isStore = false;
+    return PPCII::PPC970_Pseudo;
+  }
   Opcode -= ISD::BUILTIN_OP_END;
   
-  switch (Opcode) {
-  case PPC::FMRSD: return PseudoInst;  // Usually coallesced away.
-  case PPC::BCTRL:
-  case PPC::BL:
-  case PPC::BLA:
-  case PPC::BLR:
-    return BR;
-  case PPC::MCRF:
-  case PPC::MFCR:
-  case PPC::MFOCRF:
-    return CR;
-  case PPC::MFLR:
-  case PPC::MFCTR:
-  case PPC::MTLR:
-  case PPC::MTCTR:
-    return SPR;
-  case PPC::LFS:
-  case PPC::LFD:
-  case PPC::LWZ:
-  case PPC::LFSX:
-  case PPC::LWZX:
-  case PPC::LBZ:
-  case PPC::LHA:
-  case PPC::LHZ:
-  case PPC::LWZU:
-    return LSU_LD;
-  case PPC::STFS:
-  case PPC::STFD:
-  case PPC::STW:
-  case PPC::STB:
-  case PPC::STH:
-  case PPC::STWU:
-    return LSU_ST;
-  case PPC::DIVW:
-  case PPC::DIVWU:
-  case PPC::DIVD:
-  case PPC::DIVDU:
-    return FXU_FIRST;
-  case PPC::FADDS:
-  case PPC::FCTIWZ:
-  case PPC::FRSP:
-  case PPC::FSUB:
-    return FPU;
-  }
+  const TargetInstrDescriptor &TID = TII.get(Opcode);
+  
+  isLoad  = TID.Flags & M_LOAD_FLAG;
+  isStore = TID.Flags & M_STORE_FLAG;
   
-  return FXU;
+  unsigned TSFlags = TID.TSFlags;
+  
+  isFirst  = TSFlags & PPCII::PPC970_First;
+  isSingle = TSFlags & PPCII::PPC970_Single;
+  return (PPCII::PPC970_Unit)(TSFlags & PPCII::PPC970_Mask);
 }
 
 /// isLoadOfStoredAddress - If we have a load from the previously stored pointer
 /// as indicated by StorePtr1/StorePtr2/StoreSize, return true.
 bool PPCHazardRecognizer970::
 isLoadOfStoredAddress(unsigned LoadSize, SDOperand Ptr1, SDOperand Ptr2) const {
-  // Handle exact and commuted addresses.
-  if (Ptr1 == StorePtr1 && Ptr2 == StorePtr2)
-    return true;
-  if (Ptr2 == StorePtr1 && Ptr1 == StorePtr2)
-    return true;
-  
-  // Okay, we don't have an exact match, if this is an indexed offset, see if we
-  // have overlap (which happens during fp->int conversion for example).
-  if (StorePtr2 == Ptr2) {
-    if (ConstantSDNode *StoreOffset = dyn_cast<ConstantSDNode>(StorePtr1))
-      if (ConstantSDNode *LoadOffset = dyn_cast<ConstantSDNode>(Ptr1)) {
-        // Okay the base pointers match, so we have [c1+r] vs [c2+r].  Check to
-        // see if the load and store actually overlap.
-        int StoreOffs = StoreOffset->getValue();
-        int LoadOffs  = LoadOffset->getValue();
-        if (StoreOffs < LoadOffs) {
-          if (int(StoreOffs+StoreSize) > LoadOffs) return true;
-        } else {
-          if (int(LoadOffs+LoadSize) > StoreOffs) return true;
+  for (unsigned i = 0, e = NumStores; i != e; ++i) {
+    // Handle exact and commuted addresses.
+    if (Ptr1 == StorePtr1[i] && Ptr2 == StorePtr2[i])
+      return true;
+    if (Ptr2 == StorePtr1[i] && Ptr1 == StorePtr2[i])
+      return true;
+    
+    // Okay, we don't have an exact match, if this is an indexed offset, see if
+    // we have overlap (which happens during fp->int conversion for example).
+    if (StorePtr2[i] == Ptr2) {
+      if (ConstantSDNode *StoreOffset = dyn_cast<ConstantSDNode>(StorePtr1[i]))
+        if (ConstantSDNode *LoadOffset = dyn_cast<ConstantSDNode>(Ptr1)) {
+          // Okay the base pointers match, so we have [c1+r] vs [c2+r].  Check
+          // to see if the load and store actually overlap.
+          int StoreOffs = StoreOffset->getValue();
+          int LoadOffs  = LoadOffset->getValue();
+          if (StoreOffs < LoadOffs) {
+            if (int(StoreOffs+StoreSize) > LoadOffs) return true;
+          } else {
+            if (int(LoadOffs+LoadSize) > StoreOffs) return true;
+          }
         }
-      }
+    }
   }
   return false;
 }
@@ -157,53 +122,76 @@
 /// pipeline flush.
 HazardRecognizer::HazardType PPCHazardRecognizer970::
 getHazardType(SDNode *Node) {
-  PPC970InstrType InstrType = GetInstrType(Node->getOpcode());
-  if (InstrType == PseudoInst) return NoHazard;  
+  bool isFirst, isSingle, isLoad, isStore;
+  PPCII::PPC970_Unit InstrType = 
+    GetInstrType(Node->getOpcode(), isFirst, isSingle, isLoad, isStore);
+  if (InstrType == PPCII::PPC970_Pseudo) return NoHazard;  
   unsigned Opcode = Node->getOpcode()-ISD::BUILTIN_OP_END;
 
+  // We can only issue a PPC970_First/PPC970_Single instruction (such as
+  // crand/mtspr/etc) if this is the first cycle of the dispatch group.
+  if (NumIssued != 0 && (isFirst || isSingle) )
+    return Hazard;
+  
   switch (InstrType) {
   default: assert(0 && "Unknown instruction type!");
-  case FXU:
-  case FXU_FIRST: if (NumFXU  == 2) return Hazard;
-  case LSU_ST:
-  case LSU_LD:    if (NumLSU  == 2) return Hazard;
-  case FPU:       if (NumFPU  == 2) return Hazard;
-  case CR:        if (HasCR) return Hazard;
-  case SPR:       if (HasSPR) return Hazard;
-  case VALU:      if (HasVALU) return Hazard;
-  case VPERM:     if (HasVPERM) return Hazard;
-  case BR:  break;
+  case PPCII::PPC970_FXU:
+  case PPCII::PPC970_LSU:
+  case PPCII::PPC970_FPU:
+  case PPCII::PPC970_VALU:
+  case PPCII::PPC970_VPERM:
+    // We can only issue a branch as the last instruction in a group.
+    if (NumIssued == 4) return Hazard;
+    break;
+  case PPCII::PPC970_CRU:
+    // We can only issue a CR instruction in the first two slots.
+    if (NumIssued >= 2) return Hazard;
+    break;
+  case PPCII::PPC970_BRU:
+    break;
   }
-  
-  // We can only issue a CR or SPR instruction, or an FXU instruction that needs
-  // to lead a dispatch group as the first instruction in the group.
-  if (NumIssued != 0 && 
-      (InstrType == CR || InstrType == SPR || InstrType == FXU_FIRST))
-    return Hazard;
-  
-  // We can only issue a branch as the last instruction in a group.
-  if (NumIssued == 4 && InstrType != BR)
-    return Hazard;
-  
+
   // Do not allow MTCTR and BCTRL to be in the same dispatch group.
   if (HasCTRSet && Opcode == PPC::BCTRL)
     return NoopHazard;
   
   // If this is a load following a store, make sure it's not to the same or
   // overlapping address.
-  if (InstrType == LSU_LD && StoreSize) {
+  if (isLoad && StoreSize) {
     unsigned LoadSize;
     switch (Opcode) {
     default: assert(0 && "Unknown load!");
-    case PPC::LBZ: LoadSize = 1; break;
+    case PPC::LBZ:
+    case PPC::LBZX:
+    case PPC::LVEBX:
+      LoadSize = 1;
+      break;
     case PPC::LHA:
-    case PPC::LHZ: LoadSize = 2; break;
-    case PPC::LWZU:
-    case PPC::LFSX:
+    case PPC::LHAX:
+    case PPC::LHZ:
+    case PPC::LHZX:
+    case PPC::LVEHX:
+      LoadSize = 2;
+      break;
     case PPC::LFS:
+    case PPC::LFSX:
+    case PPC::LWZ:
     case PPC::LWZX:
-    case PPC::LWZ: LoadSize = 4; break;
-    case PPC::LFD: LoadSize = 8; break;
+    case PPC::LWZU:
+    case PPC::LWA:
+    case PPC::LWAX:
+    case PPC::LVEWX:
+      LoadSize = 4;
+      break;
+    case PPC::LFD:
+    case PPC::LFDX:
+    case PPC::LD:
+    case PPC::LDX:
+      LoadSize = 8;
+      break;
+    case PPC::LVX:
+      LoadSize = 16;
+      break;
     }
     
     if (isLoadOfStoredAddress(LoadSize, 
@@ -215,41 +203,61 @@
 }
 
 void PPCHazardRecognizer970::EmitInstruction(SDNode *Node) {
-  PPC970InstrType InstrType = GetInstrType(Node->getOpcode());
-  if (InstrType == PseudoInst) return;
+  bool isFirst, isSingle, isLoad, isStore;
+  PPCII::PPC970_Unit InstrType = 
+    GetInstrType(Node->getOpcode(), isFirst, isSingle, isLoad, isStore);
+  if (InstrType == PPCII::PPC970_Pseudo) return;  
   unsigned Opcode = Node->getOpcode()-ISD::BUILTIN_OP_END;
 
   // Update structural hazard information.
   if (Opcode == PPC::MTCTR) HasCTRSet = true;
   
   // Track the address stored to.
-  if (InstrType == LSU_ST) {
-    StorePtr1 = Node->getOperand(1);
-    StorePtr2 = Node->getOperand(2);
+  if (isStore) {
+    unsigned ThisStoreSize;
     switch (Opcode) {
     default: assert(0 && "Unknown store instruction!");
-    case PPC::STB:  StoreSize = 1; break;
-    case PPC::STH:  StoreSize = 2; break;
+    case PPC::STBX:
+    case PPC::STB:
+    case PPC::STVEBX:
+      ThisStoreSize = 1;
+      break;
+    case PPC::STHX:
+    case PPC::STH:
+    case PPC::STVEHX:
+      ThisStoreSize = 2;
+      break;
     case PPC::STFS:
+    case PPC::STFSX:
     case PPC::STWU:
-    case PPC::STW:  StoreSize = 4; break;
-    case PPC::STFD: StoreSize = 8; break;
+    case PPC::STWX:
+    case PPC::STWUX:
+    case PPC::STW:
+    case PPC::STVEWX:
+    case PPC::STFIWX:
+      ThisStoreSize = 4;
+      break;
+    case PPC::STD:
+    case PPC::STDU:
+    case PPC::STFD:
+    case PPC::STFDX:
+    case PPC::STDX:
+    case PPC::STDUX:
+      ThisStoreSize = 8;
+      break;
+    case PPC::STVX:
+      ThisStoreSize = 16;
+      break;
     }
+    
+    StoreSize[NumStores] = ThisStoreSize;
+    StorePtr1[NumStores] = Node->getOperand(1);
+    StorePtr2[NumStores] = Node->getOperand(2);
+    ++NumStores;
   }
   
-  switch (InstrType) {
-  default: assert(0 && "Unknown instruction type!");
-  case FXU:
-  case FXU_FIRST: ++NumFXU; break;
-  case LSU_LD:
-  case LSU_ST:    ++NumLSU; break;
-  case FPU:       ++NumFPU; break;
-  case CR:        HasCR    = true; break;
-  case SPR:       HasSPR   = true; break;
-  case VALU:      HasVALU  = true; break;
-  case VPERM:     HasVPERM = true; break;
-  case BR:        NumIssued = 4; return;  // ends a d-group.
-  }
+  if (InstrType == PPCII::PPC970_BRU || isSingle)
+    NumIssued = 4;  // Terminate a d-group.
   ++NumIssued;
   
   if (NumIssued == 5)


Index: llvm/lib/Target/PowerPC/PPCHazardRecognizers.h
diff -u llvm/lib/Target/PowerPC/PPCHazardRecognizers.h:1.4 llvm/lib/Target/PowerPC/PPCHazardRecognizers.h:1.5
--- llvm/lib/Target/PowerPC/PPCHazardRecognizers.h:1.4	Tue Mar  7 22:25:59 2006
+++ llvm/lib/Target/PowerPC/PPCHazardRecognizers.h	Sun Mar 12 03:13:49 2006
@@ -15,6 +15,7 @@
 #define PPCHAZRECS_H
 
 #include "llvm/CodeGen/ScheduleDAG.h"
+#include "PPCInstrInfo.h"
 
 namespace llvm {
   
@@ -25,16 +26,9 @@
 /// setting the CTR register then branching through it within a dispatch group),
 /// or storing then loading from the same address within a dispatch group.
 class PPCHazardRecognizer970 : public HazardRecognizer {
-  unsigned NumIssued;  // Number of insts issued, including advanced cycles.
+  const TargetInstrInfo &TII;
   
-  // Number of various types of instructions in the current dispatch group.
-  unsigned NumFXU;     // Number of Fixed Point (integer) instructions
-  unsigned NumLSU;     // Number of Load/Store instructions
-  unsigned NumFPU;     // Number of Floating Point instructions
-  bool     HasCR;      // True if Condition Register instruction issued
-  bool     HasSPR;     // True if Special-Purpose Register instruction used
-  bool     HasVALU;    // True if Vector Arithmetic instruction issued
-  bool     HasVPERM;   // True if Vector Permute instruction issued
+  unsigned NumIssued;  // Number of insts issued, including advanced cycles.
   
   // Various things that can cause a structural hazard.
   
@@ -42,17 +36,17 @@
   bool HasCTRSet;
   
   // StoredPtr - Keep track of the address of any store.  If we see a load from
-  // the same address (or one that aliases it), disallow the store.  We only
-  // need one pointer here, because there can only be two LSU operations and we
-  // only get an LSU reject if the first is a store and the second is a load.
+  // the same address (or one that aliases it), disallow the store.  We can have
+  // up to four stores in one dispatch group, hence we track up to 4.
   //
   // This is null if we haven't seen a store yet.  We keep track of both
   // operands of the store here, since we support [r+r] and [r+i] addressing.
-  SDOperand StorePtr1, StorePtr2;
-  unsigned  StoreSize;
+  SDOperand StorePtr1[4], StorePtr2[4];
+  unsigned  StoreSize[4];
+  unsigned NumStores;
   
 public:
-  PPCHazardRecognizer970();
+  PPCHazardRecognizer970(const TargetInstrInfo &TII);
   virtual HazardType getHazardType(SDNode *Node);
   virtual void EmitInstruction(SDNode *Node);
   virtual void AdvanceCycle();
@@ -63,13 +57,11 @@
   ///
   void EndDispatchGroup();
   
-  enum PPC970InstrType {
-    FXU, FXU_FIRST, LSU_LD, LSU_ST, FPU, CR, SPR, VALU, VPERM, BR, PseudoInst
-  };
-  
   /// GetInstrType - Classify the specified powerpc opcode according to its
   /// pipeline.
-  PPC970InstrType GetInstrType(unsigned Opcode);
+  PPCII::PPC970_Unit GetInstrType(unsigned Opcode,
+                                  bool &isFirst, bool &isSingle,
+                                  bool &isLoad, bool &isStore);
   
   bool isLoadOfStoredAddress(unsigned LoadSize,
                              SDOperand Ptr1, SDOperand Ptr2) const;


Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.163 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.164
--- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.163	Tue Mar  7 22:25:59 2006
+++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp	Sun Mar 12 03:13:49 2006
@@ -129,7 +129,9 @@
     virtual HazardRecognizer *CreateTargetHazardRecognizer() {
       // Should use subtarget info to pick the right hazard recognizer.  For
       // now, always return a PPC970 recognizer.
-      return new PPCHazardRecognizer970(); 
+      const TargetInstrInfo *II = PPCLowering.getTargetMachine().getInstrInfo();
+      assert(II && "No InstrInfo?");
+      return new PPCHazardRecognizer970(*II); 
     }
 
 // Include the pieces autogenerated from the target description.


Index: llvm/lib/Target/PowerPC/PPCInstrFormats.td
diff -u llvm/lib/Target/PowerPC/PPCInstrFormats.td:1.64 llvm/lib/Target/PowerPC/PPCInstrFormats.td:1.65
--- llvm/lib/Target/PowerPC/PPCInstrFormats.td:1.64	Thu Jan 26 19:46:15 2006
+++ llvm/lib/Target/PowerPC/PPCInstrFormats.td	Sun Mar 12 03:13:49 2006
@@ -27,7 +27,27 @@
   let OperandList = OL;
   let AsmString = asmstr;
   let Itinerary = itin;
-}
+  
+  /// These fields correspond to the fields in PPCInstrInfo.h.  Any changes to
+  /// these must be reflected there!  See comments there for what these are.
+  bits<1> PPC970_First = 0;
+  bits<1> PPC970_Single = 0;
+  bits<3> PPC970_Unit = 0;
+}
+
+class PPC970_DGroup_First  { bits<1> PPC970_First = 1;  }
+class PPC970_DGroup_Single { bits<1> PPC970_Single = 1; }
+class PPC970_MicroCode;
+
+class PPC970_Unit_Pseudo   { bits<3> PPC970_Unit = 0;   }
+class PPC970_Unit_FXU      { bits<3> PPC970_Unit = 1;   }
+class PPC970_Unit_LSU      { bits<3> PPC970_Unit = 2;   }
+class PPC970_Unit_FPU      { bits<3> PPC970_Unit = 3;   }
+class PPC970_Unit_CRU      { bits<3> PPC970_Unit = 4;   }
+class PPC970_Unit_VALU     { bits<3> PPC970_Unit = 5;   }
+class PPC970_Unit_VPERM    { bits<3> PPC970_Unit = 6;   }
+class PPC970_Unit_BRU      { bits<3> PPC970_Unit = 7;   }
+
 
 // 1.7.1 I-Form
 class IForm<bits<6> opcode, bit aa, bit lk, dag OL, string asmstr,


Index: llvm/lib/Target/PowerPC/PPCInstrInfo.h
diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.h:1.12 llvm/lib/Target/PowerPC/PPCInstrInfo.h:1.13
--- llvm/lib/Target/PowerPC/PPCInstrInfo.h:1.12	Sun Mar  5 17:49:55 2006
+++ llvm/lib/Target/PowerPC/PPCInstrInfo.h	Sun Mar 12 03:13:49 2006
@@ -19,6 +19,43 @@
 #include "PPCRegisterInfo.h"
 
 namespace llvm {
+
+/// PPCII - This namespace holds all of the PowerPC target-specific
+/// per-instruction flags.  These must match the corresponding definitions in
+/// PPC.td and PPCInstrFormats.td.
+namespace PPCII {
+enum {
+  // PPC970 Instruction Flags.  These flags describe the characteristics of the
+  // PowerPC 970 (aka G5) dispatch groups and how they are formed out of
+  // raw machine instructions.
+
+  /// PPC970_First - This instruction starts a new dispatch group, so it will
+  /// always be the first one in the group.
+  PPC970_First = 0x1,
+  
+  /// PPC970_Single - This instruction starts a new dispatch group and
+  /// terminates it, so it will be the sole instruction in the group.
+  PPC970_Single = 0x2,
+
+  /// PPC970_Mask/Shift - This is a bitmask that selects the pipeline type that
+  /// an instruction is issued to.
+  PPC970_Shift = 2,
+  PPC970_Mask = 0x07 << PPC970_Shift,
+};
+enum PPC970_Unit {
+  /// These are the various PPC970 execution unit pipelines.  Each instruction
+  /// is one of these.
+  PPC970_Pseudo = 0 << PPC970_Shift,   // Pseudo instruction
+  PPC970_FXU    = 1 << PPC970_Shift,   // Fixed Point (aka Integer/ALU) Unit
+  PPC970_LSU    = 2 << PPC970_Shift,   // Load Store Unit
+  PPC970_FPU    = 3 << PPC970_Shift,   // Floating Point Unit
+  PPC970_CRU    = 4 << PPC970_Shift,   // Control Register Unit
+  PPC970_VALU   = 5 << PPC970_Shift,   // Vector ALU
+  PPC970_VPERM  = 6 << PPC970_Shift,   // Vector Permute Unit
+  PPC970_BRU    = 7 << PPC970_Shift,   // Branch Unit
+};
+}
+  
   
 class PPCInstrInfo : public TargetInstrInfo {
   const PPCRegisterInfo RI;


Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td
diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.179 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.180
--- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.179	Sun Mar  5 17:49:55 2006
+++ llvm/lib/Target/PowerPC/PPCInstrInfo.td	Sun Mar 12 03:13:49 2006
@@ -203,7 +203,7 @@
 
 // Pseudo-instructions:
 
-let isLoad = 1, hasCtrlDep = 1 in {
+let hasCtrlDep = 1 in {
 def ADJCALLSTACKDOWN : Pseudo<(ops u16imm:$amt),
                               "; ADJCALLSTACKDOWN",
                               [(callseq_start imm:$amt)]>;
@@ -220,7 +220,8 @@
 
 // SELECT_CC_* - Used to implement the SELECT_CC DAG operation.  Expanded by the
 // scheduler into a branch sequence.
-let usesCustomDAGSchedInserter = 1 in {  // Expanded by the scheduler.
+let usesCustomDAGSchedInserter = 1,    // Expanded by the scheduler.
+    PPC970_Single = 1 in {
   def SELECT_CC_Int : Pseudo<(ops GPRC:$dst, CRRC:$cond, GPRC:$T, GPRC:$F,
                               i32imm:$BROPC), "; SELECT_CC PSEUDO!", []>;
   def SELECT_CC_F4  : Pseudo<(ops F4RC:$dst, CRRC:$cond, F4RC:$T, F4RC:$F,
@@ -229,16 +230,18 @@
                               i32imm:$BROPC), "; SELECT_CC PSEUDO!", []>;
 }
 
-let isTerminator = 1, noResults = 1 in {
+let isTerminator = 1, noResults = 1, PPC970_Unit = 7 in {
   let isReturn = 1 in
     def BLR : XLForm_2_ext<19, 16, 20, 0, 0, (ops), "blr", BrB, [(retflag)]>;
   def BCTR : XLForm_2_ext<19, 528, 20, 0, 0, (ops), "bctr", BrB, []>;
 }
 
 let Defs = [LR] in
-  def MovePCtoLR : Pseudo<(ops piclabel:$label), "bl $label", []>;
+  def MovePCtoLR : Pseudo<(ops piclabel:$label), "bl $label", []>,
+                   PPC970_Unit_BRU;
 
-let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, noResults = 1 in {
+let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, 
+    noResults = 1, PPC970_Unit = 7 in {
   def COND_BRANCH : Pseudo<(ops CRRC:$crS, u16imm:$opc,
                                 target:$true, target:$false),
                            "; COND_BRANCH", []>;
@@ -266,7 +269,7 @@
                   "bnu $crS, $block", BrB>;
 }
 
-let isCall = 1, noResults = 1, 
+let isCall = 1, noResults = 1, PPC970_Unit = 7, 
   // All calls clobber the non-callee saved registers...
   Defs = [R0,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,R12,
           F0,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11,F12,F13,
@@ -284,7 +287,7 @@
 // D-Form instructions.  Most instructions that perform an operation on a
 // register and an immediate are of this type.
 //
-let isLoad = 1 in {
+let isLoad = 1, PPC970_Unit = 2 in {
 def LBZ : DForm_1<34, (ops GPRC:$rD, memri:$src),
                   "lbz $rD, $src", LdStGeneral,
                   [(set GPRC:$rD, (zextload iaddr:$src, i8))]>;
@@ -304,6 +307,7 @@
                    "lwzu $rD, $disp($rA)", LdStGeneral,
                    []>;
 }
+let PPC970_Unit = 1 in {  // FXU Operations.
 def ADDI   : DForm_2<14, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm),
                      "addi $rD, $rA, $imm", IntGeneral,
                      [(set GPRC:$rD, (add GPRC:$rA, immSExt16:$imm))]>;
@@ -332,7 +336,8 @@
 def LIS : DForm_2_r0<15, (ops GPRC:$rD, symbolHi:$imm),
                      "lis $rD, $imm", IntGeneral,
                      [(set GPRC:$rD, imm16Shifted:$imm)]>;
-let isStore = 1, noResults = 1 in {
+}
+let isStore = 1, noResults = 1, PPC970_Unit = 2 in {
 def STMW : DForm_3<47, (ops GPRC:$rS, s16imm:$disp, GPRC:$rA),
                    "stmw $rS, $disp($rA)", LdStLMW,
                    []>;
@@ -349,6 +354,7 @@
                    "stwu $rS, $disp($rA)", LdStGeneral,
                    []>;
 }
+let PPC970_Unit = 1 in {  // FXU Operations.
 def ANDIo : DForm_4<28, (ops GPRC:$dst, GPRC:$src1, u16imm:$src2),
                     "andi. $dst, $src1, $src2", IntGeneral,
                     [(set GPRC:$dst, (and GPRC:$src1, immZExt16:$src2))]>,
@@ -383,7 +389,8 @@
                          "cmplwi $dst, $src1, $src2", IntCompare>;
 def CMPLDI : DForm_6_ext<10, (ops CRRC:$dst, GPRC:$src1, u16imm:$src2),
                          "cmpldi $dst, $src1, $src2", IntCompare>, isPPC64;
-let isLoad = 1 in {
+}
+let isLoad = 1, PPC970_Unit = 2 in {
 def LFS : DForm_8<48, (ops F4RC:$rD, memri:$src),
                   "lfs $rD, $src", LdStLFDU,
                   [(set F4RC:$rD, (load iaddr:$src))]>;
@@ -391,7 +398,7 @@
                   "lfd $rD, $src", LdStLFD,
                   [(set F8RC:$rD, (load iaddr:$src))]>;
 }
-let isStore = 1, noResults = 1 in {
+let isStore = 1, noResults = 1, PPC970_Unit = 2 in {
 def STFS : DForm_9<52, (ops F4RC:$rS, memri:$dst),
                    "stfs $rS, $dst", LdStUX,
                    [(store F4RC:$rS, iaddr:$dst)]>;
@@ -402,7 +409,7 @@
 
 // DS-Form instructions.  Load/Store instructions available in PPC-64
 //
-let isLoad = 1 in {
+let isLoad = 1, PPC970_Unit = 2 in {
 def LWA  : DSForm_1<58, 2, (ops GPRC:$rT, s16immX4:$DS, GPRC:$rA),
                     "lwa $rT, $DS($rA)", LdStLWA,
                     []>, isPPC64;
@@ -410,7 +417,7 @@
                     "ld $rT, $DS($rA)", LdStLD,
                     []>, isPPC64;
 }
-let isStore = 1, noResults = 1 in {
+let isStore = 1, noResults = 1, PPC970_Unit = 2 in {
 def STD  : DSForm_2<62, 0, (ops GPRC:$rT, s16immX4:$DS, GPRC:$rA),
                     "std $rT, $DS($rA)", LdStSTD,
                     []>, isPPC64;
@@ -422,7 +429,7 @@
 // X-Form instructions.  Most instructions that perform an operation on a
 // register and another register are of this type.
 //
-let isLoad = 1 in {
+let isLoad = 1, PPC970_Unit = 2 in {
 def LBZX : XForm_1<31,  87, (ops GPRC:$rD, memrr:$src),
                    "lbzx $rD, $src", LdStGeneral,
                    [(set GPRC:$rD, (zextload xaddr:$src, i8))]>;
@@ -456,10 +463,11 @@
 }
 def LVSL : XForm_1<31,   6, (ops VRRC:$vD,  GPRC:$base, GPRC:$rA),
                    "lvsl $vD, $base, $rA", LdStGeneral,
-                   []>;
+                   []>, PPC970_Unit_LSU;
 def LVSR : XForm_1<31,  38, (ops VRRC:$vD,  GPRC:$base, GPRC:$rA),
                    "lvsl $vD, $base, $rA", LdStGeneral,
-                   []>;
+                   []>, PPC970_Unit_LSU;
+let PPC970_Unit = 1 in {  // FXU Operations.
 def NAND : XForm_6<31, 476, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
                    "nand $rA, $rS, $rB", IntGeneral,
                    [(set GPRC:$rA, (not (and GPRC:$rS, GPRC:$rB)))]>;
@@ -517,7 +525,8 @@
 def SRAW : XForm_6<31, 792, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
                    "sraw $rA, $rS, $rB", IntShift,
                    [(set GPRC:$rA, (PPCsra GPRC:$rS, GPRC:$rB))]>;
-let isStore = 1, noResults = 1 in {
+}
+let isStore = 1, noResults = 1, PPC970_Unit = 2 in {
 def STBX  : XForm_8<31, 215, (ops GPRC:$rS, memrr:$dst),
                    "stbx $rS, $dst", LdStGeneral,
                    [(truncstore GPRC:$rS, xaddr:$dst, i8)]>;
@@ -549,6 +558,7 @@
                    "stvx $rS, $dst", LdStGeneral,
                    [(store (v4f32 VRRC:$rS), xoaddr:$dst)]>;
 }
+let PPC970_Unit = 1 in {  // FXU Operations.
 def SRAWI : XForm_10<31, 824, (ops GPRC:$rA, GPRC:$rS, u5imm:$SH), 
                      "srawi $rA, $rS, $SH", IntShift,
                      [(set GPRC:$rA, (sra GPRC:$rS, (i32 imm:$SH)))]>;
@@ -576,14 +586,16 @@
                           "cmplw $crD, $rA, $rB", IntCompare>;
 def CMPLD  : XForm_16_ext<31, 32, (ops CRRC:$crD, GPRC:$rA, GPRC:$rB),
                           "cmpld $crD, $rA, $rB", IntCompare>, isPPC64;
+}
+let PPC970_Unit = 3 in {  // FPU Operations.
 //def FCMPO  : XForm_17<63, 32, (ops CRRC:$crD, FPRC:$fA, FPRC:$fB),
 //                      "fcmpo $crD, $fA, $fB", FPCompare>;
 def FCMPUS : XForm_17<63, 0, (ops CRRC:$crD, F4RC:$fA, F4RC:$fB),
                       "fcmpu $crD, $fA, $fB", FPCompare>;
 def FCMPUD : XForm_17<63, 0, (ops CRRC:$crD, F8RC:$fA, F8RC:$fB),
                       "fcmpu $crD, $fA, $fB", FPCompare>;
-
-let isLoad = 1 in {
+}
+let isLoad = 1, PPC970_Unit = 2 in {
 def LFSX   : XForm_25<31, 535, (ops F4RC:$frD, memrr:$src),
                       "lfsx $frD, $src", LdStLFDU,
                       [(set F4RC:$frD, (load xaddr:$src))]>;
@@ -591,6 +603,7 @@
                       "lfdx $frD, $src", LdStLFDU,
                       [(set F8RC:$frD, (load xaddr:$src))]>;
 }
+let PPC970_Unit = 3 in {  // FPU Operations.
 def FCFID  : XForm_26<63, 846, (ops F8RC:$frD, F8RC:$frB),
                       "fcfid $frD, $frB", FPGeneral,
                       [(set F8RC:$frD, (PPCfcfid F8RC:$frB))]>, isPPC64;
@@ -609,18 +622,28 @@
 def FSQRTS : XForm_26<59, 22, (ops F4RC:$frD, F4RC:$frB),
                       "fsqrts $frD, $frB", FPSqrt,
                       [(set F4RC:$frD, (fsqrt F4RC:$frB))]>;
+}
 
 /// FMR is split into 3 versions, one for 4/8 byte FP, and one for extending.
+///
+/// Note that these are defined as pseudo-ops on the PPC970 because they are
+/// often coallesced away and we don't want the dispatch group builder to think
+/// that they will fill slots (which could cause the load of a LSU reject to
+/// sneak into a d-group with a store).
 def FMRS   : XForm_26<63, 72, (ops F4RC:$frD, F4RC:$frB),
                       "fmr $frD, $frB", FPGeneral,
-                      []>;  // (set F4RC:$frD, F4RC:$frB)
+                      []>,  // (set F4RC:$frD, F4RC:$frB)
+                      PPC970_Unit_Pseudo;
 def FMRD   : XForm_26<63, 72, (ops F8RC:$frD, F8RC:$frB),
                       "fmr $frD, $frB", FPGeneral,
-                      []>;  // (set F8RC:$frD, F8RC:$frB)
+                      []>,  // (set F8RC:$frD, F8RC:$frB)
+                      PPC970_Unit_Pseudo;
 def FMRSD  : XForm_26<63, 72, (ops F8RC:$frD, F4RC:$frB),
                       "fmr $frD, $frB", FPGeneral,
-                      [(set F8RC:$frD, (fextend F4RC:$frB))]>;
+                      [(set F8RC:$frD, (fextend F4RC:$frB))]>,
+                      PPC970_Unit_Pseudo;
 
+let PPC970_Unit = 3 in {  // FPU Operations.
 // These are artificially split into two different forms, for 4/8 byte FP.
 def FABSS  : XForm_26<63, 264, (ops F4RC:$frD, F4RC:$frB),
                       "fabs $frD, $frB", FPGeneral,
@@ -640,9 +663,9 @@
 def FNEGD  : XForm_26<63, 40, (ops F8RC:$frD, F8RC:$frB),
                       "fneg $frD, $frB", FPGeneral,
                       [(set F8RC:$frD, (fneg F8RC:$frB))]>;
+}
                       
-                      
-let isStore = 1, noResults = 1 in {
+let isStore = 1, noResults = 1, PPC970_Unit = 2 in {
 def STFIWX: XForm_28<31, 983, (ops F8RC:$frS, memrr:$dst),
                      "stfiwx $frS, $dst", LdStUX,
                      [(PPCstfiwx F8RC:$frS, xoaddr:$dst)]>;
@@ -657,27 +680,34 @@
 // XL-Form instructions.  condition register logical ops.
 //
 def MCRF   : XLForm_3<19, 0, (ops CRRC:$BF, CRRC:$BFA),
-                      "mcrf $BF, $BFA", BrMCR>;
+                      "mcrf $BF, $BFA", BrMCR>,
+             PPC970_DGroup_First, PPC970_Unit_CRU;
 
-// XFX-Form instructions.  Instructions that deal with SPRs
+// XFX-Form instructions.  Instructions that deal with SPRs.
 //
-// Note that although LR should be listed as `8' and CTR as `9' in the SPR
-// field, the manual lists the groups of bits as [5-9] = 0, [0-4] = 8 or 9
-// which means the SPR value needs to be multiplied by a factor of 32.
-def MFCTR : XFXForm_1_ext<31, 339, 9, (ops GPRC:$rT), "mfctr $rT", SprMFSPR>;
-def MFLR  : XFXForm_1_ext<31, 339, 8, (ops GPRC:$rT), "mflr $rT",  SprMFSPR>;
-def MFCR  : XFXForm_3<31, 19, (ops GPRC:$rT), "mfcr $rT", SprMFCR>;
+def MFCTR : XFXForm_1_ext<31, 339, 9, (ops GPRC:$rT), "mfctr $rT", SprMFSPR>,
+            PPC970_DGroup_First, PPC970_Unit_FXU;
+def MFLR  : XFXForm_1_ext<31, 339, 8, (ops GPRC:$rT), "mflr $rT",  SprMFSPR>,
+            PPC970_DGroup_First, PPC970_Unit_FXU;
+def MFCR  : XFXForm_3<31, 19, (ops GPRC:$rT), "mfcr $rT", SprMFCR>,
+            PPC970_MicroCode, PPC970_Unit_CRU;
 def MTCRF : XFXForm_5<31, 144, (ops crbitm:$FXM, GPRC:$rS),
-                      "mtcrf $FXM, $rS", BrMCRX>;
+                      "mtcrf $FXM, $rS", BrMCRX>,
+            PPC970_MicroCode, PPC970_Unit_CRU;
 def MFOCRF: XFXForm_5a<31, 19, (ops GPRC:$rT, crbitm:$FXM),
-                       "mfcr $rT, $FXM", SprMFCR>;
-def MTCTR : XFXForm_7_ext<31, 467, 9, (ops GPRC:$rS), "mtctr $rS", SprMTSPR>;
-def MTLR  : XFXForm_7_ext<31, 467, 8, (ops GPRC:$rS), "mtlr $rS", SprMTSPR>;
+                       "mfcr $rT, $FXM", SprMFCR>,
+            PPC970_DGroup_First, PPC970_Unit_CRU;
+def MTCTR : XFXForm_7_ext<31, 467, 9, (ops GPRC:$rS), "mtctr $rS", SprMTSPR>,
+            PPC970_DGroup_First, PPC970_Unit_FXU;
+def MTLR  : XFXForm_7_ext<31, 467, 8, (ops GPRC:$rS), "mtlr $rS", SprMTSPR>,
+            PPC970_DGroup_First, PPC970_Unit_FXU;
 def MTSPR : XFXForm_7<31, 467, (ops GPRC:$rS, u16imm:$UIMM), "mtspr $UIMM, $rS",
-                      SprMTSPR>;
+                      SprMTSPR>,
+            PPC970_DGroup_Single, PPC970_Unit_FXU;
 
 // XS-Form instructions.  Just 'sradi'
 //
+let PPC970_Unit = 1 in {  // FXU Operations.
 def SRADI  : XSForm_1<31, 413, (ops GPRC:$rA, GPRC:$rS, u6imm:$SH),
                       "sradi $rA, $rS, $SH", IntRotateD>, isPPC64;
 
@@ -697,16 +727,20 @@
                      [(set GPRC:$rT, (adde GPRC:$rA, GPRC:$rB))]>;
 def DIVD  : XOForm_1<31, 489, 0, (ops G8RC:$rT, G8RC:$rA, G8RC:$rB),
                      "divd $rT, $rA, $rB", IntDivD,
-                     [(set G8RC:$rT, (sdiv G8RC:$rA, G8RC:$rB))]>, isPPC64;
+                     [(set G8RC:$rT, (sdiv G8RC:$rA, G8RC:$rB))]>, isPPC64,
+                     PPC970_DGroup_First;
 def DIVDU : XOForm_1<31, 457, 0, (ops G8RC:$rT, G8RC:$rA, G8RC:$rB),
                      "divdu $rT, $rA, $rB", IntDivD,
-                     [(set G8RC:$rT, (udiv G8RC:$rA, G8RC:$rB))]>, isPPC64;
+                     [(set G8RC:$rT, (udiv G8RC:$rA, G8RC:$rB))]>, isPPC64,
+                     PPC970_DGroup_First;
 def DIVW  : XOForm_1<31, 491, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB),
                      "divw $rT, $rA, $rB", IntDivW,
-                     [(set GPRC:$rT, (sdiv GPRC:$rA, GPRC:$rB))]>;
+                     [(set GPRC:$rT, (sdiv GPRC:$rA, GPRC:$rB))]>,
+                     PPC970_DGroup_First;
 def DIVWU : XOForm_1<31, 459, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB),
                      "divwu $rT, $rA, $rB", IntDivW,
-                     [(set GPRC:$rT, (udiv GPRC:$rA, GPRC:$rB))]>;
+                     [(set GPRC:$rT, (udiv GPRC:$rA, GPRC:$rB))]>,
+                     PPC970_DGroup_First;
 def MULHD : XOForm_1<31, 73, 0, (ops G8RC:$rT, G8RC:$rA, G8RC:$rB),
                      "mulhd $rT, $rA, $rB", IntMulHW,
                      [(set G8RC:$rT, (mulhs G8RC:$rA, G8RC:$rB))]>;
@@ -749,10 +783,12 @@
 def SUBFZE : XOForm_3<31, 200, 0, (ops GPRC:$rT, GPRC:$rA),
                       "subfze $rT, $rA", IntGeneral,
                       [(set GPRC:$rT, (sube 0, GPRC:$rA))]>;
+}
 
 // A-Form instructions.  Most of the instructions executed in the FPU are of
 // this type.
 //
+let PPC970_Unit = 3 in {  // FPU Operations.
 def FMADD : AForm_1<63, 29, 
                     (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB),
                     "fmadd $FRT, $FRA, $FRC, $FRB", FPFused,
@@ -845,7 +881,9 @@
                     (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRB),
                     "fsubs $FRT, $FRA, $FRB", FPGeneral,
                     [(set F4RC:$FRT, (fsub F4RC:$FRA, F4RC:$FRB))]>;
+}
 
+let PPC970_Unit = 1 in {  // FXU Operations.
 // M-Form instructions.  rotate and mask instructions.
 //
 let isTwoAddress = 1, isCommutable = 1 in {
@@ -882,7 +920,9 @@
                       (ops G8RC:$rA, G8RC:$rS, u6imm:$SH, u6imm:$ME),
                       "rldicr $rA, $rS, $SH, $ME", IntRotateD,
                       []>, isPPC64;
+}
 
+let PPC970_Unit = 5 in {  // VALU Operations.
 // VA-Form instructions.  3-input AltiVec ops.
 def VMADDFP : VAForm_1<46, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB, VRRC:$vC),
                        "vmaddfp $vD, $vA, $vC, $vB", VecFP,
@@ -957,7 +997,7 @@
 def V_SET0 : VXForm_setzero<1220, (ops VRRC:$vD),
                       "vxor $vD, $vD, $vD", VecFP,
                       []>;
-
+}
 
 //===----------------------------------------------------------------------===//
 // DWARF Pseudo Instructions
@@ -1097,13 +1137,3 @@
                (XORIS GPRC:$tmp, (HI16 imm:$imm))]>;
 */
 
-//===----------------------------------------------------------------------===//
-// PowerPCInstrInfo Definition
-//
-def PowerPCInstrInfo : InstrInfo {
-  let TSFlagsFields = [ "VMX", "PPC64" ];
-  let TSFlagsShifts = [ 0, 1 ];
-
-  let isLittleEndianEncoding = 1;
-}
-






More information about the llvm-commits mailing list