Index: gnu/llvm/include/llvm/BinaryFormat/Dwarf.def =================================================================== RCS file: /cvs/src/gnu/llvm/include/llvm/BinaryFormat/Dwarf.def,v retrieving revision 1.1.1.2 diff -u -p -r1.1.1.2 Dwarf.def --- gnu/llvm/include/llvm/BinaryFormat/Dwarf.def 6 Apr 2018 14:26:05 -0000 1.1.1.2 +++ gnu/llvm/include/llvm/BinaryFormat/Dwarf.def 20 Jan 2019 23:34:25 -0000 @@ -351,6 +351,8 @@ HANDLE_DW_AT(0x2133, GNU_addr_base, 0, G HANDLE_DW_AT(0x2134, GNU_pubnames, 0, GNU) HANDLE_DW_AT(0x2135, GNU_pubtypes, 0, GNU) HANDLE_DW_AT(0x2136, GNU_discriminator, 0, GNU) +// Sun Extension +HANDLE_DW_AT(0x2224, SUN_amd64_parmdump, 0, GNU) // Borland extensions. HANDLE_DW_AT(0x3b11, BORLAND_property_read, 0, BORLAND) HANDLE_DW_AT(0x3b12, BORLAND_property_write, 0, BORLAND) Index: gnu/llvm/lib/Target/X86/X86.td =================================================================== RCS file: /cvs/src/gnu/llvm/lib/Target/X86/X86.td,v retrieving revision 1.1.1.5 diff -u -p -r1.1.1.5 X86.td --- gnu/llvm/lib/Target/X86/X86.td 6 Apr 2018 14:26:11 -0000 1.1.1.5 +++ gnu/llvm/lib/Target/X86/X86.td 20 Jan 2019 23:34:25 -0000 @@ -263,6 +263,9 @@ def FeatureSlowIncDec : SubtargetFeature def FeatureSoftFloat : SubtargetFeature<"soft-float", "UseSoftFloat", "true", "Use software floating point features.">; +def FeatureSaveArgs + : SubtargetFeature<"save-args", "SaveArgs", "true", + "Save register arguments on the stack.">; // On recent X86 (port bound) processors, its preferable to combine to a single shuffle // using a variable mask over multiple fixed shuffles. def FeatureFastVariableShuffle Index: gnu/llvm/lib/Target/X86/X86FrameLowering.cpp =================================================================== RCS file: /cvs/src/gnu/llvm/lib/Target/X86/X86FrameLowering.cpp,v retrieving revision 1.4 diff -u -p -r1.4 X86FrameLowering.cpp --- gnu/llvm/lib/Target/X86/X86FrameLowering.cpp 12 Aug 2018 16:59:31 -0000 1.4 +++ gnu/llvm/lib/Target/X86/X86FrameLowering.cpp 20 Jan 2019 23:34:25 -0000 @@ -48,6 +48,7 @@ X86FrameLowering::X86FrameLowering(const // 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 Machi MF.getInfo()->getForceFramePointer() || MF.callsUnwindInit() || MF.hasEHFunclets() || MF.callsEHReturn() || MFI.hasStackMap() || MFI.hasPatchPoint() || - MFI.hasCopyImplyingStackAdjustment()); + MFI.hasCopyImplyingStackAdjustment() || + SaveArgs); } static unsigned getSUBriOpcode(unsigned IsLP64, int64_t Imm) { @@ -849,6 +851,24 @@ void X86FrameLowering::BuildStackAlignAN MI->getOperand(3).setIsDead(); } +// FIXME: Get this from tablegen. +static ArrayRef 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 @@ -1131,6 +1151,43 @@ void X86FrameLowering::emitPrologue(Mach nullptr, DwarfFramePtr)); } + if (SaveArgs && !Fn.arg_empty()) { + ArrayRef 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; @@ -1583,13 +1640,6 @@ void X86FrameLowering::emitEpilogue(Mach } uint64_t SEHStackAllocAmt = NumBytes; - if (HasFP) { - // Pop EBP. - BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r), - MachineFramePtr) - .setMIFlag(MachineInstr::FrameDestroy); - } - MachineBasicBlock::iterator FirstCSPop = MBBI; // Skip the callee-saved pop instructions. while (MBBI != MBB.begin()) { @@ -1654,6 +1704,21 @@ void X86FrameLowering::emitEpilogue(Mach --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); + } + } + // 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 @@ -1725,6 +1790,8 @@ int X86FrameLowering::getFrameIndexRefer "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?!"); Index: gnu/llvm/lib/Target/X86/X86FrameLowering.h =================================================================== RCS file: /cvs/src/gnu/llvm/lib/Target/X86/X86FrameLowering.h,v retrieving revision 1.3 diff -u -p -r1.3 X86FrameLowering.h --- gnu/llvm/lib/Target/X86/X86FrameLowering.h 12 Aug 2018 16:59:31 -0000 1.3 +++ gnu/llvm/lib/Target/X86/X86FrameLowering.h 20 Jan 2019 23:34:25 -0000 @@ -37,6 +37,8 @@ public: const X86RegisterInfo *TRI; const X86ReturnProtectorLowering RPL; + bool SaveArgs; + unsigned SlotSize; /// Is64Bit implies that x86_64 instructions are available. Index: gnu/llvm/lib/Target/X86/X86MachineFunctionInfo.h =================================================================== RCS file: /cvs/src/gnu/llvm/lib/Target/X86/X86MachineFunctionInfo.h,v retrieving revision 1.1.1.2 diff -u -p -r1.1.1.2 X86MachineFunctionInfo.h --- gnu/llvm/lib/Target/X86/X86MachineFunctionInfo.h 14 Jan 2017 19:56:06 -0000 1.1.1.2 +++ gnu/llvm/lib/Target/X86/X86MachineFunctionInfo.h 20 Jan 2019 23:34:25 -0000 @@ -41,6 +41,9 @@ class X86MachineFunctionInfo : public Ma /// stack frame in bytes. unsigned CalleeSavedFrameSize = 0; + // SaveArgSize - Number of register arguments saved on the stack + unsigned SaveArgSize = 0; + /// BytesToPopOnReturn - Number of bytes function pops on return (in addition /// to the space used by the return address). /// Used on windows platform for stdcall & fastcall name decoration @@ -123,6 +126,9 @@ public: unsigned getCalleeSavedFrameSize() const { return CalleeSavedFrameSize; } void setCalleeSavedFrameSize(unsigned bytes) { CalleeSavedFrameSize = bytes; } + + unsigned getSaveArgSize() const { return SaveArgSize; } + void setSaveArgSize(unsigned bytes) { SaveArgSize = bytes; } unsigned getBytesToPopOnReturn() const { return BytesToPopOnReturn; } void setBytesToPopOnReturn (unsigned bytes) { BytesToPopOnReturn = bytes;} Index: gnu/llvm/lib/Target/X86/X86Subtarget.cpp =================================================================== RCS file: /cvs/src/gnu/llvm/lib/Target/X86/X86Subtarget.cpp,v retrieving revision 1.1.1.6 diff -u -p -r1.1.1.6 X86Subtarget.cpp --- gnu/llvm/lib/Target/X86/X86Subtarget.cpp 6 Apr 2018 14:26:11 -0000 1.1.1.6 +++ gnu/llvm/lib/Target/X86/X86Subtarget.cpp 20 Jan 2019 23:34:25 -0000 @@ -341,6 +341,7 @@ void X86Subtarget::initializeEnvironment Slow3OpsLEA = false; SlowIncDec = false; stackAlignment = 4; + SaveArgs = false; // FIXME: this is a known good value for Yonah. How about others? MaxInlineSizeThreshold = 128; UseSoftFloat = false; Index: gnu/llvm/lib/Target/X86/X86Subtarget.h =================================================================== RCS file: /cvs/src/gnu/llvm/lib/Target/X86/X86Subtarget.h,v retrieving revision 1.1.1.5 diff -u -p -r1.1.1.5 X86Subtarget.h --- gnu/llvm/lib/Target/X86/X86Subtarget.h 6 Apr 2018 14:26:11 -0000 1.1.1.5 +++ gnu/llvm/lib/Target/X86/X86Subtarget.h 20 Jan 2019 23:34:25 -0000 @@ -356,6 +356,9 @@ protected: /// entry to the function and which must be maintained by every function. unsigned stackAlignment; + /// Whether function prologues should save register arguments on the stack. + unsigned SaveArgs; + /// Max. memset / memcpy size that is turned into rep/movs, rep/stos ops. /// unsigned MaxInlineSizeThreshold; @@ -420,6 +423,8 @@ public: const X86RegisterInfo *getRegisterInfo() const override { return &getInstrInfo()->getRegisterInfo(); } + + unsigned getSaveArgs() const { return SaveArgs; } /// Returns the minimum alignment known to hold of the /// stack frame on entry to the function and which must be maintained by every Index: gnu/llvm/tools/clang/include/clang/Driver/Options.td =================================================================== RCS file: /cvs/src/gnu/llvm/tools/clang/include/clang/Driver/Options.td,v retrieving revision 1.7 diff -u -p -r1.7 Options.td --- gnu/llvm/tools/clang/include/clang/Driver/Options.td 3 Jun 2018 21:30:38 -0000 1.7 +++ gnu/llvm/tools/clang/include/clang/Driver/Options.td 20 Jan 2019 23:34:25 -0000 @@ -1978,6 +1978,7 @@ def mpie_copy_relocations : Flag<["-"], Flags<[CC1Option]>, HelpText<"Use copy relocations support for PIE builds">; def mno_pie_copy_relocations : Flag<["-"], "mno-pie-copy-relocations">, Group; +def msave_args : Flag<["-"], "msave-args">, Group; def mfentry : Flag<["-"], "mfentry">, HelpText<"Insert calls to fentry at function entry (x86 only)">, Flags<[CC1Option]>, Group; def mips16 : Flag<["-"], "mips16">, Group;