diff options
author | Chris Lattner <sabre@nondot.org> | 2008-03-09 08:49:15 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-03-09 08:49:15 +0000 |
commit | 02b6d25a2702d8857b82d333f290550e3c6ec4dc (patch) | |
tree | d2ee25b0a7ab94c316e6d7360cf46e43db51a9d1 | |
parent | 5c927500c823aecafb46881626a5db7822ad019a (diff) |
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
-rw-r--r-- | lib/CodeGen/SelectionDAG/ScheduleDAG.cpp | 35 | ||||
-rw-r--r-- | test/CodeGen/X86/inline-asm-fpstack.ll | 13 |
2 files changed, 32 insertions, 16 deletions
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp index 5c8e590459..5a2b4ede27 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 0000000000..e4a76b4d9c --- /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 +} + + |