Modify the ppc backend to use two register classes for FP: F8RC and F4RC.
authorChris Lattner <sabre@nondot.org>
Sat, 1 Oct 2005 01:35:02 +0000 (01:35 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 1 Oct 2005 01:35:02 +0000 (01:35 +0000)
These are used to represent float and double values, and the two regclasses
contain the same physical registers.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23577 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PowerPC/PPC32RegisterInfo.td
lib/Target/PowerPC/PPCBranchSelector.cpp
lib/Target/PowerPC/PPCCodeEmitter.cpp
lib/Target/PowerPC/PPCISelDAGToDAG.cpp
lib/Target/PowerPC/PPCISelLowering.cpp
lib/Target/PowerPC/PPCISelPattern.cpp
lib/Target/PowerPC/PPCInstrInfo.cpp
lib/Target/PowerPC/PPCInstrInfo.td
lib/Target/PowerPC/PPCRegisterInfo.cpp

index 2b26ea16bbf2c2ec0167530d0849b98668cf230e..ef2e62343c16fe7a44292489c8198d8529afd817 100644 (file)
@@ -39,8 +39,12 @@ def GPRC : RegisterClass<"PPC32", i32, 32,
   }];
 }
 
-def FPRC : RegisterClass<"PPC32", f64, 64, [F0, F1, F2, F3, F4, F5, F6, F7,
+def F8RC : RegisterClass<"PPC32", f64, 64, [F0, F1, F2, F3, F4, F5, F6, F7,
   F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21,
   F22, F23, F24, F25, F26, F27, F28, F29, F30, F31]>;
+def F4RC : RegisterClass<"PPC32", f32, 32, [F0, F1, F2, F3, F4, F5, F6, F7,
+  F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21,
+  F22, F23, F24, F25, F26, F27, F28, F29, F30, F31]>;
+
 
 def CRRC : RegisterClass<"PPC32", i32, 32, [CR0, CR1, CR5, CR6, CR7, CR2, CR3, CR4]>;
index 24187e3b9fe2c6c237c1e5185a305602131a7b2f..6e0e36f0a1d49f6c5ba2ba8c8d38bd416000a1f7 100644 (file)
@@ -41,7 +41,8 @@ namespace {
         // keeping the offsets up to date later when we emit long branch glue.
         return 12;
       case PPC::IMPLICIT_DEF_GPR: // no asm emitted
-      case PPC::IMPLICIT_DEF_FP: // no asm emitted
+      case PPC::IMPLICIT_DEF_F4: // no asm emitted
+      case PPC::IMPLICIT_DEF_F8: // no asm emitted
         return 0;
       default:
         break;
index 25cbda5d4b91998c6a2f4c020f604802557a9ce3..af9c4cf43391c1a0d5f0b9b196a419bf0703dc5e 100644 (file)
@@ -125,7 +125,8 @@ void PPC32CodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
       emitWord(getBinaryCodeForInstr(*I));
       break;
     case PPC::IMPLICIT_DEF_GPR:
-    case PPC::IMPLICIT_DEF_FP:
+    case PPC::IMPLICIT_DEF_F8:
+    case PPC::IMPLICIT_DEF_F4:
       break; // pseudo opcode, no side effects
     case PPC::MovePCtoLR:
       assert(0 && "CodeEmitter does not support MovePCtoLR instruction");
index c8850cd3bddc9d35db887e4f85005d0cef1721aa..ab6c14f5562948877c9bab25edc2fcc8c5fc3440 100644 (file)
@@ -443,8 +443,10 @@ SDOperand PPC32DAGToDAGISel::SelectCC(SDOperand LHS, SDOperand RHS,
                                    LHS, getI32Imm(Lo16(Imm)));
     return CurDAG->getTargetNode(U ? PPC::CMPLW : PPC::CMPW, MVT::i32,
                                  LHS, Select(RHS));
+  } else if (LHS.getValueType() == MVT::f32) {
+    return CurDAG->getTargetNode(PPC::FCMPUS, MVT::i32, LHS, Select(RHS));
   } else {
-    return CurDAG->getTargetNode(PPC::FCMPU, MVT::i32, LHS, Select(RHS));
+    return CurDAG->getTargetNode(PPC::FCMPUD, MVT::i32, LHS, Select(RHS));
   }
 }
 
@@ -679,8 +681,10 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
   case ISD::UNDEF:
     if (N->getValueType(0) == MVT::i32)
       CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_GPR, MVT::i32);
-    else
-      CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_FP, N->getValueType(0));
+    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();
@@ -749,10 +753,16 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
     return SDOperand(Result.Val, Op.ResNo);
   }      
   case PPCISD::FSEL:
-    CurDAG->SelectNodeTo(N, PPC::FSEL, N->getValueType(0),
-                         Select(N->getOperand(0)),
-                         Select(N->getOperand(1)),
-                         Select(N->getOperand(2)));
+    if (N->getValueType(0) == MVT::f32)
+      CurDAG->SelectNodeTo(N, PPC::FSELS, MVT::f32,
+                           Select(N->getOperand(0)),
+                           Select(N->getOperand(1)),
+                           Select(N->getOperand(2)));
+    else
+      CurDAG->SelectNodeTo(N, PPC::FSELD, MVT::f64,
+                           Select(N->getOperand(0)),
+                           Select(N->getOperand(1)),
+                           Select(N->getOperand(2)));
     return SDOperand(N, 0);
   case PPCISD::FCFID:
     CurDAG->SelectNodeTo(N, PPC::FCFID, N->getValueType(0),
@@ -956,15 +966,17 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
     return SDOperand(N, 0);
   } 
   case ISD::FABS:
