diff options
Diffstat (limited to 'gnu/llvm/lib/Target/X86/X86FrameLowering.cpp')
| -rw-r--r-- | gnu/llvm/lib/Target/X86/X86FrameLowering.cpp | 97 |
1 files changed, 82 insertions, 15 deletions
diff --git a/gnu/llvm/lib/Target/X86/X86FrameLowering.cpp b/gnu/llvm/lib/Target/X86/X86FrameLowering.cpp index ea076e576ef..1a8d3b03836 100644 --- a/gnu/llvm/lib/Target/X86/X86FrameLowering.cpp +++ b/gnu/llvm/lib/Target/X86/X86FrameLowering.cpp @@ -48,6 +48,7 @@ X86FrameLowering::X86FrameLowering(const X86Subtarget &STI, // standard x86_64 and NaCl use 64-bit frame/stack pointers, x32 - 32-bit. Uses64BitFramePtr = STI.isTarget64BitLP64() || STI.isTargetNaCl64(); StackPtr = TRI->getStackRegister(); + SaveArgs = Is64Bit ? STI.getSaveArgs() : 0; } bool X86FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { @@ -91,7 +92,8 @@ bool X86FrameLowering::hasFP(const MachineFunction &MF) const { MF.getInfo<X86MachineFunctionInfo>()->getForceFramePointer() || MF.callsUnwindInit() || MF.hasEHFunclets() || MF.callsEHReturn() || MFI.hasStackMap() || MFI.hasPatchPoint() || - MFI.hasCopyImplyingStackAdjustment()); + MFI.hasCopyImplyingStackAdjustment() || + SaveArgs); } static unsigned getSUBriOpcode(unsigned IsLP64, int64_t Imm) { @@ -872,6 +874,24 @@ void X86FrameLowering::BuildStackAlignAND(MachineBasicBlock &MBB, MI->getOperand(3).setIsDead(); } +// FIXME: Get this from tablegen. +static ArrayRef<MCPhysReg> get64BitArgumentGPRs(CallingConv::ID CallConv, + const X86Subtarget &Subtarget) { + assert(Subtarget.is64Bit()); + + if (Subtarget.isCallingConvWin64(CallConv)) { + static const MCPhysReg GPR64ArgRegsWin64[] = { + X86::RCX, X86::RDX, X86::R8, X86::R9 + }; + return makeArrayRef(std::begin(GPR64ArgRegsWin64), std::end(GPR64ArgRegsWin64)); + } + + static const MCPhysReg GPR64ArgRegs64Bit[] = { + X86::RDI, X86::RSI, X86::RDX, X86::RCX, X86::R8, X86::R9 + }; + return makeArrayRef(std::begin(GPR64ArgRegs64Bit), std::end(GPR64ArgRegs64Bit)); +} + /// emitPrologue - Push callee-saved registers onto the stack, which /// automatically adjust the stack pointer. Adjust the stack pointer to allocate /// space for local variables. Also emit labels used by the exception handler to @@ -1154,6 +1174,43 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF, nullptr, DwarfFramePtr)); } + if (SaveArgs && !Fn.arg_empty()) { + ArrayRef<MCPhysReg> GPRs = + get64BitArgumentGPRs(Fn.getCallingConv(), STI); + unsigned arg_size = Fn.arg_size(); + unsigned RI = 0; + int64_t SaveSize = 0; + + if (Fn.hasStructRetAttr()) { + GPRs = GPRs.drop_front(1); + arg_size--; + } + + for (MCPhysReg Reg : GPRs) { + if (++RI > arg_size) + break; + + SaveSize += SlotSize; + + BuildMI(MBB, MBBI, DL, TII.get(X86::PUSH64r)) + .addReg(Reg) + .setMIFlag(MachineInstr::FrameSetup); + } + + // Realign the stack. PUSHes are the most space efficient. + while (SaveSize % getStackAlignment()) { + BuildMI(MBB, MBBI, DL, TII.get(X86::PUSH64r)) + .addReg(GPRs.front()) + .setMIFlag(MachineInstr::FrameSetup); + + SaveSize += SlotSize; + } + + //dlg StackSize -= SaveSize; + //dlg MFI.setStackSize(StackSize); + X86FI->setSaveArgSize(SaveSize); + } + if (NeedsWinFPO) { // .cv_fpo_setframe $FramePtr HasWinCFI = true; @@ -1619,20 +1676,6 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF, } uint64_t SEHStackAllocAmt = NumBytes; - if (HasFP) { - // Pop EBP. - BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r), - MachineFramePtr) - .setMIFlag(MachineInstr::FrameDestroy); - if (NeedsDwarfCFI) { - unsigned DwarfStackPtr = - TRI->getDwarfRegNum(Is64Bit ? X86::RSP : X86::ESP, true); - BuildCFI(MBB, MBBI, DL, MCCFIInstruction::createDefCfa( - nullptr, DwarfStackPtr, -SlotSize)); - --MBBI; - } - } - MachineBasicBlock::iterator FirstCSPop = MBBI; // Skip the callee-saved pop instructions. while (MBBI != MBB.begin()) { @@ -1702,6 +1745,28 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF, --MBBI; } + if (HasFP) { + MBBI = Terminator; + + if (X86FI->getSaveArgSize()) { + // LEAVE is effectively mov rbp,rsp; pop rbp + BuildMI(MBB, MBBI, DL, TII.get(X86::LEAVE64), MachineFramePtr) + .setMIFlag(MachineInstr::FrameDestroy); + } else { + // Pop EBP. + BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r), + MachineFramePtr) + .setMIFlag(MachineInstr::FrameDestroy); + } + if (NeedsDwarfCFI) { + unsigned DwarfStackPtr = + TRI->getDwarfRegNum(Is64Bit ? X86::RSP : X86::ESP, true); + BuildCFI(MBB, MBBI, DL, MCCFIInstruction::createDefCfa( + nullptr, DwarfStackPtr, -SlotSize)); + --MBBI; + } + } + // Windows unwinder will not invoke function's exception handler if IP is // either in prologue or in epilogue. This behavior causes a problem when a // call immediately precedes an epilogue, because the return address points @@ -1790,6 +1855,8 @@ int X86FrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI, "FPDelta isn't aligned per the Win64 ABI!"); } + if (FI >= 0) + Offset -= X86FI->getSaveArgSize(); if (TRI->hasBasePointer(MF)) { assert(HasFP && "VLAs and dynamic stack realign, but no FP?!"); |
