[llvm-commits] [vector_llvm] CVS: llvm/lib/Target/PowerPC/Makefile PPC.td PPCAsmPrinter.cpp PPCISelDAGToDAG.cpp PPCISelLowering.cpp PPCISelLowering.h PPCISelPattern.cpp PPCInstrFormats.td PPCInstrInfo.cpp PPCInstrInfo.td PPCRegisterInfo.cpp PPCRegisterInfo.td PPCSchedule.td PPCScheduleG3.td PPCScheduleG4.td PPCScheduleG4Plus.td PPCScheduleG5.td PPCSubtarget.cpp PPCSubtarget.h PPCTargetMachine.cpp PPCTargetMachine.h README.txt

Robert Bocchino bocchino at cs.uiuc.edu
Wed Nov 16 10:32:49 PST 2005



Changes in directory llvm/lib/Target/PowerPC:

Makefile updated: 1.20 -> 1.20.2.1
PPC.td updated: 1.2 -> 1.2.2.1
PPCAsmPrinter.cpp updated: 1.100 -> 1.100.2.1
PPCISelDAGToDAG.cpp updated: 1.108 -> 1.108.2.1
PPCISelLowering.cpp updated: 1.33 -> 1.33.2.1
PPCISelLowering.h updated: 1.8 -> 1.8.2.1
PPCISelPattern.cpp updated: 1.190 -> 1.190.2.1
PPCInstrFormats.td updated: 1.52 -> 1.52.2.1
PPCInstrInfo.cpp updated: 1.12 -> 1.12.2.1
PPCInstrInfo.td updated: 1.124 -> 1.124.2.1
PPCRegisterInfo.cpp updated: 1.36 -> 1.36.2.1
PPCRegisterInfo.td updated: 1.18 -> 1.18.2.1
PPCSchedule.td updated: 1.1 -> 1.1.2.1
PPCScheduleG3.td updated: 1.2 -> 1.2.2.1
PPCScheduleG4.td updated: 1.2 -> 1.2.2.1
PPCScheduleG4Plus.td updated: 1.2 -> 1.2.2.1
PPCScheduleG5.td updated: 1.2 -> 1.2.2.1
PPCSubtarget.cpp updated: 1.10 -> 1.10.2.1
PPCSubtarget.h updated: 1.8 -> 1.8.2.1
PPCTargetMachine.cpp updated: 1.75 -> 1.75.2.1
PPCTargetMachine.h updated: 1.14 -> 1.14.2.1
README.txt updated: 1.33 -> 1.33.2.1
---
Log message:

Merged mainline into Vector LLVM branch


---
Diffs of the changes:  (+996 -1005)

 Makefile             |    2 
 PPC.td               |   43 ++++
 PPCAsmPrinter.cpp    |  120 +++++++-----
 PPCISelDAGToDAG.cpp  |  427 ++++++++++++---------------------------------
 PPCISelLowering.cpp  |   53 ++++-
 PPCISelLowering.h    |    3 
 PPCISelPattern.cpp   |  154 ----------------
 PPCInstrFormats.td   |  255 +++++++++++++++------------
 PPCInstrInfo.cpp     |    3 
 PPCInstrInfo.td      |  480 +++++++++++++++++++++++++++++----------------------
 PPCRegisterInfo.cpp  |   29 ++-
 PPCRegisterInfo.td   |   34 +++
 PPCSchedule.td       |  124 +++++--------
 PPCScheduleG3.td     |    8 
 PPCScheduleG4.td     |    8 
 PPCScheduleG4Plus.td |    8 
 PPCScheduleG5.td     |    8 
 PPCSubtarget.cpp     |   81 +-------
 PPCSubtarget.h       |   17 +
 PPCTargetMachine.cpp |   10 -
 PPCTargetMachine.h   |   15 +
 README.txt           |  119 ++++++++++++
 22 files changed, 996 insertions(+), 1005 deletions(-)


Index: llvm/lib/Target/PowerPC/Makefile
diff -u llvm/lib/Target/PowerPC/Makefile:1.20 llvm/lib/Target/PowerPC/Makefile:1.20.2.1
--- llvm/lib/Target/PowerPC/Makefile:1.20	Fri Oct 14 18:37:35 2005
+++ llvm/lib/Target/PowerPC/Makefile	Wed Nov 16 12:32:37 2005
@@ -14,6 +14,6 @@
 BUILT_SOURCES = PPCGenInstrNames.inc PPCGenRegisterNames.inc \
                 PPCGenAsmWriter.inc  PPCGenCodeEmitter.inc \
                 PPCGenRegisterInfo.h.inc PPCGenRegisterInfo.inc \
-                PPCGenInstrInfo.inc PPCGenDAGISel.inc
+                PPCGenInstrInfo.inc PPCGenDAGISel.inc PPCGenSubtarget.inc
 
 include $(LEVEL)/Makefile.common


Index: llvm/lib/Target/PowerPC/PPC.td
diff -u llvm/lib/Target/PowerPC/PPC.td:1.2 llvm/lib/Target/PowerPC/PPC.td:1.2.2.1
--- llvm/lib/Target/PowerPC/PPC.td:1.2	Fri Oct 14 18:40:39 2005
+++ llvm/lib/Target/PowerPC/PPC.td	Wed Nov 16 12:32:38 2005
@@ -16,12 +16,55 @@
 include "../Target.td"
 
 //===----------------------------------------------------------------------===//
+// PowerPC Subtarget features.
+//
+ 
+def Feature64Bit     : SubtargetFeature<"64bit", "bool", "Is64Bit",
+                                        "Enable 64-bit instructions">;
+def Feature64BitRegs : SubtargetFeature<"64bitregs", "bool", "Has64BitRegs",
+                                        "Enable 64-bit registers [beta]">;
+def FeatureAltivec   : SubtargetFeature<"altivec", "bool", "HasAltivec",
+                                        "Enable Altivec instructions">;
+def FeatureGPUL      : SubtargetFeature<"gpul", "bool", "IsGigaProcessor",
+                                        "Enable GPUL instructions">;
+def FeatureFSqrt     : SubtargetFeature<"fsqrt", "bool", "HasFSQRT",
+                                        "Enable the fsqrt instruction">; 
+
+//===----------------------------------------------------------------------===//
 // Register File Description
 //===----------------------------------------------------------------------===//
 
 include "PPCRegisterInfo.td"
+include "PPCSchedule.td"
 include "PPCInstrInfo.td"
 
+//===----------------------------------------------------------------------===//
+// PowerPC processors supported.
+//
+
+def : Processor<"generic", G3Itineraries, []>;
+def : Processor<"601", G3Itineraries, []>;
+def : Processor<"602", G3Itineraries, []>;
+def : Processor<"603", G3Itineraries, []>;
+def : Processor<"603e", G3Itineraries, []>;
+def : Processor<"603ev", G3Itineraries, []>;
+def : Processor<"604", G3Itineraries, []>;
+def : Processor<"604e", G3Itineraries, []>;
+def : Processor<"620", G3Itineraries, []>;
+def : Processor<"g3", G3Itineraries, []>;
+def : Processor<"7400", G4Itineraries, [FeatureAltivec]>;
+def : Processor<"g4", G4Itineraries, [FeatureAltivec]>;
+def : Processor<"7450", G4PlusItineraries, [FeatureAltivec]>;
+def : Processor<"g4+", G4PlusItineraries, [FeatureAltivec]>;
+def : Processor<"750", G3Itineraries, []>;
+def : Processor<"970", G5Itineraries,
+                  [FeatureAltivec, FeatureGPUL, FeatureFSqrt,
+                   Feature64Bit /*, Feature64BitRegs */]>;
+def : Processor<"g5", G5Itineraries,
+                  [FeatureAltivec, FeatureGPUL, FeatureFSqrt,
+                   Feature64Bit /*, Feature64BitRegs */]>;
+
+
 def PPC : Target {
   // Pointers on PPC are 32-bits in size.
   let PointerType = i32;


Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.100 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.100.2.1
--- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.100	Tue Oct 18 11:51:22 2005
+++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp	Wed Nov 16 12:32:38 2005
@@ -43,15 +43,17 @@
 namespace {
   Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed");
 
-  struct PPCAsmPrinter : public AsmPrinter {
+  class PPCAsmPrinter : public AsmPrinter {
+    std::string CurSection;
+  public:
     std::set<std::string> FnStubs, GVStubs, LinkOnceStubs;
-
+    
     PPCAsmPrinter(std::ostream &O, TargetMachine &TM)
-      : AsmPrinter(O, TM), LabelNumber(0) {}
+      : AsmPrinter(O, TM), FunctionNumber(0) {}
 
     /// Unique incrementer for label values for referencing Global values.
     ///
-    unsigned LabelNumber;
+    unsigned FunctionNumber;
 
     virtual const char *getPassName() const {
       return "PowerPC Assembly Printer";
@@ -61,6 +63,24 @@
       return static_cast<PPCTargetMachine&>(TM);
     }
 
+    /// SwitchSection - Switch to the specified section of the executable if we
+    /// are not already in it!
+    ///
+    void SwitchSection(const char *NewSection, const GlobalValue *GV) {
+      std::string NS;
+      
+      if (GV && GV->hasSection())
+        NS = ".section " + GV->getSection();
+      else
+        NS = NewSection;
+      
+      if (CurSection != NS) {
+        CurSection = NS;
+        if (!CurSection.empty())
+          O << "\t" << CurSection << "\n";
+      }
+    }
+    
     unsigned enumRegToMachineReg(unsigned enumReg) {
       switch (enumReg) {
       default: assert(0 && "Unhandled register!"); break;
@@ -135,8 +155,8 @@
     void printPICLabel(const MachineInstr *MI, unsigned OpNo,
                        MVT::ValueType VT) {
       // FIXME: should probably be converted to cout.width and cout.fill
-      O << "\"L0000" << LabelNumber << "$pb\"\n";
-      O << "\"L0000" << LabelNumber << "$pb\":";
+      O << "\"L0000" << FunctionNumber << "$pb\"\n";
+      O << "\"L0000" << FunctionNumber << "$pb\":";
     }
     void printSymbolHi(const MachineInstr *MI, unsigned OpNo,
                        MVT::ValueType VT) {
@@ -146,7 +166,7 @@
         O << "ha16(";
         printOp(MI->getOperand(OpNo));
         if (PICEnabled)
-          O << "-\"L0000" << LabelNumber << "$pb\")";
+          O << "-\"L0000" << FunctionNumber << "$pb\")";
         else
           O << ')';
       }
@@ -159,7 +179,7 @@
         O << "lo16(";
         printOp(MI->getOperand(OpNo));
         if (PICEnabled)
-          O << "-\"L0000" << LabelNumber << "$pb\")";
+          O << "-\"L0000" << FunctionNumber << "$pb\")";
         else
           O << ')';
       }
@@ -210,7 +230,7 @@
     AIXAsmPrinter(std::ostream &O, TargetMachine &TM)
       : PPCAsmPrinter(O, TM) {
       CommentString = "#";
-      GlobalPrefix = "_";
+      GlobalPrefix = ".";
       ZeroDirective = "\t.space\t";  // ".space N" emits N zeros.
       Data64bitsDirective = 0;       // we can't emit a 64-bit unit
       AlignmentIsInBytes = false;    // Alignment is by power of 2.
@@ -227,18 +247,6 @@
   };
 } // end of anonymous namespace
 
-// SwitchSection - Switch to the specified section of the executable if we are
-// not already in it!
-//
-static void SwitchSection(std::ostream &OS, std::string &CurSection,
-                          const char *NewSection) {
-  if (CurSection != NewSection) {
-    CurSection = NewSection;
-    if (!CurSection.empty())
-      OS << "\t" << NewSection << "\n";
-  }
-}
-
 /// createDarwinAsmPrinterPass - Returns a pass that prints the PPC assembly
 /// code for a MachineFunction to the given output stream, in a format that the
 /// Darwin assembler can deal with.
@@ -287,14 +295,13 @@
 
   case MachineOperand::MO_MachineBasicBlock: {
     MachineBasicBlock *MBBOp = MO.getMachineBasicBlock();
-    O << "LBB" << Mang->getValueName(MBBOp->getParent()->getFunction())
-      << "_" << MBBOp->getNumber() << "\t; "
+    O << "LBB" << FunctionNumber << "_" << MBBOp->getNumber() << "\t; "
       << MBBOp->getBasicBlock()->getName();
     return;
   }
 
   case MachineOperand::MO_ConstantPoolIndex:
-    O << ".CPI" << CurrentFnName << "_" << MO.getConstantPoolIndex();
+    O << "LCPI" << FunctionNumber << '_' << MO.getConstantPoolIndex();
     return;
 
   case MachineOperand::MO_ExternalSymbol:
@@ -388,9 +395,11 @@
   printConstantPool(MF.getConstantPool());
 
   // Print out labels for the function.
-  O << "\t.text\n";
-  emitAlignment(4);
-  O << "\t.globl\t" << CurrentFnName << "\n";
+  const Function *F = MF.getFunction();
+  SwitchSection(".text", F);
+  emitAlignment(4, F);
+  if (!F->hasInternalLinkage())
+    O << "\t.globl\t" << CurrentFnName << "\n";
   O << CurrentFnName << ":\n";
 
   // Print out code for the function.
@@ -398,7 +407,7 @@
        I != E; ++I) {
     // Print a label for the basic block.
     if (I != MF.begin()) {
-      O << "LBB" << CurrentFnName << "_" << I->getNumber() << ":\t";
+      O << "LBB" << FunctionNumber << '_' << I->getNumber() << ":\t";
       if (!I->getBasicBlock()->getName().empty())
         O << CommentString << " " << I->getBasicBlock()->getName();
       O << "\n";
@@ -410,7 +419,7 @@
       printMachineInstruction(II);
     }
   }
-  ++LabelNumber;
+  ++FunctionNumber;
 
   // We didn't modify anything.
   return false;
@@ -428,15 +437,15 @@
   if (CP.empty()) return;
 
   for (unsigned i = 0, e = CP.size(); i != e; ++i) {
-    O << "\t.const\n";
+    SwitchSection(".const", 0);
     // FIXME: force doubles to be naturally aligned.  We should handle this
     // more correctly in the future.
     if (Type::DoubleTy == CP[i]->getType())
       emitAlignment(3);
     else
       emitAlignment(TD.getTypeAlignmentShift(CP[i]->getType()));
-    O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t" << CommentString
-      << *CP[i] << "\n";
+    O << "LCPI" << FunctionNumber << '_' << i << ":\t\t\t\t\t" << CommentString
+      << *CP[i] << '\n';
     emitGlobalConstant(CP[i]);
   }
 }
@@ -444,16 +453,20 @@
 bool DarwinAsmPrinter::doInitialization(Module &M) {
   if (TM.getSubtarget<PPCSubtarget>().isGigaProcessor())
     O << "\t.machine ppc970\n";
+  SwitchSection("", 0);
   AsmPrinter::doInitialization(M);
+  
+  // Darwin wants symbols to be quoted if they have complex names.
+  Mang->setUseQuotes(true);
   return false;
 }
 
 bool DarwinAsmPrinter::doFinalization(Module &M) {
   const TargetData &TD = TM.getTargetData();
-  std::string CurSection;
 
   // Print out module-level global variables here.
-  for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
+  for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
+       I != E; ++I)
     if (I->hasInitializer()) {   // External global require no code
       O << '\n';
       std::string name = Mang->getValueName(I);
@@ -464,7 +477,7 @@
       if (C->isNullValue() && /* FIXME: Verify correct */
           (I->hasInternalLinkage() || I->hasWeakLinkage() ||
            I->hasLinkOnceLinkage())) {
-        SwitchSection(O, CurSection, ".data");
+        SwitchSection(".data", I);
         if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
         if (I->hasInternalLinkage())
           O << ".lcomm " << name << "," << Size << "," << Align;
@@ -474,6 +487,7 @@
       } else {
         switch (I->getLinkage()) {
         case GlobalValue::LinkOnceLinkage:
+          SwitchSection("", 0);
           O << ".section __TEXT,__textcoal_nt,coalesced,no_toc\n"
             << ".weak_definition " << name << '\n'
             << ".private_extern " << name << '\n'
@@ -492,14 +506,14 @@
           O << "\t.globl " << name << "\n";
           // FALL THROUGH
         case GlobalValue::InternalLinkage:
-          SwitchSection(O, CurSection, ".data");
+          SwitchSection(".data", I);
           break;
-        case GlobalValue::GhostLinkage:
-          std::cerr << "Error: unmaterialized (GhostLinkage) function in asm!";
+        default:
+          std::cerr << "Unknown linkage type!";
           abort();
         }
 
-        emitAlignment(Align);
+        emitAlignment(Align, I);
         O << name << ":\t\t\t\t; '" << I->getName() << "'\n";
         emitGlobalConstant(C);
       }
@@ -566,6 +580,13 @@
       << "\t.long\t" << *i << '\n';
   }
 
+  // Funny Darwin hack: This flag tells the linker that no global symbols
+  // contain code that falls through to other global symbols (e.g. the obvious
+  // implementation of multiple entry points).  If this doesn't occur, the
+  // linker can safely perform dead code stripping.  Since LLVM never generates
+  // code that does this, it is always safe to set.
+  O << "\t.subsections_via_symbols\n";
+
   AsmPrinter::doFinalization(M);
   return false; // success
 }
@@ -594,8 +615,8 @@
   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
        I != E; ++I) {
     // Print a label for the basic block.
-    O << "LBB" << CurrentFnName << "_" << I->getNumber() << ":\t# "
-      << I->getBasicBlock()->getName() << "\n";
+    O << "LBB" << CurrentFnName << '_' << I->getNumber() << ":\t# "
+      << I->getBasicBlock()->getName() << '\n';
     for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
       II != E; ++II) {
       // Print the assembly for the instruction.
@@ -603,7 +624,7 @@
       printMachineInstruction(II);
     }
   }
-  ++LabelNumber;
+  ++FunctionNumber;
 
   O << "LT.." << CurrentFnName << ":\n"
     << "\t.long 0\n"
@@ -629,18 +650,18 @@
   if (CP.empty()) return;
 
   for (unsigned i = 0, e = CP.size(); i != e; ++i) {
-    O << "\t.const\n";
+    SwitchSection(".const", 0);
     O << "\t.align " << (unsigned)TD.getTypeAlignment(CP[i]->getType())
       << "\n";
-    O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t;"
-      << *CP[i] << "\n";
+    O << "LCPI" << FunctionNumber << '_' << i << ":\t\t\t\t\t;"
+      << *CP[i] << '\n';
     emitGlobalConstant(CP[i]);
   }
 }
 
 bool AIXAsmPrinter::doInitialization(Module &M) {
+  SwitchSection("", 0);
   const TargetData &TD = TM.getTargetData();
-  std::string CurSection;
 
   O << "\t.machine \"ppc64\"\n"
     << "\t.toc\n"
@@ -675,7 +696,7 @@
       continue;
 
     std::string Name = GV->getName();
-    std::string Label = "LC.." + utostr(LabelNumber++);
+    std::string Label = "LC.." + utostr(FunctionNumber++);
     GVToLabelMap[GV] = Label;
     O << Label << ":\n"
       << "\t.tc " << Name << "[TC]," << Name;
@@ -683,7 +704,7 @@
     O << '\n';
   }
 
-  Mang = new Mangler(M, ".");
+  AsmPrinter::doInitialization(M);
   return false; // success
 }
 
@@ -710,7 +731,6 @@
   O << "_section_.text:\n"
     << "\t.csect .data[RW],3\n"
     << "\t.llong _section_.text\n";