-    CurDAG->SelectNodeTo(N, PPC::FABS, N->getValueType(0), 
-                         Select(N->getOperand(0)));
+    if (N->getValueType(0) == MVT::f32)
+      CurDAG->SelectNodeTo(N, PPC::FABSS, MVT::f32, Select(N->getOperand(0)));
+    else
+      CurDAG->SelectNodeTo(N, PPC::FABSD, MVT::f64, Select(N->getOperand(0)));
     return SDOperand(N, 0);
   case ISD::FP_EXTEND:
     assert(MVT::f64 == N->getValueType(0) && 
            MVT::f32 == N->getOperand(0).getValueType() && "Illegal FP_EXTEND");
     // We need to emit an FMR to make sure that the result has the right value
     // type.
-    CurDAG->SelectNodeTo(N, PPC::FMR, MVT::f64, Select(N->getOperand(0)));
+    CurDAG->SelectNodeTo(N, PPC::FMRSD, MVT::f64, Select(N->getOperand(0)));
     return SDOperand(N, 0);
   case ISD::FP_ROUND:
     assert(MVT::f32 == N->getValueType(0) && 
@@ -978,7 +990,8 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
       unsigned Opc;
       switch (Val.isTargetOpcode() ? Val.getTargetOpcode() : 0) {
       default:          Opc = 0;            break;
-      case PPC::FABS:   Opc = PPC::FNABS;   break;
+      case PPC::FABSS:  Opc = PPC::FNABSS;  break;
+      case PPC::FABSD:  Opc = PPC::FNABSD;  break;
       case PPC::FMADD:  Opc = PPC::FNMADD;  break;
       case PPC::FMADDS: Opc = PPC::FNMADDS; break;
       case PPC::FMSUB:  Opc = PPC::FNMSUB;  break;
@@ -988,7 +1001,7 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
       // inverted opcode and the original instruction's operands.  Otherwise, 
       // fall through and generate a fneg instruction.
       if (Opc) {
-        if (PPC::FNABS == Opc)
+        if (Opc == PPC::FNABSS || Opc == PPC::FNABSD)
           CurDAG->SelectNodeTo(N, Opc, Ty, Val.getOperand(0));
         else
           CurDAG->SelectNodeTo(N, Opc, Ty, Val.getOperand(0),
@@ -996,7 +1009,10 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
         return SDOperand(N, 0);
       }
     }
-    CurDAG->SelectNodeTo(N, PPC::FNEG, Ty, Val);
+    if (Ty == MVT::f32)
+      CurDAG->SelectNodeTo(N, PPC::FNEGS, MVT::f32, Val);
+    else
+      CurDAG->SelectNodeTo(N, PPC::FNEGS, MVT::f64, Val);
     return SDOperand(N, 0);
   }
   case ISD::FSQRT: {
@@ -1090,9 +1106,26 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
     case MVT::f64: Opc = isIdx ? PPC::LFDX : PPC::LFD; break;
     }
 
-    CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), MVT::Other,
-                         Op1, Op2, Select(N->getOperand(0)));
-    return SDOperand(N, Op.ResNo);
+    // If this is an f32 -> f64 load, emit the f32 load, then use an 'extending
+    // copy'.
+    if (TypeBeingLoaded != MVT::f32 || N->getOpcode() == ISD::LOAD) {
+        CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), MVT::Other,
+                             Op1, Op2, Select(N->getOperand(0)));
+      return SDOperand(N, Op.ResNo);
+    } else {
+      std::vector<SDOperand> Ops;
+      Ops.push_back(Op1);
+      Ops.push_back(Op2);
+      Ops.push_back(Select(N->getOperand(0)));
+      SDOperand Res = CurDAG->getTargetNode(Opc, MVT::f32, MVT::Other, Ops);
+      SDOperand Ext = CurDAG->getTargetNode(PPC::FMRSD, MVT::f64, Res);
+      CodeGenMap[Op.getValue(0)] = Ext;
+      CodeGenMap[Op.getValue(1)] = Res.getValue(1);
+      if (Op.ResNo)
+        return Res.getValue(1);
+      else
+        return Ext;
+    }
   }
 
   case ISD::TRUNCSTORE:
@@ -1250,7 +1283,13 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
     unsigned BROpc = getBCCForSetCC(CC);
 
     bool isFP = MVT::isFloatingPoint(N->getValueType(0));
-    unsigned SelectCCOp = isFP ? PPC::SELECT_CC_FP : PPC::SELECT_CC_Int;
+    unsigned SelectCCOp;
+    if (MVT::isInteger(N->getValueType(0)))
+      SelectCCOp = PPC::SELECT_CC_Int;
+    else if (N->getValueType(0) == MVT::f32)
+      SelectCCOp = PPC::SELECT_CC_F4;
+    else
+      SelectCCOp = PPC::SELECT_CC_F8;
     CurDAG->SelectNodeTo(N, SelectCCOp, N->getValueType(0), CCReg,
                          Select(N->getOperand(2)), Select(N->getOperand(3)),
                          getI32Imm(BROpc));
index 23d796600c70a9f8e7f0b82118dac76b32320d45..fdefef7c23730bf23bd3ce91428d685ae05d3ec0 100644 (file)
@@ -33,8 +33,8 @@ PPC32TargetLowering::PPC32TargetLowering(TargetMachine &TM)
     
   // Set up the register classes.
   addRegisterClass(MVT::i32, PPC32::GPRCRegisterClass);
-  addRegisterClass(MVT::f32, PPC32::FPRCRegisterClass);
-  addRegisterClass(MVT::f64, PPC32::FPRCRegisterClass);
+  addRegisterClass(MVT::f32, PPC32::F4RCRegisterClass);
+  addRegisterClass(MVT::f64, PPC32::F8RCRegisterClass);
   
   // PowerPC has no intrinsics for these particular operations
   setOperationAction(ISD::MEMMOVE, MVT::Other, Expand);
