Add ScheduleDAG support for copytoreg where the src/dst register are
in different register classes, e.g. copy of ST(0) to RFP*.  This gets
some really trivial inline asm working that plops things on the top of
stack (PR879)


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48105 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
index 5c8e590..5a2b4ed 100644
--- a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
@@ -433,21 +433,25 @@
       break;
   }
 
-  const TargetRegisterClass *TRC = 0;
+  const TargetRegisterClass *SrcRC = 0, *DstRC = 0;
+  SrcRC = TRI->getPhysicalRegisterRegClass(Node->getValueType(ResNo), SrcReg);
+  
   // Figure out the register class to create for the destreg.
-  if (VRBase)
-    TRC = RegInfo.getRegClass(VRBase);
-  else
-    TRC = TRI->getPhysicalRegisterRegClass(Node->getValueType(ResNo), SrcReg);
+  if (VRBase) {
+    DstRC = RegInfo.getRegClass(VRBase);
+  } else {
+    DstRC = DAG.getTargetLoweringInfo()
+             .getRegClassFor(Node->getValueType(ResNo));
+  }
     
   // If all uses are reading from the src physical register and copying the
   // register is either impossible or very expensive, then don't create a copy.
-  if (MatchReg && TRC->getCopyCost() < 0) {
+  if (MatchReg && SrcRC->getCopyCost() < 0) {
     VRBase = SrcReg;
   } else {
     // Create the reg, emit the copy.
-    VRBase = RegInfo.createVirtualRegister(TRC);
-    TII->copyRegToReg(*BB, BB->end(), VRBase, SrcReg, TRC, TRC);
+    VRBase = RegInfo.createVirtualRegister(DstRC);
+    TII->copyRegToReg(*BB, BB->end(), VRBase, SrcReg, DstRC, SrcRC);
   }
 
   if (InstanceNo > 0)
@@ -594,14 +598,14 @@
     unsigned VReg = getVR(Op, VRBaseMap);
     MI->addOperand(MachineOperand::CreateReg(VReg, false));
     
-    // Verify that it is right.
+    // Verify that it is right.  Note that the reg class of the physreg and the
+    // vreg don't necessarily need to match, but the target copy insertion has
+    // to be able to handle it.  This handles things like copies from ST(0) to
+    // an FP vreg on x86.
     assert(TargetRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?");
     if (II) {
-      const TargetRegisterClass *RC =
-                            getInstrOperandRegClass(TRI, TII, *II, IIOpNum);
-      assert(RC && "Don't have operand info for this instruction!");
-      assert(RegInfo.getRegClass(VReg) == RC &&
-             "Register class of operand and regclass of use don't agree!");
+      assert(getInstrOperandRegClass(TRI, TII, *II, IIOpNum) &&
+             "Don't have operand info for this instruction!");
     }
   }
   
@@ -674,8 +678,7 @@
 
     if (VRBase) {
       // Grab the destination register
-      const TargetRegisterClass *DRC = 0;
-      DRC = RegInfo.getRegClass(VRBase);
+      const TargetRegisterClass *DRC = RegInfo.getRegClass(VRBase);
       assert(SRC && DRC && SRC == DRC && 
              "Source subregister and destination must have the same class");
     } else {