mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-27 14:34:58 +00:00
Properly handle passing of FP stuff to varargs function on Win64:
value should be copied to the corresponding shadow reg as well. Patch by Cameron Esfahani! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112262 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
93ded7371f
commit
c52bedba54
@ -2008,6 +2008,19 @@ X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
|
||||
|
||||
if (VA.isRegLoc()) {
|
||||
RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
|
||||
if (isVarArg && Subtarget->isTargetWin64()) {
|
||||
// Win64 ABI requires argument XMM reg to be copied to the corresponding
|
||||
// shadow reg if callee is a varargs function.
|
||||
unsigned ShadowReg = 0;
|
||||
switch (VA.getLocReg()) {
|
||||
case X86::XMM0: ShadowReg = X86::RCX; break;
|
||||
case X86::XMM1: ShadowReg = X86::RDX; break;
|
||||
case X86::XMM2: ShadowReg = X86::R8; break;
|
||||
case X86::XMM3: ShadowReg = X86::R9; break;
|
||||
}
|
||||
if (ShadowReg)
|
||||
RegsToPass.push_back(std::make_pair(ShadowReg, Arg));
|
||||
}
|
||||
} else if (!IsSibcall && (!isTailCall || isByVal)) {
|
||||
assert(VA.isMemLoc());
|
||||
if (StackPtr.getNode() == 0)
|
||||
|
@ -1845,6 +1845,33 @@ static bool isHReg(unsigned Reg) {
|
||||
return X86::GR8_ABCD_HRegClass.contains(Reg);
|
||||
}
|
||||
|
||||
// Try and copy between VR128/VR64 and GR64 registers.
|
||||
static unsigned CopyToFromAsymmetricReg(unsigned DestReg, unsigned SrcReg) {
|
||||
// SrcReg(VR128) -> DestReg(GR64)
|
||||
// SrcReg(VR64) -> DestReg(GR64)
|
||||
// SrcReg(GR64) -> DestReg(VR128)
|
||||
// SrcReg(GR64) -> DestReg(VR64)
|
||||
|
||||
if (X86::GR64RegClass.contains(DestReg)) {
|
||||
if (X86::VR128RegClass.contains(SrcReg)) {
|
||||
// Copy from a VR128 register to a GR64 register.
|
||||
return X86::MOVPQIto64rr;
|
||||
} else if (X86::VR64RegClass.contains(SrcReg)) {
|
||||
// Copy from a VR64 register to a GR64 register.
|
||||
return X86::MOVSDto64rr;
|
||||
}
|
||||
} else if (X86::GR64RegClass.contains(SrcReg)) {
|
||||
// Copy from a GR64 register to a VR128 register.
|
||||
if (X86::VR128RegClass.contains(DestReg))
|
||||
return X86::MOV64toPQIrr;
|
||||
// Copy from a GR64 register to a VR64 register.
|
||||
else if (X86::VR64RegClass.contains(DestReg))
|
||||
return X86::MOV64toSDrr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void X86InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI, DebugLoc DL,
|
||||
unsigned DestReg, unsigned SrcReg,
|
||||
@ -1869,6 +1896,8 @@ void X86InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
|
||||
Opc = X86::MOVAPSrr;
|
||||
else if (X86::VR64RegClass.contains(DestReg, SrcReg))
|
||||
Opc = X86::MMX_MOVQ64rr;
|
||||
else
|
||||
Opc = CopyToFromAsymmetricReg(DestReg, SrcReg);
|
||||
|
||||
if (Opc) {
|
||||
BuildMI(MBB, MI, DL, get(Opc), DestReg)
|
||||
|
Loading…
x
Reference in New Issue
Block a user