-
-  delete Mang;
+  AsmPrinter::doFinalization(M);
   return false; // success
 }


Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.108 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.108.2.1
--- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.108	Mon Oct 17 19:28:58 2005
+++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp	Wed Nov 16 12:32:38 2005
@@ -219,6 +219,11 @@
 // and mask opcode and mask operation.
 static bool isRotateAndMask(SDNode *N, unsigned Mask, bool IsShiftMask,
                             unsigned &SH, unsigned &MB, unsigned &ME) {
+  // Don't even go down this path for i64, since different logic will be
+  // necessary for rldicl/rldicr/rldimi.
+  if (N->getValueType(0) != MVT::i32)
+    return false;
+
   unsigned Shift  = 32;
   unsigned Indeterminant = ~0;  // bit mask marking indeterminant results
   unsigned Opcode = N->getOpcode();
@@ -474,16 +479,25 @@
 static unsigned getBCCForSetCC(ISD::CondCode CC) {
   switch (CC) {
   default: assert(0 && "Unknown condition!"); abort();
+  case ISD::SETOEQ:    // FIXME: This is incorrect see PR642.
   case ISD::SETEQ:  return PPC::BEQ;
+  case ISD::SETONE:    // FIXME: This is incorrect see PR642.
   case ISD::SETNE:  return PPC::BNE;
+  case ISD::SETOLT:    // FIXME: This is incorrect see PR642.
   case ISD::SETULT:
   case ISD::SETLT:  return PPC::BLT;
+  case ISD::SETOLE:    // FIXME: This is incorrect see PR642.
   case ISD::SETULE:
   case ISD::SETLE:  return PPC::BLE;
+  case ISD::SETOGT:    // FIXME: This is incorrect see PR642.
   case ISD::SETUGT:
   case ISD::SETGT:  return PPC::BGT;
+  case ISD::SETOGE:    // FIXME: This is incorrect see PR642.
   case ISD::SETUGE:
   case ISD::SETGE:  return PPC::BGE;
+    
+  case ISD::SETO:   return PPC::BUN;
+  case ISD::SETUO:  return PPC::BNU;
   }
   return 0;
 }
@@ -494,163 +508,28 @@
 static unsigned getCRIdxForSetCC(ISD::CondCode CC, bool& Inv) {
   switch (CC) {
   default: assert(0 && "Unknown condition!"); abort();
+  case ISD::SETOLT:  // FIXME: This is incorrect see PR642.
   case ISD::SETULT:
   case ISD::SETLT:  Inv = false;  return 0;
+  case ISD::SETOGE:  // FIXME: This is incorrect see PR642.
   case ISD::SETUGE:
   case ISD::SETGE:  Inv = true;   return 0;
+  case ISD::SETOGT:  // FIXME: This is incorrect see PR642.
   case ISD::SETUGT:
   case ISD::SETGT:  Inv = false;  return 1;
+  case ISD::SETOLE:  // FIXME: This is incorrect see PR642.
   case ISD::SETULE:
   case ISD::SETLE:  Inv = true;   return 1;
+  case ISD::SETOEQ:  // FIXME: This is incorrect see PR642.
   case ISD::SETEQ:  Inv = false;  return 2;
+  case ISD::SETONE:  // FIXME: This is incorrect see PR642.
   case ISD::SETNE:  Inv = true;   return 2;
+  case ISD::SETO:   Inv = true;   return 3;
+  case ISD::SETUO:  Inv = false;  return 3;
   }
   return 0;
 }
 
-// Structure used to return the necessary information to codegen an SDIV as
-// a multiply.
-struct ms {
-  int m; // magic number
-  int s; // shift amount
-};
-
-struct mu {
-  unsigned int m; // magic number
-  int a;          // add indicator
-  int s;          // shift amount
-};
-
-/// magic - calculate the magic numbers required to codegen an integer sdiv as
-/// a sequence of multiply and shifts.  Requires that the divisor not be 0, 1,
-/// or -1.
-static struct ms magic(int d) {
-  int p;
-  unsigned int ad, anc, delta, q1, r1, q2, r2, t;
-  const unsigned int two31 = 0x80000000U;
-  struct ms mag;
-  
-  ad = abs(d);
-  t = two31 + ((unsigned int)d >> 31);
-  anc = t - 1 - t%ad;   // absolute value of nc
-  p = 31;               // initialize p
-  q1 = two31/anc;       // initialize q1 = 2p/abs(nc)
-  r1 = two31 - q1*anc;  // initialize r1 = rem(2p,abs(nc))
-  q2 = two31/ad;        // initialize q2 = 2p/abs(d)
-  r2 = two31 - q2*ad;   // initialize r2 = rem(2p,abs(d))
-  do {
-    p = p + 1;
-    q1 = 2*q1;        // update q1 = 2p/abs(nc)
-    r1 = 2*r1;        // update r1 = rem(2p/abs(nc))
-    if (r1 >= anc) {  // must be unsigned comparison
-      q1 = q1 + 1;
-      r1 = r1 - anc;
-    }
-    q2 = 2*q2;        // update q2 = 2p/abs(d)
-    r2 = 2*r2;        // update r2 = rem(2p/abs(d))
-    if (r2 >= ad) {   // must be unsigned comparison
-      q2 = q2 + 1;
-      r2 = r2 - ad;
-    }
-    delta = ad - r2;
-  } while (q1 < delta || (q1 == delta && r1 == 0));
-  
-  mag.m = q2 + 1;
-  if (d < 0) mag.m = -mag.m; // resulting magic number
-  mag.s = p - 32;            // resulting shift
-  return mag;
-}
-
-/// magicu - calculate the magic numbers required to codegen an integer udiv as
-/// a sequence of multiply, add and shifts.  Requires that the divisor not be 0.
-static struct mu magicu(unsigned d)
-{
-  int p;
-  unsigned int nc, delta, q1, r1, q2, r2;
-  struct mu magu;
-  magu.a = 0;               // initialize "add" indicator
-  nc = - 1 - (-d)%d;
-  p = 31;                   // initialize p
-  q1 = 0x80000000/nc;       // initialize q1 = 2p/nc
-  r1 = 0x80000000 - q1*nc;  // initialize r1 = rem(2p,nc)
-  q2 = 0x7FFFFFFF/d;        // initialize q2 = (2p-1)/d
-  r2 = 0x7FFFFFFF - q2*d;   // initialize r2 = rem((2p-1),d)
-  do {
-    p = p + 1;
-    if (r1 >= nc - r1 ) {
-      q1 = 2*q1 + 1;  // update q1
-      r1 = 2*r1 - nc; // update r1
-    }
-    else {
-      q1 = 2*q1; // update q1
-      r1 = 2*r1; // update r1
-    }
-    if (r2 + 1 >= d - r2) {
-      if (q2 >= 0x7FFFFFFF) magu.a = 1;
-      q2 = 2*q2 + 1;     // update q2
-      r2 = 2*r2 + 1 - d; // update r2
-    }
-    else {
-      if (q2 >= 0x80000000) magu.a = 1;
-      q2 = 2*q2;     // update q2
-      r2 = 2*r2 + 1; // update r2
-    }
-    delta = d - 1 - r2;
-  } while (p < 64 && (q1 < delta || (q1 == delta && r1 == 0)));
-  magu.m = q2 + 1; // resulting magic number
-  magu.s = p - 32;  // resulting shift
-  return magu;
-}
-
-/// BuildSDIVSequence - Given an ISD::SDIV node expressing a divide by constant,
-/// return a DAG expression to select that will generate the same value by
-/// multiplying by a magic number.  See:
-/// <http://the.wall.riscom.net/books/proc/ppc/cwg/code2.html>
-SDOperand PPCDAGToDAGISel::BuildSDIVSequence(SDNode *N) {
-  int d = (int)cast<ConstantSDNode>(N->getOperand(1))->getValue();
-  ms magics = magic(d);
-  // Multiply the numerator (operand 0) by the magic value
-  SDOperand Q = CurDAG->getNode(ISD::MULHS, MVT::i32, N->getOperand(0),
-                                CurDAG->getConstant(magics.m, MVT::i32));
-  // If d > 0 and m < 0, add the numerator
-  if (d > 0 && magics.m < 0)
-    Q = CurDAG->getNode(ISD::ADD, MVT::i32, Q, N->getOperand(0));
-  // If d < 0 and m > 0, subtract the numerator.
-  if (d < 0 && magics.m > 0)
-    Q = CurDAG->getNode(ISD::SUB, MVT::i32, Q, N->getOperand(0));
-  // Shift right algebraic if shift value is nonzero
-  if (magics.s > 0)
-    Q = CurDAG->getNode(ISD::SRA, MVT::i32, Q,
-                        CurDAG->getConstant(magics.s, MVT::i32));
-  // Extract the sign bit and add it to the quotient
-  SDOperand T =
-    CurDAG->getNode(ISD::SRL, MVT::i32, Q, CurDAG->getConstant(31, MVT::i32));
-  return CurDAG->getNode(ISD::ADD, MVT::i32, Q, T);
-}
-
-/// BuildUDIVSequence - Given an ISD::UDIV node expressing a divide by constant,
-/// return a DAG expression to select that will generate the same value by
-/// multiplying by a magic number.  See:
-/// <http://the.wall.riscom.net/books/proc/ppc/cwg/code2.html>
-SDOperand PPCDAGToDAGISel::BuildUDIVSequence(SDNode *N) {
-  unsigned d = (unsigned)cast<ConstantSDNode>(N->getOperand(1))->getValue();
-  mu magics = magicu(d);
-  // Multiply the numerator (operand 0) by the magic value
-  SDOperand Q = CurDAG->getNode(ISD::MULHU, MVT::i32, N->getOperand(0),
-                                CurDAG->getConstant(magics.m, MVT::i32));
-  if (magics.a == 0) {
-    return CurDAG->getNode(ISD::SRL, MVT::i32, Q,
-                           CurDAG->getConstant(magics.s, MVT::i32));
-  } else {
-    SDOperand NPQ = CurDAG->getNode(ISD::SUB, MVT::i32, N->getOperand(0), Q);
-    NPQ = CurDAG->getNode(ISD::SRL, MVT::i32, NPQ,
-                           CurDAG->getConstant(1, MVT::i32));
-    NPQ = CurDAG->getNode(ISD::ADD, MVT::i32, NPQ, Q);
-    return CurDAG->getNode(ISD::SRL, MVT::i32, NPQ,
-                           CurDAG->getConstant(magics.s-1, MVT::i32));
-  }
-}
-
 SDOperand PPCDAGToDAGISel::SelectDYNAMIC_STACKALLOC(SDOperand Op) {
   SDNode *N = Op.Val;
 
@@ -759,65 +638,63 @@
     if (Imm == 0) {
       SDOperand Op = Select(N->getOperand(0));
       switch (CC) {
-        default: assert(0 && "Unhandled SetCC condition"); abort();
-        case ISD::SETEQ:
-          Op = CurDAG->getTargetNode(PPC::CNTLZW, MVT::i32, Op);
-          CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Op, getI32Imm(27),
-                               getI32Imm(5), getI32Imm(31));
-          break;
-        case ISD::SETNE: {
-          SDOperand AD = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag,
-                                               Op, getI32Imm(~0U));
-          CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, AD, Op, AD.getValue(1));
-          break;
-        }
-        case ISD::SETLT:
-          CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Op, getI32Imm(1),
-                               getI32Imm(31), getI32Imm(31));
-          break;
-        case ISD::SETGT: {
-          SDOperand T = CurDAG->getTargetNode(PPC::NEG, MVT::i32, Op);
-          T = CurDAG->getTargetNode(PPC::ANDC, MVT::i32, T, Op);;
-          CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, T, getI32Imm(1),
-                               getI32Imm(31), getI32Imm(31));
-          break;
-        }
+      default: break;
+      case ISD::SETEQ:
+        Op = CurDAG->getTargetNode(PPC::CNTLZW, MVT::i32, Op);
+        CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Op, getI32Imm(27),
+                             getI32Imm(5), getI32Imm(31));
+        return SDOperand(N, 0);
+      case ISD::SETNE: {
+        SDOperand AD = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag,
+                                             Op, getI32Imm(~0U));
+        CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, AD, Op, AD.getValue(1));
+        return SDOperand(N, 0);
+      }
+      case ISD::SETLT:
+        CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Op, getI32Imm(1),
+                             getI32Imm(31), getI32Imm(31));
+        return SDOperand(N, 0);
+      case ISD::SETGT: {
+        SDOperand T = CurDAG->getTargetNode(PPC::NEG, MVT::i32, Op);
+        T = CurDAG->getTargetNode(PPC::ANDC, MVT::i32, T, Op);;
+        CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, T, getI32Imm(1),
+                             getI32Imm(31), getI32Imm(31));
+        return SDOperand(N, 0);
+      }
       }
-      return SDOperand(N, 0);
     } else if (Imm == ~0U) {        // setcc op, -1
       SDOperand Op = Select(N->getOperand(0));
       switch (CC) {
-        default: assert(0 && "Unhandled SetCC condition"); abort();
-        case ISD::SETEQ:
-          Op = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag,
-                                     Op, getI32Imm(1));
-          CurDAG->SelectNodeTo(N, PPC::ADDZE, MVT::i32, 
-                               CurDAG->getTargetNode(PPC::LI, MVT::i32,
-                                                     getI32Imm(0)),
-                               Op.getValue(1));
-          break;
-        case ISD::SETNE: {
-          Op = CurDAG->getTargetNode(PPC::NOR, MVT::i32, Op, Op);
-          SDOperand AD = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag,
-                                               Op, getI32Imm(~0U));
-          CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, AD, Op, AD.getValue(1));
-          break;
-        }
-        case ISD::SETLT: {
-          SDOperand AD = CurDAG->getTargetNode(PPC::ADDI, MVT::i32, Op,
-                                               getI32Imm(1));
-          SDOperand AN = CurDAG->getTargetNode(PPC::AND, MVT::i32, AD, Op);
-          CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, AN, getI32Imm(1),
-                               getI32Imm(31), getI32Imm(31));
-          break;
-        }
-        case ISD::SETGT:
-          Op = CurDAG->getTargetNode(PPC::RLWINM, MVT::i32, Op, getI32Imm(1),
-                                     getI32Imm(31), getI32Imm(31));
-          CurDAG->SelectNodeTo(N, PPC::XORI, MVT::i32, Op, getI32Imm(1));
-          break;
+      default: break;
+      case ISD::SETEQ:
+        Op = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag,
+                                   Op, getI32Imm(1));
+        CurDAG->SelectNodeTo(N, PPC::ADDZE, MVT::i32, 
+                             CurDAG->getTargetNode(PPC::LI, MVT::i32,
+                                                   getI32Imm(0)),
+                             Op.getValue(1));
+        return SDOperand(N, 0);
+      case ISD::SETNE: {
+        Op = CurDAG->getTargetNode(PPC::NOR, MVT::i32, Op, Op);
+        SDOperand AD = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag,
+                                             Op, getI32Imm(~0U));
+        CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, AD, Op, AD.getValue(1));
+        return SDOperand(N, 0);
+      }
+      case ISD::SETLT: {
+        SDOperand AD = CurDAG->getTargetNode(PPC::ADDI, MVT::i32, Op,
+                                             getI32Imm(1));
+        SDOperand AN = CurDAG->getTargetNode(PPC::AND, MVT::i32, AD, Op);
+        CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, AN, getI32Imm(1),
+                             getI32Imm(31), getI32Imm(31));
+        return SDOperand(N, 0);
+      }
+      case ISD::SETGT:
+        Op = CurDAG->getTargetNode(PPC::RLWINM, MVT::i32, Op, getI32Imm(1),
+                                   getI32Imm(31), getI32Imm(31));
+        CurDAG->SelectNodeTo(N, PPC::XORI, MVT::i32, Op, getI32Imm(1));
+        return SDOperand(N, 0);
       }
-      return SDOperand(N, 0);
     }
   }
   
@@ -845,11 +722,13 @@
   
   if (!Inv) {
     CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, IntCR,
-                         getI32Imm(32-(3-Idx)), getI32Imm(31), getI32Imm(31));
+                         getI32Imm((32-(3-Idx)) & 31),
+                                   getI32Imm(31), getI32Imm(31));
   } else {
     SDOperand Tmp =
     CurDAG->getTargetNode(PPC::RLWINM, MVT::i32, IntCR,
-                          getI32Imm(32-(3-Idx)), getI32Imm(31),getI32Imm(31));
+                          getI32Imm((32-(3-Idx)) & 31),
+                          getI32Imm(31),getI32Imm(31));
     CurDAG->SelectNodeTo(N, PPC::XORI, MVT::i32, Tmp, getI32Imm(1));
   }
   
@@ -984,52 +863,17 @@
   case ISD::CALL:               return SelectCALL(Op);
   case ISD::TAILCALL:           return SelectCALL(Op);
 
-  case ISD::TokenFactor: {
-    SDOperand New;
-    if (N->getNumOperands() == 2) {
-      SDOperand Op0 = Select(N->getOperand(0));
-      SDOperand Op1 = Select(N->getOperand(1));
-      New = CurDAG->getNode(ISD::TokenFactor, MVT::Other, Op0, Op1);
-    } else {
-      std::vector<SDOperand> Ops;
-      for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
-        Ops.push_back(Select(N->getOperand(i)));
-      New = CurDAG->getNode(ISD::TokenFactor, MVT::Other, Ops);
-    }
-    
-    CodeGenMap[Op] = New;
-    return New;
-  }
-  case ISD::CopyFromReg: {
-    SDOperand Chain = Select(N->getOperand(0));
-    if (Chain == N->getOperand(0)) return Op; // No change
-    SDOperand New = CurDAG->getCopyFromReg(Chain,
-         cast<RegisterSDNode>(N->getOperand(1))->getReg(), N->getValueType(0));
-    return New.getValue(Op.ResNo);
-  }
-  case ISD::CopyToReg: {
-    SDOperand Chain = Select(N->getOperand(0));
-    SDOperand Reg = N->getOperand(1);
-    SDOperand Val = Select(N->getOperand(2));
-    SDOperand New = CurDAG->getNode(ISD::CopyToReg, MVT::Other,
-                                    Chain, Reg, Val);
-    CodeGenMap[Op] = New;
-    return New;
-  }
-  case ISD::UNDEF:
-    if (N->getValueType(0) == MVT::i32)
-      CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_GPR, MVT::i32);
-    else if (N->getValueType(0) == MVT::f32)
-      CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_F4, MVT::f32);
-    else 
-      CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_F8, MVT::f64);
-    return SDOperand(N, 0);
   case ISD::FrameIndex: {
     int FI = cast<FrameIndexSDNode>(N)->getIndex();
-    CurDAG->SelectNodeTo(N, PPC::ADDI, MVT::i32,
-                         CurDAG->getTargetFrameIndex(FI, MVT::i32),
-                         getI32Imm(0));
-    return SDOperand(N, 0);
+    if (N->hasOneUse()) {
+      CurDAG->SelectNodeTo(N, PPC::ADDI, MVT::i32,
+                           CurDAG->getTargetFrameIndex(FI, MVT::i32),
+                           getI32Imm(0));
+      return SDOperand(N, 0);
+    }
+    return CurDAG->getTargetNode(PPC::ADDI, MVT::i32,
+                                 CurDAG->getTargetFrameIndex(FI, MVT::i32),
+                                 getI32Imm(0));
   }
   case ISD::ConstantPool: {
     Constant *C = cast<ConstantPoolSDNode>(N)->get();
@@ -1038,8 +882,11 @@
       Tmp = CurDAG->getTargetNode(PPC::ADDIS, MVT::i32, getGlobalBaseReg(),CPI);
     else
       Tmp = CurDAG->getTargetNode(PPC::LIS, MVT::i32, CPI);
-    CurDAG->SelectNodeTo(N, PPC::LA, MVT::i32, Tmp, CPI);
-    return SDOperand(N, 0);
+    if (N->hasOneUse()) {
+      CurDAG->SelectNodeTo(N, PPC::LA, MVT::i32, Tmp, CPI);
+      return SDOperand(N, 0);
+    }
+    return CurDAG->getTargetNode(PPC::LA, MVT::i32, Tmp, CPI);
   }
   case ISD::GlobalAddress: {
     GlobalValue *GV = cast<GlobalAddressSDNode>(N)->getGlobal();
@@ -1051,35 +898,10 @@
       Tmp = CurDAG->getTargetNode(PPC::LIS, MVT::i32, GA);
 
     if (GV->hasWeakLinkage() || GV->isExternal())
-      CurDAG->SelectNodeTo(N, PPC::LWZ, MVT::i32, GA, Tmp);
+      return CurDAG->getTargetNode(PPC::LWZ, MVT::i32, GA, Tmp);
     else
-      CurDAG->SelectNodeTo(N, PPC::LA, MVT::i32, Tmp, GA);
-    return SDOperand(N, 0);
+      return CurDAG->getTargetNode(PPC::LA, MVT::i32, Tmp, GA);
   }
-    
-  case PPCISD::FSEL: {
-    SDOperand Comparison = Select(N->getOperand(0));
-    // Extend the comparison to 64-bits.
-    if (Comparison.getValueType() == MVT::f32)
-      Comparison = CurDAG->getTargetNode(PPC::FMRSD, MVT::f64, Comparison);
-    
-    unsigned Opc = N->getValueType(0) == MVT::f32 ? PPC::FSELS : PPC::FSELD;
-    CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), Comparison,
-                         Select(N->getOperand(1)), Select(N->getOperand(2)));
-    return SDOperand(N, 0);
-  }
-  case PPCISD::FCFID:
-    CurDAG->SelectNodeTo(N, PPC::FCFID, N->getValueType(0),
-                         Select(N->getOperand(0)));
-    return SDOperand(N, 0);
-  case PPCISD::FCTIDZ:
-    CurDAG->SelectNodeTo(N, PPC::FCTIDZ, N->getValueType(0),
-                         Select(N->getOperand(0)));
-    return SDOperand(N, 0);
-  case PPCISD::FCTIWZ:
-    CurDAG->SelectNodeTo(N, PPC::FCTIWZ, N->getValueType(0),
-                         Select(N->getOperand(0)));
-    return SDOperand(N, 0);
   case ISD::FADD: {
     MVT::ValueType Ty = N->getValueType(0);
     if (!NoExcessFPPrecision) {  // Match FMA ops
@@ -1134,6 +956,11 @@
     return SDOperand(N, 0);
   }
   case ISD::SDIV: {
+    // FIXME: since this depends on the setting of the carry flag from the srawi
+    //        we should really be making notes about that for the scheduler.
+    // FIXME: It sure would be nice if we could cheaply recognize the 
+    //        srl/add/sra pattern the dag combiner will generate for this as
+    //        sra/addze rather than having to handle sdiv ourselves.  oh well.
     unsigned Imm;
     if (isIntImmediate(N->getOperand(1), Imm)) {
       if ((signed)Imm > 0 && isPowerOf2_32(Imm)) {
@@ -1154,29 +981,12 @@
                                 Op.getValue(1));
         CurDAG->SelectNodeTo(N, PPC::NEG, MVT::i32, PT);
         return SDOperand(N, 0);
-      } else if (Imm) {
-        SDOperand Result = Select(BuildSDIVSequence(N));
-        CodeGenMap[Op] = Result;
-        return Result;
       }
     }
     
     // Other cases are autogenerated.
     break;
   }
-  case ISD::UDIV: {
-    // If this is a divide by constant, we can emit code using some magic
-    // constants to implement it as a multiply instead.
-    unsigned Imm;
-    if (isIntImmediate(N->getOperand(1), Imm) && Imm) {
-      SDOperand Result = Select(BuildUDIVSequence(N));
-      CodeGenMap[Op] = Result;
-      return Result;
-    }
-    
-    // Other cases are autogenerated.
-    break;
-  }
   case ISD::AND: {
     unsigned Imm;
     // If this is an and of a value rotated between 0 and 31 bits and then and'd
@@ -1187,7 +997,10 @@
       unsigned SH, MB, ME;
       if (isRotateAndMask(N->getOperand(0).Val, Imm, false, SH, MB, ME)) {
         Val = Select(N->getOperand(0).getOperand(0));
-      } else {
+      } else if (Imm == 0) {
+        // AND X, 0 -> 0, not "rlwinm 32".
+        return Select(N->getOperand(1));
+      } else {        
         Val = Select(N->getOperand(0));
         isRunOfOnes(Imm, MB, ME);
         SH = 0;
@@ -1209,33 +1022,28 @@
   case ISD::SHL: {
     unsigned Imm, SH, MB, ME;
     if (isOpcWithIntImmediate(N->getOperand(0).Val, ISD::AND, Imm) &&
-        isRotateAndMask(N, Imm, true, SH, MB, ME))
+        isRotateAndMask(N, Imm, true, SH, MB, ME)) {
       CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, 
                            Select(N->getOperand(0).getOperand(0)),
                            getI32Imm(SH), getI32Imm(MB), getI32Imm(ME));
-    else if (isIntImmediate(N->getOperand(1), Imm))
-      CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Select(N->getOperand(0)),
-                           getI32Imm(Imm), getI32Imm(0), getI32Imm(31-Imm));
-    else
-      CurDAG->SelectNodeTo(N, PPC::SLW, MVT::i32, Select(N->getOperand(0)),
-                           Select(N->getOperand(1)));
-    return SDOperand(N, 0);
+      return SDOperand(N, 0);
+    }
+    
+    // Other cases are autogenerated.
+    break;
   }
   case ISD::SRL: {
     unsigned Imm, SH, MB, ME;
     if (isOpcWithIntImmediate(N->getOperand(0).Val, ISD::AND, Imm) &&
-        isRotateAndMask(N, Imm, true, SH, MB, ME))
+        isRotateAndMask(N, Imm, true, SH, MB, ME)) { 
       CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, 
                            Select(N->getOperand(0).getOperand(0)),
                            getI32Imm(SH & 0x1F), getI32Imm(MB), getI32Imm(ME));
