1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-20 19:42:54 +02:00

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.

llvm-svn: 48107
This commit is contained in:
Chris Lattner 2008-03-09 09:15:31 +00:00
parent 1d6b50743f
commit b6bfedbcfd
3 changed files with 57 additions and 16 deletions

View File

@ -844,23 +844,31 @@ void ScheduleDAG::EmitNode(SDNode *Node, unsigned InstanceNo,
case ISD::SRCVALUE: case ISD::SRCVALUE:
break; break;
case ISD::CopyToReg: { case ISD::CopyToReg: {
unsigned InReg; unsigned SrcReg;
if (RegisterSDNode *R = dyn_cast<RegisterSDNode>(Node->getOperand(2))) SDOperand SrcVal = Node->getOperand(2);
InReg = R->getReg(); if (RegisterSDNode *R = dyn_cast<RegisterSDNode>(SrcVal))
SrcReg = R->getReg();
else else
InReg = getVR(Node->getOperand(2), VRBaseMap); SrcReg = getVR(SrcVal, VRBaseMap);
unsigned DestReg = cast<RegisterSDNode>(Node->getOperand(1))->getReg(); unsigned DestReg = cast<RegisterSDNode>(Node->getOperand(1))->getReg();
if (InReg != DestReg) {// Coalesced away the copy? if (SrcReg == DestReg) // Coalesced away the copy? Ignore.
const TargetRegisterClass *TRC = 0; break;
// Get the target register class
if (TargetRegisterInfo::isVirtualRegister(InReg)) const TargetRegisterClass *SrcTRC = 0, *DstTRC = 0;
TRC = RegInfo.getRegClass(InReg); // Get the register classes of the src/dst.
else if (TargetRegisterInfo::isVirtualRegister(SrcReg))
TRC = SrcTRC = RegInfo.getRegClass(SrcReg);
TRI->getPhysicalRegisterRegClass(Node->getOperand(2).getValueType(), else
InReg); SrcTRC = TRI->getPhysicalRegisterRegClass(SrcVal.getValueType(),SrcReg);
TII->copyRegToReg(*BB, BB->end(), DestReg, InReg, TRC, TRC);
} 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; break;
} }
case ISD::CopyFromReg: { case ISD::CopyFromReg: {

View File

@ -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) { if (SrcRC == &X86::RSTRegClass) {
// Copying from ST(0). FIXME: handle ST(1) also // Copying from ST(0). FIXME: handle ST(1) also
assert(SrcReg == X86::ST0 && "Can only copy from TOS right now"); 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); BuildMI(MBB, MI, get(Opc), DestReg);
return; 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!"; cerr << "Not yet supported!";
abort(); abort();

View File

@ -10,4 +10,20 @@ define double @test2() {
ret double %tmp85 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
}