From 02b6d25a2702d8857b82d333f290550e3c6ec4dc Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 9 Mar 2008 08:49:15 +0000 Subject: [PATCH] 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 --- lib/CodeGen/SelectionDAG/ScheduleDAG.cpp | 35 +++++++++++++----------- test/CodeGen/X86/inline-asm-fpstack.ll | 13 +++++++++ 2 files changed, 32 insertions(+), 16 deletions(-) create mode 100644 test/CodeGen/X86/inline-asm-fpstack.ll diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp index 5c8e5904592..5a2b4ede278 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp @@ -433,21 +433,25 @@ void ScheduleDAG::EmitCopyFromReg(SDNode *Node, unsigned ResNo, 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 @@ void ScheduleDAG::AddOperand(MachineInstr *MI, SDOperand Op, 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 @@ void ScheduleDAG::EmitSubregNode(SDNode *Node, 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 { diff --git a/test/CodeGen/X86/inline-asm-fpstack.ll b/test/CodeGen/X86/inline-asm-fpstack.ll new file mode 100644 index 00000000000..e4a76b4d9c2 --- /dev/null +++ b/test/CodeGen/X86/inline-asm-fpstack.ll @@ -0,0 +1,13 @@ +; RUN: llvm-as < %s | llc -march=x86 + +define x86_fp80 @test1() { + %tmp85 = call x86_fp80 asm sideeffect "fld0", "={st(0)}"() + ret x86_fp80 %tmp85 +} + +define double @test2() { + %tmp85 = call double asm sideeffect "fld0", "={st(0)}"() + ret double %tmp85 +} + +