-    else if (isIntImmediate(N->getOperand(1), Imm))
-      CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Select(N->getOperand(0)),
-                           getI32Imm((32-Imm) & 0x1F), getI32Imm(Imm),
-                           getI32Imm(31));
-    else
-      CurDAG->SelectNodeTo(N, PPC::SRW, MVT::i32, Select(N->getOperand(0)),
-                           Select(N->getOperand(1)));
-    return SDOperand(N, 0);
+      return SDOperand(N, 0);
+    }
+    
+    // Other cases are autogenerated.
+    break;
   }
   case ISD::FNEG: {
     SDOperand Val = Select(N->getOperand(0));
@@ -1393,11 +1201,6 @@
       SDOperand Val = Select(N->getOperand(1));
       if (N->getOperand(1).getValueType() == MVT::i32) {
         Chain = CurDAG->getCopyToReg(Chain, PPC::R3, Val);
-      } else if (N->getOperand(1).getValueType() == MVT::i64) {
-        SDOperand Srl = CurDAG->getTargetNode(PPC::RLDICL, MVT::i64, Val,
-                                              getI32Imm(32), getI32Imm(32));
-        Chain = CurDAG->getCopyToReg(Chain, PPC::R4, Val);
-        Chain = CurDAG->getCopyToReg(Chain, PPC::R3, Srl);
       } else {
         assert(MVT::isFloatingPoint(N->getOperand(1).getValueType()));
         Chain = CurDAG->getCopyToReg(Chain, PPC::F1, Val);


Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.33 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.33.2.1
--- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.33	Mon Oct 17 19:56:42 2005
+++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp	Wed Nov 16 12:32:38 2005
@@ -27,6 +27,7 @@
     
   // Fold away setcc operations if possible.
   setSetCCIsExpensive();
+  setPow2DivIsCheap();
   
   // Use _setjmp/_longjmp instead of setjmp/longjmp.
   setUseUnderscoreSetJmpLongJmp(true);
@@ -80,9 +81,6 @@
   setOperationAction(ISD::BRCOND,       MVT::Other, Expand);
   setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand);
   
-  // PowerPC does not have FP_TO_UINT
-  setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand);
-  
   // PowerPC turns FP_TO_SINT into FCTIWZ and some load/stores.
   setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
 
@@ -97,6 +95,11 @@
     // They also have instructions for converting between i64 and fp.
     setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
     setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
+    // To take advantage of the above i64 FP_TO_SINT, promote i32 FP_TO_UINT
+    setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote);
+  } else {
+    // PowerPC does not have FP_TO_UINT on 32 bit implementations.
+    setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand);
   }
 
   if (TM.getSubtarget<PPCSubtarget>().has64BitRegs()) {
@@ -203,34 +206,47 @@
         std::swap(TV, FV);  // fsel is natively setge, swap operands for setlt
       case ISD::SETUGE:
       case ISD::SETGE:
+        if (LHS.getValueType() == MVT::f32)   // Comparison is always 64-bits
+          LHS = DAG.getNode(ISD::FP_EXTEND, MVT::f64, LHS);
         return DAG.getNode(PPCISD::FSEL, ResVT, LHS, TV, FV);
       case ISD::SETUGT:
       case ISD::SETGT:
         std::swap(TV, FV);  // fsel is natively setge, swap operands for setlt
       case ISD::SETULE:
       case ISD::SETLE:
+        if (LHS.getValueType() == MVT::f32)   // Comparison is always 64-bits
+          LHS = DAG.getNode(ISD::FP_EXTEND, MVT::f64, LHS);
         return DAG.getNode(PPCISD::FSEL, ResVT,
-                           DAG.getNode(ISD::FNEG, ResVT, LHS), TV, FV);
+                           DAG.getNode(ISD::FNEG, MVT::f64, LHS), TV, FV);
       }
     
+    SDOperand Cmp;
     switch (CC) {
     default: assert(0 && "Invalid FSEL condition"); abort();
     case ISD::SETULT:
     case ISD::SETLT:
-      return DAG.getNode(PPCISD::FSEL, ResVT,
-                         DAG.getNode(ISD::FSUB, CmpVT, LHS, RHS), FV, TV);
+      Cmp = DAG.getNode(ISD::FSUB, CmpVT, LHS, RHS);
+      if (Cmp.getValueType() == MVT::f32)   // Comparison is always 64-bits
+        Cmp = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Cmp);
+      return DAG.getNode(PPCISD::FSEL, ResVT, Cmp, FV, TV);
     case ISD::SETUGE:
     case ISD::SETGE:
-      return DAG.getNode(PPCISD::FSEL, ResVT,
-                         DAG.getNode(ISD::FSUB, CmpVT, LHS, RHS), TV, FV);
+      Cmp = DAG.getNode(ISD::FSUB, CmpVT, LHS, RHS);
+      if (Cmp.getValueType() == MVT::f32)   // Comparison is always 64-bits
+        Cmp = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Cmp);
+      return DAG.getNode(PPCISD::FSEL, ResVT, Cmp, TV, FV);
     case ISD::SETUGT:
     case ISD::SETGT:
-      return DAG.getNode(PPCISD::FSEL, ResVT,
-                         DAG.getNode(ISD::FSUB, CmpVT, RHS, LHS), FV, TV);
+      Cmp = DAG.getNode(ISD::FSUB, CmpVT, RHS, LHS);
+      if (Cmp.getValueType() == MVT::f32)   // Comparison is always 64-bits
+        Cmp = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Cmp);
+      return DAG.getNode(PPCISD::FSEL, ResVT, Cmp, FV, TV);
     case ISD::SETULE:
     case ISD::SETLE:
-      return DAG.getNode(PPCISD::FSEL, ResVT,
-                         DAG.getNode(ISD::FSUB, CmpVT, RHS, LHS), TV, FV);
+      Cmp = DAG.getNode(ISD::FSUB, CmpVT, RHS, LHS);
+      if (Cmp.getValueType() == MVT::f32)   // Comparison is always 64-bits
+        Cmp = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Cmp);
+      return DAG.getNode(PPCISD::FSEL, ResVT, Cmp, TV, FV);
     }
     break;
   }
@@ -693,6 +709,19 @@
   return std::make_pair(RetVal, Chain);
 }
 
+SDOperand PPCTargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op,
+                                           SelectionDAG &DAG) {
+  if (Op.getValueType() == MVT::i64) {
+    SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op, 
+                               DAG.getConstant(1, MVT::i32));
+    SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op,
+                               DAG.getConstant(0, MVT::i32));
+    return DAG.getNode(ISD::RET, MVT::Other, Chain, Lo, Hi);
+  } else {
+    return DAG.getNode(ISD::RET, MVT::Other, Chain, Op);
+  }
+}
+
 SDOperand PPCTargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP,
                                           Value *VAListV, SelectionDAG &DAG) {
   // vastart just stores the address of the VarArgsFrameIndex slot into the


Index: llvm/lib/Target/PowerPC/PPCISelLowering.h
diff -u llvm/lib/Target/PowerPC/PPCISelLowering.h:1.8 llvm/lib/Target/PowerPC/PPCISelLowering.h:1.8.2.1
--- llvm/lib/Target/PowerPC/PPCISelLowering.h:1.8	Sun Oct 16 00:39:50 2005
+++ llvm/lib/Target/PowerPC/PPCISelLowering.h	Wed Nov 16 12:32:38 2005
@@ -63,6 +63,9 @@
                   unsigned CC,
                   bool isTailCall, SDOperand Callee, ArgListTy &Args,
                   SelectionDAG &DAG);
+
+    virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op,
+                                    SelectionDAG &DAG);
     
     virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP,
                                    Value *VAListV, SelectionDAG &DAG);


Index: llvm/lib/Target/PowerPC/PPCISelPattern.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelPattern.cpp:1.190 llvm/lib/Target/PowerPC/PPCISelPattern.cpp:1.190.2.1
--- llvm/lib/Target/PowerPC/PPCISelPattern.cpp:1.190	Mon Oct 17 19:28:58 2005
+++ llvm/lib/Target/PowerPC/PPCISelPattern.cpp	Wed Nov 16 12:32:38 2005
@@ -274,151 +274,6 @@
   }
   return 0;
 }
-
-// Structure used to return the necessary information to codegen an SDIV as
-// a multiply.
-struct ms {
-  int m; // magic number
-  int s; // shift amount
-};
-
-struct mu {
-  unsigned int m; // magic number
-  int a;          // add indicator
-  int s;          // shift amount
-};
-
-/// magic - calculate the magic numbers required to codegen an integer sdiv as
-/// a sequence of multiply and shifts.  Requires that the divisor not be 0, 1,
-/// or -1.
-static struct ms magic(int d) {
-  int p;
-  unsigned int ad, anc, delta, q1, r1, q2, r2, t;
-  const unsigned int two31 = 0x80000000U;
-  struct ms mag;
-
-  ad = abs(d);
-  t = two31 + ((unsigned int)d >> 31);
-  anc = t - 1 - t%ad;   // absolute value of nc
-  p = 31;               // initialize p
-  q1 = two31/anc;       // initialize q1 = 2p/abs(nc)
-  r1 = two31 - q1*anc;  // initialize r1 = rem(2p,abs(nc))
-  q2 = two31/ad;        // initialize q2 = 2p/abs(d)
-  r2 = two31 - q2*ad;   // initialize r2 = rem(2p,abs(d))
-  do {
-    p = p + 1;
-    q1 = 2*q1;        // update q1 = 2p/abs(nc)
-    r1 = 2*r1;        // update r1 = rem(2p/abs(nc))
-    if (r1 >= anc) {  // must be unsigned comparison
-      q1 = q1 + 1;
-      r1 = r1 - anc;
-    }
-    q2 = 2*q2;        // update q2 = 2p/abs(d)
-    r2 = 2*r2;        // update r2 = rem(2p/abs(d))
-    if (r2 >= ad) {   // must be unsigned comparison
-      q2 = q2 + 1;
-      r2 = r2 - ad;
-    }
-    delta = ad - r2;
-  } while (q1 < delta || (q1 == delta && r1 == 0));
-
-  mag.m = q2 + 1;
-  if (d < 0) mag.m = -mag.m; // resulting magic number
-  mag.s = p - 32;            // resulting shift
-  return mag;
-}
-
-/// magicu - calculate the magic numbers required to codegen an integer udiv as
-/// a sequence of multiply, add and shifts.  Requires that the divisor not be 0.
-static struct mu magicu(unsigned d)
-{
-  int p;
-  unsigned int nc, delta, q1, r1, q2, r2;
-  struct mu magu;
-  magu.a = 0;               // initialize "add" indicator
-  nc = - 1 - (-d)%d;
-  p = 31;                   // initialize p
-  q1 = 0x80000000/nc;       // initialize q1 = 2p/nc
-  r1 = 0x80000000 - q1*nc;  // initialize r1 = rem(2p,nc)
-  q2 = 0x7FFFFFFF/d;        // initialize q2 = (2p-1)/d
-  r2 = 0x7FFFFFFF - q2*d;   // initialize r2 = rem((2p-1),d)
-  do {
-    p = p + 1;
-    if (r1 >= nc - r1 ) {
-      q1 = 2*q1 + 1;  // update q1
-      r1 = 2*r1 - nc; // update r1
-    }
-    else {
-      q1 = 2*q1; // update q1
-      r1 = 2*r1; // update r1
-    }
-    if (r2 + 1 >= d - r2) {
-      if (q2 >= 0x7FFFFFFF) magu.a = 1;
-      q2 = 2*q2 + 1;     // update q2
-      r2 = 2*r2 + 1 - d; // update r2
-    }
-    else {
-      if (q2 >= 0x80000000) magu.a = 1;
-      q2 = 2*q2;     // update q2
-      r2 = 2*r2 + 1; // update r2
-    }
-    delta = d - 1 - r2;
-  } while (p < 64 && (q1 < delta || (q1 == delta && r1 == 0)));
-  magu.m = q2 + 1; // resulting magic number
-  magu.s = p - 32;  // resulting shift
-  return magu;
-}
-}
-
-/// BuildSDIVSequence - Given an ISD::SDIV node expressing a divide by constant,
-/// return a DAG expression to select that will generate the same value by
-/// multiplying by a magic number.  See:
-/// <http://the.wall.riscom.net/books/proc/ppc/cwg/code2.html>
-SDOperand ISel::BuildSDIVSequence(SDOperand N) {
-  int d = (int)cast<ConstantSDNode>(N.getOperand(1))->getSignExtended();
-  ms magics = magic(d);
-  // Multiply the numerator (operand 0) by the magic value
-  SDOperand Q = ISelDAG->getNode(ISD::MULHS, MVT::i32, N.getOperand(0),
-                                 ISelDAG->getConstant(magics.m, MVT::i32));
-  // If d > 0 and m < 0, add the numerator
-  if (d > 0 && magics.m < 0)
-    Q = ISelDAG->getNode(ISD::ADD, MVT::i32, Q, N.getOperand(0));
-  // If d < 0 and m > 0, subtract the numerator.
-  if (d < 0 && magics.m > 0)
-    Q = ISelDAG->getNode(ISD::SUB, MVT::i32, Q, N.getOperand(0));
-  // Shift right algebraic if shift value is nonzero
-  if (magics.s > 0)
-    Q = ISelDAG->getNode(ISD::SRA, MVT::i32, Q,
-                         ISelDAG->getConstant(magics.s, MVT::i32));
-  // Extract the sign bit and add it to the quotient
-  SDOperand T =
-    ISelDAG->getNode(ISD::SRL, MVT::i32, Q, ISelDAG->getConstant(31, MVT::i32));
-  return ISelDAG->getNode(ISD::ADD, MVT::i32, Q, T);
-}
-
-/// BuildUDIVSequence - Given an ISD::UDIV node expressing a divide by constant,
-/// return a DAG expression to select that will generate the same value by
-/// multiplying by a magic number.  See:
-/// <http://the.wall.riscom.net/books/proc/ppc/cwg/code2.html>
-SDOperand ISel::BuildUDIVSequence(SDOperand N) {
-  unsigned d =
-    (unsigned)cast<ConstantSDNode>(N.getOperand(1))->getSignExtended();
-  mu magics = magicu(d);
-  // Multiply the numerator (operand 0) by the magic value
-  SDOperand Q = ISelDAG->getNode(ISD::MULHU, MVT::i32, N.getOperand(0),
-                                 ISelDAG->getConstant(magics.m, MVT::i32));
-  if (magics.a == 0) {
-    Q = ISelDAG->getNode(ISD::SRL, MVT::i32, Q,
-                         ISelDAG->getConstant(magics.s, MVT::i32));
-  } else {
-    SDOperand NPQ = ISelDAG->getNode(ISD::SUB, MVT::i32, N.getOperand(0), Q);
-    NPQ = ISelDAG->getNode(ISD::SRL, MVT::i32, NPQ,
-                           ISelDAG->getConstant(1, MVT::i32));
-    NPQ = ISelDAG->getNode(ISD::ADD, MVT::i32, NPQ, Q);
-    Q = ISelDAG->getNode(ISD::SRL, MVT::i32, NPQ,
-                           ISelDAG->getConstant(magics.s-1, MVT::i32));
-  }
-  return Q;
 }
 
 /// getGlobalBaseReg - Output the instructions required to put the
@@ -1395,19 +1250,10 @@
         BuildMI(BB, PPC::ADDZE, 1, Tmp4).addReg(Tmp1);
         BuildMI(BB, PPC::NEG, 1, Result).addReg(Tmp4);
         return Result;
-      } else if (Tmp3) {
-        ExprMap.erase(N);
-        return SelectExpr(BuildSDIVSequence(N));
       }
     }
     // fall thru
   case ISD::UDIV:
-    // If this is a divide by constant, we can emit code using some magic
-    // constants to implement it as a multiply instead.
-    if (isIntImmediate(N.getOperand(1), Tmp3) && Tmp3) {
-      ExprMap.erase(N);
-      return SelectExpr(BuildUDIVSequence(N));
-    }
     Tmp1 = SelectExpr(N.getOperand(0));
     Tmp2 = SelectExpr(N.getOperand(1));
     Opc = (ISD::UDIV == opcode) ? PPC::DIVWU : PPC::DIVW; break;


Index: llvm/lib/Target/PowerPC/PPCInstrFormats.td
diff -u llvm/lib/Target/PowerPC/PPCInstrFormats.td:1.52 llvm/lib/Target/PowerPC/PPCInstrFormats.td:1.52.2.1
--- llvm/lib/Target/PowerPC/PPCInstrFormats.td:1.52	Fri Oct 14 17:44:13 2005
+++ llvm/lib/Target/PowerPC/PPCInstrFormats.td	Wed Nov 16 12:32:38 2005
@@ -14,7 +14,8 @@
 //
 // PowerPC instruction formats
 
