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
This commit is contained in:
Chris Lattner
2008-03-09 08:49:15 +00:00
parent 5c927500c8
commit 02b6d25a27
2 changed files with 32 additions and 16 deletions

View File

@@ -433,21 +433,25 @@ void ScheduleDAG::EmitCopyFromReg(SDNode *Node, unsigned ResNo,
break; 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. // Figure out the register class to create for the destreg.
if (VRBase) if (VRBase) {
TRC = RegInfo.getRegClass(VRBase); DstRC = RegInfo.getRegClass(VRBase);
else } else {
TRC = TRI->getPhysicalRegisterRegClass(Node->getValueType(ResNo), SrcReg); DstRC = DAG.getTargetLoweringInfo()
.getRegClassFor(Node->getValueType(ResNo));
}
// If all uses are reading from the src physical register and copying the // 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. // 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; VRBase = SrcReg;
} else { } else {
// Create the reg, emit the copy. // Create the reg, emit the copy.
VRBase = RegInfo.createVirtualRegister(TRC); VRBase = RegInfo.createVirtualRegister(DstRC);
TII->copyRegToReg(*BB, BB->end(), VRBase, SrcReg, TRC, TRC); TII->copyRegToReg(*BB, BB->end(), VRBase, SrcReg, DstRC, SrcRC);
} }
if (InstanceNo > 0) if (InstanceNo > 0)
@@ -594,14 +598,14 @@ void ScheduleDAG::AddOperand(MachineInstr *MI, SDOperand Op,
unsigned VReg = getVR(Op, VRBaseMap); unsigned VReg = getVR(Op, VRBaseMap);
MI->addOperand(MachineOperand::CreateReg(VReg, false)); 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?"); assert(TargetRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?");
if (II) { if (II) {
const TargetRegisterClass *RC = assert(getInstrOperandRegClass(TRI, TII, *II, IIOpNum) &&
getInstrOperandRegClass(TRI, TII, *II, IIOpNum); "Don't have operand info for this instruction!");
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!");
} }
} }
@@ -674,8 +678,7 @@ void ScheduleDAG::EmitSubregNode(SDNode *Node,
if (VRBase) { if (VRBase) {
// Grab the destination register // Grab the destination register
const TargetRegisterClass *DRC = 0; const TargetRegisterClass *DRC = RegInfo.getRegClass(VRBase);
DRC = RegInfo.getRegClass(VRBase);
assert(SRC && DRC && SRC == DRC && assert(SRC && DRC && SRC == DRC &&
"Source subregister and destination must have the same class"); "Source subregister and destination must have the same class");
} else { } else {

View File

@@ -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
}