@@ -396,7 +396,11 @@ PPC32TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
       ObjSize = (ObjectVT == MVT::f64) ? 8 : 4;
       if (!ArgLive) break;
       if (FPR_remaining > 0) {
-        unsigned VReg = RegMap->createVirtualRegister(&PPC32::FPRCRegClass);
+        unsigned VReg;
+        if (ObjectVT == MVT::f32)
+          VReg = RegMap->createVirtualRegister(&PPC32::F4RCRegClass);
+        else
+          VReg = RegMap->createVirtualRegister(&PPC32::F8RCRegClass);
         MF.addLiveIn(FPR[FPR_idx], VReg);
         argt = newroot = DAG.getCopyFromReg(DAG.getRoot(), VReg, ObjectVT);
         --FPR_remaining;
@@ -724,7 +728,8 @@ MachineBasicBlock *
 PPC32TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
                                              MachineBasicBlock *BB) {
   assert((MI->getOpcode() == PPC::SELECT_CC_Int ||
-          MI->getOpcode() == PPC::SELECT_CC_FP) &&
+          MI->getOpcode() == PPC::SELECT_CC_F4 ||
+          MI->getOpcode() == PPC::SELECT_CC_F8) &&
          "Unexpected instr type to insert");
   
   // To "insert" a SELECT_CC instruction, we actually have to insert the diamond
index 9be798499c697629699f108f0b52695d88135d7d..057104999d36d5aaca36bd79399f16f7b35a69a0 100644 (file)
@@ -87,9 +87,6 @@ public:
   inline unsigned MakeIntReg() {
     return RegMap->createVirtualRegister(PPC32::GPRCRegisterClass);
   }
-  inline unsigned MakeFPReg() {
-    return RegMap->createVirtualRegister(PPC32::FPRCRegisterClass);
-  }
   
   // dag -> dag expanders for integer divide by constant
   SDOperand BuildSDIVSequence(SDOperand N);
@@ -593,8 +590,6 @@ unsigned ISel::FoldIfWideZeroExtend(SDOperand N) {
 unsigned ISel::SelectCC(SDOperand LHS, SDOperand RHS, ISD::CondCode CC) {
   unsigned Result, Tmp1, Tmp2;
   bool AlreadySelected = false;
-  static const unsigned CompareOpcodes[] =
-    { PPC::FCMPU, PPC::FCMPU, PPC::CMPW, PPC::CMPLW };
 
   // Allocate a condition register for this expression
   Result = RegMap->createVirtualRegister(PPC32::CRRCRegisterClass);
@@ -626,8 +621,13 @@ unsigned ISel::SelectCC(SDOperand LHS, SDOperand RHS, ISD::CondCode CC) {
     else
       BuildMI(BB, PPC::CMPWI, 2, Result).addReg(Tmp1).addSImm(Tmp2);
   } else {
-    bool IsInteger = MVT::isInteger(LHS.getValueType());
-    unsigned CompareOpc = CompareOpcodes[2 * IsInteger + U];
+    unsigned CompareOpc;
+    if (MVT::isInteger(LHS.getValueType()))
+      CompareOpc = U ? PPC::CMPLW : PPC::CMPW;
+    else if (LHS.getValueType() == MVT::f32)
+      CompareOpc = PPC::FCMPUS;
+    else
+      CompareOpc = PPC::FCMPUD;
     Tmp1 = SelectExpr(LHS);
     Tmp2 = SelectExpr(RHS);
     BuildMI(BB, CompareOpc, 2, Result).addReg(Tmp1).addReg(Tmp2);
@@ -815,7 +815,10 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
     Tmp1 = SelectExpr(N.getOperand(0));
     Tmp2 = SelectExpr(N.getOperand(1));
     Tmp3 = SelectExpr(N.getOperand(2));
-    BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
+    if (N.getOperand(0).getValueType() == MVT::f32)
+      BuildMI(BB, PPC::FSELS, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
+    else
+      BuildMI(BB, PPC::FSELD, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
     return Result;
   case PPCISD::FCFID:
     Tmp1 = SelectExpr(N.getOperand(0));
@@ -832,8 +835,10 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
   case ISD::UNDEF:
     if (Node->getValueType(0) == MVT::i32)
       BuildMI(BB, PPC::IMPLICIT_DEF_GPR, 0, Result);
+    else if (Node->getValueType(0) == MVT::f32)
+      BuildMI(BB, PPC::IMPLICIT_DEF_F4, 0, Result);
     else
-      BuildMI(BB, PPC::IMPLICIT_DEF_FP, 0, Result);
+      BuildMI(BB, PPC::IMPLICIT_DEF_F8, 0, Result);
     return Result;
   case ISD::DYNAMIC_STACKALLOC:
     // Generate both result values.  FIXME: Need a better commment here?
@@ -1011,7 +1016,8 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
       case MVT::f64:
       case MVT::f32:
         assert(FPR_idx < 13 && "Too many fp args");
-        BuildMI(BB, PPC::FMR, 1, FPR[FPR_idx]).addReg(ArgVR[i]);
+        BuildMI(BB, N.getOperand(i+2).getValueType() == MVT::f32 ? PPC::FMRS :
+                PPC::FMRD, 1, FPR[FPR_idx]).addReg(ArgVR[i]);
         CallMI->addRegOperand(FPR[FPR_idx], MachineOperand::Use);
         ++FPR_idx;
         break;
@@ -1033,14 +1039,15 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
       }
       break;
     case MVT::f32:
+      BuildMI(BB, PPC::FMRS, 1, Result).addReg(PPC::F1);
+      break;
     case MVT::f64:
-      BuildMI(BB, PPC::FMR, 1, Result).addReg(PPC::F1);
+      BuildMI(BB, PPC::FMRD, 1, Result).addReg(PPC::F1);
       break;
     }
     return Result+N.ResNo;
   }
 
-  case ISD::SIGN_EXTEND:
   case ISD::SIGN_EXTEND_INREG:
     Tmp1 = SelectExpr(N.getOperand(0));
     switch(cast<VTSDNode>(Node->getOperand(1))->getVT()) {
@@ -1063,8 +1070,10 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
     Tmp1 = dyn_cast<RegisterSDNode>(Node->getOperand(1))->getReg();
     if (MVT::isInteger(DestType))
       BuildMI(BB, PPC::OR, 2, Result).addReg(Tmp1).addReg(Tmp1);
+    else if (DestType == MVT::f32)
+      BuildMI(BB, PPC::FMRS, 1, Result).addReg(Tmp1);
     else
-      BuildMI(BB, PPC::FMR, 1, Result).addReg(Tmp1);
+      BuildMI(BB, PPC::FMRD, 1, Result).addReg(Tmp1);
     return Result;
 
   case ISD::SHL:
@@ -1655,16 +1664,26 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
       BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
     } else if (ISD::FABS == N.getOperand(0).getOpcode()) {
       Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
-      BuildMI(BB, PPC::FNABS, 1, Result).addReg(Tmp1);
+      if (N.getOperand(0).getValueType() == MVT::f32)
+        BuildMI(BB, PPC::FNABSS, 1, Result).addReg(Tmp1);
+      else
+        BuildMI(BB, PPC::FNABSD, 1, Result).addReg(Tmp1);
+
     } else {
       Tmp1 = SelectExpr(N.getOperand(0));
-      BuildMI(BB, PPC::FNEG, 1, Result).addReg(Tmp1);
+      if (N.getOperand(0).getValueType() == MVT::f32)
+        BuildMI(BB, PPC::FNEGS, 1, Result).addReg(Tmp1);
+      else
+        BuildMI(BB, PPC::FNEGD, 1, Result).addReg(Tmp1);
     }
     return Result;
 
   case ISD::FABS:
     Tmp1 = SelectExpr(N.getOperand(0));
-    BuildMI(BB, PPC::FABS, 1, Result).addReg(Tmp1);
+    if (N.getOperand(0).getValueType() == MVT::f32)
+      BuildMI(BB, PPC::FABSS, 1, Result).addReg(Tmp1);
+    else
+      BuildMI(BB, PPC::FABSD, 1, Result).addReg(Tmp1);
     return Result;
 
   case ISD::FSQRT:
@@ -1686,7 +1705,7 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
             N.getOperand(0).getValueType() == MVT::f32 &&
             "only f32 to f64 conversion supported here");
     Tmp1 = SelectExpr(N.getOperand(0));
-    BuildMI(BB, PPC::FMR, 1, Result).addReg(Tmp1);
+    BuildMI(BB, PPC::FMRSD, 1, Result).addReg(Tmp1);
     return Result;
   }
   return 0;
