[llvm-commits] [llvm] r48107 - in /llvm/trunk: lib/CodeGen/SelectionDAG/ScheduleDAG.cpp lib/Target/X86/X86InstrInfo.cpp test/CodeGen/X86/inline-asm-fpstack.ll

Chris Lattner sabre at nondot.org
Sun Mar 9 01:15:33 PST 2008


Author: lattner
Date: Sun Mar  9 04:15:31 2008
New Revision: 48107

URL: http://llvm.org/viewvc/llvm-project?rev=48107&view=rev
Log:
teach X86InstrInfo::copyRegToReg how to copy into ST(0) from 
an RFP register class.

Teach ScheduleDAG how to handle CopyToReg with different src/dst 
reg classes.

This allows us to compile trivial inline asms that expect stuff
on the top of x87-fp stack.

Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
    llvm/trunk/lib/Target/X86/X86InstrInfo.cpp
    llvm/trunk/test/CodeGen/X86/inline-asm-fpstack.ll

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp?rev=48107&r1=48106&r2=48107&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Sun Mar  9 04:15:31 2008
@@ -844,23 +844,31 @@
     case ISD::SRCVALUE:
       break;
     case ISD::CopyToReg: {
-      unsigned InReg;
-      if (RegisterSDNode *R = dyn_cast<RegisterSDNode>(Node->getOperand(2)))
-        InReg = R->getReg();
+      unsigned SrcReg;
+      SDOperand SrcVal = Node->getOperand(2);
+      if (RegisterSDNode *R = dyn_cast<RegisterSDNode>(SrcVal))
+        SrcReg = R->getReg();
       else
-        InReg = getVR(Node->getOperand(2), VRBaseMap);
+        SrcReg = getVR(SrcVal, VRBaseMap);
+      
       unsigned DestReg = cast<RegisterSDNode>(Node->getOperand(1))->getReg();
-      if (InReg != DestReg)  {// Coalesced away the copy?
-        const TargetRegisterClass *TRC = 0;
-        // Get the target register class
-        if (TargetRegisterInfo::isVirtualRegister(InReg))
-          TRC = RegInfo.getRegClass(InReg);
-        else
-          TRC =
-            TRI->getPhysicalRegisterRegClass(Node->getOperand(2).getValueType(),
-                                            InReg);
-        TII->copyRegToReg(*BB, BB->end(), DestReg, InReg, TRC, TRC);
-      }
+      if (SrcReg == DestReg) // Coalesced away the copy? Ignore.
+        break;
+      
+      const TargetRegisterClass *SrcTRC = 0, *DstTRC = 0;
+      // Get the register classes of the src/dst.
+      if (TargetRegisterInfo::isVirtualRegister(SrcReg))
+        SrcTRC = RegInfo.getRegClass(SrcReg);
+      else
+        SrcTRC = TRI->getPhysicalRegisterRegClass(SrcVal.getValueType(),SrcReg);
+
+      if (TargetRegisterInfo::isVirtualRegister(DestReg))
+        DstTRC = RegInfo.getRegClass(DestReg);
+      else
+        DstTRC = TRI->getPhysicalRegisterRegClass(
+                                            Node->getOperand(1).getValueType(),
+                                                  DestReg);
+      TII->copyRegToReg(*BB, BB->end(), DestReg, SrcReg, DstTRC, SrcTRC);
       break;
     }
     case ISD::CopyFromReg: {

Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=48107&r1=48106&r2=48107&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Sun Mar  9 04:15:31 2008
@@ -1465,7 +1465,7 @@
     }
   }
   
-  // Moving ST(0) to/from a register turns into FpGET_ST0_32 etc.
+  // Moving from ST(0) turns into FpGET_ST0_32 etc.
   if (SrcRC == &X86::RSTRegClass) {
     // Copying from ST(0).  FIXME: handle ST(1) also
     assert(SrcReg == X86::ST0 && "Can only copy from TOS right now");
@@ -1481,6 +1481,23 @@
     BuildMI(MBB, MI, get(Opc), DestReg);
     return;
   }
+
+  // Moving to ST(0) turns into FpSET_ST0_32 etc.
+  if (DestRC == &X86::RSTRegClass) {
+    // Copying to ST(0).  FIXME: handle ST(1) also
+    assert(DestReg == X86::ST0 && "Can only copy to TOS right now");
+    unsigned Opc;
+    if (SrcRC == &X86::RFP32RegClass)
+      Opc = X86::FpSET_ST0_32;
+    else if (SrcRC == &X86::RFP64RegClass)
+      Opc = X86::FpSET_ST0_64;
+    else {
+      assert(SrcRC == &X86::RFP80RegClass);
+      Opc = X86::FpSET_ST0_80;
+    }
+    BuildMI(MBB, MI, get(Opc)).addReg(SrcReg);
+    return;
+  }
   
   cerr << "Not yet supported!";
   abort();

Modified: llvm/trunk/test/CodeGen/X86/inline-asm-fpstack.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/inline-asm-fpstack.ll?rev=48107&r1=48106&r2=48107&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/X86/inline-asm-fpstack.ll (original)
+++ llvm/trunk/test/CodeGen/X86/inline-asm-fpstack.ll Sun Mar  9 04:15:31 2008
@@ -10,4 +10,20 @@
         ret double %tmp85
 }
 
+define void @test3(x86_fp80 %X) {
+        call void asm sideeffect "frob ", "{st(0)},~{dirflag},~{fpsr},~{flags}"( x86_fp80 %X)
+        ret void
+}
+
+define void @test4(double %X) {
+        call void asm sideeffect "frob ", "{st(0)},~{dirflag},~{fpsr},~{flags}"( double %X)
+        ret void
+}
+
+define void @test5(double %X) {
+        %Y = add double %X, 123.0
+        call void asm sideeffect "frob ", "{st(0)},~{dirflag},~{fpsr},~{flags}"( double %Y)
+        ret void
+}
+
 





More information about the llvm-commits mailing list