From f30e1cf9b7f96395768e710b4707ecd5587e1185 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 9 Mar 2008 09:15:31 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48107 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/ScheduleDAG.cpp | 38 ++++++++++++++---------- lib/Target/X86/X86InstrInfo.cpp | 19 +++++++++++- test/CodeGen/X86/inline-asm-fpstack.ll | 16 ++++++++++ 3 files changed, 57 insertions(+), 16 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp index 5a2b4ede278..31a784eca88 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp @@ -844,23 +844,31 @@ void ScheduleDAG::EmitNode(SDNode *Node, unsigned InstanceNo, case ISD::SRCVALUE: break; case ISD::CopyToReg: { - unsigned InReg; - if (RegisterSDNode *R = dyn_cast(Node->getOperand(2))) - InReg = R->getReg(); + unsigned SrcReg; + SDOperand SrcVal = Node->getOperand(2); + if (RegisterSDNode *R = dyn_cast(SrcVal)) + SrcReg = R->getReg(); else - InReg = getVR(Node->getOperand(2), VRBaseMap); + SrcReg = getVR(SrcVal, VRBaseMap); + unsigned DestReg = cast(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: { diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp index 01a7cd401f9..3c12fa17356 100644 --- a/lib/Target/X86/X86InstrInfo.cpp +++ b/lib/Target/X86/X86InstrInfo.cpp @@ -1465,7 +1465,7 @@ void X86InstrInfo::copyRegToReg(MachineBasicBlock &MBB, } } - // 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 @@ void X86InstrInfo::copyRegToReg(MachineBasicBlock &MBB, 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(); diff --git a/test/CodeGen/X86/inline-asm-fpstack.ll b/test/CodeGen/X86/inline-asm-fpstack.ll index e4a76b4d9c2..1e308d9b78d 100644 --- a/test/CodeGen/X86/inline-asm-fpstack.ll +++ b/test/CodeGen/X86/inline-asm-fpstack.ll @@ -10,4 +10,20 @@ define double @test2() { 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 +} + -- 2.34.1