@@ -1735,9 +1754,10 @@ void ISel::Select(SDOperand N) {
     Tmp2 = cast<RegisterSDNode>(N.getOperand(1))->getReg();
 
     if (Tmp1 != Tmp2) {
-      if (N.getOperand(2).getValueType() == MVT::f64 ||
-          N.getOperand(2).getValueType() == MVT::f32)
-        BuildMI(BB, PPC::FMR, 1, Tmp2).addReg(Tmp1);
+      if (N.getOperand(2).getValueType() == MVT::f64)
+        BuildMI(BB, PPC::FMRD, 1, Tmp2).addReg(Tmp1);
+      else if (N.getOperand(2).getValueType() == MVT::f32)
+        BuildMI(BB, PPC::FMRS, 1, Tmp2).addReg(Tmp1);
       else
         BuildMI(BB, PPC::OR, 2, Tmp2).addReg(Tmp1).addReg(Tmp1);
     }
@@ -1747,8 +1767,10 @@ void ISel::Select(SDOperand N) {
     Tmp1 = cast<RegisterSDNode>(N.getOperand(1))->getReg();
     if (N.getOperand(1).getValueType() == MVT::i32)
       BuildMI(BB, PPC::IMPLICIT_DEF_GPR, 0, Tmp1);
+    else if (N.getOperand(1).getValueType() == MVT::f32)
+      BuildMI(BB, PPC::IMPLICIT_DEF_F4, 0, Tmp1);
     else
-      BuildMI(BB, PPC::IMPLICIT_DEF_FP, 0, Tmp1);
+      BuildMI(BB, PPC::IMPLICIT_DEF_F8, 0, Tmp1);
     return;
   case ISD::RET:
     switch (N.getNumOperands()) {
@@ -1771,8 +1793,10 @@ void ISel::Select(SDOperand N) {
         default:
           assert(0 && "Unknown return type!");
         case MVT::f64:
+          BuildMI(BB, PPC::FMRD, 1, PPC::F1).addReg(Tmp1);
+          break;
         case MVT::f32:
-          BuildMI(BB, PPC::FMR, 1, PPC::F1).addReg(Tmp1);
+          BuildMI(BB, PPC::FMRS, 1, PPC::F1).addReg(Tmp1);
           break;
         case MVT::i32:
           BuildMI(BB, PPC::OR, 2, PPC::R3).addReg(Tmp1).addReg(Tmp1);
index 3ec78e3456bb306ad04b7c171c18732031114e87..dc84075eba1c72357255a52c8e1aeeaf11f51aec 100644 (file)
@@ -57,7 +57,7 @@ bool PPC32InstrInfo::isMoveInstr(const MachineInstr& MI,
       destReg = MI.getOperand(0).getReg();
       return true;
     }
-  } else if (oc == PPC::FMR) {              // fmr r1, r2
+  } else if (oc == PPC::FMRS || oc == PPC::FMRD) {      // fmr r1, r2
     assert(MI.getNumOperands() == 2 &&
            MI.getOperand(0).isRegister() &&
            MI.getOperand(1).isRegister() &&
index 98f6359ba5c1b820fe73c92d7dd45671e13dc7df..bc4278c24b1606d5e87d13301c88b7b99df83cdc 100644 (file)
@@ -317,14 +317,17 @@ 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_FP  : Pseudo<(ops FPRC:$rD), "; %rD = IMPLICIT_DEF_FP">;
+def IMPLICIT_DEF_F8  : Pseudo<(ops F8RC:$rD), "; %rD = IMPLICIT_DEF_F8">;
+def IMPLICIT_DEF_F4  : Pseudo<(ops F4RC:$rD), "; %rD = IMPLICIT_DEF_F4">;
 
 // 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!">;
-  def SELECT_CC_FP  : Pseudo<(ops FPRC:$dst, CRRC:$cond, FPRC:$T, FPRC:$F,
+  def SELECT_CC_F4  : Pseudo<(ops F4RC:$dst, CRRC:$cond, F4RC:$T, F4RC:$F,
+                              i32imm:$BROPC), "; SELECT_CC PSEUDO!">;
+  def SELECT_CC_F8  : Pseudo<(ops F8RC:$dst, CRRC:$cond, F8RC:$T, F8RC:$F,
                               i32imm:$BROPC), "; SELECT_CC PSEUDO!">;
 }
 
@@ -463,15 +466,15 @@ def CMPLWI : DForm_6_ext<10, (ops CRRC:$dst, GPRC:$src1, u16imm:$src2),
 def CMPLDI : DForm_6_ext<10, (ops CRRC:$dst, GPRC:$src1, u16imm:$src2),
                          "cmpldi $dst, $src1, $src2">, isPPC64;
 let isLoad = 1 in {
-def LFS : DForm_8<48, (ops FPRC:$rD, symbolLo:$disp, GPRC:$rA),
+def LFS : DForm_8<48, (ops F4RC:$rD, symbolLo:$disp, GPRC:$rA),
                   "lfs $rD, $disp($rA)">;
-def LFD : DForm_8<50, (ops FPRC:$rD, symbolLo:$disp, GPRC:$rA),
+def LFD : DForm_8<50, (ops F8RC:$rD, symbolLo:$disp, GPRC:$rA),
                   "lfd $rD, $disp($rA)">;
 }
 let isStore = 1 in {
-def STFS : DForm_9<52, (ops FPRC:$rS, symbolLo:$disp, GPRC:$rA),
+def STFS : DForm_9<52, (ops F4RC:$rS, symbolLo:$disp, GPRC:$rA),
                    "stfs $rS, $disp($rA)">;
-def STFD : DForm_9<54, (ops FPRC:$rS, symbolLo:$disp, GPRC:$rA),
+def STFD : DForm_9<54, (ops F8RC:$rS, symbolLo:$disp, GPRC:$rA),
                    "stfd $rS, $disp($rA)">;
 }
 
@@ -596,51 +599,74 @@ def CMPLW  : XForm_16_ext<31, 32, (ops CRRC:$crD, GPRC:$rA, GPRC:$rB),
                           "cmplw $crD, $rA, $rB">;
 def CMPLD  : XForm_16_ext<31, 32, (ops CRRC:$crD, GPRC:$rA, GPRC:$rB),
                           "cmpld $crD, $rA, $rB">, isPPC64;
-def FCMPO  : XForm_17<63, 32, (ops CRRC:$crD, FPRC:$fA, FPRC:$fB),
-                      "fcmpo $crD, $fA, $fB">;
-def FCMPU  : XForm_17<63, 0, (ops CRRC:$crD, FPRC:$fA, FPRC:$fB),
+//def FCMPO  : XForm_17<63, 32, (ops CRRC:$crD, FPRC:$fA, FPRC:$fB),
+//                      "fcmpo $crD, $fA, $fB">;
+def FCMPUS : XForm_17<63, 0, (ops CRRC:$crD, F4RC:$fA, F4RC:$fB),
+                      "fcmpu $crD, $fA, $fB">;
+def FCMPUD : XForm_17<63, 0, (ops CRRC:$crD, F8RC:$fA, F8RC:$fB),
                       "fcmpu $crD, $fA, $fB">;
+
 let isLoad = 1 in {
-def LFSX   : XForm_25<31, 535, (ops FPRC:$dst, GPRC:$base, GPRC:$index),
+def LFSX   : XForm_25<31, 535, (ops F4RC:$dst, GPRC:$base, GPRC:$index),
                       "lfsx $dst, $base, $index">;
-def LFDX   : XForm_25<31, 599, (ops FPRC:$dst, GPRC:$base, GPRC:$index),
+def LFDX   : XForm_25<31, 599, (ops F8RC:$dst, GPRC:$base, GPRC:$index),
                       "lfdx $dst, $base, $index">;
 }
-def FCFID  : XForm_26<63, 846, (ops FPRC:$frD, FPRC:$frB),
+def FCFID  : XForm_26<63, 846, (ops F8RC:$frD, F8RC:$frB),
                       "fcfid $frD, $frB",
                       []>, isPPC64;
-def FCTIDZ : XForm_26<63, 815, (ops FPRC:$frD, FPRC:$frB),
+def FCTIDZ : XForm_26<63, 815, (ops F8RC:$frD, F8RC:$frB),
                       "fctidz $frD, $frB",
                       []>, isPPC64;
-def FCTIWZ : XForm_26<63, 15, (ops FPRC:$frD, FPRC:$frB),
+def FCTIWZ : XForm_26<63, 15, (ops F8RC:$frD, F8RC:$frB),
                       "fctiwz $frD, $frB",
                       []>;
-def FABS   : XForm_26<63, 264, (ops FPRC:$frD, FPRC:$frB),
-                      "fabs $frD, $frB",
-                      [(set FPRC:$frD, (fabs FPRC:$frB))]>;
-def FMR    : XForm_26<63, 72, (ops FPRC:$frD, FPRC:$frB),
-                      "fmr $frD, $frB",
-                      []>;  // (set FPRC:$frD, FPRC:$frB)
-def FNABS  : XForm_26<63, 136, (ops FPRC:$frD, FPRC:$frB),
-                      "fnabs $frD, $frB",
-                      [(set FPRC:$frD, (fneg (fabs FPRC:$frB)))]>;
-def FNEG   : XForm_26<63, 40, (ops FPRC:$frD, FPRC:$frB),
-                      "fneg $frD, $frB",
-                      [(set FPRC:$frD, (fneg FPRC:$frB))]>;
-def FRSP   : XForm_26<63, 12, (ops FPRC:$frD, FPRC:$frB),
+def FRSP   : XForm_26<63, 12, (ops F4RC:$frD, F8RC:$frB),
                       "frsp $frD, $frB",
                       []>;
-def FSQRT  : XForm_26<63, 22, (ops FPRC:$frD, FPRC:$frB),
+def FSQRT  : XForm_26<63, 22, (ops F8RC:$frD, F8RC:$frB),
                       "fsqrt $frD, $frB",
-                      [(set FPRC:$frD, (fsqrt FPRC:$frB))]>;
-def FSQRTS : XForm_26<59, 22, (ops FPRC:$frD, FPRC:$frB),
+                      [(set F8RC:$frD, (fsqrt F8RC:$frB))]>;
+def FSQRTS : XForm_26<59, 22, (ops F4RC:$frD, F4RC:$frB),
                       "fsqrts $frD, $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",
+                      []>;  // (set F4RC:$frD, F4RC:$frB)
+def FMRD   : XForm_26<63, 72, (ops F8RC:$frD, F8RC:$frB),
+                      "fmr $frD, $frB",
+                      []>;  // (set F8RC:$frD, F8RC:$frB)
+def FMRSD  : XForm_26<63, 72, (ops F8RC:$frD, F4RC:$frB),
+                      "fmr $frD, $frB",
+                      []>;  // (set F8RC:$frD, (fpextend 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",
+                      [(set F4RC:$frD, (fabs F4RC:$frB))]>;
+def FABSD  : XForm_26<63, 264, (ops F8RC:$frD, F8RC:$frB),
+                      "fabs $frD, $frB",
+                      [(set F8RC:$frD, (fabs F8RC:$frB))]>;
+def FNABSS : XForm_26<63, 136, (ops F4RC:$frD, F4RC:$frB),
+                      "fnabs $frD, $frB",
+                      [(set F4RC:$frD, (fneg (fabs F4RC:$frB)))]>;
+def FNABSD : XForm_26<63, 136, (ops F8RC:$frD, F8RC:$frB),
+                      "fnabs $frD, $frB",
+                      [(set F8RC:$frD, (fneg (fabs F8RC:$frB)))]>;
+def FNEGS  : XForm_26<63, 40, (ops F4RC:$frD, F4RC:$frB),
+                      "fneg $frD, $frB",
+                      [(set F4RC:$frD, (fneg F4RC:$frB))]>;
+def FNEGD  : XForm_26<63, 40, (ops F8RC:$frD, F8RC:$frB),
+                      "fneg $frD, $frB",
+                      [(set F8RC:$frD, (fneg F8RC:$frB))]>;
+                      
                       
 let isStore = 1 in {
-def STFSX : XForm_28<31, 663, (ops FPRC:$frS, GPRC:$rA, GPRC:$rB),
+def STFSX : XForm_28<31, 663, (ops F4RC:$frS, GPRC:$rA, GPRC:$rB),
                      "stfsx $frS, $rA, $rB">;
-def STFDX : XForm_28<31, 727, (ops FPRC:$frS, GPRC:$rA, GPRC:$rB),
+def STFDX : XForm_28<31, 727, (ops F8RC:$frS, GPRC:$rA, GPRC:$rB),
                      "stfdx $frS, $rA, $rB">;
 }
 
@@ -730,75 +756,80 @@ def SUBFZE : XOForm_3<31, 200, 0, (ops GPRC:$rT, GPRC:$rA),
 // this type.
 //
 def FMADD : AForm_1<63, 29, 
-                    (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB),
+                    (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB),
                     "fmadd $FRT, $FRA, $FRC, $FRB",
-                    [(set FPRC:$FRT, (fadd (fmul FPRC:$FRA, FPRC:$FRC),
-                                           FPRC:$FRB))]>;
+                    [(set F8RC:$FRT, (fadd (fmul F8RC:$FRA, F8RC:$FRC),
+                                           F8RC:$FRB))]>;
 def FMADDS : AForm_1<59, 29,
-                    (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB),
+                    (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB),
                     "fmadds $FRT, $FRA, $FRC, $FRB",
                     []>;
 def FMSUB : AForm_1<63, 28,
-                    (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB),
+                    (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB),
                     "fmsub $FRT, $FRA, $FRC, $FRB",
-                    [(set FPRC:$FRT, (fsub (fmul FPRC:$FRA, FPRC:$FRC),
-                                           FPRC:$FRB))]>;
+                    [(set F8RC:$FRT, (fsub (fmul F8RC:$FRA, F8RC:$FRC),
+                                           F8RC:$FRB))]>;
 def FMSUBS : AForm_1<59, 28,
-                    (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB),
+                    (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB),
                     "fmsubs $FRT, $FRA, $FRC, $FRB",
                     []>;
 def FNMADD : AForm_1<63, 31,
-                    (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB),
+                    (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB),
                     "fnmadd $FRT, $FRA, $FRC, $FRB",
-                    [(set FPRC:$FRT, (fneg (fadd (fmul FPRC:$FRA, FPRC:$FRC),
-                                                 FPRC:$FRB)))]>;
+                    [(set F8RC:$FRT, (fneg (fadd (fmul F8RC:$FRA, F8RC:$FRC),
+                                                 F8RC:$FRB)))]>;
 def FNMADDS : AForm_1<59, 31,
-                    (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB),
+                    (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB),
                     "fnmadds $FRT, $FRA, $FRC, $FRB",
                     []>;
 def FNMSUB : AForm_1<63, 30,
-                    (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB),
+                    (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB),
                     "fnmsub $FRT, $FRA, $FRC, $FRB",
-                    [(set FPRC:$FRT, (fneg (fsub (fmul FPRC:$FRA, FPRC:$FRC),
-                                                 FPRC:$FRB)))]>;
+                    [(set F8RC:$FRT, (fneg (fsub (fmul F8RC:$FRA, F8RC:$FRC),
+                                                 F8RC:$FRB)))]>;
 def FNMSUBS : AForm_1<59, 30,
-                    (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB),
+                    (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB),
                     "fnmsubs $FRT, $FRA, $FRC, $FRB",
                     []>;
-def FSEL  : AForm_1<63, 23,
-                    (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRC, FPRC:$FRB),
+// FSEL is artificially split into 4 and 8-byte forms.
+def FSELD : AForm_1<63, 23,
+                    (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB),
+                    "fsel $FRT, $FRA, $FRC, $FRB",
+                    []>;
+def FSELS : AForm_1<63, 23,
+                    (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB),
                     "fsel $FRT, $FRA, $FRC, $FRB",
                     []>;
 def FADD  : AForm_2<63, 21,
-                    (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB),
+                    (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRB),
                     "fadd $FRT, $FRA, $FRB",
-                    [(set FPRC:$FRT, (fadd FPRC:$FRA, FPRC:$FRB))]>;
+                    [(set F8RC:$FRT, (fadd F8RC:$FRA, F8RC:$FRB))]>;
 def FADDS : AForm_2<59, 21,
-                    (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB),
+                    (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRB),
                     "fadds $FRT, $FRA, $FRB",
                     []>;
 def FDIV  : AForm_2<63, 18,
-                    (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB),
+                    (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRB),
                     "fdiv $FRT, $FRA, $FRB",
-                    [(set FPRC:$FRT, (fdiv FPRC:$FRA, FPRC:$FRB))]>;
+                    [(set F8RC:$FRT, (fdiv F8RC:$FRA, F8RC:$FRB))]>;
 def FDIVS : AForm_2<59, 18,
-                    (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB),
+                    (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRB),
                     "fdivs $FRT, $FRA, $FRB",
                     []>;
 def FMUL  : AForm_3<63, 25,
-                    (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB),
+                    (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRB),
                     "fmul $FRT, $FRA, $FRB",
-                    [(set FPRC:$FRT, (fmul FPRC:$FRA, FPRC:$FRB))]>;
+                    [(set F8RC:$FRT, (fmul F8RC:$FRA, F8RC:$FRB))]>;
 def FMULS : AForm_3<59, 25,
-                    (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB),
+                    (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRB),
                     "fmuls $FRT, $FRA, $FRB",
                     []>;
 def FSUB  : AForm_2<63, 20,
-                    (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB),
+                    (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRB),
                     "fsub $FRT, $FRA, $FRB",
-                    [(set FPRC:$FRT, (fsub FPRC:$FRA, FPRC:$FRB))]>;
+                    [(set F8RC:$FRT, (fsub F8RC:$FRA, F8RC:$FRB))]>;
 def FSUBS : AForm_2<59, 20,
-                    (ops FPRC:$FRT, FPRC:$FRA, FPRC:$FRB),
+                    (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRB),
                     "fsubs $FRT, $FRA, $FRB",
                     []>;
 
index 76b0c59aab473bf137c6e97ee495065b73706613..955cb6ba2ef60f147252956f3455ea672b72eac6 100644 (file)
@@ -43,47 +43,26 @@ PPC32RegisterInfo::PPC32RegisterInfo()
   ImmToIdxMap[PPC::ADDI] = PPC::ADD;
 }
 
-static unsigned getIdx(const TargetRegisterClass *RC) {
-  if (RC == PPC32::GPRCRegisterClass) {
-    switch (RC->getSize()) {
-      default: assert(0 && "Invalid data size!");
-      case 1:  return 0;
-      case 2:  return 1;
-      case 4:  return 2;
-    }
-  } else if (RC == PPC32::FPRCRegisterClass) {
-    switch (RC->getSize()) {
-      default: assert(0 && "Invalid data size!");
-      case 4:  return 3;
-      case 8:  return 4;
-    }
-  } else if (RC == PPC32::CRRCRegisterClass) {
-    switch (RC->getSize()) {
-      default: assert(0 && "Invalid data size!");
-      case 4:  return 2;
-    }
-  }
-  std::cerr << "Invalid register class to getIdx()!\n";
-  abort();
-}
-
 void
 PPC32RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
                                        MachineBasicBlock::iterator MI,
                                        unsigned SrcReg, int FrameIdx,
                                        const TargetRegisterClass *RC) const {
-  static const unsigned Opcode[] = {
-    PPC::STB, PPC::STH, PPC::STW, PPC::STFS, PPC::STFD
-  };
-  unsigned OC = Opcode[getIdx(RC)];
   if (SrcReg == PPC::LR) {
     BuildMI(MBB, MI, PPC::MFLR, 1, PPC::R11);
-    addFrameReference(BuildMI(MBB, MI, OC, 3).addReg(PPC::R11),FrameIdx);
+    addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(PPC::R11), FrameIdx);
   } else if (RC == PPC32::CRRCRegisterClass) {
     BuildMI(MBB, MI, PPC::MFCR, 0, PPC::R11);
-    addFrameReference(BuildMI(MBB, MI, OC, 3).addReg(PPC::R11),FrameIdx);
+    addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(PPC::R11), FrameIdx);
+  } else if (RC == PPC32::GPRCRegisterClass) {
+    addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(SrcReg),FrameIdx);
+  } else if (RC == PPC32::F8RCRegisterClass) {
+    addFrameReference(BuildMI(MBB, MI, PPC::STFD, 3).addReg(SrcReg),FrameIdx);
+  } else if (RC == PPC32::F4RCRegisterClass) {
+    addFrameReference(BuildMI(MBB, MI, PPC::STFS, 3).addReg(SrcReg),FrameIdx);
   } else {
-    addFrameReference(BuildMI(MBB, MI, OC, 3).addReg(SrcReg),FrameIdx);
+    assert(0 && "Unknown regclass!");
+    abort();
   }
 }
 