-class I<bits<6> opcode, dag OL, string asmstr> : Instruction {
+class I<bits<6> opcode, dag OL, string asmstr, InstrItinClass itin>
+        : Instruction {
   field bits<32> Inst;
 
   bit PPC64 = 0;  // Default value, override with isPPC64
@@ -25,11 +26,13 @@
   let Inst{0-5} = opcode;
   let OperandList = OL;
   let AsmString = asmstr;
+  let Itinerary = itin;
 }
 
 // 1.7.1 I-Form
-class IForm<bits<6> opcode, bit aa, bit lk, dag OL, string asmstr>
-         : I<opcode, OL, asmstr> {
+class IForm<bits<6> opcode, bit aa, bit lk, dag OL, string asmstr,
+            InstrItinClass itin>
+         : I<opcode, OL, asmstr, itin> {
   bits<24> LI;
 
   let Inst{6-29}  = LI;
@@ -39,8 +42,8 @@
 
 // 1.7.2 B-Form
 class BForm<bits<6> opcode, bit aa, bit lk, bits<5> bo, bits<2> bicode, dag OL, 
-            string asmstr>
-  : I<opcode, OL, asmstr> {
+            string asmstr, InstrItinClass itin>
+  : I<opcode, OL, asmstr, itin> {
   bits<3>  CR;
   bits<14> BD;
 
@@ -53,8 +56,9 @@
 }
 
 // 1.7.4 D-Form
-class DForm_base<bits<6> opcode, dag OL, string asmstr, list<dag> pattern>
-   : I<opcode, OL, asmstr> {
+class DForm_base<bits<6> opcode, dag OL, string asmstr, InstrItinClass itin,
+                 list<dag> pattern>
+   : I<opcode, OL, asmstr, itin> {
   let Pattern = pattern;
   bits<5>  A;
   bits<5>  B;
@@ -65,8 +69,8 @@
   let Inst{16-31} = C;
 }
 
-class DForm_1<bits<6> opcode, dag OL, string asmstr>
-   : I<opcode, OL, asmstr> {
+class DForm_1<bits<6> opcode, dag OL, string asmstr, InstrItinClass itin>
+   : I<opcode, OL, asmstr, itin> {
   bits<5>  A;
   bits<16> C;
   bits<5>  B;
@@ -76,11 +80,13 @@
   let Inst{16-31} = C;
 }
 
-class DForm_2<bits<6> opcode, dag OL, string asmstr, list<dag> pattern>
-  : DForm_base<opcode, OL, asmstr, pattern>;
+class DForm_2<bits<6> opcode, dag OL, string asmstr, InstrItinClass itin,
+              list<dag> pattern>
+  : DForm_base<opcode, OL, asmstr, itin, pattern>;
 
-class DForm_2_r0<bits<6> opcode, dag OL, string asmstr, list<dag> pattern>
-  : I<opcode, OL, asmstr> {
+class DForm_2_r0<bits<6> opcode, dag OL, string asmstr, InstrItinClass itin,
+                 list<dag> pattern>
+  : I<opcode, OL, asmstr, itin> {
   bits<5>  A;
   bits<16> B;
   
@@ -92,11 +98,12 @@
 }
 
 // Currently we make the use/def reg distinction in ISel, not tablegen
-class DForm_3<bits<6> opcode, dag OL, string asmstr>
-  : DForm_1<opcode, OL, asmstr>;
+class DForm_3<bits<6> opcode, dag OL, string asmstr, InstrItinClass itin>
+  : DForm_1<opcode, OL, asmstr, itin>;
 
-class DForm_4<bits<6> opcode, dag OL, string asmstr, list<dag> pattern>
- : I<opcode, OL, asmstr> {
+class DForm_4<bits<6> opcode, dag OL, string asmstr, InstrItinClass itin,
+              list<dag> pattern>
+ : I<opcode, OL, asmstr, itin> {
   bits<5>  B;
   bits<5>  A;
   bits<16> C;
@@ -108,14 +115,15 @@
   let Inst{16-31} = C;
 }
               
-class DForm_4_zero<bits<6> opcode, dag OL, string asmstr>
-  : DForm_1<opcode, OL, asmstr> {
+class DForm_4_zero<bits<6> opcode, dag OL, string asmstr, InstrItinClass itin>
+  : DForm_1<opcode, OL, asmstr, itin> {
   let A = 0;
   let B = 0;
   let C = 0;
 }
 
-class DForm_5<bits<6> opcode, dag OL, string asmstr> : I<opcode, OL, asmstr> {
+class DForm_5<bits<6> opcode, dag OL, string asmstr, InstrItinClass itin>
+  : I<opcode, OL, asmstr, itin> {
   bits<3>  BF;
   bits<1>  L;
   bits<5>  RA;
@@ -128,30 +136,31 @@
   let Inst{16-31} = I;
 }
 
-class DForm_5_ext<bits<6> opcode, dag OL, string asmstr>
-  : DForm_5<opcode, OL, asmstr> {
+class DForm_5_ext<bits<6> opcode, dag OL, string asmstr, InstrItinClass itin>
+  : DForm_5<opcode, OL, asmstr, itin> {
   let L = PPC64;
 }
 
-class DForm_6<bits<6> opcode, dag OL, string asmstr> 
-  : DForm_5<opcode, OL, asmstr>;
+class DForm_6<bits<6> opcode, dag OL, string asmstr, InstrItinClass itin> 
+  : DForm_5<opcode, OL, asmstr, itin>;
 
-class DForm_6_ext<bits<6> opcode, dag OL, string asmstr>
-  : DForm_6<opcode, OL, asmstr> {
+class DForm_6_ext<bits<6> opcode, dag OL, string asmstr, InstrItinClass itin>
+  : DForm_6<opcode, OL, asmstr, itin> {
   let L = PPC64;
 }
 
-class DForm_8<bits<6> opcode, dag OL, string asmstr>
-  : DForm_1<opcode, OL, asmstr> {
+class DForm_8<bits<6> opcode, dag OL, string asmstr, InstrItinClass itin>
+  : DForm_1<opcode, OL, asmstr, itin> {
 }
 
-class DForm_9<bits<6> opcode, dag OL, string asmstr>
-  : DForm_1<opcode, OL, asmstr> {
+class DForm_9<bits<6> opcode, dag OL, string asmstr, InstrItinClass itin>
+  : DForm_1<opcode, OL, asmstr, itin> {
 }
 
 // 1.7.5 DS-Form
-class DSForm_1<bits<6> opcode, bits<2> xo, dag OL, string asmstr>
-         : I<opcode, OL, asmstr> {
+class DSForm_1<bits<6> opcode, bits<2> xo, dag OL, string asmstr,
+               InstrItinClass itin>
+         : I<opcode, OL, asmstr, itin> {
   bits<5>  RST;
   bits<14> DS;
   bits<5>  RA;
@@ -162,12 +171,14 @@
   let Inst{30-31} = xo;
 }
 
-class DSForm_2<bits<6> opcode, bits<2> xo, dag OL, string asmstr>
-  : DSForm_1<opcode, xo, OL, asmstr>;
+class DSForm_2<bits<6> opcode, bits<2> xo, dag OL, string asmstr,
+               InstrItinClass itin>
+  : DSForm_1<opcode, xo, OL, asmstr, itin>;
 
 // 1.7.6 X-Form
 class XForm_base_r3xo<bits<6> opcode, bits<10> xo, 
-                      dag OL, string asmstr> : I<opcode, OL, asmstr> {
+                      dag OL, string asmstr, InstrItinClass itin>
+  : I<opcode, OL, asmstr, itin> {
   bits<5> RST;
   bits<5> A;
   bits<5> B;
@@ -184,8 +195,9 @@
 // This is the same as XForm_base_r3xo, but the first two operands are swapped
 // when code is emitted.
 class XForm_base_r3xo_swapped
-        <bits<6> opcode, bits<10> xo, dag OL, string asmstr> 
-  : I<opcode, OL, asmstr> {
+        <bits<6> opcode, bits<10> xo, dag OL, string asmstr,
+        InstrItinClass itin> 
+  : I<opcode, OL, asmstr, itin> {
   bits<5> A;
   bits<5> RST;
   bits<5> B;
@@ -200,32 +212,36 @@
 }
 
 
-class XForm_1<bits<6> opcode, bits<10> xo, dag OL, string asmstr> 
-  : XForm_base_r3xo<opcode, xo, OL, asmstr>;
-
-class XForm_6<bits<6> opcode, bits<10> xo, dag OL, string asmstr, 
-              list<dag> pattern> 
-  : XForm_base_r3xo_swapped<opcode, xo, OL, asmstr> {
+class XForm_1<bits<6> opcode, bits<10> xo, dag OL, string asmstr,
+              InstrItinClass itin> 
+  : XForm_base_r3xo<opcode, xo, OL, asmstr, itin>;
+
+class XForm_6<bits<6> opcode, bits<10> xo, dag OL, string asmstr,
+              InstrItinClass itin, list<dag> pattern> 
+  : XForm_base_r3xo_swapped<opcode, xo, OL, asmstr, itin> {
   let Pattern = pattern;
 }
 
-class XForm_8<bits<6> opcode, bits<10> xo, dag OL, string asmstr> 
-  : XForm_base_r3xo<opcode, xo, OL, asmstr>;
-
-class XForm_10<bits<6> opcode, bits<10> xo, dag OL, string asmstr, list<dag> pt> 
-  : XForm_base_r3xo_swapped<opcode, xo, OL, asmstr> {
-    let Pattern = pt;
+class XForm_8<bits<6> opcode, bits<10> xo, dag OL, string asmstr,
+              InstrItinClass itin> 
+  : XForm_base_r3xo<opcode, xo, OL, asmstr, itin>;
+
+class XForm_10<bits<6> opcode, bits<10> xo, dag OL, string asmstr,
+               InstrItinClass itin, list<dag> pattern> 
+  : XForm_base_r3xo_swapped<opcode, xo, OL, asmstr, itin> {
+    let Pattern = pattern;
 }
 
 class XForm_11<bits<6> opcode, bits<10> xo, dag OL, string asmstr,
-               list<dag> pattern> 
-  : XForm_base_r3xo_swapped<opcode, xo, OL, asmstr> {
+               InstrItinClass itin, list<dag> pattern> 
+  : XForm_base_r3xo_swapped<opcode, xo, OL, asmstr, itin> {
   let B = 0;
   let Pattern = pattern;
 }
 
-class XForm_16<bits<6> opcode, bits<10> xo, dag OL, string asmstr>
-         : I<opcode, OL, asmstr> {
+class XForm_16<bits<6> opcode, bits<10> xo, dag OL, string asmstr,
+               InstrItinClass itin>
+         : I<opcode, OL, asmstr, itin> {
   bits<3> BF;
   bits<1> L; 
   bits<5> RA;
@@ -240,13 +256,15 @@
   let Inst{31}    = 0;
 }
 
-class XForm_16_ext<bits<6> opcode, bits<10> xo, dag OL, string asmstr>
-  : XForm_16<opcode, xo, OL, asmstr> {
+class XForm_16_ext<bits<6> opcode, bits<10> xo, dag OL, string asmstr,
+                   InstrItinClass itin>
+  : XForm_16<opcode, xo, OL, asmstr, itin> {
   let L = PPC64;
 }
 
-class XForm_17<bits<6> opcode, bits<10> xo, dag OL, string asmstr>
-         : I<opcode, OL, asmstr> {
+class XForm_17<bits<6> opcode, bits<10> xo, dag OL, string asmstr,
+               InstrItinClass itin>
+         : I<opcode, OL, asmstr, itin> {
   bits<3> BF;
   bits<5> FRA;
   bits<5> FRB;
@@ -259,23 +277,27 @@
   let Inst{31}    = 0;
 }
 
-class XForm_25<bits<6> opcode, bits<10> xo, dag OL, string asmstr> 
-  : XForm_base_r3xo<opcode, xo, OL, asmstr> {
+class XForm_25<bits<6> opcode, bits<10> xo, dag OL, string asmstr,
+               InstrItinClass itin> 
+  : XForm_base_r3xo<opcode, xo, OL, asmstr, itin> {
 }
 
-class XForm_26<bits<6> opcode, bits<10> xo, dag OL, string asmstr, list<dag> pt>
-  : XForm_base_r3xo<opcode, xo, OL, asmstr> {
+class XForm_26<bits<6> opcode, bits<10> xo, dag OL, string asmstr,
+               InstrItinClass itin, list<dag> pattern>
+  : XForm_base_r3xo<opcode, xo, OL, asmstr, itin> {
   let A = 0;
-  let Pattern = pt;
+  let Pattern = pattern;
 }
 
-class XForm_28<bits<6> opcode, bits<10> xo, dag OL, string asmstr> 
-  : XForm_base_r3xo<opcode, xo, OL, asmstr> {
+class XForm_28<bits<6> opcode, bits<10> xo, dag OL, string asmstr,
+               InstrItinClass itin> 
+  : XForm_base_r3xo<opcode, xo, OL, asmstr, itin> {
 }
 
 // 1.7.7 XL-Form
-class XLForm_1<bits<6> opcode, bits<10> xo, dag OL, string asmstr>
-         : I<opcode, OL, asmstr> {
+class XLForm_1<bits<6> opcode, bits<10> xo, dag OL, string asmstr,
+               InstrItinClass itin>
+    : I<opcode, OL, asmstr, itin> {
   bits<3> CRD;
   bits<2> CRDb;
   bits<3> CRA;
@@ -293,8 +315,9 @@
   let Inst{31}    = 0;
 }
 
-class XLForm_2<bits<6> opcode, bits<10> xo, bit lk, 
-               dag OL, string asmstr> : I<opcode, OL, asmstr> {
+class XLForm_2<bits<6> opcode, bits<10> xo, bit lk, dag OL, string asmstr, 
+               InstrItinClass itin>
+    : I<opcode, OL, asmstr, itin> {
   bits<5> BO;
   bits<5> BI;
   bits<2> BH;
@@ -307,16 +330,17 @@
   let Inst{31}    = lk;
 }
 
-class XLForm_2_ext<bits<6> opcode, bits<10> xo, bits<5> bo, 
-                   bits<5> bi, bit lk, dag OL, string asmstr>
-  : XLForm_2<opcode, xo, lk, OL, asmstr> {
+class XLForm_2_ext<bits<6> opcode, bits<10> xo, bits<5> bo,  bits<5> bi, bit lk,
+                  dag OL, string asmstr, InstrItinClass itin>
+  : XLForm_2<opcode, xo, lk, OL, asmstr, itin> {
   let BO = bo;
   let BI = bi;
   let BH = 0;
 }
 
-class XLForm_3<bits<6> opcode, bits<10> xo, dag OL, string asmstr>
-         : I<opcode, OL, asmstr> {
+class XLForm_3<bits<6> opcode, bits<10> xo, dag OL, string asmstr,
+               InstrItinClass itin>
+         : I<opcode, OL, asmstr, itin> {
   bits<3> BF;
   bits<3> BFA;
   
@@ -330,8 +354,9 @@
 }
 
 // 1.7.8 XFX-Form
-class XFXForm_1<bits<6> opcode, bits<10> xo, dag OL, string asmstr>
-         : I<opcode, OL, asmstr> {
+class XFXForm_1<bits<6> opcode, bits<10> xo, dag OL, string asmstr,
+                InstrItinClass itin>
+         : I<opcode, OL, asmstr, itin> {
   bits<5>  RT;
   bits<10> SPR;
 
@@ -342,13 +367,14 @@
 }
 
 class XFXForm_1_ext<bits<6> opcode, bits<10> xo, bits<10> spr, 
-                   dag OL, string asmstr> 
-  : XFXForm_1<opcode, xo, OL, asmstr> {
+                   dag OL, string asmstr, InstrItinClass itin> 
+  : XFXForm_1<opcode, xo, OL, asmstr, itin> {
   let SPR = spr;
 }
 
-class XFXForm_3<bits<6> opcode, bits<10> xo, dag OL, string asmstr>
-         : I<opcode, OL, asmstr> {
+class XFXForm_3<bits<6> opcode, bits<10> xo, dag OL, string asmstr,
+                InstrItinClass itin>
+         : I<opcode, OL, asmstr, itin> {
   bits<5>  RT;
    
   let Inst{6-10}  = RT;
@@ -357,8 +383,9 @@
   let Inst{31}    = 0;
 }
 
-class XFXForm_5<bits<6> opcode, bits<10> xo, dag OL, string asmstr> 
-  : I<opcode, OL, asmstr> {
+class XFXForm_5<bits<6> opcode, bits<10> xo, dag OL, string asmstr,
+                InstrItinClass itin> 
+  : I<opcode, OL, asmstr, itin> {
   bits<8>  FXM;
   bits<5>  ST;
    
@@ -370,8 +397,9 @@
   let Inst{31}    = 0;
 }
 
-class XFXForm_5a<bits<6> opcode, bits<10> xo, dag OL, string asmstr> 
-  : I<opcode, OL, asmstr> {
+class XFXForm_5a<bits<6> opcode, bits<10> xo, dag OL, string asmstr,
+                 InstrItinClass itin> 
+  : I<opcode, OL, asmstr, itin> {
   bits<5>  ST;
   bits<8>  FXM;
    
@@ -384,18 +412,20 @@
 }
 
 
-class XFXForm_7<bits<6> opcode, bits<10> xo, dag OL, string asmstr>
-  : XFXForm_1<opcode, xo, OL, asmstr>;
+class XFXForm_7<bits<6> opcode, bits<10> xo, dag OL, string asmstr,
+                InstrItinClass itin>
+  : XFXForm_1<opcode, xo, OL, asmstr, itin>;
 
 class XFXForm_7_ext<bits<6> opcode, bits<10> xo, bits<10> spr, 
-                    dag OL, string asmstr> 
-  : XFXForm_7<opcode, xo, OL, asmstr> {
+                    dag OL, string asmstr, InstrItinClass itin> 
+  : XFXForm_7<opcode, xo, OL, asmstr, itin> {
   let SPR = spr;
 }
 
 // 1.7.10 XS-Form
-class XSForm_1<bits<6> opcode, bits<9> xo, dag OL, string asmstr>
-         : I<opcode, OL, asmstr> {
+class XSForm_1<bits<6> opcode, bits<9> xo, dag OL, string asmstr,
+               InstrItinClass itin>
+         : I<opcode, OL, asmstr, itin> {
   bits<5> RS;
   bits<5> A;
   bits<6> SH;
@@ -412,8 +442,8 @@
 
 // 1.7.11 XO-Form
 class XOForm_1<bits<6> opcode, bits<9> xo, bit oe, dag OL, string asmstr,
-               list<dag> pattern>
-         : I<opcode, OL, asmstr> {
+               InstrItinClass itin, list<dag> pattern>
+         : I<opcode, OL, asmstr, itin> {
   bits<5> RT;
   bits<5> RA;
   bits<5> RB;
@@ -431,15 +461,15 @@
 }
 
 class XOForm_3<bits<6> opcode, bits<9> xo, bit oe, 
-               dag OL, string asmstr, list<dag> pattern>
-  : XOForm_1<opcode, xo, oe, OL, asmstr, pattern> {
+               dag OL, string asmstr, InstrItinClass itin, list<dag> pattern>
+  : XOForm_1<opcode, xo, oe, OL, asmstr, itin, pattern> {
   let RB = 0;
 }
 
 // 1.7.12 A-Form
 class AForm_1<bits<6> opcode, bits<5> xo, dag OL, string asmstr, 
-              list<dag> pattern>
-         : I<opcode, OL, asmstr> {
+              InstrItinClass itin, list<dag> pattern>
+         : I<opcode, OL, asmstr, itin> {
   bits<5> FRT;
   bits<5> FRA;
   bits<5> FRC;
@@ -457,24 +487,30 @@
   let Inst{31}    = RC;
 }
 
-class AForm_2<bits<6> opcode, bits<5> xo, dag OL, string asmstr, list<dag> pat>
-  : AForm_1<opcode, xo, OL, asmstr, pat> {
+class AForm_2<bits<6> opcode, bits<5> xo, dag OL, string asmstr,
+              InstrItinClass itin, list<dag> pattern>
+  : AForm_1<opcode, xo, OL, asmstr, itin, pattern> {
   let FRC = 0;
 }
 
-class AForm_3<bits<6> opcode, bits<5> xo, dag OL, string asmstr, list<dag> pat> 
-  : AForm_1<opcode, xo, OL, asmstr, pat> {
+class AForm_3<bits<6> opcode, bits<5> xo, dag OL, string asmstr,
+              InstrItinClass itin, list<dag> pattern> 
+  : AForm_1<opcode, xo, OL, asmstr, itin, pattern> {
   let FRB = 0;
 }
 
 // 1.7.13 M-Form
-class MForm_1<bits<6> opcode, dag OL, string asmstr> : I<opcode, OL, asmstr> {
+class MForm_1<bits<6> opcode, dag OL, string asmstr,
+              InstrItinClass itin, list<dag> pattern>
+    : I<opcode, OL, asmstr, itin> {
   bits<5> RA;
   bits<5> RS;
   bits<5> RB;
   bits<5> MB;
   bits<5> ME;
 
+  let Pattern = pattern;
+
   bit RC = 0;    // set by isDOT
 
   let Inst{6-10}  = RS;
@@ -485,18 +521,22 @@
   let Inst{31}    = RC;
 }
 
-class MForm_2<bits<6> opcode, dag OL, string asmstr>
-  : MForm_1<opcode, OL, asmstr> {
+class MForm_2<bits<6> opcode, dag OL, string asmstr,
+              InstrItinClass itin, list<dag> pattern>
+  : MForm_1<opcode, OL, asmstr, itin, pattern> {
 }
 
 // 1.7.14 MD-Form
-class MDForm_1<bits<6> opcode, bits<3> xo, dag OL, string asmstr>
-         : I<opcode, OL, asmstr> {
+class MDForm_1<bits<6> opcode, bits<3> xo, dag OL, string asmstr,
+               InstrItinClass itin, list<dag> pattern>
+    : I<opcode, OL, asmstr, itin> {
   bits<5> RS;
   bits<5> RA;
   bits<6> SH;
   bits<6> MBE;
 
+  let Pattern = pattern;
+
   bit RC = 0;    // set by isDOT
 
   let Inst{6-10}  = RS;
@@ -509,10 +549,11 @@
 }
 
 //===----------------------------------------------------------------------===//
-
-class Pseudo<dag OL, string asmstr> : I<0, OL, asmstr> {
+def NoItin : InstrItinClass;
+class Pseudo<dag OL, string asmstr, list<dag> pattern>
+    : I<0, OL, asmstr, NoItin> {
   let PPC64 = 0;
   let VMX = 0;
-
+  let Pattern = pattern;
   let Inst{31-0} = 0;
 }


Index: llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.cpp:1.12 llvm/lib/Target/PowerPC/PPCInstrInfo.cpp:1.12.2.1
--- llvm/lib/Target/PowerPC/PPCInstrInfo.cpp:1.12	Mon Oct 17 19:28:58 2005
+++ llvm/lib/Target/PowerPC/PPCInstrInfo.cpp	Wed Nov 16 12:32:38 2005
@@ -25,7 +25,8 @@
                                unsigned& sourceReg,
                                unsigned& destReg) const {
   MachineOpCode oc = MI.getOpcode();
-  if (oc == PPC::OR4 || oc == PPC::OR8) {                      // or r1, r2, r2
+  if (oc == PPC::OR4 || oc == PPC::OR8 || 
+      oc == PPC::OR4To8 || oc == PPC::OR8To4) {                // or r1, r2, r2
     assert(MI.getNumOperands() == 3 &&
            MI.getOperand(0).isRegister() &&
            MI.getOperand(1).isRegister() &&


Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td
diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.124 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.124.2.1
--- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.124	Tue Oct 18 11:51:22 2005
+++ llvm/lib/Target/PowerPC/PPCInstrInfo.td	Wed Nov 16 12:32:38 2005
@@ -14,10 +14,43 @@
 
 include "PPCInstrFormats.td"
 
+//===----------------------------------------------------------------------===//
+// PowerPC specific DAG Nodes.
+//
+
+def PPCfcfid  : SDNode<"PPCISD::FCFID" , SDTFPUnaryOp, []>;
+def PPCfctidz : SDNode<"PPCISD::FCTIDZ", SDTFPUnaryOp, []>;
+def PPCfctiwz : SDNode<"PPCISD::FCTIWZ", SDTFPUnaryOp, []>;
+
+def PPCfsel   : SDNode<"PPCISD::FSEL",  
+   // Type constraint for fsel.
+   SDTypeProfile<1, 3, [SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>, 
+                        SDTCisFP<0>, SDTCisVT<1, f64>]>, []>;
 
 //===----------------------------------------------------------------------===//
 // PowerPC specific transformation functions and pattern fragments.
 //
+
+def SHL32 : SDNodeXForm<imm, [{
+  // Transformation function: 31 - imm
+  return getI32Imm(31 - N->getValue());
+}]>;
+
+def SHL64 : SDNodeXForm<imm, [{
+  // Transformation function: 63 - imm
+  return getI32Imm(63 - N->getValue());
+}]>;
+
+def SRL32 : SDNodeXForm<imm, [{
+  // Transformation function: 32 - imm
+  return N->getValue() ? getI32Imm(32 - N->getValue()) : getI32Imm(0);
+}]>;
+
+def SRL64 : SDNodeXForm<imm, [{
+  // Transformation function: 64 - imm
+  return N->getValue() ? getI32Imm(64 - N->getValue()) : getI32Imm(0);
+}]>;
+
 def LO16 : SDNodeXForm<imm, [{
   // Transformation function: get the low 16 bits.
   return getI32Imm((unsigned short)N->getValue());
@@ -114,60 +147,67 @@
 // PowerPC Instruction Definitions.
 
 // Pseudo-instructions:
-def PHI : Pseudo<(ops variable_ops), "; PHI">;
+def PHI : Pseudo<(ops variable_ops), "; PHI", []>;
 
 let isLoad = 1 in {
-def ADJCALLSTACKDOWN : Pseudo<(ops u16imm:$amt), "; ADJCALLSTACKDOWN">;
-def ADJCALLSTACKUP : Pseudo<(ops u16imm:$amt), "; ADJCALLSTACKUP">;
+def ADJCALLSTACKDOWN : Pseudo<(ops u16imm:$amt), "; ADJCALLSTACKDOWN", []>;
+def ADJCALLSTACKUP : Pseudo<(ops u16imm:$amt), "; ADJCALLSTACKUP", []>;
 }
-def IMPLICIT_DEF_GPR : Pseudo<(ops GPRC:$rD), "; $rD = IMPLICIT_DEF_GPRC">;
-def IMPLICIT_DEF_F8  : Pseudo<(ops F8RC:$rD), "; %rD = IMPLICIT_DEF_F8">;
-def IMPLICIT_DEF_F4  : Pseudo<(ops F4RC:$rD), "; %rD = IMPLICIT_DEF_F4">;
+def IMPLICIT_DEF_GPR : Pseudo<(ops GPRC:$rD), "; $rD = IMPLICIT_DEF_GPRC",
+                              [(set GPRC:$rD, (undef))]>;
+def IMPLICIT_DEF_F8  : Pseudo<(ops F8RC:$rD), "; %rD = IMPLICIT_DEF_F8",
+                              [(set F8RC:$rD, (undef))]>;
+def IMPLICIT_DEF_F4  : Pseudo<(ops F4RC:$rD), "; %rD = IMPLICIT_DEF_F4",
+                              [(set F4RC:$rD, (undef))]>;
 
 // 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.
   def SELECT_CC_Int : Pseudo<(ops GPRC:$dst, CRRC:$cond, GPRC:$T, GPRC:$F,
-                              i32imm:$BROPC), "; SELECT_CC PSEUDO!">;
+                              i32imm:$BROPC), "; SELECT_CC PSEUDO!", []>;
   def SELECT_CC_F4  : Pseudo<(ops F4RC:$dst, CRRC:$cond, F4RC:$T, F4RC:$F,
-                              i32imm:$BROPC), "; SELECT_CC PSEUDO!">;
+                              i32imm:$BROPC), "; SELECT_CC PSEUDO!", []>;
   def SELECT_CC_F8  : Pseudo<(ops F8RC:$dst, CRRC:$cond, F8RC:$T, F8RC:$F,
-                              i32imm:$BROPC), "; SELECT_CC PSEUDO!">;
+                              i32imm:$BROPC), "; SELECT_CC PSEUDO!", []>;
 }
 
 
 let isTerminator = 1 in {
   let isReturn = 1 in
-    def BLR : XLForm_2_ext<19, 16, 20, 0, 0, (ops), "blr">;
-  def BCTR : XLForm_2_ext<19, 528, 20, 0, 0, (ops), "bctr">;
+    def BLR : XLForm_2_ext<19, 16, 20, 0, 0, (ops), "blr", BrB>;
+  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", []>;
 
 let isBranch = 1, isTerminator = 1 in {
   def COND_BRANCH : Pseudo<(ops CRRC:$crS, u16imm:$opc,
                                 target:$true, target:$false),
-                           "; COND_BRANCH">;
-  def B   : IForm<18, 0, 0, (ops target:$func), "b $func">;
-//def BA  : IForm<18, 1, 0, (ops target:$func), "ba $func">;
-  def BL  : IForm<18, 0, 1, (ops target:$func), "bl $func">;
-//def BLA : IForm<18, 1, 1, (ops target:$func), "bla $func">;
+                           "; COND_BRANCH", []>;
+  def B   : IForm<18, 0, 0, (ops target:$func), "b $func", BrB>;
+//def BA  : IForm<18, 1, 0, (ops target:$func), "ba $func", BrB>;
+  def BL  : IForm<18, 0, 1, (ops target:$func), "bl $func", BrB>;
+//def BLA : IForm<18, 1, 1, (ops target:$func), "bla $func", BrB>;
 
   // FIXME: 4*CR# needs to be added to the BI field!
   // This will only work for CR0 as it stands now
   def BLT : BForm<16, 0, 0, 12, 0, (ops CRRC:$crS, target:$block),
-                  "blt $crS, $block">;
+                  "blt $crS, $block", BrB>;
   def BLE : BForm<16, 0, 0, 4,  1, (ops CRRC:$crS, target:$block),
-                  "ble $crS, $block">;
+                  "ble $crS, $block", BrB>;
   def BEQ : BForm<16, 0, 0, 12, 2, (ops CRRC:$crS, target:$block),
-                  "beq $crS, $block">;
+                  "beq $crS, $block", BrB>;
   def BGE : BForm<16, 0, 0, 4,  0, (ops CRRC:$crS, target:$block),
-                  "bge $crS, $block">;
+                  "bge $crS, $block", BrB>;
   def BGT : BForm<16, 0, 0, 12, 1, (ops CRRC:$crS, target:$block),
-                  "bgt $crS, $block">;
+                  "bgt $crS, $block", BrB>;
   def BNE : BForm<16, 0, 0, 4,  2, (ops CRRC:$crS, target:$block),
-                  "bne $crS, $block">;
+                  "bne $crS, $block", BrB>;
+  def BUN : BForm<16, 0, 0, 12, 3, (ops CRRC:$crS, target:$block),
+                  "bun $crS, $block", BrB>;
+  def BNU : BForm<16, 0, 0, 4,  3, (ops CRRC:$crS, target:$block),
+                  "bnu $crS, $block", BrB>;
 }
 
 let isCall = 1, 
@@ -177,9 +217,10 @@
           LR,CTR,
           CR0,CR1,CR5,CR6,CR7] in {
   // Convenient aliases for call instructions
-  def CALLpcrel : IForm<18, 0, 1, (ops target:$func, variable_ops), "bl $func">;
+  def CALLpcrel : IForm<18, 0, 1, (ops target:$func, variable_ops),
+                        "bl $func", BrB>;
   def CALLindirect : XLForm_2_ext<19, 528, 20, 0, 1,
-                                  (ops variable_ops), "bctrl">;
+                                  (ops variable_ops), "bctrl", BrB>;
 }
 
 // D-Form instructions.  Most instructions that perform an operation on a
@@ -187,114 +228,114 @@
 //
 let isLoad = 1 in {
 def LBZ : DForm_1<34, (ops GPRC:$rD, symbolLo:$disp, GPRC:$rA),
-                  "lbz $rD, $disp($rA)">;
+                  "lbz $rD, $disp($rA)", LdStGeneral>;
 def LHA : DForm_1<42, (ops GPRC:$rD, symbolLo:$disp, GPRC:$rA),
-                  "lha $rD, $disp($rA)">;
+                  "lha $rD, $disp($rA)", LdStLHA>;
 def LHZ : DForm_1<40, (ops GPRC:$rD, symbolLo:$disp, GPRC:$rA),
-                  "lhz $rD, $disp($rA)">;
+                  "lhz $rD, $disp($rA)", LdStGeneral>;
 def LMW : DForm_1<46, (ops GPRC:$rD, s16imm:$disp, GPRC:$rA),
-                  "lmw $rD, $disp($rA)">;
+                  "lmw $rD, $disp($rA)", LdStLMW>;
 def LWZ : DForm_1<32, (ops GPRC:$rD, symbolLo:$disp, GPRC:$rA),
-                  "lwz $rD, $disp($rA)">;
+                  "lwz $rD, $disp($rA)", LdStGeneral>;
 def LWZU : DForm_1<35, (ops GPRC:$rD, s16imm:$disp, GPRC:$rA),
-                   "lwzu $rD, $disp($rA)">;
+                   "lwzu $rD, $disp($rA)", LdStGeneral>;
 }
 def ADDI   : DForm_2<14, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm),
-                     "addi $rD, $rA, $imm",
+                     "addi $rD, $rA, $imm", IntGeneral,
                      [(set GPRC:$rD, (add GPRC:$rA, immSExt16:$imm))]>;
 def ADDIC  : DForm_2<12, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm),
-                     "addic $rD, $rA, $imm",
+                     "addic $rD, $rA, $imm", IntGeneral,
                      []>;
 def ADDICo : DForm_2<13, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm),
-                     "addic. $rD, $rA, $imm",
+                     "addic. $rD, $rA, $imm", IntGeneral,
                      []>;
 def ADDIS  : DForm_2<15, (ops GPRC:$rD, GPRC:$rA, symbolHi:$imm),
-                     "addis $rD, $rA, $imm",
+                     "addis $rD, $rA, $imm", IntGeneral,
                      [(set GPRC:$rD, (add GPRC:$rA, imm16Shifted:$imm))]>;
 def LA     : DForm_2<14, (ops GPRC:$rD, GPRC:$rA, symbolLo:$sym),
-                     "la $rD, $sym($rA)",
+                     "la $rD, $sym($rA)", IntGeneral,
                      []>;
 def MULLI  : DForm_2< 7, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm),
-                     "mulli $rD, $rA, $imm",
+                     "mulli $rD, $rA, $imm", IntMulLI,
                      [(set GPRC:$rD, (mul GPRC:$rA, immSExt16:$imm))]>;
 def SUBFIC : DForm_2< 8, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm),
-                     "subfic $rD, $rA, $imm",
+                     "subfic $rD, $rA, $imm", IntGeneral,
                      [(set GPRC:$rD, (sub immSExt16:$imm, GPRC:$rA))]>;
 def LI  : DForm_2_r0<14, (ops GPRC:$rD, s16imm:$imm),
-                     "li $rD, $imm",
+                     "li $rD, $imm", IntGeneral,
                      [(set GPRC:$rD, immSExt16:$imm)]>;
 def LIS : DForm_2_r0<15, (ops GPRC:$rD, symbolHi:$imm),
-                     "lis $rD, $imm",
+                     "lis $rD, $imm", IntGeneral,
                      [(set GPRC:$rD, imm16Shifted:$imm)]>;
 let isStore = 1 in {
 def STMW : DForm_3<47, (ops GPRC:$rS, s16imm:$disp, GPRC:$rA),
-                   "stmw $rS, $disp($rA)">;
+                   "stmw $rS, $disp($rA)", LdStLMW>;
 def STB  : DForm_3<38, (ops GPRC:$rS, symbolLo:$disp, GPRC:$rA),
-                   "stb $rS, $disp($rA)">;
+                   "stb $rS, $disp($rA)", LdStGeneral>;
 def STH  : DForm_3<44, (ops GPRC:$rS, symbolLo:$disp, GPRC:$rA),
-                   "sth $rS, $disp($rA)">;
+                   "sth $rS, $disp($rA)", LdStGeneral>;
 def STW  : DForm_3<36, (ops GPRC:$rS, symbolLo:$disp, GPRC:$rA),
-                   "stw $rS, $disp($rA)">;
+                   "stw $rS, $disp($rA)", LdStGeneral>;
 def STWU : DForm_3<37, (ops GPRC:$rS, s16imm:$disp, GPRC:$rA),
-                   "stwu $rS, $disp($rA)">;
+                   "stwu $rS, $disp($rA)", LdStGeneral>;
 }
 def ANDIo : DForm_4<28, (ops GPRC:$dst, GPRC:$src1, u16imm:$src2),
-                    "andi. $dst, $src1, $src2",
+                    "andi. $dst, $src1, $src2", IntGeneral,
                     []>, isDOT;
 def ANDISo : DForm_4<29, (ops GPRC:$dst, GPRC:$src1, u16imm:$src2),
-                    "andis. $dst, $src1, $src2",
+                    "andis. $dst, $src1, $src2", IntGeneral,
                     []>, isDOT;
 def ORI   : DForm_4<24, (ops GPRC:$dst, GPRC:$src1, u16imm:$src2),
-                    "ori $dst, $src1, $src2",
+                    "ori $dst, $src1, $src2", IntGeneral,
                     [(set GPRC:$dst, (or GPRC:$src1, immZExt16:$src2))]>;
 def ORIS  : DForm_4<25, (ops GPRC:$dst, GPRC:$src1, u16imm:$src2),
-                    "oris $dst, $src1, $src2",
+                    "oris $dst, $src1, $src2", IntGeneral,
                     [(set GPRC:$dst, (or GPRC:$src1, imm16Shifted:$src2))]>;
 def XORI  : DForm_4<26, (ops GPRC:$dst, GPRC:$src1, u16imm:$src2),
-                    "xori $dst, $src1, $src2",
+                    "xori $dst, $src1, $src2", IntGeneral,
                     [(set GPRC:$dst, (xor GPRC:$src1, immZExt16:$src2))]>;
 def XORIS : DForm_4<27, (ops GPRC:$dst, GPRC:$src1, u16imm:$src2),
-                    "xoris $dst, $src1, $src2",
+                    "xoris $dst, $src1, $src2", IntGeneral,
                     [(set GPRC:$dst, (xor GPRC:$src1, imm16Shifted:$src2))]>;
-def NOP   : DForm_4_zero<24, (ops), "nop">;
+def NOP   : DForm_4_zero<24, (ops), "nop", IntGeneral>;
 def CMPI  : DForm_5<11, (ops CRRC:$crD, i1imm:$L, GPRC:$rA, s16imm:$imm),
-                    "cmpi $crD, $L, $rA, $imm">;
+                    "cmpi $crD, $L, $rA, $imm", IntCompare>;
 def CMPWI : DForm_5_ext<11, (ops CRRC:$crD, GPRC:$rA, s16imm:$imm),
-                        "cmpwi $crD, $rA, $imm">;
+                        "cmpwi $crD, $rA, $imm", IntCompare>;
 def CMPDI : DForm_5_ext<11, (ops CRRC:$crD, GPRC:$rA, s16imm:$imm),
-                        "cmpdi $crD, $rA, $imm">, isPPC64;
+                        "cmpdi $crD, $rA, $imm", IntCompare>, isPPC64;
 def CMPLI  : DForm_6<10, (ops CRRC:$dst, i1imm:$size, GPRC:$src1, u16imm:$src2),
-                     "cmpli $dst, $size, $src1, $src2">;
+                     "cmpli $dst, $size, $src1, $src2", IntCompare>;
 def CMPLWI : DForm_6_ext<10, (ops CRRC:$dst, GPRC:$src1, u16imm:$src2),
-                         "cmplwi $dst, $src1, $src2">;
+                         "cmplwi $dst, $src1, $src2", IntCompare>;
 def CMPLDI : DForm_6_ext<10, (ops CRRC:$dst, GPRC:$src1, u16imm:$src2),
-                         "cmpldi $dst, $src1, $src2">, isPPC64;
+                         "cmpldi $dst, $src1, $src2", IntCompare>, isPPC64;
 let isLoad = 1 in {
 def LFS : DForm_8<48, (ops F4RC:$rD, symbolLo:$disp, GPRC:$rA),
-                  "lfs $rD, $disp($rA)">;
+                  "lfs $rD, $disp($rA)", LdStLFDU>;
 def LFD : DForm_8<50, (ops F8RC:$rD, symbolLo:$disp, GPRC:$rA),
-                  "lfd $rD, $disp($rA)">;
+                  "lfd $rD, $disp($rA)", LdStLFD>;
 }
 let isStore = 1 in {
 def STFS : DForm_9<52, (ops F4RC:$rS, symbolLo:$disp, GPRC:$rA),
-                   "stfs $rS, $disp($rA)">;
+                   "stfs $rS, $disp($rA)", LdStUX>;
 def STFD : DForm_9<54, (ops F8RC:$rS, symbolLo:$disp, GPRC:$rA),
-                   "stfd $rS, $disp($rA)">;
+                   "stfd $rS, $disp($rA)", LdStUX>;
 }
 
 // DS-Form instructions.  Load/Store instructions available in PPC-64
 //
 let isLoad = 1 in {
 def LWA  : DSForm_1<58, 2, (ops GPRC:$rT, s16immX4:$DS, GPRC:$rA),
-                    "lwa $rT, $DS($rA)">, isPPC64;
+                    "lwa $rT, $DS($rA)", LdStLWA>, isPPC64;
 def LD   : DSForm_2<58, 0, (ops GPRC:$rT, s16immX4:$DS, GPRC:$rA),
-                    "ld $rT, $DS($rA)">, isPPC64;
+                    "ld $rT, $DS($rA)", LdStLD>, isPPC64;
 }
 let isStore = 1 in {
 def STD  : DSForm_2<62, 0, (ops GPRC:$rT, s16immX4:$DS, GPRC:$rA),
-                    "std $rT, $DS($rA)">, isPPC64;
+                    "std $rT, $DS($rA)", LdStSTD>, isPPC64;
 def STDU : DSForm_2<62, 1, (ops GPRC:$rT, s16immX4:$DS, GPRC:$rA),
-                    "stdu $rT, $DS($rA)">, isPPC64;
+                    "stdu $rT, $DS($rA)", LdStSTD>, isPPC64;
 }
 
 // X-Form instructions.  Most instructions that perform an operation on a
@@ -302,264 +343,276 @@
 //
 let isLoad = 1 in {
 def LBZX : XForm_1<31,  87, (ops GPRC:$dst, GPRC:$base, GPRC:$index),
-                   "lbzx $dst, $base, $index">;
+                   "lbzx $dst, $base, $index", LdStGeneral>;
 def LHAX : XForm_1<31, 343, (ops GPRC:$dst, GPRC:$base, GPRC:$index),
-                   "lhax $dst, $base, $index">;
+                   "lhax $dst, $base, $index", LdStLHA>;
 def LHZX : XForm_1<31, 279, (ops GPRC:$dst, GPRC:$base, GPRC:$index),
-                   "lhzx $dst, $base, $index">;
+                   "lhzx $dst, $base, $index", LdStGeneral>;
 def LWAX : XForm_1<31, 341, (ops GPRC:$dst, GPRC:$base, GPRC:$index),
-                   "lwax $dst, $base, $index">, isPPC64;
+                   "lwax $dst, $base, $index", LdStLHA>, isPPC64;
 def LWZX : XForm_1<31,  23, (ops GPRC:$dst, GPRC:$base, GPRC:$index),
-                   "lwzx $dst, $base, $index">;
+                   "lwzx $dst, $base, $index", LdStGeneral>;
 def LDX  : XForm_1<31,  21, (ops GPRC:$dst, GPRC:$base, GPRC:$index),
-                   "ldx $dst, $base, $index">, isPPC64;
+                   "ldx $dst, $base, $index", LdStLD>, isPPC64;
 }
 def NAND : XForm_6<31, 476, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
-                   "nand $rA, $rS, $rB",
+                   "nand $rA, $rS, $rB", IntGeneral,
                    [(set GPRC:$rA, (not (and GPRC:$rS, GPRC:$rB)))]>;
 def AND  : XForm_6<31,  28, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
-                   "and $rA, $rS, $rB",
+                   "and $rA, $rS, $rB", IntGeneral,
                    [(set GPRC:$rA, (and GPRC:$rS, GPRC:$rB))]>;
 def ANDo : XForm_6<31,  28, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
-                   "and. $rA, $rS, $rB",
+                   "and. $rA, $rS, $rB", IntGeneral,
                    []>, isDOT;
 def ANDC : XForm_6<31,  60, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
-                   "andc $rA, $rS, $rB",
+                   "andc $rA, $rS, $rB", IntGeneral,
                    [(set GPRC:$rA, (and GPRC:$rS, (not GPRC:$rB)))]>;
 def OR4  : XForm_6<31, 444, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
-                   "or $rA, $rS, $rB",
+                   "or $rA, $rS, $rB", IntGeneral,
                    [(set GPRC:$rA, (or GPRC:$rS, GPRC:$rB))]>;
 def OR8  : XForm_6<31, 444, (ops G8RC:$rA, G8RC:$rS, G8RC:$rB),
-                   "or $rA, $rS, $rB",
+                   "or $rA, $rS, $rB", IntGeneral,
                    [(set G8RC:$rA, (or G8RC:$rS, G8RC:$rB))]>;
+def OR4To8  : XForm_6<31, 444, (ops G8RC:$rA, GPRC:$rS, GPRC:$rB),
+                   "or $rA, $rS, $rB", IntGeneral,
+                   []>;
+def OR8To4  : XForm_6<31, 444, (ops GPRC:$rA, G8RC:$rS, G8RC:$rB),
+                   "or $rA, $rS, $rB", IntGeneral,
+                   []>;
 def NOR  : XForm_6<31, 124, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
-                   "nor $rA, $rS, $rB",
+                   "nor $rA, $rS, $rB", IntGeneral,
                    [(set GPRC:$rA, (not (or GPRC:$rS, GPRC:$rB)))]>;
 def ORo  : XForm_6<31, 444, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
-                   "or. $rA, $rS, $rB",
+                   "or. $rA, $rS, $rB", IntGeneral,
                    []>, isDOT;
 def ORC  : XForm_6<31, 412, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
-                   "orc $rA, $rS, $rB",
+                   "orc $rA, $rS, $rB", IntGeneral,
                    [(set GPRC:$rA, (or GPRC:$rS, (not GPRC:$rB)))]>;
 def EQV  : XForm_6<31, 284, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
-                   "eqv $rA, $rS, $rB",
+                   "eqv $rA, $rS, $rB", IntGeneral,
                    [(set GPRC:$rA, (not (xor GPRC:$rS, GPRC:$rB)))]>;
 def XOR  : XForm_6<31, 316, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
-                   "xor $rA, $rS, $rB",
+                   "xor $rA, $rS, $rB", IntGeneral,
                    [(set GPRC:$rA, (xor GPRC:$rS, GPRC:$rB))]>;                   
-def SLD  : XForm_6<31,  27, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
-                   "sld $rA, $rS, $rB",
-                   []>, isPPC64;
+def SLD  : XForm_6<31,  27, (ops G8RC:$rA, G8RC:$rS, G8RC:$rB),
+                   "sld $rA, $rS, $rB", IntRotateD,
+                   [(set G8RC:$rA, (shl G8RC:$rS, G8RC:$rB))]>, isPPC64;
 def SLW  : XForm_6<31,  24, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
-                   "slw $rA, $rS, $rB",
+                   "slw $rA, $rS, $rB", IntGeneral,
                    [(set GPRC:$rA, (shl GPRC:$rS, GPRC:$rB))]>;
-def SRD  : XForm_6<31, 539, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
-                   "srd $rA, $rS, $rB",
-                   []>, isPPC64;
+def SRD  : XForm_6<31, 539, (ops G8RC:$rA, G8RC:$rS, G8RC:$rB),
+                   "srd $rA, $rS, $rB", IntRotateD,
+                   [(set G8RC:$rA, (srl G8RC:$rS, G8RC:$rB))]>, isPPC64;
 def SRW  : XForm_6<31, 536, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
-                   "srw $rA, $rS, $rB",
+                   "srw $rA, $rS, $rB", IntGeneral,
                    [(set GPRC:$rA, (srl GPRC:$rS, GPRC:$rB))]>;
-def SRAD : XForm_6<31, 794, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
-                   "srad $rA, $rS, $rB",
-                   []>, isPPC64;
+def SRAD : XForm_6<31, 794, (ops G8RC:$rA, G8RC:$rS, G8RC:$rB),
+                   "srad $rA, $rS, $rB", IntRotateD,
+                   [(set G8RC:$rA, (sra G8RC:$rS, G8RC:$rB))]>, isPPC64;
 def SRAW : XForm_6<31, 792, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
-                   "sraw $rA, $rS, $rB",
+                   "sraw $rA, $rS, $rB", IntShift,
                    [(set GPRC:$rA, (sra GPRC:$rS, GPRC:$rB))]>;
 let isStore = 1 in {
 def STBX  : XForm_8<31, 215, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB),
-                   "stbx $rS, $rA, $rB">;
+                   "stbx $rS, $rA, $rB", LdStGeneral>;
 def STHX  : XForm_8<31, 407, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB),
-                   "sthx $rS, $rA, $rB">;
+                   "sthx $rS, $rA, $rB", LdStGeneral>;
 def STWX  : XForm_8<31, 151, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB),
-                   "stwx $rS, $rA, $rB">;
+                   "stwx $rS, $rA, $rB", LdStGeneral>;
 def STWUX : XForm_8<31, 183, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB),
-                   "stwux $rS, $rA, $rB">;
+                   "stwux $rS, $rA, $rB", LdStGeneral>;
 def STDX  : XForm_8<31, 149, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB),
-                   "stdx $rS, $rA, $rB">, isPPC64;
+                   "stdx $rS, $rA, $rB", LdStSTD>, isPPC64;
 def STDUX : XForm_8<31, 181, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB),
-                   "stdux $rS, $rA, $rB">, isPPC64;
+                   "stdux $rS, $rA, $rB", LdStSTD>, isPPC64;
 }
 def SRAWI : XForm_10<31, 824, (ops GPRC:$rA, GPRC:$rS, u5imm:$SH), 
-                     "srawi $rA, $rS, $SH",
+                     "srawi $rA, $rS, $SH", IntShift,
                      [(set GPRC:$rA, (sra GPRC:$rS, imm:$SH))]>;
 def CNTLZW : XForm_11<31,  26, (ops GPRC:$rA, GPRC:$rS),
-                      "cntlzw $rA, $rS",
+                      "cntlzw $rA, $rS", IntGeneral,
                       [(set GPRC:$rA, (ctlz GPRC:$rS))]>;
 def EXTSB  : XForm_11<31, 954, (ops GPRC:$rA, GPRC:$rS),
-                      "extsb $rA, $rS",
+                      "extsb $rA, $rS", IntGeneral,
                       [(set GPRC:$rA, (sext_inreg GPRC:$rS, i8))]>;
 def EXTSH  : XForm_11<31, 922, (ops GPRC:$rA, GPRC:$rS),
-                      "extsh $rA, $rS",
+                      "extsh $rA, $rS", IntGeneral,
                       [(set GPRC:$rA, (sext_inreg GPRC:$rS, i16))]>;
 def EXTSW  : XForm_11<31, 986, (ops GPRC:$rA, GPRC:$rS),
-                      "extsw $rA, $rS",
+                      "extsw $rA, $rS", IntRotateD,
                       []>, isPPC64;
 def CMP    : XForm_16<31, 0, (ops CRRC:$crD, i1imm:$long, GPRC:$rA, GPRC:$rB),
-                      "cmp $crD, $long, $rA, $rB">;
+                      "cmp $crD, $long, $rA, $rB", IntCompare>;
 def CMPL   : XForm_16<31, 32, (ops CRRC:$crD, i1imm:$long, GPRC:$rA, GPRC:$rB),
-                      "cmpl $crD, $long, $rA, $rB">;
+                      "cmpl $crD, $long, $rA, $rB", IntCompare>;
 def CMPW   : XForm_16_ext<31, 0, (ops CRRC:$crD, GPRC:$rA, GPRC:$rB),
-                          "cmpw $crD, $rA, $rB">;
+                          "cmpw $crD, $rA, $rB", IntCompare>;
 def CMPD   : XForm_16_ext<31, 0, (ops CRRC:$crD, GPRC:$rA, GPRC:$rB),
-                          "cmpd $crD, $rA, $rB">, isPPC64;
+                          "cmpd $crD, $rA, $rB", IntCompare>, isPPC64;
 def CMPLW  : XForm_16_ext<31, 32, (ops CRRC:$crD, GPRC:$rA, GPRC:$rB),
-                          "cmplw $crD, $rA, $rB">;
+                          "cmplw $crD, $rA, $rB", IntCompare>;
 def CMPLD  : XForm_16_ext<31, 32, (ops CRRC:$crD, GPRC:$rA, GPRC:$rB),
-                          "cmpld $crD, $rA, $rB">, isPPC64;
+                          "cmpld $crD, $rA, $rB", IntCompare>, isPPC64;
 //def FCMPO  : XForm_17<63, 32, (ops CRRC:$crD, FPRC:$fA, FPRC:$fB),
-//                      "fcmpo $crD, $fA, $fB">;
+//                      "fcmpo $crD, $fA, $fB", FPCompare>;
 def FCMPUS : XForm_17<63, 0, (ops CRRC:$crD, F4RC:$fA, F4RC:$fB),
-                      "fcmpu $crD, $fA, $fB">;
+                      "fcmpu $crD, $fA, $fB", FPCompare>;
 def FCMPUD : XForm_17<63, 0, (ops CRRC:$crD, F8RC:$fA, F8RC:$fB),
-                      "fcmpu $crD, $fA, $fB">;
+                      "fcmpu $crD, $fA, $fB", FPCompare>;
 
 let isLoad = 1 in {
 def LFSX   : XForm_25<31, 535, (ops F4RC:$dst, GPRC:$base, GPRC:$index),
-                      "lfsx $dst, $base, $index">;
+                      "lfsx $dst, $base, $index", LdStLFDU>;
 def LFDX   : XForm_25<31, 599, (ops F8RC:$dst, GPRC:$base, GPRC:$index),
-                      "lfdx $dst, $base, $index">;
+                      "lfdx $dst, $base, $index", LdStLFDU>;
 }
 def FCFID  : XForm_26<63, 846, (ops F8RC:$frD, F8RC:$frB),
-                      "fcfid $frD, $frB",
-                      []>, isPPC64;
+                      "fcfid $frD, $frB", FPGeneral,
+                      [(set F8RC:$frD, (PPCfcfid F8RC:$frB))]>, isPPC64;
 def FCTIDZ : XForm_26<63, 815, (ops F8RC:$frD, F8RC:$frB),
-                      "fctidz $frD, $frB",
-                      []>, isPPC64;
+                      "fctidz $frD, $frB", FPGeneral,
+                      [(set F8RC:$frD, (PPCfctidz F8RC:$frB))]>, isPPC64;
 def FCTIWZ : XForm_26<63, 15, (ops F8RC:$frD, F8RC:$frB),
-                      "fctiwz $frD, $frB",
-                      []>;
+                      "fctiwz $frD, $frB", FPGeneral,
+                      [(set F8RC:$frD, (PPCfctiwz F8RC:$frB))]>;
 def FRSP   : XForm_26<63, 12, (ops F4RC:$frD, F8RC:$frB),
-                      "frsp $frD, $frB",
+                      "frsp $frD, $frB", FPGeneral,
                       [(set F4RC:$frD, (fround F8RC:$frB))]>;
 def FSQRT  : XForm_26<63, 22, (ops F8RC:$frD, F8RC:$frB),
-                      "fsqrt $frD, $frB",
+                      "fsqrt $frD, $frB", FPSqrt,
                       [(set F8RC:$frD, (fsqrt F8RC:$frB))]>;
 def FSQRTS : XForm_26<59, 22, (ops F4RC:$frD, F4RC:$frB),
-                      "fsqrts $frD, $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.
 def FMRS   : XForm_26<63, 72, (ops F4RC:$frD, F4RC:$frB),
-                      "fmr $frD, $frB",
+                      "fmr $frD, $frB", FPGeneral,
                       []>;  // (set F4RC:$frD, F4RC:$frB)
 def FMRD   : XForm_26<63, 72, (ops F8RC:$frD, F8RC:$frB),
-                      "fmr $frD, $frB",
+                      "fmr $frD, $frB", FPGeneral,
                       []>;  // (set F8RC:$frD, F8RC:$frB)
 def FMRSD  : XForm_26<63, 72, (ops F8RC:$frD, F4RC:$frB),
-                      "fmr $frD, $frB",
+                      "fmr $frD, $frB", FPGeneral,
                       [(set F8RC:$frD, (fextend F4RC:$frB))]>;
 
 // 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",
+                      "fabs $frD, $frB", FPGeneral,
                       [(set F4RC:$frD, (fabs F4RC:$frB))]>;
 def FABSD  : XForm_26<63, 264, (ops F8RC:$frD, F8RC:$frB),
-                      "fabs $frD, $frB",
+                      "fabs $frD, $frB", FPGeneral,
                       [(set F8RC:$frD, (fabs F8RC:$frB))]>;
 def FNABSS : XForm_26<63, 136, (ops F4RC:$frD, F4RC:$frB),
-                      "fnabs $frD, $frB",
+                      "fnabs $frD, $frB", FPGeneral,
                       [(set F4RC:$frD, (fneg (fabs F4RC:$frB)))]>;
 def FNABSD : XForm_26<63, 136, (ops F8RC:$frD, F8RC:$frB),
-                      "fnabs $frD, $frB",
+                      "fnabs $frD, $frB", FPGeneral,
                       [(set F8RC:$frD, (fneg (fabs F8RC:$frB)))]>;
 def FNEGS  : XForm_26<63, 40, (ops F4RC:$frD, F4RC:$frB),
-                      "fneg $frD, $frB",
+                      "fneg $frD, $frB", FPGeneral,
                       [(set F4RC:$frD, (fneg F4RC:$frB))]>;
 def FNEGD  : XForm_26<63, 40, (ops F8RC:$frD, F8RC:$frB),
-                      "fneg $frD, $frB",
+                      "fneg $frD, $frB", FPGeneral,
                       [(set F8RC:$frD, (fneg F8RC:$frB))]>;
                       
                       
 let isStore = 1 in {
 def STFSX : XForm_28<31, 663, (ops F4RC:$frS, GPRC:$rA, GPRC:$rB),
-                     "stfsx $frS, $rA, $rB">;
+                     "stfsx $frS, $rA, $rB", LdStUX>;
 def STFDX : XForm_28<31, 727, (ops F8RC:$frS, GPRC:$rA, GPRC:$rB),
-                     "stfdx $frS, $rA, $rB">;
+                     "stfdx $frS, $rA, $rB", LdStUX>;
 }
 
 // XL-Form instructions.  condition register logical ops.
 //
 def MCRF   : XLForm_3<19, 0, (ops CRRC:$BF, CRRC:$BFA),
-                      "mcrf $BF, $BFA">;
+                      "mcrf $BF, $BFA", BrMCR>;
 
 // 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, 288, (ops GPRC:$rT), "mfctr $rT">;
-def MFLR  : XFXForm_1_ext<31, 339, 256, (ops GPRC:$rT), "mflr $rT">;
-def MFCR  : XFXForm_3<31, 19, (ops GPRC:$rT), "mfcr $rT">;
+def MFCTR : XFXForm_1_ext<31, 339, 288, (ops GPRC:$rT), "mfctr $rT", SprMFSPR>;
+def MFLR  : XFXForm_1_ext<31, 339, 256, (ops GPRC:$rT), "mflr $rT", SprMFSPR>;
+def MFCR  : XFXForm_3<31, 19, (ops GPRC:$rT), "mfcr $rT", SprMFCR>;
 def MTCRF : XFXForm_5<31, 144, (ops crbitm:$FXM, GPRC:$rS),
-                      "mtcrf $FXM, $rS">;
+                      "mtcrf $FXM, $rS", BrMCRX>;
 def MFOCRF : XFXForm_5a<31, 19, (ops GPRC:$rT, crbitm:$FXM),
-                        "mfcr $rT, $FXM">;
-def MTCTR : XFXForm_7_ext<31, 467, 288, (ops GPRC:$rS), "mtctr $rS">;
-def MTLR  : XFXForm_7_ext<31, 467, 256, (ops GPRC:$rS), "mtlr $rS">;
+                        "mfcr $rT, $FXM", SprMFCR>;
+def MTCTR : XFXForm_7_ext<31, 467, 288, (ops GPRC:$rS), "mtctr $rS", SprMTSPR>;
+def MTLR  : XFXForm_7_ext<31, 467, 256, (ops GPRC:$rS), "mtlr $rS", SprMTSPR>;
 
 // XS-Form instructions.  Just 'sradi'
 //
 def SRADI  : XSForm_1<31, 413, (ops GPRC:$rA, GPRC:$rS, u6imm:$SH),
-                      "sradi $rA, $rS, $SH">, isPPC64;
+                      "sradi $rA, $rS, $SH", IntRotateD>, isPPC64;
 
 // XO-Form instructions.  Arithmetic instructions that can set overflow bit
 //
 def ADD4  : XOForm_1<31, 266, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB),
-                     "add $rT, $rA, $rB",
+                     "add $rT, $rA, $rB", IntGeneral,
                      [(set GPRC:$rT, (add GPRC:$rA, GPRC:$rB))]>;
 def ADD8  : XOForm_1<31, 266, 0, (ops G8RC:$rT, G8RC:$rA, G8RC:$rB),
-                     "add $rT, $rA, $rB",
+                     "add $rT, $rA, $rB", IntGeneral,
                      [(set G8RC:$rT, (add G8RC:$rA, G8RC:$rB))]>;
 def ADDC  : XOForm_1<31, 10, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB),
-                     "addc $rT, $rA, $rB",
+                     "addc $rT, $rA, $rB", IntGeneral,
                      []>;
 def ADDE  : XOForm_1<31, 138, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB),
-                     "adde $rT, $rA, $rB",
+                     "adde $rT, $rA, $rB", IntGeneral,
                      []>;
-def DIVD  : XOForm_1<31, 489, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB),
-                     "divd $rT, $rA, $rB",
-                     []>, isPPC64;
-def DIVDU : XOForm_1<31, 457, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB),
-                     "divdu $rT, $rA, $rB",
-                     []>, isPPC64;
+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;
+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;
 def DIVW  : XOForm_1<31, 491, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB),
-                     "divw $rT, $rA, $rB",
+                     "divw $rT, $rA, $rB", IntDivW,
                      [(set GPRC:$rT, (sdiv GPRC:$rA, GPRC:$rB))]>;
 def DIVWU : XOForm_1<31, 459, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB),
-                     "divwu $rT, $rA, $rB",
+                     "divwu $rT, $rA, $rB", IntDivW,
                      [(set GPRC:$rT, (udiv GPRC:$rA, GPRC:$rB))]>;
+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))]>;
+def MULHDU : XOForm_1<31, 9, 0, (ops G8RC:$rT, G8RC:$rA, G8RC:$rB),
+                     "mulhdu $rT, $rA, $rB", IntMulHWU,
+                     [(set G8RC:$rT, (mulhu G8RC:$rA, G8RC:$rB))]>;
 def MULHW : XOForm_1<31, 75, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB),
-                     "mulhw $rT, $rA, $rB",
+                     "mulhw $rT, $rA, $rB", IntMulHW,
                      [(set GPRC:$rT, (mulhs GPRC:$rA, GPRC:$rB))]>;
 def MULHWU : XOForm_1<31, 11, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB),
-                     "mulhwu $rT, $rA, $rB",
+                     "mulhwu $rT, $rA, $rB", IntMulHWU,
                      [(set GPRC:$rT, (mulhu GPRC:$rA, GPRC:$rB))]>;
-def MULLD : XOForm_1<31, 233, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB),
-                     "mulld $rT, $rA, $rB",
-                     []>, isPPC64;
+def MULLD : XOForm_1<31, 233, 0, (ops G8RC:$rT, G8RC:$rA, G8RC:$rB),
+                     "mulld $rT, $rA, $rB", IntMulHD,
+                     [(set G8RC:$rT, (mul G8RC:$rA, G8RC:$rB))]>, isPPC64;
 def MULLW : XOForm_1<31, 235, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB),
-                     "mullw $rT, $rA, $rB",
+                     "mullw $rT, $rA, $rB", IntMulHW,
                      [(set GPRC:$rT, (mul GPRC:$rA, GPRC:$rB))]>;
 def SUBF  : XOForm_1<31, 40, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB),
-                     "subf $rT, $rA, $rB",
+                     "subf $rT, $rA, $rB", IntGeneral,
                      [(set GPRC:$rT, (sub GPRC:$rB, GPRC:$rA))]>;
 def SUBFC : XOForm_1<31, 8, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB),
-                     "subfc $rT, $rA, $rB",
+                     "subfc $rT, $rA, $rB", IntGeneral,
                      []>;
 def SUBFE : XOForm_1<31, 136, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB),
-                     "subfe $rT, $rA, $rB",
+                     "subfe $rT, $rA, $rB", IntGeneral,
                      []>;
 def ADDME  : XOForm_3<31, 234, 0, (ops GPRC:$rT, GPRC:$rA),
-                      "addme $rT, $rA",
+                      "addme $rT, $rA", IntGeneral,
                       []>;
 def ADDZE  : XOForm_3<31, 202, 0, (ops GPRC:$rT, GPRC:$rA),
-                      "addze $rT, $rA",
+                      "addze $rT, $rA", IntGeneral,
                       []>;
 def NEG    : XOForm_3<31, 104, 0, (ops GPRC:$rT, GPRC:$rA),
-                      "neg $rT, $rA",
+                      "neg $rT, $rA", IntGeneral,
                       [(set GPRC:$rT, (ineg GPRC:$rA))]>;
 def SUBFZE : XOForm_3<31, 200, 0, (ops GPRC:$rT, GPRC:$rA),
-                      "subfze $rT, $rA",
+                      "subfze $rT, $rA", IntGeneral,
                       []>;
 
 // A-Form instructions.  Most of the instructions executed in the FPU are of
@@ -567,42 +620,42 @@
 //
 def FMADD : AForm_1<63, 29, 
                     (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB),
-                    "fmadd $FRT, $FRA, $FRC, $FRB",
+                    "fmadd $FRT, $FRA, $FRC, $FRB", FPFused,
                     [(set F8RC:$FRT, (fadd (fmul F8RC:$FRA, F8RC:$FRC),
                                            F8RC:$FRB))]>;
 def FMADDS : AForm_1<59, 29,
                     (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB),
-                    "fmadds $FRT, $FRA, $FRC, $FRB",
+                    "fmadds $FRT, $FRA, $FRC, $FRB", FPGeneral,
                     [(set F4RC:$FRT, (fadd (fmul F4RC:$FRA, F4RC:$FRC),
                                            F4RC:$FRB))]>;
 def FMSUB : AForm_1<63, 28,
                     (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB),
-                    "fmsub $FRT, $FRA, $FRC, $FRB",
+                    "fmsub $FRT, $FRA, $FRC, $FRB", FPFused,
                     [(set F8RC:$FRT, (fsub (fmul F8RC:$FRA, F8RC:$FRC),
                                            F8RC:$FRB))]>;
 def FMSUBS : AForm_1<59, 28,
                     (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB),
-                    "fmsubs $FRT, $FRA, $FRC, $FRB",
+                    "fmsubs $FRT, $FRA, $FRC, $FRB", FPGeneral,
                     [(set F4RC:$FRT, (fsub (fmul F4RC:$FRA, F4RC:$FRC),
                                            F4RC:$FRB))]>;
 def FNMADD : AForm_1<63, 31,
                     (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB),
-                    "fnmadd $FRT, $FRA, $FRC, $FRB",
+                    "fnmadd $FRT, $FRA, $FRC, $FRB", FPFused,
                     [(set F8RC:$FRT, (fneg (fadd (fmul F8RC:$FRA, F8RC:$FRC),
                                                  F8RC:$FRB)))]>;
 def FNMADDS : AForm_1<59, 31,
                     (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB),
-                    "fnmadds $FRT, $FRA, $FRC, $FRB",
+                    "fnmadds $FRT, $FRA, $FRC, $FRB", FPGeneral,
                     [(set F4RC:$FRT, (fneg (fadd (fmul F4RC:$FRA, F4RC:$FRC),
                                                  F4RC:$FRB)))]>;
 def FNMSUB : AForm_1<63, 30,
                     (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB),
-                    "fnmsub $FRT, $FRA, $FRC, $FRB",
+                    "fnmsub $FRT, $FRA, $FRC, $FRB", FPFused,
                     [(set F8RC:$FRT, (fneg (fsub (fmul F8RC:$FRA, F8RC:$FRC),
                                                  F8RC:$FRB)))]>;
 def FNMSUBS : AForm_1<59, 30,
                     (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB),
-                    "fnmsubs $FRT, $FRA, $FRC, $FRB",
+                    "fnmsubs $FRT, $FRA, $FRC, $FRB", FPGeneral,
                     [(set F4RC:$FRT, (fneg (fsub (fmul F4RC:$FRA, F4RC:$FRC),
                                                  F4RC:$FRB)))]>;
 // FSEL is artificially split into 4 and 8-byte forms for the result.  To avoid
@@ -611,43 +664,43 @@
 // and 4/8 byte forms for the result and operand type..
 def FSELD : AForm_1<63, 23,
                     (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB),
-                    "fsel $FRT, $FRA, $FRC, $FRB",
-                    []>;
+                    "fsel $FRT, $FRA, $FRC, $FRB", FPGeneral,
+                    [(set F8RC:$FRT, (PPCfsel F8RC:$FRA,F8RC:$FRC,F8RC:$FRB))]>;
 def FSELS : AForm_1<63, 23,
                      (ops F4RC:$FRT, F8RC:$FRA, F4RC:$FRC, F4RC:$FRB),
-                     "fsel $FRT, $FRA, $FRC, $FRB",
-                     []>;
+                     "fsel $FRT, $FRA, $FRC, $FRB", FPGeneral,
+                    [(set F4RC:$FRT, (PPCfsel F8RC:$FRA,F4RC:$FRC,F4RC:$FRB))]>;
 def FADD  : AForm_2<63, 21,
                     (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRB),
-                    "fadd $FRT, $FRA, $FRB",
+                    "fadd $FRT, $FRA, $FRB", FPGeneral,
                     [(set F8RC:$FRT, (fadd F8RC:$FRA, F8RC:$FRB))]>;
 def FADDS : AForm_2<59, 21,
                     (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRB),
-                    "fadds $FRT, $FRA, $FRB",
+                    "fadds $FRT, $FRA, $FRB", FPGeneral,
                     [(set F4RC:$FRT, (fadd F4RC:$FRA, F4RC:$FRB))]>;
 def FDIV  : AForm_2<63, 18,
                     (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRB),
-                    "fdiv $FRT, $FRA, $FRB",
+                    "fdiv $FRT, $FRA, $FRB", FPDivD,
                     [(set F8RC:$FRT, (fdiv F8RC:$FRA, F8RC:$FRB))]>;
 def FDIVS : AForm_2<59, 18,
                     (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRB),
-                    "fdivs $FRT, $FRA, $FRB",
+                    "fdivs $FRT, $FRA, $FRB", FPDivS,
                     [(set F4RC:$FRT, (fdiv F4RC:$FRA, F4RC:$FRB))]>;
 def FMUL  : AForm_3<63, 25,
                     (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRB),
-                    "fmul $FRT, $FRA, $FRB",
+                    "fmul $FRT, $FRA, $FRB", FPFused,
                     [(set F8RC:$FRT, (fmul F8RC:$FRA, F8RC:$FRB))]>;
 def FMULS : AForm_3<59, 25,
                     (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRB),
-                    "fmuls $FRT, $FRA, $FRB",
+                    "fmuls $FRT, $FRA, $FRB", FPGeneral,
                     [(set F4RC:$FRT, (fmul F4RC:$FRA, F4RC:$FRB))]>;
 def FSUB  : AForm_2<63, 20,
                     (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRB),
-                    "fsub $FRT, $FRA, $FRB",
+                    "fsub $FRT, $FRA, $FRB", FPGeneral,
                     [(set F8RC:$FRT, (fsub F8RC:$FRA, F8RC:$FRB))]>;
 def FSUBS : AForm_2<59, 20,
                     (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRB),
-                    "fsubs $FRT, $FRA, $FRB",
+                    "fsubs $FRT, $FRA, $FRB", FPGeneral,
                     [(set F4RC:$FRT, (fsub F4RC:$FRA, F4RC:$FRB))]>;
 
 // M-Form instructions.  rotate and mask instructions.
@@ -656,29 +709,36 @@
 // RLWIMI can be commuted if the rotate amount is zero.
 def RLWIMI : MForm_2<20,
                      (ops GPRC:$rA, GPRC:$rSi, GPRC:$rS, u5imm:$SH, u5imm:$MB, 
-                      u5imm:$ME), "rlwimi $rA, $rS, $SH, $MB, $ME">;
+                      u5imm:$ME), "rlwimi $rA, $rS, $SH, $MB, $ME", IntRotate,
+                      []>;
 def RLDIMI : MDForm_1<30, 3,
                       (ops G8RC:$rA, G8RC:$rSi, G8RC:$rS, u6imm:$SH, u6imm:$MB),
-                      "rldimi $rA, $rS, $SH, $MB">, isPPC64;
+                      "rldimi $rA, $rS, $SH, $MB", IntRotateD,
+                      []>, isPPC64;
 }
 def RLWINM : MForm_2<21,
                      (ops GPRC:$rA, GPRC:$rS, u5imm:$SH, u5imm:$MB, u5imm:$ME),
-                     "rlwinm $rA, $rS, $SH, $MB, $ME">;
+                     "rlwinm $rA, $rS, $SH, $MB, $ME", IntGeneral,
+                     []>;
 def RLWINMo : MForm_2<21,
                      (ops GPRC:$rA, GPRC:$rS, u5imm:$SH, u5imm:$MB, u5imm:$ME),
-                     "rlwinm. $rA, $rS, $SH, $MB, $ME">, isDOT;
+                     "rlwinm. $rA, $rS, $SH, $MB, $ME", IntGeneral,
+                     []>, isDOT;
 def RLWNM  : MForm_2<23,
                      (ops GPRC:$rA, GPRC:$rS, GPRC:$rB, u5imm:$MB, u5imm:$ME),
-                     "rlwnm $rA, $rS, $rB, $MB, $ME">;
+                     "rlwnm $rA, $rS, $rB, $MB, $ME", IntGeneral,
+                     []>;
 
 // MD-Form instructions.  64 bit rotate instructions.
 //
 def RLDICL : MDForm_1<30, 0,
                       (ops G8RC:$rA, G8RC:$rS, u6imm:$SH, u6imm:$MB),
-                      "rldicl $rA, $rS, $SH, $MB">, isPPC64;
+                      "rldicl $rA, $rS, $SH, $MB", IntRotateD,
+                      []>, isPPC64;
 def RLDICR : MDForm_1<30, 1,
                       (ops G8RC:$rA, G8RC:$rS, u6imm:$SH, u6imm:$ME),
-                      "rldicr $rA, $rS, $SH, $ME">, isPPC64;
+                      "rldicr $rA, $rS, $SH, $ME", IntRotateD,
+                      []>, isPPC64;
 
 //===----------------------------------------------------------------------===//
 // PowerPC Instruction Patterns
@@ -701,8 +761,27 @@
 // XOR an arbitrary immediate.
 def : Pat<(xor GPRC:$in, imm:$imm),
           (XORIS (XORI GPRC:$in, (LO16 imm:$imm)), (HI16 imm:$imm))>;
-
-
+def : Pat<(or (shl GPRC:$rS, GPRC:$rB),
+              (srl GPRC:$rS, (sub 32, GPRC:$rB))),
+          (RLWNM GPRC:$rS, GPRC:$rB, 0, 31)>;
+
+def : Pat<(zext GPRC:$in),
+          (RLDICL (OR4To8 GPRC:$in, GPRC:$in), 0, 32)>;
+def : Pat<(anyext GPRC:$in),
+          (OR4To8 GPRC:$in, GPRC:$in)>;
+def : Pat<(trunc G8RC:$in),
+          (OR8To4 G8RC:$in, G8RC:$in)>;
+
+// SHL
+def : Pat<(shl GPRC:$in, imm:$imm),
+          (RLWINM GPRC:$in, imm:$imm, 0, (SHL32 imm:$imm))>;
+def : Pat<(shl G8RC:$in, imm:$imm),
+          (RLDICR G8RC:$in, imm:$imm, (SHL64 imm:$imm))>;
+// SRL
+def : Pat<(srl GPRC:$in, imm:$imm),
+          (RLWINM GPRC:$in, (SRL32 imm:$imm), imm:$imm, 31)>;
+def : Pat<(srl G8RC:$in, imm:$imm),
+          (RLDICL G8RC:$in, (SRL64 imm:$imm), imm:$imm)>;
 
 // Same as above, but using a temporary. FIXME: implement temporaries :)
 /*
@@ -711,7 +790,6 @@
                (XORIS GPRC:$tmp, (HI16 imm:$imm))]>;
 */
 
-
 //===----------------------------------------------------------------------===//
 // PowerPCInstrInfo Definition
 //


Index: llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
diff -u llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.36 llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.36.2.1
--- llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.36	Tue Oct 18 11:51:22 2005
+++ llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp	Wed Nov 16 12:32:38 2005
@@ -26,6 +26,7 @@
 #include "llvm/Target/TargetOptions.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
 #include "llvm/ADT/STLExtras.h"
 #include <cstdlib>
 #include <iostream>
@@ -294,6 +295,11 @@
 
   // Get the number of bytes to allocate from the FrameInfo
   unsigned NumBytes = MFI->getStackSize();
+  
+  // Get the alignments provided by the target, and the maximum alignment
+  // (if any) of the fixed frame objects.
+  unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment();
+  unsigned MaxAlign = MFI->getMaxAlignment();
 
   // If we have calls, we cannot use the red zone to store callee save registers
   // and we must set up a stack frame, so calculate the necessary size here.
@@ -307,14 +313,15 @@
   // If we are a leaf function, and use up to 224 bytes of stack space,
   // and don't have a frame pointer, then we do not need to adjust the stack
   // pointer (we fit in the Red Zone).
-  if ((NumBytes == 0) || (NumBytes <= 224 && !hasFP(MF) && !MFI->hasCalls())) {
+  if ((NumBytes == 0) || (NumBytes <= 224 && !hasFP(MF) && !MFI->hasCalls() &&
+                          MaxAlign <= TargetAlign)) {
     MFI->setStackSize(0);
     return;
   }
 
   // Add the size of R1 to  NumBytes size for the store of R1 to the bottom
   // of the stack and round the size to a multiple of the alignment.
-  unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
+  unsigned Align = std::max(TargetAlign, MaxAlign);
   unsigned GPRSize = 4;
   unsigned Size = hasFP(MF) ? GPRSize + GPRSize : GPRSize;
   NumBytes = (NumBytes+Size+Align-1)/Align*Align;
@@ -336,7 +343,23 @@
     MI = BuildMI(PPC::STWUX, 3).addReg(PPC::R1).addReg(PPC::R1).addReg(PPC::R0);
     MBB.insert(MBBI, MI);
   }
-
+  
+  // If there is a preferred stack alignment, align R1 now
+  // FIXME: If this ever matters, this could be made more efficient by folding
+  // this into the code above, so that we don't issue two store+update
+  // instructions.
+  if (MaxAlign > TargetAlign) {
+    assert(isPowerOf2_32(MaxAlign) && MaxAlign < 32767 && "Invalid alignment!");
+    MI = BuildMI(PPC::RLWINM, 4, PPC::R0).addReg(PPC::R1).addImm(0)
+      .addImm(32-Log2_32(MaxAlign)).addImm(31);
+    MBB.insert(MBBI, MI);
+    MI = BuildMI(PPC::SUBFIC, 2, PPC::R0).addReg(PPC::R0).addImm(MaxAlign);
+    MBB.insert(MBBI, MI);
+    MI = BuildMI(PPC::STWUX, 3).addReg(PPC::R1).addReg(PPC::R1).addReg(PPC::R0);
+    MBB.insert(MBBI, MI);
+  }
+  
+  // If there is a frame pointer, copy R1 (SP) into R31 (FP)
   if (hasFP(MF)) {
     MI = BuildMI(PPC::STW, 3).addReg(PPC::R31).addSImm(GPRSize).addReg(PPC::R1);
     MBB.insert(MBBI, MI);


Index: llvm/lib/Target/PowerPC/PPCRegisterInfo.td
diff -u llvm/lib/Target/PowerPC/PPCRegisterInfo.td:1.18 llvm/lib/Target/PowerPC/PPCRegisterInfo.td:1.18.2.1
--- llvm/lib/Target/PowerPC/PPCRegisterInfo.td:1.18	Mon Oct 17 19:28:58 2005
+++ llvm/lib/Target/PowerPC/PPCRegisterInfo.td	Wed Nov 16 12:32:38 2005
@@ -21,6 +21,12 @@
   field bits<5> Num = num;
 }
 
+// GP8 - One of the 32 64-bit general-purpose registers
+class GP8<GPR Alias> : PPCReg<Alias.Name> {
+  field bits<5> Num = Alias.Num;
+  let Aliases = [Alias];
+}
+
 // SPR - One of the 32-bit special-purpose registers
 class SPR<bits<5> num, string n> : PPCReg<n> {
   field bits<5> Num = num;
@@ -54,6 +60,24 @@
 def R28 : GPR<28, "r28">;  def R29 : GPR<29, "r29">;
 def R30 : GPR<30, "r30">;  def R31 : GPR<31, "r31">;
 
+// 64-bit General-purpose registers
+def X0  : GP8< R0>;  def X1  : GP8< R1>;
+def X2  : GP8< R2>;  def X3  : GP8< R3>;
+def X4  : GP8< R4>;  def X5  : GP8< R5>;
+def X6  : GP8< R6>;  def X7  : GP8< R7>;
+def X8  : GP8< R8>;  def X9  : GP8< R9>;
+def X10 : GP8<R10>;  def X11 : GP8<R11>;
+def X12 : GP8<R12>;  def X13 : GP8<R13>;
+def X14 : GP8<R14>;  def X15 : GP8<R15>;
+def X16 : GP8<R16>;  def X17 : GP8<R17>;
+def X18 : GP8<R18>;  def X19 : GP8<R19>;
+def X20 : GP8<R20>;  def X21 : GP8<R21>;
+def X22 : GP8<R22>;  def X23 : GP8<R23>;
+def X24 : GP8<R24>;  def X25 : GP8<R25>;
+def X26 : GP8<R26>;  def X27 : GP8<R27>;
+def X28 : GP8<R28>;  def X29 : GP8<R29>;
+def X30 : GP8<R30>;  def X31 : GP8<R31>;
+
 // Floating-point registers
 def F0  : FPR< 0,  "f0">;  def F1  : FPR< 1,  "f1">;
 def F2  : FPR< 2,  "f2">;  def F3  : FPR< 3,  "f3">;
@@ -111,9 +135,9 @@
   }];
 }
 def G8RC : RegisterClass<"PPC", i64, 64,
-     [R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12,
-      R30, R29, R28, R27, R26, R25, R24, R23, R22, R21, R20, R19, R18, R17,
-      R16, R15, R14, R13, R31, R0, R1, LR]>
+     [X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12,
+      X30, X29, X28, X27, X26, X25, X24, X23, X22, X21, X20, X19, X18, X17,
+      X16, X15, X14, X13, X31, X0, X1]>
 {
   let MethodProtos = [{
     iterator allocation_order_begin(MachineFunction &MF) const;
@@ -127,9 +151,9 @@
     G8RCClass::iterator
     G8RCClass::allocation_order_end(MachineFunction &MF) const {
       if (hasFP(MF))
-        return end()-4;
-      else
         return end()-3;
+      else
+        return end()-2;
     }
   }];
 }


Index: llvm/lib/Target/PowerPC/PPCSchedule.td
diff -u llvm/lib/Target/PowerPC/PPCSchedule.td:1.1 llvm/lib/Target/PowerPC/PPCSchedule.td:1.1.2.1
--- llvm/lib/Target/PowerPC/PPCSchedule.td:1.1	Tue Oct 18 11:23:40 2005
+++ llvm/lib/Target/PowerPC/PPCSchedule.td	Wed Nov 16 12:32:38 2005
@@ -7,20 +7,9 @@
 // 
 //===----------------------------------------------------------------------===//
 
-#include "../TargetSchedule.td"
-
-//===----------------------------------------------------------------------===//
-// PowerPC chips sets supported by scheduling (Apple naming)
-//
-def G3      : Processor;
-def G4      : Processor;
-def G4Plus  : Processor;
-def G5      : Processor;
-
 //===----------------------------------------------------------------------===//
 // Functional units across PowerPC chips sets
 //
-def NoUnit : FuncUnit; // Instruction not supported on chip set
 def BPU    : FuncUnit; // Branch unit
 def SLU    : FuncUnit; // Store/load unit
 def SRU    : FuncUnit; // special register unit
@@ -64,17 +53,17 @@
 def LdStDCBA     : InstrItinClass;
 def LdStDCBF     : InstrItinClass;
 def LdStDCBI     : InstrItinClass;
-def LdStDCBT     : InstrItinClass;
+def LdStGeneral  : InstrItinClass;
 def LdStDSS      : InstrItinClass;
 def LdStICBI     : InstrItinClass;
-def LdStLBZUX    : InstrItinClass;
+def LdStUX       : InstrItinClass;
 def LdStLD       : InstrItinClass;
 def LdStLDARX    : InstrItinClass;
 def LdStLFD      : InstrItinClass;
 def LdStLFDU     : InstrItinClass;
 def LdStLHA      : InstrItinClass;
 def LdStLMW      : InstrItinClass;
-def LdStLVEBX    : InstrItinClass;
+def LdStLVecX    : InstrItinClass;
 def LdStLWA      : InstrItinClass;
 def LdStLWARX    : InstrItinClass;
 def LdStSLBIA    : InstrItinClass;
@@ -116,10 +105,10 @@
 //===----------------------------------------------------------------------===//
 // Processor instruction itineraries.
 
-#include "PPCScheduleG3.td"
-#include "PPCScheduleG4.td"
-#include "PPCScheduleG4Plus.td"
-#include "PPCScheduleG5.td"
+include "PPCScheduleG3.td"
+include "PPCScheduleG4.td"
+include "PPCScheduleG4Plus.td"
+include "PPCScheduleG5.td"
 
 //===----------------------------------------------------------------------===//
 // Instruction to itinerary class map - When add new opcodes to the supported
@@ -163,8 +152,8 @@
 //    dcbf       LdStDCBF
 //    dcbi       LdStDCBI
 //    dcbst      LdStDCBF
-//    dcbt       LdStDCBT
-//    dcbtst     LdStDCBT
+//    dcbt       LdStGeneral
+//    dcbtst     LdStGeneral
 //    dcbz       LdStDCBF
 //    divd       IntDivD
 //    divdu      IntDivD
@@ -173,9 +162,9 @@
 //    dss        LdStDSS
 //    dst        LdStDSS
 //    dstst      LdStDSS
-//    eciwx      LdStDCBT
-//    ecowx      LdStDCBT
-//    eieio      LdStDCBT
+//    eciwx      LdStGeneral
+//    ecowx      LdStGeneral
+//    eieio      LdStGeneral
 //    eqv        IntGeneral
 //    extsb      IntGeneral
 //    extsh      IntGeneral
@@ -215,10 +204,10 @@
 //    fsubs      FPGeneral
 //    icbi       LdStICBI
 //    isync      SprISYNC
-//    lbz        LdStDCBT
-//    lbzu       LdStDCBT
-//    lbzux      LdStLBZUX
-//    lbzx       LdStDCBT
+//    lbz        LdStGeneral
+//    lbzu       LdStGeneral
+//    lbzux      LdStUX
+//    lbzx       LdStGeneral
 //    ld         LdStLD
 //    ldarx      LdStLDARX
 //    ldu        LdStLD
@@ -236,30 +225,30 @@
 //    lhau       LdStLHA
 //    lhaux      LdStLHA
 //    lhax       LdStLHA
-//    lhbrx      LdStDCBT
-//    lhz        LdStDCBT
-//    lhzu       LdStDCBT
-//    lhzux      LdStLBZUX
-//    lhzx       LdStDCBT
+//    lhbrx      LdStGeneral
+//    lhz        LdStGeneral
+//    lhzu       LdStGeneral
+//    lhzux      LdStUX
+//    lhzx       LdStGeneral
 //    lmw        LdStLMW
 //    lswi       LdStLMW
 //    lswx       LdStLMW
-//    lvebx      LdStLVEBX
-//    lvehx      LdStLVEBX
-//    lvewx      LdStLVEBX
-//    lvsl       LdStLVEBX
-//    lvsr       LdStLVEBX
-//    lvx        LdStLVEBX
-//    lvxl       LdStLVEBX
+//    lvebx      LdStLVecX
+//    lvehx      LdStLVecX
+//    lvewx      LdStLVecX
+//    lvsl       LdStLVecX
+//    lvsr       LdStLVecX
+//    lvx        LdStLVecX
+//    lvxl       LdStLVecX
 //    lwa        LdStLWA
 //    lwarx      LdStLWARX
 //    lwaux      LdStLHA
 //    lwax       LdStLHA
-//    lwbrx      LdStDCBT
-//    lwz        LdStDCBT
-//    lwzu       LdStDCBT
-//    lwzux      LdStLBZUX
-//    lwzx       LdStDCBT
+//    lwbrx      LdStGeneral
+//    lwz        LdStGeneral
+//    lwzu       LdStGeneral
+//    lwzux      LdStUX
+//    lwzx       LdStGeneral
 //    mcrf       BrMCR
 //    mcrfs      FPGeneral
 //    mcrxr      BrMCRX
@@ -320,29 +309,29 @@
 //    srawi      IntShift
 //    srd        IntRotateD
 //    srw        IntGeneral
-//    stb        LdStDCBT
-//    stbu       LdStDCBT
-//    stbux      LdStDCBT
-//    stbx       LdStDCBT
+//    stb        LdStGeneral
+//    stbu       LdStGeneral
+//    stbux      LdStGeneral
+//    stbx       LdStGeneral
 //    std        LdStSTD
 //    stdcx.     LdStSTDCX
 //    stdu       LdStSTD
 //    stdux      LdStSTD
 //    stdx       LdStSTD
-//    stfd       LdStLBZUX
-//    stfdu      LdStLBZUX
-//    stfdux     LdStLBZUX
-//    stfdx      LdStLBZUX
-//    stfiwx     LdStLBZUX
-//    stfs       LdStLBZUX
-//    stfsu      LdStLBZUX
-//    stfsux     LdStLBZUX
-//    stfsx      LdStLBZUX
-//    sth        LdStDCBT
-//    sthbrx     LdStDCBT
-//    sthu       LdStDCBT
-//    sthux      LdStDCBT
-//    sthx       LdStDCBT
+//    stfd       LdStUX
+//    stfdu      LdStUX
+//    stfdux     LdStUX
+//    stfdx      LdStUX
+//    stfiwx     LdStUX
+//    stfs       LdStUX
+//    stfsu      LdStUX
+//    stfsux     LdStUX
+//    stfsx      LdStUX
+//    sth        LdStGeneral
+//    sthbrx     LdStGeneral
+//    sthu       LdStGeneral
+//    sthux      LdStGeneral
+//    sthx       LdStGeneral
 //    stmw       LdStLMW
 //    stswi      LdStLMW
 //    stswx      LdStLMW
@@ -351,12 +340,12 @@
 //    stvewx     LdStSTVEBX
 //    stvx       LdStSTVEBX
 //    stvxl      LdStSTVEBX
-//    stw        LdStDCBT
-//    stwbrx     LdStDCBT
+//    stw        LdStGeneral
+//    stwbrx     LdStGeneral
 //    stwcx.     LdStSTWCX
-//    stwu       LdStDCBT
-//    stwux      LdStDCBT
-//    stwx       LdStDCBT
+//    stwu       LdStGeneral
+//    stwux      LdStGeneral
+//    stwx       LdStGeneral
 //    subf       IntGeneral
 //    subfc      IntGeneral
 //    subfe      IntGeneral
@@ -517,4 +506,3 @@
 //    xori       IntGeneral
 //    xoris      IntGeneral
 //
-


Index: llvm/lib/Target/PowerPC/PPCScheduleG3.td
diff -u llvm/lib/Target/PowerPC/PPCScheduleG3.td:1.2 llvm/lib/Target/PowerPC/PPCScheduleG3.td:1.2.2.1
--- llvm/lib/Target/PowerPC/PPCScheduleG3.td:1.2	Tue Oct 18 11:59:23 2005
+++ llvm/lib/Target/PowerPC/PPCScheduleG3.td	Wed Nov 16 12:32:38 2005
@@ -12,7 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 
-def G3Itineraries : ProcessorItineraries<G3, [
+def G3Itineraries : ProcessorItineraries<[
   InstrItinData<IntGeneral  , [InstrStage<1, [IU1, IU2]>]>,
   InstrItinData<IntCompare  , [InstrStage<1, [IU1, IU2]>]>,
   InstrItinData<IntDivW     , [InstrStage<19, [IU1]>]>,
@@ -31,9 +31,9 @@
   InstrItinData<LdStDCBA    , [InstrStage<2, [SLU]>]>,
   InstrItinData<LdStDCBF    , [InstrStage<3, [SLU]>]>,
   InstrItinData<LdStDCBI    , [InstrStage<3, [SLU]>]>,
-  InstrItinData<LdStDCBT    , [InstrStage<2, [SLU]>]>,
+  InstrItinData<LdStGeneral , [InstrStage<2, [SLU]>]>,
   InstrItinData<LdStICBI    , [InstrStage<3, [SLU]>]>,
-  InstrItinData<LdStLBZUX   , [InstrStage<2, [SLU]>]>,
+  InstrItinData<LdStUX      , [InstrStage<2, [SLU]>]>,
   InstrItinData<LdStLFD     , [InstrStage<2, [SLU]>]>,
   InstrItinData<LdStLFDU    , [InstrStage<2, [SLU]>]>,
   InstrItinData<LdStLHA     , [InstrStage<2, [SLU]>]>,
@@ -59,5 +59,5 @@
   InstrItinData<FPDivD      , [InstrStage<31, [FPU1]>]>,
   InstrItinData<FPDivS      , [InstrStage<17, [FPU1]>]>,
   InstrItinData<FPFused     , [InstrStage<2, [FPU1]>]>,
-  InstrItinData<FPRes       , [InstrStage<10, [FPU1]>]>,
+  InstrItinData<FPRes       , [InstrStage<10, [FPU1]>]>
 ]>;


Index: llvm/lib/Target/PowerPC/PPCScheduleG4.td
diff -u llvm/lib/Target/PowerPC/PPCScheduleG4.td:1.2 llvm/lib/Target/PowerPC/PPCScheduleG4.td:1.2.2.1
--- llvm/lib/Target/PowerPC/PPCScheduleG4.td:1.2	Tue Oct 18 11:59:23 2005
+++ llvm/lib/Target/PowerPC/PPCScheduleG4.td	Wed Nov 16 12:32:38 2005
@@ -11,7 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-def G4Itineraries : ProcessorItineraries<G4, [
+def G4Itineraries : ProcessorItineraries<[
   InstrItinData<IntGeneral  , [InstrStage<1, [IU1, IU2]>]>,
   InstrItinData<IntCompare  , [InstrStage<1, [IU1, IU2]>]>,
   InstrItinData<IntDivW     , [InstrStage<19, [IU1]>]>,
@@ -30,15 +30,15 @@
   InstrItinData<BrMCRX      , [InstrStage<1, [SRU]>]>,
   InstrItinData<LdStDCBF    , [InstrStage<2, [SLU]>]>,
   InstrItinData<LdStDCBI    , [InstrStage<2, [SLU]>]>,
-  InstrItinData<LdStDCBT    , [InstrStage<2, [SLU]>]>,
+  InstrItinData<LdStGeneral , [InstrStage<2, [SLU]>]>,
   InstrItinData<LdStDSS     , [InstrStage<2, [SLU]>]>,
   InstrItinData<LdStICBI    , [InstrStage<2, [SLU]>]>,
-  InstrItinData<LdStLBZUX   , [InstrStage<2, [SLU]>]>,
+  InstrItinData<LdStUX      , [InstrStage<2, [SLU]>]>,
   InstrItinData<LdStLFD     , [InstrStage<2, [SLU]>]>,
   InstrItinData<LdStLFDU    , [InstrStage<2, [SLU]>]>,
   InstrItinData<LdStLHA     , [InstrStage<2, [SLU]>]>,
   InstrItinData<LdStLMW     , [InstrStage<34, [SLU]>]>,
-  InstrItinData<LdStLVEBX   , [InstrStage<2, [SLU]>]>,
+  InstrItinData<LdStLVecX   , [InstrStage<2, [SLU]>]>,
   InstrItinData<LdStLWARX   , [InstrStage<3, [SLU]>]>,
   InstrItinData<LdStSTVEBX  , [InstrStage<2, [SLU]>]>,
   InstrItinData<LdStSTWCX   , [InstrStage<5, [SLU]>]>,


Index: llvm/lib/Target/PowerPC/PPCScheduleG4Plus.td
diff -u llvm/lib/Target/PowerPC/PPCScheduleG4Plus.td:1.2 llvm/lib/Target/PowerPC/PPCScheduleG4Plus.td:1.2.2.1
--- llvm/lib/Target/PowerPC/PPCScheduleG4Plus.td:1.2	Tue Oct 18 11:59:23 2005
+++ llvm/lib/Target/PowerPC/PPCScheduleG4Plus.td	Wed Nov 16 12:32:38 2005
@@ -11,7 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-def G4PlusItineraries : ProcessorItineraries<G4Plus, [
+def G4PlusItineraries : ProcessorItineraries<[
   InstrItinData<IntGeneral  , [InstrStage<1, [IU1, IU2, IU3, IU4]>]>,
   InstrItinData<IntCompare  , [InstrStage<1, [IU1, IU2, IU3, IU4]>]>,
   InstrItinData<IntDivW     , [InstrStage<23, [IU2]>]>,
@@ -30,15 +30,15 @@
   InstrItinData<BrMCRX      , [InstrStage<2, [IU2]>]>,
   InstrItinData<LdStDCBF    , [InstrStage<3, [SLU]>]>,
   InstrItinData<LdStDCBI    , [InstrStage<3, [SLU]>]>,
-  InstrItinData<LdStDCBT    , [InstrStage<3, [SLU]>]>,
+  InstrItinData<LdStGeneral , [InstrStage<3, [SLU]>]>,
   InstrItinData<LdStDSS     , [InstrStage<3, [SLU]>]>,
   InstrItinData<LdStICBI    , [InstrStage<3, [IU2]>]>,
-  InstrItinData<LdStLBZUX   , [InstrStage<3, [SLU]>]>,
+  InstrItinData<LdStUX      , [InstrStage<3, [SLU]>]>,
   InstrItinData<LdStLFD     , [InstrStage<4, [SLU]>]>,
   InstrItinData<LdStLFDU    , [InstrStage<4, [SLU]>]>,
   InstrItinData<LdStLHA     , [InstrStage<3, [SLU]>]>,
   InstrItinData<LdStLMW     , [InstrStage<37, [SLU]>]>,
-  InstrItinData<LdStLVEBX   , [InstrStage<3, [SLU]>]>,
+  InstrItinData<LdStLVecX   , [InstrStage<3, [SLU]>]>,
   InstrItinData<LdStLWA     , [InstrStage<3, [SLU]>]>,
   InstrItinData<LdStLWARX   , [InstrStage<3, [SLU]>]>,
   InstrItinData<LdStSTD     , [InstrStage<3, [SLU]>]>,


Index: llvm/lib/Target/PowerPC/PPCScheduleG5.td
diff -u llvm/lib/Target/PowerPC/PPCScheduleG5.td:1.2 llvm/lib/Target/PowerPC/PPCScheduleG5.td:1.2.2.1
--- llvm/lib/Target/PowerPC/PPCScheduleG5.td:1.2	Tue Oct 18 11:59:23 2005
+++ llvm/lib/Target/PowerPC/PPCScheduleG5.td	Wed Nov 16 12:32:38 2005
@@ -11,7 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-def G5Itineraries : ProcessorItineraries<G5, [
+def G5Itineraries : ProcessorItineraries<[
   InstrItinData<IntGeneral  , [InstrStage<2, [IU1, IU2]>]>,
   InstrItinData<IntCompare  , [InstrStage<3, [IU1, IU2]>]>,
   InstrItinData<IntDivD     , [InstrStage<68, [IU1]>]>,
@@ -34,17 +34,17 @@
   InstrItinData<BrMCR       , [InstrStage<2, [BPU]>]>,
   InstrItinData<BrMCRX      , [InstrStage<3, [BPU]>]>,
   InstrItinData<LdStDCBF    , [InstrStage<3, [SLU]>]>,
-  InstrItinData<LdStDCBT    , [InstrStage<3, [SLU]>]>,
+  InstrItinData<LdStGeneral , [InstrStage<3, [SLU]>]>,
   InstrItinData<LdStDSS     , [InstrStage<10, [SLU]>]>,
   InstrItinData<LdStICBI    , [InstrStage<40, [SLU]>]>,
-  InstrItinData<LdStLBZUX   , [InstrStage<4, [SLU]>]>,
+  InstrItinData<LdStUX      , [InstrStage<4, [SLU]>]>,
   InstrItinData<LdStLD      , [InstrStage<3, [SLU]>]>,
   InstrItinData<LdStLDARX   , [InstrStage<11, [SLU]>]>,
   InstrItinData<LdStLFD     , [InstrStage<3, [SLU]>]>,
   InstrItinData<LdStLFDU    , [InstrStage<5, [SLU]>]>,
   InstrItinData<LdStLHA     , [InstrStage<5, [SLU]>]>,
   InstrItinData<LdStLMW     , [InstrStage<64, [SLU]>]>,
-  InstrItinData<LdStLVEBX   , [InstrStage<3, [SLU]>]>,
+  InstrItinData<LdStLVecX   , [InstrStage<3, [SLU]>]>,
   InstrItinData<LdStLWA     , [InstrStage<5, [SLU]>]>,
   InstrItinData<LdStLWARX   , [InstrStage<11, [SLU]>]>,
   InstrItinData<LdStSLBIA   , [InstrStage<40, [SLU]>]>, // needs work


Index: llvm/lib/Target/PowerPC/PPCSubtarget.cpp
diff -u llvm/lib/Target/PowerPC/PPCSubtarget.cpp:1.10 llvm/lib/Target/PowerPC/PPCSubtarget.cpp:1.10.2.1
--- llvm/lib/Target/PowerPC/PPCSubtarget.cpp:1.10	Mon Oct 17 19:56:42 2005
+++ llvm/lib/Target/PowerPC/PPCSubtarget.cpp	Wed Nov 16 12:32:38 2005
@@ -15,7 +15,7 @@
 #include "PPC.h"
 #include "llvm/Module.h"
 #include "llvm/Support/CommandLine.h"
-#include "llvm/Target/SubtargetFeature.h"
+#include "PPCGenSubtarget.inc"
 
 using namespace llvm;
 PPCTargetEnum llvm::PPCTarget = TargetDefault;
@@ -29,61 +29,8 @@
                                      "  Enable Darwin codegen"),
                           clEnumValEnd),
                cl::location(PPCTarget), cl::init(TargetDefault));
-}
-
-enum PowerPCFeature {
-  PowerPCFeature64Bit   = 1 << 0,
-  PowerPCFeatureAltivec = 1 << 1,
-  PowerPCFeatureFSqrt   = 1 << 2,
-  PowerPCFeatureGPUL    = 1 << 3,
-  PowerPCFeature64BRegs = 1 << 4
-};
-
-/// Sorted (by key) array of values for CPU subtype.
-static const SubtargetFeatureKV PowerPCSubTypeKV[] = {
-  { "601"    , "Select the PowerPC 601 processor", 0 },
-  { "602"    , "Select the PowerPC 602 processor", 0 },
-  { "603"    , "Select the PowerPC 603 processor", 0 },
-  { "603e"   , "Select the PowerPC 603e processor", 0 },
-  { "603ev"  , "Select the PowerPC 603ev processor", 0 },
-  { "604"    , "Select the PowerPC 604 processor", 0 },
-  { "604e"   , "Select the PowerPC 604e processor", 0 },
-  { "620"    , "Select the PowerPC 620 processor", 0 },
-  { "7400"   , "Select the PowerPC 7400 (G4) processor",
-               PowerPCFeatureAltivec },
-  { "7450"   , "Select the PowerPC 7450 (G4+) processor",
-               PowerPCFeatureAltivec },
-  { "750"    , "Select the PowerPC 750 (G3) processor", 0 },
-  { "970"    , "Select the PowerPC 970 (G5 - GPUL) processor",
-               PowerPCFeature64Bit | PowerPCFeatureAltivec |
-               PowerPCFeatureFSqrt | PowerPCFeatureGPUL },
-  { "g3"     , "Select the PowerPC G3 (750) processor", 0 },
-  { "g4"     , "Select the PowerPC G4 (7400) processor",
-               PowerPCFeatureAltivec },
-  { "g4+"    , "Select the PowerPC G4+ (7450) processor",
-               PowerPCFeatureAltivec },
-  { "g5"     , "Select the PowerPC g5 (970 - GPUL)  processor",
-               PowerPCFeature64Bit | PowerPCFeatureAltivec |
-               PowerPCFeatureFSqrt | PowerPCFeatureGPUL },
-  { "generic", "Select instructions for a generic PowerPC processor", 0 }
-};
-/// Length of PowerPCSubTypeKV.
-static const unsigned PowerPCSubTypeKVSize = sizeof(PowerPCSubTypeKV)
-                                             / sizeof(SubtargetFeatureKV);
-
-/// Sorted (by key) array of values for CPU features.
-static SubtargetFeatureKV PowerPCFeatureKV[] = {
-  { "64bit"  , "Should 64 bit instructions be used"  , PowerPCFeature64Bit   },
-  { "64bitregs", "Should 64 bit registers be used"   , PowerPCFeature64BRegs },
-  { "altivec", "Should Altivec instructions be used" , PowerPCFeatureAltivec },
-  { "fsqrt"  , "Should the fsqrt instruction be used", PowerPCFeatureFSqrt   },
-  { "gpul"   , "Should GPUL instructions be used"    , PowerPCFeatureGPUL    }
- };
-/// Length of PowerPCFeatureKV.
-static const unsigned PowerPCFeatureKVSize = sizeof(PowerPCFeatureKV)
-                                          / sizeof(SubtargetFeatureKV);
-
-
+} 
+ 
 #if defined(__APPLE__)
 #include <mach/mach.h>
 #include <mach/mach_host.h>
@@ -121,22 +68,26 @@
 }
 #endif
 
+
 PPCSubtarget::PPCSubtarget(const Module &M, const std::string &FS)
-  : StackAlignment(16), IsGigaProcessor(false), IsAIX(false), IsDarwin(false) {
+  : StackAlignment(16)
+  , InstrItins()
+  , IsGigaProcessor(false)
+  , Is64Bit(false)
+  , Has64BitRegs(false)
+  , HasAltivec(false)
+  , HasFSQRT(false)
+  , IsAIX(false)
+  , IsDarwin(false) {
 
   // Determine default and user specified characteristics
   std::string CPU = "generic";
 #if defined(__APPLE__)
   CPU = GetCurrentPowerPCCPU();
 #endif
-  uint32_t Bits =
-  SubtargetFeatures::Parse(FS, CPU,
-                           PowerPCSubTypeKV, PowerPCSubTypeKVSize,
-                           PowerPCFeatureKV, PowerPCFeatureKVSize);
-  IsGigaProcessor = (Bits & PowerPCFeatureGPUL ) != 0;
-  Is64Bit         = (Bits & PowerPCFeature64Bit) != 0;
-  HasFSQRT        = (Bits & PowerPCFeatureFSqrt) != 0;
-  Has64BitRegs    = (Bits & PowerPCFeature64BRegs) != 0;
+
+  // Parse features string.
+  ParseSubtargetFeatures(FS, CPU);
 
   // Set the boolean corresponding to the current target triple, or the default
   // if one cannot be determined, to true.


Index: llvm/lib/Target/PowerPC/PPCSubtarget.h
diff -u llvm/lib/Target/PowerPC/PPCSubtarget.h:1.8 llvm/lib/Target/PowerPC/PPCSubtarget.h:1.8.2.1
--- llvm/lib/Target/PowerPC/PPCSubtarget.h:1.8	Mon Oct 17 19:56:42 2005
+++ llvm/lib/Target/PowerPC/PPCSubtarget.h	Wed Nov 16 12:32:38 2005
@@ -14,6 +14,7 @@
 #ifndef POWERPCSUBTARGET_H
 #define POWERPCSUBTARGET_H
 
+#include "llvm/Target/TargetInstrItineraries.h"
 #include "llvm/Target/TargetSubtarget.h"
 
 #include <string>
@@ -26,11 +27,15 @@
   /// stackAlignment - The minimum alignment known to hold of the stack frame on
   /// entry to the function and which must be maintained by every function.
   unsigned StackAlignment;
+  
+  /// Selected instruction itineraries (one entry per itinerary class.)
+  InstrItineraryData InstrItins;
 
   /// Used by the ISel to turn in optimizations for POWER4-derived architectures
   bool IsGigaProcessor;
   bool Is64Bit;
   bool Has64BitRegs;
+  bool HasAltivec;
   bool HasFSQRT;
   bool IsAIX;
   bool IsDarwin;
@@ -39,18 +44,28 @@
   /// of the specified module.
   ///
   PPCSubtarget(const Module &M, const std::string &FS);
+  
+  /// ParseSubtargetFeatures - Parses features string setting specified 
+  /// subtarget options.  Definition of function is auto generated by tblgen.
+  void ParseSubtargetFeatures(const std::string &FS, const std::string &CPU);
 
   /// getStackAlignment - Returns the minimum alignment known to hold of the
   /// stack frame on entry to the function and which must be maintained by every
   /// function for this subtarget.
   unsigned getStackAlignment() const { return StackAlignment; }
+  
+  /// getInstrItins - Return the instruction itineraies based on subtarget 
+  /// selection.
+  const InstrItineraryData getInstrItineraryData() const { return InstrItins; }
+  
 
   bool hasFSQRT() const { return HasFSQRT; }
+  bool has64BitRegs() const { return Has64BitRegs; }
+  bool hasAltivec() const { return HasAltivec; }
   
   bool isAIX() const { return IsAIX; }
   bool isDarwin() const { return IsDarwin; }
   bool is64Bit() const { return Is64Bit; }
-  bool has64BitRegs() const { return Has64BitRegs; }
   bool isGigaProcessor() const { return IsGigaProcessor; }
 };
 } // End llvm namespace


Index: llvm/lib/Target/PowerPC/PPCTargetMachine.cpp
diff -u llvm/lib/Target/PowerPC/PPCTargetMachine.cpp:1.75 llvm/lib/Target/PowerPC/PPCTargetMachine.cpp:1.75.2.1
--- llvm/lib/Target/PowerPC/PPCTargetMachine.cpp:1.75	Mon Oct 17 19:28:58 2005
+++ llvm/lib/Target/PowerPC/PPCTargetMachine.cpp	Wed Nov 16 12:32:38 2005
@@ -64,7 +64,8 @@
 PPCTargetMachine::PPCTargetMachine(const Module &M, IntrinsicLowering *IL,
                                    const std::string &FS)
 : TargetMachine("PowerPC", IL, false, 4, 4, 4, 4, 4, 4, 2, 1, 1),
-  Subtarget(M, FS), FrameInfo(*this, false), JITInfo(*this) {
+  Subtarget(M, FS), FrameInfo(*this, false), JITInfo(*this),
+  InstrItins(Subtarget.getInstrItineraryData()) {
   if (TargetDefault == PPCTarget) {
     if (Subtarget.isAIX()) PPCTarget = TargetAIX;
     if (Subtarget.isDarwin()) PPCTarget = TargetDarwin;
@@ -76,11 +77,12 @@
 ///
 bool PPCTargetMachine::addPassesToEmitFile(PassManager &PM,
                                            std::ostream &Out,
-                                           CodeGenFileType FileType) {
+                                           CodeGenFileType FileType,
+                                           bool Fast) {
   if (FileType != TargetMachine::AssemblyFile) return true;
 
   // Run loop strength reduction before anything else.
-  PM.add(createLoopStrengthReducePass());
+  if (!Fast) PM.add(createLoopStrengthReducePass());
 
   // FIXME: Implement efficient support for garbage collection intrinsics.
   PM.add(createLowerGCPass());
@@ -89,7 +91,7 @@
   PM.add(createLowerInvokePass());
   
   // Clean up after other passes, e.g. merging critical edges.
-  PM.add(createCFGSimplificationPass());
+  if (!Fast) PM.add(createCFGSimplificationPass());
 
   // FIXME: Implement the switch instruction in the instruction selector!
   PM.add(createLowerSwitchPass());


Index: llvm/lib/Target/PowerPC/PPCTargetMachine.h
diff -u llvm/lib/Target/PowerPC/PPCTargetMachine.h:1.14 llvm/lib/Target/PowerPC/PPCTargetMachine.h:1.14.2.1
--- llvm/lib/Target/PowerPC/PPCTargetMachine.h:1.14	Sun Oct 16 00:39:50 2005
+++ llvm/lib/Target/PowerPC/PPCTargetMachine.h	Wed Nov 16 12:32:38 2005
@@ -27,10 +27,11 @@
 class IntrinsicLowering;
 
 class PPCTargetMachine : public TargetMachine {
-  PPCInstrInfo    InstrInfo;
-  PPCSubtarget    Subtarget;
-  PPCFrameInfo    FrameInfo;
-  PPCJITInfo      JITInfo;
+  PPCInstrInfo           InstrInfo;
+  PPCSubtarget           Subtarget;
+  PPCFrameInfo           FrameInfo;
+  PPCJITInfo             JITInfo;
+  InstrItineraryData     InstrItins;
 public:
   PPCTargetMachine(const Module &M, IntrinsicLowering *IL,
                    const std::string &FS);
@@ -42,13 +43,17 @@
   virtual const MRegisterInfo    *getRegisterInfo() const {
     return &InstrInfo.getRegisterInfo();
   }
+  virtual const InstrItineraryData getInstrItineraryData() const {  
+    return InstrItins;
+  }
+  
 
   static unsigned getJITMatchQuality();
 
   static unsigned getModuleMatchQuality(const Module &M);
   
   virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out,
-                                   CodeGenFileType FileType);
+                                   CodeGenFileType FileType, bool Fast);
   
   bool addPassesToEmitMachineCode(FunctionPassManager &PM,
                                   MachineCodeEmitter &MCE);


Index: llvm/lib/Target/PowerPC/README.txt
diff -u llvm/lib/Target/PowerPC/README.txt:1.33 llvm/lib/Target/PowerPC/README.txt:1.33.2.1
--- llvm/lib/Target/PowerPC/README.txt:1.33	Tue Oct 18 01:30:51 2005
+++ llvm/lib/Target/PowerPC/README.txt	Wed Nov 16 12:32:38 2005
@@ -121,3 +121,122 @@
 
 If we exposed the srl & mask ops after the MFCR that we are doing to select
 the correct CR bit, then we could fold the slwi into the rlwinm before it.
+
+===-------------------------------------------------------------------------===
+
+#define  ARRAY_LENGTH  16
+
+union bitfield {
+	struct {
+#ifndef	__ppc__
+		unsigned int                       field0 : 6;
+		unsigned int                       field1 : 6;
+		unsigned int                       field2 : 6;
+		unsigned int                       field3 : 6;
+		unsigned int                       field4 : 3;
+		unsigned int                       field5 : 4;
+		unsigned int                       field6 : 1;
+#else
+		unsigned int                       field6 : 1;
+		unsigned int                       field5 : 4;
+		unsigned int                       field4 : 3;
+		unsigned int                       field3 : 6;
+		unsigned int                       field2 : 6;
+		unsigned int                       field1 : 6;
+		unsigned int                       field0 : 6;
+#endif
+	} bitfields, bits;
+	unsigned int	u32All;
+	signed int	i32All;
+	float	f32All;
+};
+
+
+typedef struct program_t {
+	union bitfield    array[ARRAY_LENGTH];
+    int               size;
+    int               loaded;
+} program;
+
+
+void AdjustBitfields(program* prog, unsigned int fmt1)
+{
+	unsigned int shift = 0;
+	unsigned int texCount = 0;
+	unsigned int i;
+	
+	for (i = 0; i < 8; i++)
+	{
+		prog->array[i].bitfields.field0 = texCount;
+		prog->array[i].bitfields.field1 = texCount + 1;
+		prog->array[i].bitfields.field2 = texCount + 2;
+		prog->array[i].bitfields.field3 = texCount + 3;
+
+		texCount += (fmt1 >> shift) & 0x7;
+		shift    += 3;
+	}
+}
+
+In the loop above, the bitfield adds get generated as 
+(add (shl bitfield, C1), (shl C2, C1)) where C2 is 1, 2 or 3.
+
+Since the input to the (or and, and) is an (add) rather than a (shl), the shift
+doesn't get folded into the rlwimi instruction.  We should ideally see through
+things like this, rather than forcing llvm to generate the equivalent
+
+(shl (add bitfield, C2), C1) with some kind of mask.
+
+===-------------------------------------------------------------------------===
+
+Compile this (standard bitfield insert of a constant):
+void %test(uint* %tmp1) {
+        %tmp2 = load uint* %tmp1                ; <uint> [#uses=1]
+        %tmp5 = or uint %tmp2, 257949696                ; <uint> [#uses=1]
+        %tmp6 = and uint %tmp5, 4018143231              ; <uint> [#uses=1]
+        store uint %tmp6, uint* %tmp1
+        ret void
+}
+
+to:
+
+_test:
+        lwz r0,0(r3)
+        li r2,123
+        rlwimi r0,r2,21,3,10
+        stw r0,0(r3)
+        blr
+
+instead of:
+
+_test:
+        lis r2, -4225
+        lwz r4, 0(r3)
+        ori r2, r2, 65535
+        oris r4, r4, 3936
+        and r2, r4, r2
+        stw r2, 0(r3)
+        blr
+
+===-------------------------------------------------------------------------===
+
+Compile this:
+
+int %f1(int %a, int %b) {
+        %tmp.1 = and int %a, 15         ; <int> [#uses=1]
+        %tmp.3 = and int %b, 240                ; <int> [#uses=1]
+        %tmp.4 = or int %tmp.3, %tmp.1          ; <int> [#uses=1]
+        ret int %tmp.4
+}
+
+without a copy.  We make this currently:
+
+_f1:
+        rlwinm r2, r4, 0, 24, 27
+        rlwimi r2, r3, 0, 28, 31
+        or r3, r2, r2
+        blr
+
+The two-addr pass or RA needs to learn when it is profitable to commute an
+instruction to avoid a copy AFTER the 2-addr instruction.  The 2-addr pass
+currently only commutes to avoid inserting a copy BEFORE the two addr instr.
+






More information about the llvm-commits mailing list