@@ -92,18 +71,21 @@ PPC32RegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
                                         MachineBasicBlock::iterator MI,
                                         unsigned DestReg, int FrameIdx,
                                         const TargetRegisterClass *RC) const {
-  static const unsigned Opcode[] = {
-    PPC::LBZ, PPC::LHZ, PPC::LWZ, PPC::LFS, PPC::LFD
-  };
-  unsigned OC = Opcode[getIdx(RC)];
   if (DestReg == PPC::LR) {
-    addFrameReference(BuildMI(MBB, MI, OC, 2, PPC::R11), FrameIdx);
+    addFrameReference(BuildMI(MBB, MI, PPC::LWZ, 2, PPC::R11), FrameIdx);
     BuildMI(MBB, MI, PPC::MTLR, 1).addReg(PPC::R11);
   } else if (RC == PPC32::CRRCRegisterClass) {
-    addFrameReference(BuildMI(MBB, MI, OC, 2, PPC::R11), FrameIdx);
+    addFrameReference(BuildMI(MBB, MI, PPC::LWZ, 2, PPC::R11), FrameIdx);
     BuildMI(MBB, MI, PPC::MTCRF, 1, DestReg).addReg(PPC::R11);
+  } else if (RC == PPC32::GPRCRegisterClass) {
+    addFrameReference(BuildMI(MBB, MI, PPC::LWZ, 2, DestReg), FrameIdx);
+  } else if (RC == PPC32::F8RCRegisterClass) {
+    addFrameReference(BuildMI(MBB, MI, PPC::LFD, 2, DestReg), FrameIdx);
+  } else if (RC == PPC32::F4RCRegisterClass) {
+    addFrameReference(BuildMI(MBB, MI, PPC::LFS, 2, DestReg), FrameIdx);
   } else {
-    addFrameReference(BuildMI(MBB, MI, OC, 2, DestReg), FrameIdx);
+    assert(0 && "Unknown regclass!");
+    abort();
   }
 }
 
@@ -115,8 +97,10 @@ void PPC32RegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
 
   if (RC == PPC32::GPRCRegisterClass) {
     BuildMI(MBB, MI, PPC::OR, 2, DestReg).addReg(SrcReg).addReg(SrcReg);
-  } else if (RC == PPC32::FPRCRegisterClass) {
-    BuildMI(MBB, MI, PPC::FMR, 1, DestReg).addReg(SrcReg);
+  } else if (RC == PPC32::F4RCRegisterClass) {
+    BuildMI(MBB, MI, PPC::FMRS, 1, DestReg).addReg(SrcReg);
+  } else if (RC == PPC32::F8RCRegisterClass) {
+    BuildMI(MBB, MI, PPC::FMRD, 1, DestReg).addReg(SrcReg);
   } else if (RC == PPC32::CRRCRegisterClass) {
     BuildMI(MBB, MI, PPC::MCRF, 1, DestReg).addReg(SrcReg);
   } else {
@@ -130,6 +114,9 @@ unsigned PPC32RegisterInfo::isLoadFromStackSlot(MachineInstr *MI,
   switch (MI->getOpcode()) {
   default: break;
   case PPC::LWZ:
+    //
+  // case PPC::LFS: // ENABLE!!
+    //
   case PPC::LFD:
     if (MI->getOperand(1).isImmediate() && !MI->getOperand(1).getImmedValue() &&
         MI->getOperand(2).isFrameIndex()) {
@@ -161,8 +148,7 @@ MachineInstr *PPC32RegisterInfo::foldMemoryOperand(MachineInstr *MI,
       return addFrameReference(BuildMI(PPC::LWZ, 2, OutReg), FrameIndex);
     }
     
-  } else if (Opc == PPC::FMR) {
-    // We currently always spill FP values as doubles.  :(
+  } else if (Opc == PPC::FMRD) {
     if (OpNum == 0) {  // move -> store
       unsigned InReg = MI->getOperand(1).getReg();
       return addFrameReference(BuildMI(PPC::STFD,
@@ -171,6 +157,15 @@ MachineInstr *PPC32RegisterInfo::foldMemoryOperand(MachineInstr *MI,
       unsigned OutReg = MI->getOperand(0).getReg();
       return addFrameReference(BuildMI(PPC::LFD, 2, OutReg), FrameIndex);
     }
+  } else if (Opc == PPC::FMRS) {
+    if (OpNum == 0) {  // move -> store
+      unsigned InReg = MI->getOperand(1).getReg();
+      return addFrameReference(BuildMI(PPC::STFS,
+                                       3).addReg(InReg), FrameIndex);
+    } else {           // move -> load
+      unsigned OutReg = MI->getOperand(0).getReg();
+      return addFrameReference(BuildMI(PPC::LFS, 2, OutReg), FrameIndex);
+    }
   }
   return 0;
 }
@@ -262,7 +257,8 @@ PPC32RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const {
     MI.SetMachineOperandReg(1, MI.getOperand(i).getReg());
     MI.SetMachineOperandReg(2, PPC::R0);
   } else {
-    MI.SetMachineOperandConst(OffIdx,MachineOperand::MO_SignExtendedImmed,Offset);
+    MI.SetMachineOperandConst(OffIdx, MachineOperand::MO_SignExtendedImmed,
+                              Offset);
   }
 }