X86FrameLowering.cpp revision 89ec1c5c9c744c125b61145ed59783eb5c68ebf8
131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- X86FrameLowering.cpp - X86 Frame Information ----------------------===// 233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// The LLVM Compiler Infrastructure 433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// This file is distributed under the University of Illinois Open Source 633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// License. See LICENSE.TXT for details. 733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov//===----------------------------------------------------------------------===// 933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 1016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov// This file contains the X86 implementation of TargetFrameLowering class. 1133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 1233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov//===----------------------------------------------------------------------===// 1333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 1416c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov#include "X86FrameLowering.h" 1533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "X86InstrBuilder.h" 1633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "X86InstrInfo.h" 1733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "X86MachineFunctionInfo.h" 1876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola#include "X86Subtarget.h" 19d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov#include "X86TargetMachine.h" 20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/SmallSet.h" 2133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineFrameInfo.h" 2233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineFunction.h" 2333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineInstrBuilder.h" 2433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineModuleInfo.h" 2533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineRegisterInfo.h" 260b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h" 270b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h" 28f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola#include "llvm/MC/MCAsmInfo.h" 296a6b8c3e96b9e1ca7092eafd0cfb219cbbfbdfc4Bill Wendling#include "llvm/MC/MCSymbol.h" 3033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/Support/CommandLine.h" 31d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetOptions.h" 3233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 3333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovusing namespace llvm; 3433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 3533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// FIXME: completely move here. 3633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovextern cl::opt<bool> ForceStackAlign; 3733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 3816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovbool X86FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 39d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov return !MF.getFrameInfo()->hasVarSizedObjects(); 40d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov} 41d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 42d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov/// hasFP - Return true if the specified function should have a dedicated frame 43d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov/// pointer register. This is true if the function has variable sized allocas 44d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov/// or if frame pointer elimination is disabled. 4516c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovbool X86FrameLowering::hasFP(const MachineFunction &MF) const { 46d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov const MachineFrameInfo *MFI = MF.getFrameInfo(); 47d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov const MachineModuleInfo &MMI = MF.getMMI(); 483fb6eca0cd4c2b31b06543ca2ac60b9c91c2264dChad Rosier const TargetRegisterInfo *RegInfo = TM.getRegisterInfo(); 49d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 508a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky return (MF.getTarget().Options.DisableFramePointerElim(MF) || 513fb6eca0cd4c2b31b06543ca2ac60b9c91c2264dChad Rosier RegInfo->needsStackRealignment(MF) || 52d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov MFI->hasVarSizedObjects() || 53b56606274d43c7a3e01b18a08d1115fbf2889996Chad Rosier MFI->isFrameAddressTaken() || MF.hasMSInlineAsm() || 54d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov MF.getInfo<X86MachineFunctionInfo>()->getForceFramePointer() || 55e208c491726bb1efbfc4fc05a9f73ad808432979Jakob Stoklund Olesen MMI.callsUnwindInit() || MMI.callsEHReturn()); 56d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov} 57d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 58700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Benderskystatic unsigned getSUBriOpcode(unsigned IsLP64, int64_t Imm) { 59700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (IsLP64) { 6033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (isInt<8>(Imm)) 6133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::SUB64ri8; 6233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::SUB64ri32; 6333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 6433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (isInt<8>(Imm)) 6533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::SUB32ri8; 6633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::SUB32ri; 6733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 6833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 6933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 7016221a60a00e52b078f6164ba4475c6e8e918e4bEli Benderskystatic unsigned getADDriOpcode(unsigned IsLP64, int64_t Imm) { 7116221a60a00e52b078f6164ba4475c6e8e918e4bEli Bendersky if (IsLP64) { 7233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (isInt<8>(Imm)) 7333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::ADD64ri8; 7433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::ADD64ri32; 7533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 7633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (isInt<8>(Imm)) 7733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::ADD32ri8; 7833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::ADD32ri; 7933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 8033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 8133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 8216221a60a00e52b078f6164ba4475c6e8e918e4bEli Benderskystatic unsigned getLEArOpcode(unsigned IsLP64) { 8316221a60a00e52b078f6164ba4475c6e8e918e4bEli Bendersky return IsLP64 ? X86::LEA64r : X86::LEA32r; 84de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng} 85de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng 867158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng/// findDeadCallerSavedReg - Return a caller-saved register that isn't live 877158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng/// when it reaches the "return" instruction. We can then pop a stack object 887158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng/// to this register without worry about clobbering it. 897158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Chengstatic unsigned findDeadCallerSavedReg(MachineBasicBlock &MBB, 907158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng MachineBasicBlock::iterator &MBBI, 917158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng const TargetRegisterInfo &TRI, 927158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng bool Is64Bit) { 937158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng const MachineFunction *MF = MBB.getParent(); 947158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng const Function *F = MF->getFunction(); 957158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng if (!F || MF->getMMI().callsEHReturn()) 967158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng return 0; 977158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 98e4fd907e72a599eddfa7a81eac4366b5b82523e3Craig Topper static const uint16_t CallerSavedRegs32Bit[] = { 9932a183c84ad0cbe492119c37f1a7941ace61dd79Andrew Trick X86::EAX, X86::EDX, X86::ECX, 0 1007158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng }; 1017158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 102e4fd907e72a599eddfa7a81eac4366b5b82523e3Craig Topper static const uint16_t CallerSavedRegs64Bit[] = { 1037158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng X86::RAX, X86::RDX, X86::RCX, X86::RSI, X86::RDI, 10432a183c84ad0cbe492119c37f1a7941ace61dd79Andrew Trick X86::R8, X86::R9, X86::R10, X86::R11, 0 1057158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng }; 1067158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 1077158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng unsigned Opc = MBBI->getOpcode(); 1087158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng switch (Opc) { 1097158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng default: return 0; 1107158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::RET: 1117158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::RETI: 1127158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::TCRETURNdi: 1137158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::TCRETURNri: 1147158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::TCRETURNmi: 1157158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::TCRETURNdi64: 1167158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::TCRETURNri64: 1177158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::TCRETURNmi64: 1187158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::EH_RETURN: 1197158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::EH_RETURN64: { 120e4fd907e72a599eddfa7a81eac4366b5b82523e3Craig Topper SmallSet<uint16_t, 8> Uses; 1217158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng for (unsigned i = 0, e = MBBI->getNumOperands(); i != e; ++i) { 1227158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng MachineOperand &MO = MBBI->getOperand(i); 1237158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng if (!MO.isReg() || MO.isDef()) 1247158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng continue; 1257158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng unsigned Reg = MO.getReg(); 1267158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng if (!Reg) 1277158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng continue; 128396618b43a85e12d290a90b181c6af5d7c0c5f11Jakob Stoklund Olesen for (MCRegAliasIterator AI(Reg, &TRI, true); AI.isValid(); ++AI) 129396618b43a85e12d290a90b181c6af5d7c0c5f11Jakob Stoklund Olesen Uses.insert(*AI); 1307158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng } 1317158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 132e4fd907e72a599eddfa7a81eac4366b5b82523e3Craig Topper const uint16_t *CS = Is64Bit ? CallerSavedRegs64Bit : CallerSavedRegs32Bit; 1337158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng for (; *CS; ++CS) 1347158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng if (!Uses.count(*CS)) 1357158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng return *CS; 1367158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng } 1377158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng } 1387158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 1397158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng return 0; 1407158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng} 1417158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 1427158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 14333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// emitSPUpdate - Emit a series of instructions to increment / decrement the 14433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// stack pointer by a constant value. 14533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovstatic 14633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovvoid emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, 1477158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng unsigned StackPtr, int64_t NumBytes, 1482a1b60d791522d73be91d4281c90d25bd5e3d117Eli Bendersky bool Is64Bit, bool IsLP64, bool UseLEA, 14976ad43c6e1619ed4c087b8ccb2cd573eb9d7093eEric Christopher const TargetInstrInfo &TII, const TargetRegisterInfo &TRI) { 15033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool isSub = NumBytes < 0; 15133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t Offset = isSub ? -NumBytes : NumBytes; 152de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng unsigned Opc; 153de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng if (UseLEA) 15416221a60a00e52b078f6164ba4475c6e8e918e4bEli Bendersky Opc = getLEArOpcode(IsLP64); 155de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng else 156de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng Opc = isSub 1572a1b60d791522d73be91d4281c90d25bd5e3d117Eli Bendersky ? getSUBriOpcode(IsLP64, Offset) 1582a1b60d791522d73be91d4281c90d25bd5e3d117Eli Bendersky : getADDriOpcode(IsLP64, Offset); 159de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng 16033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t Chunk = (1LL << 31) - 1; 16176ad43c6e1619ed4c087b8ccb2cd573eb9d7093eEric Christopher DebugLoc DL = MBB.findDebugLoc(MBBI); 16233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 16333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov while (Offset) { 16433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t ThisVal = (Offset > Chunk) ? Chunk : Offset; 1657158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng if (ThisVal == (Is64Bit ? 8 : 4)) { 1667158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng // Use push / pop instead. 1677158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng unsigned Reg = isSub 1681e08cd1eaef8acbcfaf7db48d859a29583c29897Dale Johannesen ? (unsigned)(Is64Bit ? X86::RAX : X86::EAX) 1697158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng : findDeadCallerSavedReg(MBB, MBBI, TRI, Is64Bit); 1707158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng if (Reg) { 1717158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng Opc = isSub 1727158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng ? (Is64Bit ? X86::PUSH64r : X86::PUSH32r) 1737158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng : (Is64Bit ? X86::POP64r : X86::POP32r); 174aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis MachineInstr *MI = BuildMI(MBB, MBBI, DL, TII.get(Opc)) 1757158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng .addReg(Reg, getDefRegState(!isSub) | getUndefRegState(isSub)); 176aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis if (isSub) 177aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis MI->setFlag(MachineInstr::FrameSetup); 1787158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng Offset -= ThisVal; 1797158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng continue; 1807158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng } 1817158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng } 1827158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 183de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng MachineInstr *MI = NULL; 184de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng 185de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng if (UseLEA) { 186de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng MI = addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr), 187de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng StackPtr, false, isSub ? -ThisVal : ThisVal); 188de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng } else { 189de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng MI = BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr) 190de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng .addReg(StackPtr) 191de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng .addImm(ThisVal); 192de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng MI->getOperand(3).setIsDead(); // The EFLAGS implicit def is dead. 193de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng } 194de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng 195aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis if (isSub) 196aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis MI->setFlag(MachineInstr::FrameSetup); 197de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng 19833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Offset -= ThisVal; 19933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 20033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 20133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 20233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// mergeSPUpdatesUp - Merge two stack-manipulating instructions upper iterator. 20333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovstatic 20433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovvoid mergeSPUpdatesUp(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, 20533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackPtr, uint64_t *NumBytes = NULL) { 20633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MBBI == MBB.begin()) return; 20733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 20833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator PI = prior(MBBI); 20933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Opc = PI->getOpcode(); 21033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 || 211de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng Opc == X86::ADD32ri || Opc == X86::ADD32ri8 || 212de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng Opc == X86::LEA32r || Opc == X86::LEA64_32r) && 21333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PI->getOperand(0).getReg() == StackPtr) { 21433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (NumBytes) 21533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *NumBytes += PI->getOperand(2).getImm(); 21633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBB.erase(PI); 21733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 || 21833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Opc == X86::SUB32ri || Opc == X86::SUB32ri8) && 21933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PI->getOperand(0).getReg() == StackPtr) { 22033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (NumBytes) 22133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *NumBytes -= PI->getOperand(2).getImm(); 22233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBB.erase(PI); 22333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 22433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 22533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 22633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// mergeSPUpdatesDown - Merge two stack-manipulating instructions lower iterator. 22733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovstatic 22833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovvoid mergeSPUpdatesDown(MachineBasicBlock &MBB, 22933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator &MBBI, 23033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackPtr, uint64_t *NumBytes = NULL) { 231fc9261279aa140542cf9b7c2c384d000ad97aca0Sanjoy Das // FIXME: THIS ISN'T RUN!!! 23233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return; 23333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 23433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MBBI == MBB.end()) return; 23533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 23633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator NI = llvm::next(MBBI); 23733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (NI == MBB.end()) return; 23833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 23933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Opc = NI->getOpcode(); 24033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 || 24133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Opc == X86::ADD32ri || Opc == X86::ADD32ri8) && 24233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov NI->getOperand(0).getReg() == StackPtr) { 24333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (NumBytes) 24433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *NumBytes -= NI->getOperand(2).getImm(); 24533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBB.erase(NI); 24633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBBI = NI; 24733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 || 24833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Opc == X86::SUB32ri || Opc == X86::SUB32ri8) && 24933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov NI->getOperand(0).getReg() == StackPtr) { 25033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (NumBytes) 25133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *NumBytes += NI->getOperand(2).getImm(); 25233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBB.erase(NI); 25333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBBI = NI; 25433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 25533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 25633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 25733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// mergeSPUpdates - Checks the instruction before/after the passed 258de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng/// instruction. If it is an ADD/SUB/LEA instruction it is deleted argument and the 259de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng/// stack adjustment is returned as a positive value for ADD/LEA and a negative for 26033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// SUB. 26133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovstatic int mergeSPUpdates(MachineBasicBlock &MBB, 26233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator &MBBI, 26333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackPtr, 26433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool doMergeWithPrevious) { 26533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if ((doMergeWithPrevious && MBBI == MBB.begin()) || 26633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov (!doMergeWithPrevious && MBBI == MBB.end())) 26733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return 0; 26833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 26933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator PI = doMergeWithPrevious ? prior(MBBI) : MBBI; 27033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator NI = doMergeWithPrevious ? 0 : llvm::next(MBBI); 27133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Opc = PI->getOpcode(); 27233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int Offset = 0; 27333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 27433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 || 275de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng Opc == X86::ADD32ri || Opc == X86::ADD32ri8 || 276de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng Opc == X86::LEA32r || Opc == X86::LEA64_32r) && 27733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PI->getOperand(0).getReg() == StackPtr){ 27833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Offset += PI->getOperand(2).getImm(); 27933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBB.erase(PI); 28033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!doMergeWithPrevious) MBBI = NI; 28133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 || 28233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Opc == X86::SUB32ri || Opc == X86::SUB32ri8) && 28333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PI->getOperand(0).getReg() == StackPtr) { 28433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Offset -= PI->getOperand(2).getImm(); 28533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBB.erase(PI); 28633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!doMergeWithPrevious) MBBI = NI; 28733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 28833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 28933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return Offset; 29033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 29133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 29233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovstatic bool isEAXLiveIn(MachineFunction &MF) { 29333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (MachineRegisterInfo::livein_iterator II = MF.getRegInfo().livein_begin(), 29433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov EE = MF.getRegInfo().livein_end(); II != EE; ++II) { 29533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Reg = II->first; 29633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 29733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (Reg == X86::EAX || Reg == X86::AX || 29833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Reg == X86::AH || Reg == X86::AL) 29933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return true; 30033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 30133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 30233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return false; 30333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 30433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 30516c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid X86FrameLowering::emitCalleeSavedFrameMoves(MachineFunction &MF, 30609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling MCSymbol *Label, 30709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned FramePtr) const { 30833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 30933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineModuleInfo &MMI = MF.getMMI(); 31033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 31133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Add callee saved registers to move list. 31233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 31333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (CSI.empty()) return; 31433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 31533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov std::vector<MachineMove> &Moves = MMI.getFrameMoves(); 316aa3c2c09d9d5bc67c6ca2fbc6697257b15476684Michael Liao const X86RegisterInfo *RegInfo = TM.getRegisterInfo(); 317d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov bool HasFP = hasFP(MF); 31833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 31933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Calculate amount of bytes used for return address storing. 320aa3c2c09d9d5bc67c6ca2fbc6697257b15476684Michael Liao int stackGrowth = -RegInfo->getSlotSize(); 32133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 32233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // FIXME: This is dirty hack. The code itself is pretty mess right now. 32333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // It should be rewritten from scratch and generalized sometimes. 32433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 3257a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // Determine maximum offset (minimum due to stack growth). 32633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int64_t MaxOffset = 0; 32733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (std::vector<CalleeSavedInfo>::const_iterator 32833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov I = CSI.begin(), E = CSI.end(); I != E; ++I) 32933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MaxOffset = std::min(MaxOffset, 33033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MFI->getObjectOffset(I->getFrameIdx())); 33133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 33233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Calculate offsets. 33333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int64_t saveAreaOffset = (HasFP ? 3 : 2) * stackGrowth; 33433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (std::vector<CalleeSavedInfo>::const_iterator 33533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov I = CSI.begin(), E = CSI.end(); I != E; ++I) { 33633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int64_t Offset = MFI->getObjectOffset(I->getFrameIdx()); 33733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Reg = I->getReg(); 33833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Offset = MaxOffset - Offset + saveAreaOffset; 33933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 34033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Don't output a new machine move if we're re-saving the frame 34133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // pointer. This happens when the PrologEpilogInserter has inserted an extra 34233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // "PUSH" of the frame pointer -- the "emitPrologue" method automatically 34333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // generates one when frame pointers are used. If we generate a "machine 34433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // move" for this extra "PUSH", the linker will lose track of the fact that 34533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // the frame pointer should have the value of the first "PUSH" when it's 34633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // trying to unwind. 3472763538609fd455d63c192b320c73fb5d48c3e47NAKAMURA Takumi // 34833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // FIXME: This looks inelegant. It's possibly correct, but it's covering up 34933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // another bug. I.e., one where we generate a prolog like this: 35033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // 35133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // pushl %ebp 35233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // movl %esp, %ebp 35333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // pushl %ebp 35433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // pushl %esi 35533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // ... 35633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // 35733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // The immediate re-push of EBP is unnecessary. At the least, it's an 35833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // optimization bug. EBP can be used as a scratch register in certain 35933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // cases, but probably not when we have a frame pointer. 36033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP && FramePtr == Reg) 36133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov continue; 36233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 36333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation CSDst(MachineLocation::VirtualFP, Offset); 36433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation CSSrc(Reg); 36533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(Label, CSDst, CSSrc)); 36633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 36733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 36833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 36909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling/// getCompactUnwindRegNum - Get the compact unwind number for a given 37009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling/// register. The number corresponds to the enum lists in 37109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling/// compact_unwind_encoding.h. 37253146a29bc0c8f835c8c05a5a9a966b887cbb214Craig Topperstatic int getCompactUnwindRegNum(const uint16_t *CURegs, unsigned Reg) { 37310e412ec6b761952b95710203e6d2d89f4fee53aBill Wendling for (int Idx = 1; *CURegs; ++CURegs, ++Idx) 37409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling if (*CURegs == Reg) 37509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling return Idx; 37609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 37709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling return -1; 37809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling} 37909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 38057a3cd2f326269dd1431cf430db50239a93450f2Bill Wendling// Number of registers that can be saved in a compact unwind encoding. 38157a3cd2f326269dd1431cf430db50239a93450f2Bill Wendling#define CU_NUM_SAVED_REGS 6 38257a3cd2f326269dd1431cf430db50239a93450f2Bill Wendling 38309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling/// encodeCompactUnwindRegistersWithoutFrame - Create the permutation encoding 38409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling/// used with frameless stacks. It is passed the number of registers to be saved 38509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling/// and an array of the registers saved. 38657a3cd2f326269dd1431cf430db50239a93450f2Bill Wendlingstatic uint32_t 38757a3cd2f326269dd1431cf430db50239a93450f2Bill WendlingencodeCompactUnwindRegistersWithoutFrame(unsigned SavedRegs[CU_NUM_SAVED_REGS], 38857a3cd2f326269dd1431cf430db50239a93450f2Bill Wendling unsigned RegCount, bool Is64Bit) { 38909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // The saved registers are numbered from 1 to 6. In order to encode the order 39009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // in which they were saved, we re-number them according to their place in the 39109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // register order. The re-numbering is relative to the last re-numbered 39209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // register. E.g., if we have registers {6, 2, 4, 5} saved in that order: 39309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // 39409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // Orig Re-Num 39509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // ---- ------ 39609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // 6 6 39709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // 2 2 39809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // 4 3 39909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // 5 3 40009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // 40153146a29bc0c8f835c8c05a5a9a966b887cbb214Craig Topper static const uint16_t CU32BitRegs[] = { 40209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling X86::EBX, X86::ECX, X86::EDX, X86::EDI, X86::ESI, X86::EBP, 0 40309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling }; 40453146a29bc0c8f835c8c05a5a9a966b887cbb214Craig Topper static const uint16_t CU64BitRegs[] = { 40509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0 40609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling }; 40753146a29bc0c8f835c8c05a5a9a966b887cbb214Craig Topper const uint16_t *CURegs = (Is64Bit ? CU64BitRegs : CU32BitRegs); 40809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 40910e412ec6b761952b95710203e6d2d89f4fee53aBill Wendling for (unsigned i = 0; i != CU_NUM_SAVED_REGS; ++i) { 41009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling int CUReg = getCompactUnwindRegNum(CURegs, SavedRegs[i]); 41109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling if (CUReg == -1) return ~0U; 41209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling SavedRegs[i] = CUReg; 41379df986c60094e9ea29f081295aea08b1680a999Bill Wendling } 41409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 41510e412ec6b761952b95710203e6d2d89f4fee53aBill Wendling // Reverse the list. 41610e412ec6b761952b95710203e6d2d89f4fee53aBill Wendling std::swap(SavedRegs[0], SavedRegs[5]); 41710e412ec6b761952b95710203e6d2d89f4fee53aBill Wendling std::swap(SavedRegs[1], SavedRegs[4]); 41810e412ec6b761952b95710203e6d2d89f4fee53aBill Wendling std::swap(SavedRegs[2], SavedRegs[3]); 41910e412ec6b761952b95710203e6d2d89f4fee53aBill Wendling 42057a3cd2f326269dd1431cf430db50239a93450f2Bill Wendling uint32_t RenumRegs[CU_NUM_SAVED_REGS]; 42157a3cd2f326269dd1431cf430db50239a93450f2Bill Wendling for (unsigned i = CU_NUM_SAVED_REGS - RegCount; i < CU_NUM_SAVED_REGS; ++i) { 42209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned Countless = 0; 42357a3cd2f326269dd1431cf430db50239a93450f2Bill Wendling for (unsigned j = CU_NUM_SAVED_REGS - RegCount; j < i; ++j) 42409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling if (SavedRegs[j] < SavedRegs[i]) 42509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling ++Countless; 42609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 42709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling RenumRegs[i] = SavedRegs[i] - Countless - 1; 42809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling } 42909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 43009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // Take the renumbered values and encode them into a 10-bit number. 43109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling uint32_t permutationEncoding = 0; 43209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling switch (RegCount) { 43309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling case 6: 43409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling permutationEncoding |= 120 * RenumRegs[0] + 24 * RenumRegs[1] 43509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling + 6 * RenumRegs[2] + 2 * RenumRegs[3] 43609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling + RenumRegs[4]; 43709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling break; 43809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling case 5: 43909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling permutationEncoding |= 120 * RenumRegs[1] + 24 * RenumRegs[2] 44009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling + 6 * RenumRegs[3] + 2 * RenumRegs[4] 44109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling + RenumRegs[5]; 44209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling break; 44309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling case 4: 44409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling permutationEncoding |= 60 * RenumRegs[2] + 12 * RenumRegs[3] 44509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling + 3 * RenumRegs[4] + RenumRegs[5]; 44609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling break; 44709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling case 3: 44809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling permutationEncoding |= 20 * RenumRegs[3] + 4 * RenumRegs[4] 44909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling + RenumRegs[5]; 45009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling break; 45109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling case 2: 45209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling permutationEncoding |= 5 * RenumRegs[4] + RenumRegs[5]; 45309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling break; 45409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling case 1: 45509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling permutationEncoding |= RenumRegs[5]; 45609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling break; 45709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling } 45809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 45909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling assert((permutationEncoding & 0x3FF) == permutationEncoding && 46009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling "Invalid compact register encoding!"); 46109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling return permutationEncoding; 46209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling} 46309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 46409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling/// encodeCompactUnwindRegistersWithFrame - Return the registers encoded for a 46509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling/// compact encoding with a frame pointer. 46657a3cd2f326269dd1431cf430db50239a93450f2Bill Wendlingstatic uint32_t 46757a3cd2f326269dd1431cf430db50239a93450f2Bill WendlingencodeCompactUnwindRegistersWithFrame(unsigned SavedRegs[CU_NUM_SAVED_REGS], 46857a3cd2f326269dd1431cf430db50239a93450f2Bill Wendling bool Is64Bit) { 46953146a29bc0c8f835c8c05a5a9a966b887cbb214Craig Topper static const uint16_t CU32BitRegs[] = { 47009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling X86::EBX, X86::ECX, X86::EDX, X86::EDI, X86::ESI, X86::EBP, 0 47109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling }; 47253146a29bc0c8f835c8c05a5a9a966b887cbb214Craig Topper static const uint16_t CU64BitRegs[] = { 47309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0 47409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling }; 47553146a29bc0c8f835c8c05a5a9a966b887cbb214Craig Topper const uint16_t *CURegs = (Is64Bit ? CU64BitRegs : CU32BitRegs); 47609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 47709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // Encode the registers in the order they were saved, 3-bits per register. The 47886b1a7d61413aed40a68f98f1e8f17fd79ebd7a2Bill Wendling // registers are numbered from 1 to CU_NUM_SAVED_REGS. 47909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling uint32_t RegEnc = 0; 480b4ee5168abd0580a29f5c9becce26e3ea7bb2b8dBill Wendling for (int I = CU_NUM_SAVED_REGS - 1, Idx = 0; I != -1; --I) { 48109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned Reg = SavedRegs[I]; 48286b1a7d61413aed40a68f98f1e8f17fd79ebd7a2Bill Wendling if (Reg == 0) continue; 48386b1a7d61413aed40a68f98f1e8f17fd79ebd7a2Bill Wendling 48409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling int CURegNum = getCompactUnwindRegNum(CURegs, Reg); 48586b1a7d61413aed40a68f98f1e8f17fd79ebd7a2Bill Wendling if (CURegNum == -1) return ~0U; 48680caf9c2737d4f1bf5bae3a283fe9d538f5e2970Bill Wendling 48780caf9c2737d4f1bf5bae3a283fe9d538f5e2970Bill Wendling // Encode the 3-bit register number in order, skipping over 3-bits for each 48880caf9c2737d4f1bf5bae3a283fe9d538f5e2970Bill Wendling // register. 48986b1a7d61413aed40a68f98f1e8f17fd79ebd7a2Bill Wendling RegEnc |= (CURegNum & 0x7) << (Idx++ * 3); 49009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling } 49109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 492dec1f996152d4292133e81527ad710fbc1280946Jakob Stoklund Olesen assert((RegEnc & 0x3FFFF) == RegEnc && "Invalid compact register encoding!"); 49309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling return RegEnc; 49409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling} 49509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 49609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendlinguint32_t X86FrameLowering::getCompactUnwindEncoding(MachineFunction &MF) const { 49709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling const X86RegisterInfo *RegInfo = TM.getRegisterInfo(); 49809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned FramePtr = RegInfo->getFrameRegister(MF); 49909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned StackPtr = RegInfo->getStackRegister(); 50009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 50109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling bool Is64Bit = STI.is64Bit(); 50209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling bool HasFP = hasFP(MF); 50309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 50457a3cd2f326269dd1431cf430db50239a93450f2Bill Wendling unsigned SavedRegs[CU_NUM_SAVED_REGS] = { 0, 0, 0, 0, 0, 0 }; 50510e412ec6b761952b95710203e6d2d89f4fee53aBill Wendling unsigned SavedRegIdx = 0; 50609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 50709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned OffsetSize = (Is64Bit ? 8 : 4); 50809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 50909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned PushInstr = (Is64Bit ? X86::PUSH64r : X86::PUSH32r); 51009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned PushInstrSize = 1; 51109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned MoveInstr = (Is64Bit ? X86::MOV64rr : X86::MOV32rr); 51209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned MoveInstrSize = (Is64Bit ? 3 : 2); 51309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned SubtractInstrIdx = (Is64Bit ? 3 : 2); 51409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 515de77055a68a3fc495e01b682f00059af3e38822eBill Wendling unsigned StackDivide = (Is64Bit ? 8 : 4); 516de77055a68a3fc495e01b682f00059af3e38822eBill Wendling 51709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned InstrOffset = 0; 51809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned StackAdjust = 0; 51957a3cd2f326269dd1431cf430db50239a93450f2Bill Wendling unsigned StackSize = 0; 52009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 52109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling MachineBasicBlock &MBB = MF.front(); // Prologue is in entry BB. 52209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling bool ExpectEnd = false; 52309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling for (MachineBasicBlock::iterator 52409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling MBBI = MBB.begin(), MBBE = MBB.end(); MBBI != MBBE; ++MBBI) { 52509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling MachineInstr &MI = *MBBI; 52609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned Opc = MI.getOpcode(); 52709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling if (Opc == X86::PROLOG_LABEL) continue; 52809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling if (!MI.getFlag(MachineInstr::FrameSetup)) break; 52909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 53009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // We don't exect any more prolog instructions. 53189ec1c5c9c744c125b61145ed59783eb5c68ebf8Bill Wendling if (ExpectEnd) return CU::UNWIND_MODE_DWARF; 53209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 53309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling if (Opc == PushInstr) { 53409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // If there are too many saved registers, we cannot use compact encoding. 53589ec1c5c9c744c125b61145ed59783eb5c68ebf8Bill Wendling if (SavedRegIdx >= CU_NUM_SAVED_REGS) return CU::UNWIND_MODE_DWARF; 53609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 53710e412ec6b761952b95710203e6d2d89f4fee53aBill Wendling SavedRegs[SavedRegIdx++] = MI.getOperand(0).getReg(); 53857a3cd2f326269dd1431cf430db50239a93450f2Bill Wendling StackAdjust += OffsetSize; 53909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling InstrOffset += PushInstrSize; 54009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling } else if (Opc == MoveInstr) { 54109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned SrcReg = MI.getOperand(1).getReg(); 54209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned DstReg = MI.getOperand(0).getReg(); 54309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 54409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling if (DstReg != FramePtr || SrcReg != StackPtr) 54589ec1c5c9c744c125b61145ed59783eb5c68ebf8Bill Wendling return CU::UNWIND_MODE_DWARF; 54609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 54757a3cd2f326269dd1431cf430db50239a93450f2Bill Wendling StackAdjust = 0; 54809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling memset(SavedRegs, 0, sizeof(SavedRegs)); 54910e412ec6b761952b95710203e6d2d89f4fee53aBill Wendling SavedRegIdx = 0; 55009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling InstrOffset += MoveInstrSize; 55184d518af1991f581b748c4d11dbeb1c54573556bBill Wendling } else if (Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 || 55284d518af1991f581b748c4d11dbeb1c54573556bBill Wendling Opc == X86::SUB32ri || Opc == X86::SUB32ri8) { 55357a3cd2f326269dd1431cf430db50239a93450f2Bill Wendling if (StackSize) 55457a3cd2f326269dd1431cf430db50239a93450f2Bill Wendling // We already have a stack size. 55589ec1c5c9c744c125b61145ed59783eb5c68ebf8Bill Wendling return CU::UNWIND_MODE_DWARF; 55609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 55709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling if (!MI.getOperand(0).isReg() || 55809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling MI.getOperand(0).getReg() != MI.getOperand(1).getReg() || 55909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling MI.getOperand(0).getReg() != StackPtr || !MI.getOperand(2).isImm()) 56009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // We need this to be a stack adjustment pointer. Something like: 56109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // 56209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // %RSP<def> = SUB64ri8 %RSP, 48 56389ec1c5c9c744c125b61145ed59783eb5c68ebf8Bill Wendling return CU::UNWIND_MODE_DWARF; 56409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 56557a3cd2f326269dd1431cf430db50239a93450f2Bill Wendling StackSize = MI.getOperand(2).getImm() / StackDivide; 56609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling SubtractInstrIdx += InstrOffset; 56709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling ExpectEnd = true; 56809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling } 56909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling } 57009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 57109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // Encode that we are using EBP/RBP as the frame pointer. 57209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling uint32_t CompactUnwindEncoding = 0; 57357a3cd2f326269dd1431cf430db50239a93450f2Bill Wendling StackAdjust /= StackDivide; 57409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling if (HasFP) { 57557a3cd2f326269dd1431cf430db50239a93450f2Bill Wendling if ((StackAdjust & 0xFF) != StackAdjust) 57609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // Offset was too big for compact encoding. 57789ec1c5c9c744c125b61145ed59783eb5c68ebf8Bill Wendling return CU::UNWIND_MODE_DWARF; 57809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 57909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // Get the encoding of the saved registers when we have a frame pointer. 58009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling uint32_t RegEnc = encodeCompactUnwindRegistersWithFrame(SavedRegs, Is64Bit); 58189ec1c5c9c744c125b61145ed59783eb5c68ebf8Bill Wendling if (RegEnc == ~0U) return CU::UNWIND_MODE_DWARF; 58209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 58389ec1c5c9c744c125b61145ed59783eb5c68ebf8Bill Wendling CompactUnwindEncoding |= CU::UNWIND_MODE_BP_FRAME; 58457a3cd2f326269dd1431cf430db50239a93450f2Bill Wendling CompactUnwindEncoding |= (StackAdjust & 0xFF) << 16; 58589ec1c5c9c744c125b61145ed59783eb5c68ebf8Bill Wendling CompactUnwindEncoding |= RegEnc & CU::UNWIND_BP_FRAME_REGISTERS; 58609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling } else { 587b3ec329c14fa3d37b5963f188db54ba03c6b97c0Bill Wendling ++StackAdjust; 588b3ec329c14fa3d37b5963f188db54ba03c6b97c0Bill Wendling uint32_t TotalStackSize = StackAdjust + StackSize; 589581ac2723c5cb5182114092591eb5e21ceea2e77Bill Wendling if ((TotalStackSize & 0xFF) == TotalStackSize) { 5905b2c4978ce56455689c515c9d74cc1d92871f3bbBill Wendling // Frameless stack with a small stack size. 59189ec1c5c9c744c125b61145ed59783eb5c68ebf8Bill Wendling CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IMMD; 5925b2c4978ce56455689c515c9d74cc1d92871f3bbBill Wendling 5935b2c4978ce56455689c515c9d74cc1d92871f3bbBill Wendling // Encode the stack size. 594581ac2723c5cb5182114092591eb5e21ceea2e77Bill Wendling CompactUnwindEncoding |= (TotalStackSize & 0xFF) << 16; 59509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling } else { 59657a3cd2f326269dd1431cf430db50239a93450f2Bill Wendling if ((StackAdjust & 0x7) != StackAdjust) 59709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // The extra stack adjustments are too big for us to handle. 59889ec1c5c9c744c125b61145ed59783eb5c68ebf8Bill Wendling return CU::UNWIND_MODE_DWARF; 59909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 60009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // Frameless stack with an offset too large for us to encode compactly. 60189ec1c5c9c744c125b61145ed59783eb5c68ebf8Bill Wendling CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IND; 60209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 60309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // Encode the offset to the nnnnnn value in the 'subl $nnnnnn, ESP' 60409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // instruction. 60509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling CompactUnwindEncoding |= (SubtractInstrIdx & 0xFF) << 16; 60609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 60757a3cd2f326269dd1431cf430db50239a93450f2Bill Wendling // Encode any extra stack stack adjustments (done via push instructions). 60857a3cd2f326269dd1431cf430db50239a93450f2Bill Wendling CompactUnwindEncoding |= (StackAdjust & 0x7) << 13; 60909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling } 61009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 6115b2c4978ce56455689c515c9d74cc1d92871f3bbBill Wendling // Encode the number of registers saved. 61210e412ec6b761952b95710203e6d2d89f4fee53aBill Wendling CompactUnwindEncoding |= (SavedRegIdx & 0x7) << 10; 61375e14e0ebd29bb2b1893948037c0ae5df4e09a41Bill Wendling 61409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // Get the encoding of the saved registers when we don't have a frame 61509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // pointer. 61657a3cd2f326269dd1431cf430db50239a93450f2Bill Wendling uint32_t RegEnc = 61710e412ec6b761952b95710203e6d2d89f4fee53aBill Wendling encodeCompactUnwindRegistersWithoutFrame(SavedRegs, SavedRegIdx, 61857a3cd2f326269dd1431cf430db50239a93450f2Bill Wendling Is64Bit); 61989ec1c5c9c744c125b61145ed59783eb5c68ebf8Bill Wendling if (RegEnc == ~0U) return CU::UNWIND_MODE_DWARF; 6205b2c4978ce56455689c515c9d74cc1d92871f3bbBill Wendling 6215b2c4978ce56455689c515c9d74cc1d92871f3bbBill Wendling // Encode the register encoding. 62289ec1c5c9c744c125b61145ed59783eb5c68ebf8Bill Wendling CompactUnwindEncoding |= 62389ec1c5c9c744c125b61145ed59783eb5c68ebf8Bill Wendling RegEnc & CU::UNWIND_FRAMELESS_STACK_REG_PERMUTATION; 62409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling } 62509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 62609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling return CompactUnwindEncoding; 62709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling} 62809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 629677689cf5dc65404645462464682a0696cc84532Nadav Rotem/// usesTheStack - This function checks if any of the users of EFLAGS 630d0696ef8c33b9b2504e89bc0aab2ea99a6c90756Nadav Rotem/// copies the EFLAGS. We know that the code that lowers COPY of EFLAGS has 631d0696ef8c33b9b2504e89bc0aab2ea99a6c90756Nadav Rotem/// to use the stack, and if we don't adjust the stack we clobber the first 632d0696ef8c33b9b2504e89bc0aab2ea99a6c90756Nadav Rotem/// frame index. 633677689cf5dc65404645462464682a0696cc84532Nadav Rotem/// See X86InstrInfo::copyPhysReg. 634677689cf5dc65404645462464682a0696cc84532Nadav Rotemstatic bool usesTheStack(MachineFunction &MF) { 635d0696ef8c33b9b2504e89bc0aab2ea99a6c90756Nadav Rotem MachineRegisterInfo &MRI = MF.getRegInfo(); 636d0696ef8c33b9b2504e89bc0aab2ea99a6c90756Nadav Rotem 637d0696ef8c33b9b2504e89bc0aab2ea99a6c90756Nadav Rotem for (MachineRegisterInfo::reg_iterator ri = MRI.reg_begin(X86::EFLAGS), 638d0696ef8c33b9b2504e89bc0aab2ea99a6c90756Nadav Rotem re = MRI.reg_end(); ri != re; ++ri) 639d0696ef8c33b9b2504e89bc0aab2ea99a6c90756Nadav Rotem if (ri->isCopy()) 640d0696ef8c33b9b2504e89bc0aab2ea99a6c90756Nadav Rotem return true; 641d0696ef8c33b9b2504e89bc0aab2ea99a6c90756Nadav Rotem 642d0696ef8c33b9b2504e89bc0aab2ea99a6c90756Nadav Rotem return false; 643d0696ef8c33b9b2504e89bc0aab2ea99a6c90756Nadav Rotem} 644d0696ef8c33b9b2504e89bc0aab2ea99a6c90756Nadav Rotem 64533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// emitPrologue - Push callee-saved registers onto the stack, which 64633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// automatically adjust the stack pointer. Adjust the stack pointer to allocate 64733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// space for local variables. Also emit labels used by the exception handler to 64833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// generate the exception handling frames. 64916c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid X86FrameLowering::emitPrologue(MachineFunction &MF) const { 65033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock &MBB = MF.front(); // Prologue goes in entry BB. 65133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator MBBI = MBB.begin(); 65233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 65333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const Function *Fn = MF.getFunction(); 654d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov const X86RegisterInfo *RegInfo = TM.getRegisterInfo(); 655d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov const X86InstrInfo &TII = *TM.getInstrInfo(); 65633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineModuleInfo &MMI = MF.getMMI(); 65733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>(); 65833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool needsFrameMoves = MMI.hasDebugInfo() || 659fc2bb8c4448fa884d79e437cc2d2627a7d7740a8Rafael Espindola Fn->needsUnwindTableEntry(); 66033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t MaxAlign = MFI->getMaxAlignment(); // Desired stack alignment. 66133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t StackSize = MFI->getStackSize(); // Number of bytes to allocate. 662d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov bool HasFP = hasFP(MF); 66333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool Is64Bit = STI.is64Bit(); 6642a1b60d791522d73be91d4281c90d25bd5e3d117Eli Bendersky bool IsLP64 = STI.isTarget64BitLP64(); 66533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool IsWin64 = STI.isTargetWin64(); 666de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng bool UseLEA = STI.useLeaForSP(); 66733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackAlign = getStackAlignment(); 66833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned SlotSize = RegInfo->getSlotSize(); 66933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned FramePtr = RegInfo->getFrameRegister(MF); 67033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackPtr = RegInfo->getStackRegister(); 6713f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier unsigned BasePtr = RegInfo->getBaseRegister(); 67233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DebugLoc DL; 67333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 67433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If we're forcing a stack realignment we can't rely on just the frame 67533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // info, we need to know the ABI stack alignment as well in case we 67633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // have a call out. Otherwise just make sure we have some alignment - we'll 67733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // go with the minimum SlotSize. 67833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (ForceStackAlign) { 67933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MFI->hasCalls()) 68033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MaxAlign = (StackAlign > MaxAlign) ? StackAlign : MaxAlign; 68133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov else if (MaxAlign < SlotSize) 68233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MaxAlign = SlotSize; 68333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 68433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 68533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Add RETADDR move area to callee saved frame size. 68633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta(); 68733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (TailCallReturnAddrDelta < 0) 68833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov X86FI->setCalleeSavedFrameSize( 68933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov X86FI->getCalleeSavedFrameSize() - TailCallReturnAddrDelta); 69033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 69133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If this is x86-64 and the Red Zone is not disabled, if we are a leaf 69233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // function, and use up to 128 bytes of stack space, don't have a frame 69333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // pointer, calls, or dynamic alloca then we do not need to adjust the 694d0696ef8c33b9b2504e89bc0aab2ea99a6c90756Nadav Rotem // stack pointer (we fit in the Red Zone). We also check that we don't 695d0696ef8c33b9b2504e89bc0aab2ea99a6c90756Nadav Rotem // push and pop from the stack. 696831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling if (Is64Bit && !Fn->getAttributes().hasAttribute(AttributeSet::FunctionIndex, 697831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling Attribute::NoRedZone) && 69833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov !RegInfo->needsStackRealignment(MF) && 6998a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky !MFI->hasVarSizedObjects() && // No dynamic alloca. 7008a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky !MFI->adjustsStack() && // No calls. 7018a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky !IsWin64 && // Win64 has no Red Zone 702677689cf5dc65404645462464682a0696cc84532Nadav Rotem !usesTheStack(MF) && // Don't push and pop. 7038a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky !MF.getTarget().Options.EnableSegmentedStacks) { // Regular stack 70433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t MinSize = X86FI->getCalleeSavedFrameSize(); 70533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) MinSize += SlotSize; 70633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov StackSize = std::max(MinSize, StackSize > 128 ? StackSize - 128 : 0); 70733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MFI->setStackSize(StackSize); 70833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 70933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 71033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Insert stack pointer adjustment for later moving of return addr. Only 71133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // applies to tail call optimized functions where the callee argument stack 71233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // size is bigger than the callers. 71333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (TailCallReturnAddrDelta < 0) { 71433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineInstr *MI = 71533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, 7162a1b60d791522d73be91d4281c90d25bd5e3d117Eli Bendersky TII.get(getSUBriOpcode(IsLP64, -TailCallReturnAddrDelta)), 71733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov StackPtr) 71833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(StackPtr) 719aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis .addImm(-TailCallReturnAddrDelta) 720aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis .setMIFlag(MachineInstr::FrameSetup); 72133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MI->getOperand(3).setIsDead(); // The EFLAGS implicit def is dead. 72233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 72333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 72433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Mapping for machine moves: 72533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // 72633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // DST: VirtualFP AND 72733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // SRC: VirtualFP => DW_CFA_def_cfa_offset 72833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // ELSE => DW_CFA_def_cfa 72933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // 73033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // SRC: VirtualFP AND 73133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // DST: Register => DW_CFA_def_cfa_register 73233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // 73333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // ELSE 73433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // OFFSET < 0 => DW_CFA_offset_extended_sf 73533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // REG < 64 => DW_CFA_offset + Reg 73633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // ELSE => DW_CFA_offset_extended 73733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 73833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov std::vector<MachineMove> &Moves = MMI.getFrameMoves(); 73933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t NumBytes = 0; 740aa3c2c09d9d5bc67c6ca2fbc6697257b15476684Michael Liao int stackGrowth = -SlotSize; 74133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 74233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) { 74333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Calculate required stack adjustment. 74433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t FrameSize = StackSize - SlotSize; 74599a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov if (RegInfo->needsStackRealignment(MF)) { 74699a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov // Callee-saved registers are pushed on stack before the stack 74799a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov // is realigned. 74899a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov FrameSize -= X86FI->getCalleeSavedFrameSize(); 74999a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov NumBytes = (FrameSize + MaxAlign - 1) / MaxAlign * MaxAlign; 75099a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov } else { 75199a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov NumBytes = FrameSize - X86FI->getCalleeSavedFrameSize(); 75299a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov } 75333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 75433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get the offset of the stack slot for the EBP register, which is 75533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // guaranteed to be the last slot by processFunctionBeforeFrameFinalized. 75633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Update the frame offset adjustment. 75733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MFI->setOffsetAdjustment(-NumBytes); 75833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 75933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Save EBP/RBP into the appropriate stack slot. 76033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::PUSH64r : X86::PUSH32r)) 761aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis .addReg(FramePtr, RegState::Kill) 762aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis .setMIFlag(MachineInstr::FrameSetup); 76333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 76433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (needsFrameMoves) { 76533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Mark the place where EBP/RBP was saved. 76633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MCSymbol *FrameLabel = MMI.getContext().CreateTempSymbol(); 767fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling BuildMI(MBB, MBBI, DL, TII.get(X86::PROLOG_LABEL)) 768fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .addSym(FrameLabel); 76933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 77033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Define the current CFA rule to use the provided offset. 77133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (StackSize) { 77233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPDst(MachineLocation::VirtualFP); 77333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPSrc(MachineLocation::VirtualFP, 2 * stackGrowth); 77433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc)); 77533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 77633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPDst(StackPtr); 77733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPSrc(StackPtr, stackGrowth); 77833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc)); 77933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 78033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 78133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Change the rule for the FramePtr to be an "offset" rule. 78233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation FPDst(MachineLocation::VirtualFP, 2 * stackGrowth); 78333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation FPSrc(FramePtr); 78433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(FrameLabel, FPDst, FPSrc)); 78533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 78633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 78709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // Update EBP with the new base value. 78833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, 78933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr), FramePtr) 790aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis .addReg(StackPtr) 791aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis .setMIFlag(MachineInstr::FrameSetup); 79233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 79333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (needsFrameMoves) { 79433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Mark effective beginning of when frame pointer becomes valid. 79533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MCSymbol *FrameLabel = MMI.getContext().CreateTempSymbol(); 796fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling BuildMI(MBB, MBBI, DL, TII.get(X86::PROLOG_LABEL)) 797fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .addSym(FrameLabel); 79833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 79933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Define the current CFA to use the EBP/RBP register. 80033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation FPDst(FramePtr); 80133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation FPSrc(MachineLocation::VirtualFP); 80233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(FrameLabel, FPDst, FPSrc)); 80333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 80433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 80533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Mark the FramePtr as live-in in every block except the entry. 80633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (MachineFunction::iterator I = llvm::next(MF.begin()), E = MF.end(); 80733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov I != E; ++I) 80833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov I->addLiveIn(FramePtr); 80933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 81033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov NumBytes = StackSize - X86FI->getCalleeSavedFrameSize(); 81133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 81233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 81333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Skip the callee-saved push instructions. 81433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool PushedRegs = false; 81533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int StackOffset = 2 * stackGrowth; 81633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 81733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov while (MBBI != MBB.end() && 81833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov (MBBI->getOpcode() == X86::PUSH32r || 81933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBBI->getOpcode() == X86::PUSH64r)) { 82033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PushedRegs = true; 821fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling MBBI->setFlag(MachineInstr::FrameSetup); 82233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov ++MBBI; 82333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 82433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!HasFP && needsFrameMoves) { 82533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Mark callee-saved push instruction. 82633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MCSymbol *Label = MMI.getContext().CreateTempSymbol(); 82733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(X86::PROLOG_LABEL)).addSym(Label); 82833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 82933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Define the current CFA rule to use the provided offset. 83009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned Ptr = StackSize ? MachineLocation::VirtualFP : StackPtr; 83133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPDst(Ptr); 83233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPSrc(Ptr, StackOffset); 83333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(Label, SPDst, SPSrc)); 83433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov StackOffset += stackGrowth; 83533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 83633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 83733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 83899a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov // Realign stack after we pushed callee-saved registers (so that we'll be 83999a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov // able to calculate their offsets from the frame pointer). 84099a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov 84199a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov // NOTE: We push the registers before realigning the stack, so 84299a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov // vector callee-saved (xmm) registers may be saved w/o proper 84399a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov // alignment in this way. However, currently these regs are saved in 84499a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov // stack slots (see X86FrameLowering::spillCalleeSavedRegisters()), so 84599a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov // this shouldn't be a problem. 84699a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov if (RegInfo->needsStackRealignment(MF)) { 84799a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov assert(HasFP && "There should be a frame pointer if stack is realigned."); 84899a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov MachineInstr *MI = 84999a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov BuildMI(MBB, MBBI, DL, 85099a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov TII.get(Is64Bit ? X86::AND64ri32 : X86::AND32ri), StackPtr) 85199a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov .addReg(StackPtr) 85299a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov .addImm(-MaxAlign) 85399a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov .setMIFlag(MachineInstr::FrameSetup); 85499a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov 85599a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov // The EFLAGS implicit def is dead. 85699a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov MI->getOperand(3).setIsDead(); 85799a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov } 85899a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov 85933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If there is an SUB32ri of ESP immediately before this instruction, merge 86033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // the two. This can be the case when tail call elimination is enabled and 86133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // the callee has more arguments then the caller. 86233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov NumBytes -= mergeSPUpdates(MBB, MBBI, StackPtr, true); 86333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 86433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If there is an ADD32ri or SUB32ri of ESP immediately after this 86533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // instruction, merge the two instructions. 86633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov mergeSPUpdatesDown(MBB, MBBI, StackPtr, &NumBytes); 86733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 86833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Adjust stack pointer: ESP -= numbytes. 86933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 87033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Windows and cygwin/mingw require a prologue helper routine when allocating 87133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // more than 4K bytes on the stack. Windows uses __chkstk and cygwin/mingw 87233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // uses __alloca. __alloca and the 32-bit version of __chkstk will probe the 87333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // stack and adjust the stack pointer in one go. The 64-bit version of 87433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // __chkstk is only responsible for probing the stack. The 64-bit prologue is 87533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // responsible for adjusting the stack pointer. Touching the stack at 4K 87633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // increments is necessary to ensure that the guard pages used by the OS 87733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // virtual memory manager are allocated in correct sequence. 878a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi if (NumBytes >= 4096 && STI.isTargetCOFF() && !STI.isTargetEnvMacho()) { 879a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi const char *StackProbeSymbol; 880a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi bool isSPUpdateNeeded = false; 881a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi 882a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi if (Is64Bit) { 883a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi if (STI.isTargetCygMing()) 884a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi StackProbeSymbol = "___chkstk"; 885a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi else { 886a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi StackProbeSymbol = "__chkstk"; 887a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi isSPUpdateNeeded = true; 888a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi } 889a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi } else if (STI.isTargetCygMing()) 890a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi StackProbeSymbol = "_alloca"; 891a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi else 892a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi StackProbeSymbol = "_chkstk"; 893a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi 89433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Check whether EAX is livein for this function. 89533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool isEAXAlive = isEAXLiveIn(MF); 89633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 897a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi if (isEAXAlive) { 898a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // Sanity check that EAX is not livein for this function. 899a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // It should not be, so throw an assert. 900a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi assert(!Is64Bit && "EAX is livein in x64 case!"); 901a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi 90233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Save EAX 90333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(X86::PUSH32r)) 904fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .addReg(X86::EAX, RegState::Kill) 905fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .setMIFlag(MachineInstr::FrameSetup); 906a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi } 90733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 908a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi if (Is64Bit) { 909a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // Handle the 64-bit Windows ABI case where we need to call __chkstk. 910a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // Function prologue is responsible for adjusting the stack pointer. 911a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi BuildMI(MBB, MBBI, DL, TII.get(X86::MOV64ri), X86::RAX) 912fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .addImm(NumBytes) 913fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .setMIFlag(MachineInstr::FrameSetup); 914a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi } else { 915a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // Allocate NumBytes-4 bytes on stack in case of isEAXAlive. 916a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // We'll also use 4 already allocated bytes for EAX. 91733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX) 918fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .addImm(isEAXAlive ? NumBytes - 4 : NumBytes) 919fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .setMIFlag(MachineInstr::FrameSetup); 920a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi } 921a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi 922a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi BuildMI(MBB, MBBI, DL, 923a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi TII.get(Is64Bit ? X86::W64ALLOCA : X86::CALLpcrel32)) 924a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi .addExternalSymbol(StackProbeSymbol) 925a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi .addReg(StackPtr, RegState::Define | RegState::Implicit) 926fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .addReg(X86::EFLAGS, RegState::Define | RegState::Implicit) 927fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .setMIFlag(MachineInstr::FrameSetup); 928a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi 929a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // MSVC x64's __chkstk needs to adjust %rsp. 930a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // FIXME: %rax preserves the offset and should be available. 931a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi if (isSPUpdateNeeded) 9322a1b60d791522d73be91d4281c90d25bd5e3d117Eli Bendersky emitSPUpdate(MBB, MBBI, StackPtr, -(int64_t)NumBytes, Is64Bit, IsLP64, 93376ad43c6e1619ed4c087b8ccb2cd573eb9d7093eEric Christopher UseLEA, TII, *RegInfo); 934a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi 935a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi if (isEAXAlive) { 936a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // Restore EAX 937a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi MachineInstr *MI = addRegOffset(BuildMI(MF, DL, TII.get(X86::MOV32rm), 938a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi X86::EAX), 939a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi StackPtr, false, NumBytes - 4); 940fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling MI->setFlag(MachineInstr::FrameSetup); 941a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi MBB.insert(MBBI, MI); 94233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 94333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (NumBytes) 9442a1b60d791522d73be91d4281c90d25bd5e3d117Eli Bendersky emitSPUpdate(MBB, MBBI, StackPtr, -(int64_t)NumBytes, Is64Bit, IsLP64, 94576ad43c6e1619ed4c087b8ccb2cd573eb9d7093eEric Christopher UseLEA, TII, *RegInfo); 94633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 9473f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier // If we need a base pointer, set it up here. It's whatever the value 9483f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier // of the stack pointer is at this point. Any variable size objects 9493f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier // will be allocated after this, so we can still use the base pointer 9503f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier // to reference locals. 9513f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier if (RegInfo->hasBasePointer(MF)) { 9523f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier // Update the frame pointer with the current stack pointer. 9533f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier unsigned Opc = Is64Bit ? X86::MOV64rr : X86::MOV32rr; 9543f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier BuildMI(MBB, MBBI, DL, TII.get(Opc), BasePtr) 9553f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier .addReg(StackPtr) 9563f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier .setMIFlag(MachineInstr::FrameSetup); 9573f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier } 9583f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier 959f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola if (( (!HasFP && NumBytes) || PushedRegs) && needsFrameMoves) { 96033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Mark end of stack pointer adjustment. 96133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MCSymbol *Label = MMI.getContext().CreateTempSymbol(); 962fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling BuildMI(MBB, MBBI, DL, TII.get(X86::PROLOG_LABEL)) 963fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .addSym(Label); 96433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 96533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!HasFP && NumBytes) { 96633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Define the current CFA rule to use the provided offset. 96733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (StackSize) { 96833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPDst(MachineLocation::VirtualFP); 96933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPSrc(MachineLocation::VirtualFP, 97033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov -StackSize + stackGrowth); 97133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(Label, SPDst, SPSrc)); 97233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 97333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPDst(StackPtr); 97433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPSrc(StackPtr, stackGrowth); 97533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(Label, SPDst, SPSrc)); 97633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 97733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 97833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 97933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Emit DWARF info specifying the offsets of the callee-saved registers. 98033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (PushedRegs) 98133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov emitCalleeSavedFrameMoves(MF, Label, HasFP ? FramePtr : StackPtr); 98233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 98309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 98409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // Darwin 10.7 and greater has support for compact unwind encoding. 985c8725d11f8756c57bdbceccc61062a9d560261c5Bill Wendling if (STI.getTargetTriple().isMacOSX() && 986ac86d43eae8bbfe5284d8e5fa17c141d1a7b1194Eli Friedman !STI.getTargetTriple().isMacOSXVersionLT(10, 7)) 98709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling MMI.setCompactUnwindEncoding(getCompactUnwindEncoding(MF)); 98833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 98933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 99016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid X86FrameLowering::emitEpilogue(MachineFunction &MF, 9913c2f0a11cce5a1e828e20675fa8467b624795e0aNick Lewycky MachineBasicBlock &MBB) const { 99233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const MachineFrameInfo *MFI = MF.getFrameInfo(); 99333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>(); 994d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov const X86RegisterInfo *RegInfo = TM.getRegisterInfo(); 995d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov const X86InstrInfo &TII = *TM.getInstrInfo(); 9964f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 9974f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen assert(MBBI != MBB.end() && "Returning block has no instructions"); 99833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned RetOpcode = MBBI->getOpcode(); 99933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DebugLoc DL = MBBI->getDebugLoc(); 100033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool Is64Bit = STI.is64Bit(); 10012a1b60d791522d73be91d4281c90d25bd5e3d117Eli Bendersky bool IsLP64 = STI.isTarget64BitLP64(); 1002de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng bool UseLEA = STI.useLeaForSP(); 100333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackAlign = getStackAlignment(); 100433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned SlotSize = RegInfo->getSlotSize(); 100533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned FramePtr = RegInfo->getFrameRegister(MF); 100633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackPtr = RegInfo->getStackRegister(); 100733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 100833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov switch (RetOpcode) { 100933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov default: 101033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov llvm_unreachable("Can only insert epilog into returning blocks"); 101133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::RET: 101233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::RETI: 101333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::TCRETURNdi: 101433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::TCRETURNri: 101533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::TCRETURNmi: 101633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::TCRETURNdi64: 101733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::TCRETURNri64: 101833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::TCRETURNmi64: 101933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::EH_RETURN: 102033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::EH_RETURN64: 102133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov break; // These are ok 102233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 102333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 102433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get the number of bytes to allocate from the FrameInfo. 102533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t StackSize = MFI->getStackSize(); 102633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t MaxAlign = MFI->getMaxAlignment(); 102733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned CSSize = X86FI->getCalleeSavedFrameSize(); 102833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t NumBytes = 0; 102933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 103033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If we're forcing a stack realignment we can't rely on just the frame 103133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // info, we need to know the ABI stack alignment as well in case we 103233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // have a call out. Otherwise just make sure we have some alignment - we'll 103333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // go with the minimum. 103433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (ForceStackAlign) { 103533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MFI->hasCalls()) 103633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MaxAlign = (StackAlign > MaxAlign) ? StackAlign : MaxAlign; 103733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov else 103833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MaxAlign = MaxAlign ? MaxAlign : 4; 103933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 104033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 1041d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (hasFP(MF)) { 104233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Calculate required stack adjustment. 104333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t FrameSize = StackSize - SlotSize; 104499a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov if (RegInfo->needsStackRealignment(MF)) { 104599a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov // Callee-saved registers were pushed on stack before the stack 104699a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov // was realigned. 104799a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov FrameSize -= CSSize; 104899a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov NumBytes = (FrameSize + MaxAlign - 1) / MaxAlign * MaxAlign; 104999a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov } else { 105099a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov NumBytes = FrameSize - CSSize; 105199a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov } 105233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 105333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Pop EBP. 105433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, 105533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov TII.get(Is64Bit ? X86::POP64r : X86::POP32r), FramePtr); 105633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 105733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov NumBytes = StackSize - CSSize; 105833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 105933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 106033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Skip the callee-saved pop instructions. 106133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov while (MBBI != MBB.begin()) { 106233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator PI = prior(MBBI); 106333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Opc = PI->getOpcode(); 106433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 10654f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen if (Opc != X86::POP32r && Opc != X86::POP64r && Opc != X86::DBG_VALUE && 10665a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng !PI->isTerminator()) 106733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov break; 106833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 106933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov --MBBI; 107033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 107199a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov MachineBasicBlock::iterator FirstCSPop = MBBI; 107233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 107333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DL = MBBI->getDebugLoc(); 107433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 107533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If there is an ADD32ri or SUB32ri of ESP immediately before this 107633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // instruction, merge the two instructions. 107733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (NumBytes || MFI->hasVarSizedObjects()) 107833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes); 107933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 108033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If dynamic alloca is used, then reset esp to point to the last callee-saved 108133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // slot before popping them off! Same applies for the case, when stack was 108233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // realigned. 108399a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov if (RegInfo->needsStackRealignment(MF) || MFI->hasVarSizedObjects()) { 108499a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov if (RegInfo->needsStackRealignment(MF)) 108599a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov MBBI = FirstCSPop; 108699a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov if (CSSize != 0) { 108716221a60a00e52b078f6164ba4475c6e8e918e4bEli Bendersky unsigned Opc = getLEArOpcode(IsLP64); 108899a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr), 108999a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov FramePtr, false, -CSSize); 109033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 109199a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov unsigned Opc = (Is64Bit ? X86::MOV64rr : X86::MOV32rr); 109299a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr) 109333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(FramePtr); 109433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 109533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (NumBytes) { 109633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Adjust stack pointer back: ESP += numbytes. 10972a1b60d791522d73be91d4281c90d25bd5e3d117Eli Bendersky emitSPUpdate(MBB, MBBI, StackPtr, NumBytes, Is64Bit, IsLP64, UseLEA, 10982a1b60d791522d73be91d4281c90d25bd5e3d117Eli Bendersky TII, *RegInfo); 109933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 110033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 110133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // We're returning from function via eh_return. 110233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (RetOpcode == X86::EH_RETURN || RetOpcode == X86::EH_RETURN64) { 11034f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MBBI = MBB.getLastNonDebugInstr(); 110433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineOperand &DestAddr = MBBI->getOperand(0); 110533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(DestAddr.isReg() && "Offset should be in register!"); 110633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, 110733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr), 110833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov StackPtr).addReg(DestAddr.getReg()); 110933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (RetOpcode == X86::TCRETURNri || RetOpcode == X86::TCRETURNdi || 111033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RetOpcode == X86::TCRETURNmi || 111133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RetOpcode == X86::TCRETURNri64 || RetOpcode == X86::TCRETURNdi64 || 111233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RetOpcode == X86::TCRETURNmi64) { 111333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool isMem = RetOpcode == X86::TCRETURNmi || RetOpcode == X86::TCRETURNmi64; 111433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Tail call return: adjust the stack pointer and jump to callee. 1115f7ca976e74eafeeab0e9097f0fb07d6bb447415bJakob Stoklund Olesen MBBI = MBB.getLastNonDebugInstr(); 111633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineOperand &JumpTarget = MBBI->getOperand(0); 111733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineOperand &StackAdjust = MBBI->getOperand(isMem ? 5 : 1); 111833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(StackAdjust.isImm() && "Expecting immediate value."); 111933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 112033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Adjust stack pointer. 112133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int StackAdj = StackAdjust.getImm(); 112233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int MaxTCDelta = X86FI->getTCReturnAddrDelta(); 112333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int Offset = 0; 112433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(MaxTCDelta <= 0 && "MaxTCDelta should never be positive"); 112533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 112633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Incoporate the retaddr area. 112733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Offset = StackAdj-MaxTCDelta; 112833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(Offset >= 0 && "Offset should never be negative"); 112933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 113033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (Offset) { 11317a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // Check for possible merge with preceding ADD instruction. 113233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Offset += mergeSPUpdates(MBB, MBBI, StackPtr, true); 11332a1b60d791522d73be91d4281c90d25bd5e3d117Eli Bendersky emitSPUpdate(MBB, MBBI, StackPtr, Offset, Is64Bit, IsLP64, 11342a1b60d791522d73be91d4281c90d25bd5e3d117Eli Bendersky UseLEA, TII, *RegInfo); 113533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 113633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 113733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Jump to label or value in register. 113833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (RetOpcode == X86::TCRETURNdi || RetOpcode == X86::TCRETURNdi64) { 11393d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng MachineInstrBuilder MIB = 11403d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng BuildMI(MBB, MBBI, DL, TII.get((RetOpcode == X86::TCRETURNdi) 11413d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng ? X86::TAILJMPd : X86::TAILJMPd64)); 11423d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng if (JumpTarget.isGlobal()) 11433d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng MIB.addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset(), 11443d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng JumpTarget.getTargetFlags()); 11453d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng else { 11463d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng assert(JumpTarget.isSymbol()); 11473d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng MIB.addExternalSymbol(JumpTarget.getSymbolName(), 11483d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng JumpTarget.getTargetFlags()); 11493d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng } 115033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (RetOpcode == X86::TCRETURNmi || RetOpcode == X86::TCRETURNmi64) { 115133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineInstrBuilder MIB = 115233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get((RetOpcode == X86::TCRETURNmi) 115333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov ? X86::TAILJMPm : X86::TAILJMPm64)); 115433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (unsigned i = 0; i != 5; ++i) 115533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MIB.addOperand(MBBI->getOperand(i)); 115633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (RetOpcode == X86::TCRETURNri64) { 115733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(X86::TAILJMPr64)). 115833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov addReg(JumpTarget.getReg(), RegState::Kill); 115933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 116033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(X86::TAILJMPr)). 116133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov addReg(JumpTarget.getReg(), RegState::Kill); 116233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 116333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 116433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineInstr *NewMI = prior(MBBI); 1165be06aacaa9a270384599bbfa850b967e9996b9fbJakob Stoklund Olesen NewMI->copyImplicitOps(MF, MBBI); 116633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 116733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Delete the pseudo instruction TCRETURN. 116833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBB.erase(MBBI); 116933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if ((RetOpcode == X86::RET || RetOpcode == X86::RETI) && 117033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov (X86FI->getTCReturnAddrDelta() < 0)) { 117133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Add the return addr area delta back since we are not tail calling. 117233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int delta = -1*X86FI->getTCReturnAddrDelta(); 11734f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MBBI = MBB.getLastNonDebugInstr(); 117433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 11757a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // Check for possible merge with preceding ADD instruction. 117633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov delta += mergeSPUpdates(MBB, MBBI, StackPtr, true); 11772a1b60d791522d73be91d4281c90d25bd5e3d117Eli Bendersky emitSPUpdate(MBB, MBBI, StackPtr, delta, Is64Bit, IsLP64, UseLEA, TII, 11782a1b60d791522d73be91d4281c90d25bd5e3d117Eli Bendersky *RegInfo); 117933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 118033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 1181d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov 118216c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovint X86FrameLowering::getFrameIndexOffset(const MachineFunction &MF, int FI) const { 11833fb6eca0cd4c2b31b06543ca2ac60b9c91c2264dChad Rosier const X86RegisterInfo *RegInfo = 118482f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov static_cast<const X86RegisterInfo*>(MF.getTarget().getRegisterInfo()); 118582f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov const MachineFrameInfo *MFI = MF.getFrameInfo(); 118682f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov int Offset = MFI->getObjectOffset(FI) - getOffsetOfLocalArea(); 118782f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov uint64_t StackSize = MFI->getStackSize(); 118882f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov 11893f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier if (RegInfo->hasBasePointer(MF)) { 11903f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier assert (hasFP(MF) && "VLAs and dynamic stack realign, but no FP?!"); 11913f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier if (FI < 0) { 11923f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier // Skip the saved EBP. 11933f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier return Offset + RegInfo->getSlotSize(); 11943f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier } else { 11953f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier assert((-(Offset + StackSize)) % MFI->getObjectAlignment(FI) == 0); 11963f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier return Offset + StackSize; 11973f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier } 11983f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier } else if (RegInfo->needsStackRealignment(MF)) { 119982f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov if (FI < 0) { 120082f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov // Skip the saved EBP. 12013fb6eca0cd4c2b31b06543ca2ac60b9c91c2264dChad Rosier return Offset + RegInfo->getSlotSize(); 120282f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov } else { 120317001ce25cc205ac1cd2604492c2bce310964220Duncan Sands assert((-(Offset + StackSize)) % MFI->getObjectAlignment(FI) == 0); 120482f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov return Offset + StackSize; 120582f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov } 120682f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov // FIXME: Support tail calls 120782f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov } else { 120882f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov if (!hasFP(MF)) 120982f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov return Offset + StackSize; 121082f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov 121182f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov // Skip the saved EBP. 12123fb6eca0cd4c2b31b06543ca2ac60b9c91c2264dChad Rosier Offset += RegInfo->getSlotSize(); 121382f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov 121482f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov // Skip the RETADDR move area 121582f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov const X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>(); 121682f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov int TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta(); 121782f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov if (TailCallReturnAddrDelta < 0) 121882f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov Offset -= TailCallReturnAddrDelta; 121982f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov } 122082f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov 122182f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov return Offset; 122282f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov} 1223cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 1224d07d06ceef942c478c0f75a4c4d7442e61ddff1dAlexey Samsonovint X86FrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI, 1225d07d06ceef942c478c0f75a4c4d7442e61ddff1dAlexey Samsonov unsigned &FrameReg) const { 12263fb6eca0cd4c2b31b06543ca2ac60b9c91c2264dChad Rosier const X86RegisterInfo *RegInfo = 1227d07d06ceef942c478c0f75a4c4d7442e61ddff1dAlexey Samsonov static_cast<const X86RegisterInfo*>(MF.getTarget().getRegisterInfo()); 1228d07d06ceef942c478c0f75a4c4d7442e61ddff1dAlexey Samsonov // We can't calculate offset from frame pointer if the stack is realigned, 12293f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier // so enforce usage of stack/base pointer. The base pointer is used when we 12303f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier // have dynamic allocas in addition to dynamic realignment. 12313f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier if (RegInfo->hasBasePointer(MF)) 12323f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier FrameReg = RegInfo->getBaseRegister(); 12333f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier else if (RegInfo->needsStackRealignment(MF)) 12343f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier FrameReg = RegInfo->getStackRegister(); 12353f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier else 12363f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier FrameReg = RegInfo->getFrameRegister(MF); 1237d07d06ceef942c478c0f75a4c4d7442e61ddff1dAlexey Samsonov return getFrameIndexOffset(MF, FI); 1238d07d06ceef942c478c0f75a4c4d7442e61ddff1dAlexey Samsonov} 1239d07d06ceef942c478c0f75a4c4d7442e61ddff1dAlexey Samsonov 124016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovbool X86FrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB, 1241cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov MachineBasicBlock::iterator MI, 1242cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov const std::vector<CalleeSavedInfo> &CSI, 1243cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov const TargetRegisterInfo *TRI) const { 1244cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov if (CSI.empty()) 1245cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov return false; 1246cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 1247cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov DebugLoc DL = MBB.findDebugLoc(MI); 1248cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 1249cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov MachineFunction &MF = *MBB.getParent(); 1250cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 1251cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov unsigned SlotSize = STI.is64Bit() ? 8 : 4; 1252cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov unsigned FPReg = TRI->getFrameRegister(MF); 1253cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov unsigned CalleeFrameSize = 0; 1254cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 1255cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 1256cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>(); 1257cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 1258419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi // Push GPRs. It increases frame size. 1259cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov unsigned Opc = STI.is64Bit() ? X86::PUSH64r : X86::PUSH32r; 1260cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov for (unsigned i = CSI.size(); i != 0; --i) { 1261cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov unsigned Reg = CSI[i-1].getReg(); 1262419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi if (!X86::GR64RegClass.contains(Reg) && 1263419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi !X86::GR32RegClass.contains(Reg)) 1264419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi continue; 1265cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov // Add the callee-saved register as live-in. It's killed at the spill. 1266cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov MBB.addLiveIn(Reg); 1267cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov if (Reg == FPReg) 1268cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov // X86RegisterInfo::emitPrologue will handle spilling of frame register. 1269cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov continue; 1270419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi CalleeFrameSize += SlotSize; 1271aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis BuildMI(MBB, MI, DL, TII.get(Opc)).addReg(Reg, RegState::Kill) 1272aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis .setMIFlag(MachineInstr::FrameSetup); 1273cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov } 1274cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 1275cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov X86FI->setCalleeSavedFrameSize(CalleeFrameSize); 1276419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi 1277419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi // Make XMM regs spilled. X86 does not have ability of push/pop XMM. 1278419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi // It can be done by spilling XMMs to stack frame. 1279419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi // Note that only Win64 ABI might spill XMMs. 1280419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi for (unsigned i = CSI.size(); i != 0; --i) { 1281419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi unsigned Reg = CSI[i-1].getReg(); 1282419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi if (X86::GR64RegClass.contains(Reg) || 1283419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi X86::GR32RegClass.contains(Reg)) 1284419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi continue; 1285419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi // Add the callee-saved register as live-in. It's killed at the spill. 1286419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi MBB.addLiveIn(Reg); 1287419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 1288419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi TII.storeRegToStackSlot(MBB, MI, Reg, true, CSI[i-1].getFrameIdx(), 1289419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi RC, TRI); 1290419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi } 1291419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi 1292cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov return true; 1293cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov} 1294cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 129516c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovbool X86FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 1296cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov MachineBasicBlock::iterator MI, 1297cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov const std::vector<CalleeSavedInfo> &CSI, 1298cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov const TargetRegisterInfo *TRI) const { 1299cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov if (CSI.empty()) 1300cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov return false; 1301cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 1302cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov DebugLoc DL = MBB.findDebugLoc(MI); 1303cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 1304cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov MachineFunction &MF = *MBB.getParent(); 1305cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 1306419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi 1307419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi // Reload XMMs from stack frame. 1308419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 1309419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi unsigned Reg = CSI[i].getReg(); 1310419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi if (X86::GR64RegClass.contains(Reg) || 1311419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi X86::GR32RegClass.contains(Reg)) 1312419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi continue; 1313419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 1314419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi TII.loadRegFromStackSlot(MBB, MI, Reg, CSI[i].getFrameIdx(), 1315419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi RC, TRI); 1316419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi } 1317419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi 1318419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi // POP GPRs. 1319cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov unsigned FPReg = TRI->getFrameRegister(MF); 1320cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov unsigned Opc = STI.is64Bit() ? X86::POP64r : X86::POP32r; 1321cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 1322cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov unsigned Reg = CSI[i].getReg(); 1323419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi if (!X86::GR64RegClass.contains(Reg) && 1324419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi !X86::GR32RegClass.contains(Reg)) 1325419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi continue; 1326cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov if (Reg == FPReg) 1327cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov // X86RegisterInfo::emitEpilogue will handle restoring of frame register. 1328cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov continue; 1329419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi BuildMI(MBB, MI, DL, TII.get(Opc), Reg); 1330cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov } 1331cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov return true; 1332cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov} 133394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 133494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikovvoid 133516c29b5f285f375be53dabaa73e3e91107485fe4Anton KorobeynikovX86FrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, 133694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov RegScavenger *RS) const { 133794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 133894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov const X86RegisterInfo *RegInfo = TM.getRegisterInfo(); 133994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned SlotSize = RegInfo->getSlotSize(); 134094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 134194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>(); 134294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int32_t TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta(); 134394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 134494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (TailCallReturnAddrDelta < 0) { 134594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // create RETURNADDR area 134694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // arg 134794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // arg 134894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // RETADDR 134994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // { ... 135094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // RETADDR area 135194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // ... 135294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // } 135394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // [EBP] 135494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MFI->CreateFixedObject(-TailCallReturnAddrDelta, 135594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov (-1U*SlotSize)+TailCallReturnAddrDelta, true); 135694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 135794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 135894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (hasFP(MF)) { 135994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov assert((TailCallReturnAddrDelta <= 0) && 136094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov "The Delta should always be zero or negative"); 136116c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering &TFI = *MF.getTarget().getFrameLowering(); 136294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 136394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Create a frame entry for the EBP register that must be saved. 136494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int FrameIdx = MFI->CreateFixedObject(SlotSize, 136594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov -(int)SlotSize + 136694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov TFI.getOffsetOfLocalArea() + 136794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov TailCallReturnAddrDelta, 136894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov true); 136994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov assert(FrameIdx == MFI->getObjectIndexBegin() && 137094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov "Slot for EBP register must be last in order to be found!"); 137117001ce25cc205ac1cd2604492c2bce310964220Duncan Sands (void)FrameIdx; 137294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 13733f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier 13743f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier // Spill the BasePtr if it's used. 13753f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier if (RegInfo->hasBasePointer(MF)) 13763f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier MF.getRegInfo().setPhysRegUsed(RegInfo->getBaseRegister()); 137794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov} 137876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 137976927d758657b3a511c73467ec5a7288795c1513Rafael Espindolastatic bool 138076927d758657b3a511c73467ec5a7288795c1513Rafael EspindolaHasNestArgument(const MachineFunction *MF) { 138176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola const Function *F = MF->getFunction(); 138276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end(); 138376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola I != E; I++) { 138476927d758657b3a511c73467ec5a7288795c1513Rafael Espindola if (I->hasNestAttr()) 138576927d758657b3a511c73467ec5a7288795c1513Rafael Espindola return true; 138676927d758657b3a511c73467ec5a7288795c1513Rafael Espindola } 138776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola return false; 138876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola} 138976927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 139098fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer/// GetScratchRegister - Get a temp register for performing work in the 139198fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer/// segmented stack and the Erlang/HiPE stack prologue. Depending on platform 139298fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer/// and the properties of the function either one or two registers will be 139398fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer/// needed. Set primary to true for the first register, false for the second. 139476927d758657b3a511c73467ec5a7288795c1513Rafael Espindolastatic unsigned 13952028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael EspindolaGetScratchRegister(bool Is64Bit, const MachineFunction &MF, bool Primary) { 139698fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer CallingConv::ID CallingConvention = MF.getFunction()->getCallingConv(); 139798fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer 139898fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // Erlang stuff. 139998fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer if (CallingConvention == CallingConv::HiPE) { 140098fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer if (Is64Bit) 140198fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer return Primary ? X86::R14 : X86::R13; 140298fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer else 140398fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer return Primary ? X86::EBX : X86::EDI; 140498fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer } 140598fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer 14064d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie if (Is64Bit) 14072028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola return Primary ? X86::R11 : X86::R12; 14084d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie 14094d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie bool IsNested = HasNestArgument(&MF); 14104d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie 14114d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie if (CallingConvention == CallingConv::X86_FastCall || 14124d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie CallingConvention == CallingConv::Fast) { 14134d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie if (IsNested) 14144d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie report_fatal_error("Segmented stacks does not support fastcall with " 14154d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie "nested function."); 14164d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie return Primary ? X86::EAX : X86::ECX; 141776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola } 14184d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie if (IsNested) 14194d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie return Primary ? X86::EDX : X86::EAX; 14204d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie return Primary ? X86::ECX : X86::EAX; 142176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola} 142276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 1423199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das// The stack limit in the TCB is set to this many bytes above the actual stack 1424199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das// limit. 1425199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Dasstatic const uint64_t kSplitStackAvailable = 256; 1426199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das 142776927d758657b3a511c73467ec5a7288795c1513Rafael Espindolavoid 142876927d758657b3a511c73467ec5a7288795c1513Rafael EspindolaX86FrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const { 142976927d758657b3a511c73467ec5a7288795c1513Rafael Espindola MachineBasicBlock &prologueMBB = MF.front(); 143076927d758657b3a511c73467ec5a7288795c1513Rafael Espindola MachineFrameInfo *MFI = MF.getFrameInfo(); 143176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola const X86InstrInfo &TII = *TM.getInstrInfo(); 143276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola uint64_t StackSize; 143376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola bool Is64Bit = STI.is64Bit(); 143476927d758657b3a511c73467ec5a7288795c1513Rafael Espindola unsigned TlsReg, TlsOffset; 143576927d758657b3a511c73467ec5a7288795c1513Rafael Espindola DebugLoc DL; 143676927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 14372028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola unsigned ScratchReg = GetScratchRegister(Is64Bit, MF, true); 143876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola assert(!MF.getRegInfo().isLiveIn(ScratchReg) && 143976927d758657b3a511c73467ec5a7288795c1513Rafael Espindola "Scratch register is live-in"); 144076927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 144176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola if (MF.getFunction()->isVarArg()) 144276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola report_fatal_error("Segmented stacks do not support vararg functions."); 1443b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer if (!STI.isTargetLinux() && !STI.isTargetDarwin() && 1444b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer !STI.isTargetWin32() && !STI.isTargetFreeBSD()) 144585b9d43d4c7a4a5e6e7da651a159353a9a00e227Rafael Espindola report_fatal_error("Segmented stacks not supported on this platform."); 144676927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 144776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola MachineBasicBlock *allocMBB = MF.CreateMachineBasicBlock(); 144876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola MachineBasicBlock *checkMBB = MF.CreateMachineBasicBlock(); 144976927d758657b3a511c73467ec5a7288795c1513Rafael Espindola X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>(); 145076927d758657b3a511c73467ec5a7288795c1513Rafael Espindola bool IsNested = false; 145176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 145276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // We need to know if the function has a nest argument only in 64 bit mode. 145376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola if (Is64Bit) 145476927d758657b3a511c73467ec5a7288795c1513Rafael Espindola IsNested = HasNestArgument(&MF); 145576927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 14564e68054b20725f6ec1cac33630258f749fe5debeBill Wendling // The MOV R10, RAX needs to be in a different block, since the RET we emit in 14574e68054b20725f6ec1cac33630258f749fe5debeBill Wendling // allocMBB needs to be last (terminating) instruction. 14584e68054b20725f6ec1cac33630258f749fe5debeBill Wendling 145976927d758657b3a511c73467ec5a7288795c1513Rafael Espindola for (MachineBasicBlock::livein_iterator i = prologueMBB.livein_begin(), 146076927d758657b3a511c73467ec5a7288795c1513Rafael Espindola e = prologueMBB.livein_end(); i != e; i++) { 146176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola allocMBB->addLiveIn(*i); 146276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola checkMBB->addLiveIn(*i); 146376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola } 146476927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 1465e840e88239cf92a065cbf5f5b9c7d18bc139c0e1Rafael Espindola if (IsNested) 146676927d758657b3a511c73467ec5a7288795c1513Rafael Espindola allocMBB->addLiveIn(X86::R10); 146776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 146876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola MF.push_front(allocMBB); 146976927d758657b3a511c73467ec5a7288795c1513Rafael Espindola MF.push_front(checkMBB); 147076927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 147176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // Eventually StackSize will be calculated by a link-time pass; which will 147276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // also decide whether checking code needs to be injected into this particular 147376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // prologue. 147476927d758657b3a511c73467ec5a7288795c1513Rafael Espindola StackSize = MFI->getStackSize(); 147576927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 14762028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola // When the frame size is less than 256 we just compare the stack 14772028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola // boundary directly to the value of the stack pointer, per gcc. 14782028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola bool CompareStackPointer = StackSize < kSplitStackAvailable; 14792028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola 148076927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // Read the limit off the current stacklet off the stack_guard location. 148176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola if (Is64Bit) { 1482b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer if (STI.isTargetLinux()) { 14832028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola TlsReg = X86::FS; 14842028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola TlsOffset = 0x70; 1485b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer } else if (STI.isTargetDarwin()) { 14862028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola TlsReg = X86::GS; 14872028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola TlsOffset = 0x60 + 90*8; // See pthread_machdep.h. Steal TLS slot 90. 1488b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer } else if (STI.isTargetFreeBSD()) { 148985b9d43d4c7a4a5e6e7da651a159353a9a00e227Rafael Espindola TlsReg = X86::FS; 149085b9d43d4c7a4a5e6e7da651a159353a9a00e227Rafael Espindola TlsOffset = 0x18; 1491e4d18de5d15c6c1d4d279788b35d0cd1ab237e82Rafael Espindola } else { 1492e4d18de5d15c6c1d4d279788b35d0cd1ab237e82Rafael Espindola report_fatal_error("Segmented stacks not supported on this platform."); 14932028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola } 149476927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 14952028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola if (CompareStackPointer) 1496199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das ScratchReg = X86::RSP; 1497199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das else 1498199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das BuildMI(checkMBB, DL, TII.get(X86::LEA64r), ScratchReg).addReg(X86::RSP) 1499014f7a3b3798580d5aac80b83bcb67e03d302fa4Rafael Espindola .addImm(1).addReg(0).addImm(-StackSize).addReg(0); 1500199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das 150176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola BuildMI(checkMBB, DL, TII.get(X86::CMP64rm)).addReg(ScratchReg) 1502014f7a3b3798580d5aac80b83bcb67e03d302fa4Rafael Espindola .addReg(0).addImm(1).addReg(0).addImm(TlsOffset).addReg(TlsReg); 150376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola } else { 1504b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer if (STI.isTargetLinux()) { 1505e4d18de5d15c6c1d4d279788b35d0cd1ab237e82Rafael Espindola TlsReg = X86::GS; 1506e4d18de5d15c6c1d4d279788b35d0cd1ab237e82Rafael Espindola TlsOffset = 0x30; 1507b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer } else if (STI.isTargetDarwin()) { 1508e4d18de5d15c6c1d4d279788b35d0cd1ab237e82Rafael Espindola TlsReg = X86::GS; 1509e4d18de5d15c6c1d4d279788b35d0cd1ab237e82Rafael Espindola TlsOffset = 0x48 + 90*4; 1510b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer } else if (STI.isTargetWin32()) { 1511e4d18de5d15c6c1d4d279788b35d0cd1ab237e82Rafael Espindola TlsReg = X86::FS; 1512e4d18de5d15c6c1d4d279788b35d0cd1ab237e82Rafael Espindola TlsOffset = 0x14; // pvArbitrary, reserved for application use 1513b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer } else if (STI.isTargetFreeBSD()) { 151485b9d43d4c7a4a5e6e7da651a159353a9a00e227Rafael Espindola report_fatal_error("Segmented stacks not supported on FreeBSD i386."); 1515e4d18de5d15c6c1d4d279788b35d0cd1ab237e82Rafael Espindola } else { 1516e4d18de5d15c6c1d4d279788b35d0cd1ab237e82Rafael Espindola report_fatal_error("Segmented stacks not supported on this platform."); 1517e4d18de5d15c6c1d4d279788b35d0cd1ab237e82Rafael Espindola } 151876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 15192028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola if (CompareStackPointer) 1520199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das ScratchReg = X86::ESP; 1521199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das else 1522199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das BuildMI(checkMBB, DL, TII.get(X86::LEA32r), ScratchReg).addReg(X86::ESP) 1523014f7a3b3798580d5aac80b83bcb67e03d302fa4Rafael Espindola .addImm(1).addReg(0).addImm(-StackSize).addReg(0); 1524199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das 1525b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer if (STI.isTargetLinux() || STI.isTargetWin32()) { 15262028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola BuildMI(checkMBB, DL, TII.get(X86::CMP32rm)).addReg(ScratchReg) 15272028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola .addReg(0).addImm(0).addReg(0).addImm(TlsOffset).addReg(TlsReg); 1528b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer } else if (STI.isTargetDarwin()) { 15292028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola 15302028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola // TlsOffset doesn't fit into a mod r/m byte so we need an extra register 15312028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola unsigned ScratchReg2; 15322028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola bool SaveScratch2; 15332028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola if (CompareStackPointer) { 15342028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola // The primary scratch register is available for holding the TLS offset 15352028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola ScratchReg2 = GetScratchRegister(Is64Bit, MF, true); 15362028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola SaveScratch2 = false; 15372028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola } else { 15382028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola // Need to use a second register to hold the TLS offset 15392028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola ScratchReg2 = GetScratchRegister(Is64Bit, MF, false); 15402028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola 15412028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola // Unfortunately, with fastcc the second scratch register may hold an arg 15422028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola SaveScratch2 = MF.getRegInfo().isLiveIn(ScratchReg2); 15432028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola } 15442028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola 15452028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola // If Scratch2 is live-in then it needs to be saved 15462028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola assert((!MF.getRegInfo().isLiveIn(ScratchReg2) || SaveScratch2) && 15472028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola "Scratch register is live-in and not saved"); 15482028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola 15492028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola if (SaveScratch2) 15502028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola BuildMI(checkMBB, DL, TII.get(X86::PUSH32r)) 15512028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola .addReg(ScratchReg2, RegState::Kill); 15522028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola 15532028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola BuildMI(checkMBB, DL, TII.get(X86::MOV32ri), ScratchReg2) 15542028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola .addImm(TlsOffset); 15552028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola BuildMI(checkMBB, DL, TII.get(X86::CMP32rm)) 15562028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola .addReg(ScratchReg) 15572028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola .addReg(ScratchReg2).addImm(1).addReg(0) 15582028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola .addImm(0) 15592028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola .addReg(TlsReg); 15602028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola 15612028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola if (SaveScratch2) 15622028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola BuildMI(checkMBB, DL, TII.get(X86::POP32r), ScratchReg2); 15632028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola } 156476927d758657b3a511c73467ec5a7288795c1513Rafael Espindola } 156576927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 156676927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // This jump is taken if SP >= (Stacklet Limit + Stack Space required). 156776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // It jumps to normal execution of the function body. 1568313c7038319422cff0b2ea1015e180575cab4b7aRafael Espindola BuildMI(checkMBB, DL, TII.get(X86::JA_4)).addMBB(&prologueMBB); 156976927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 157076927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // On 32 bit we first push the arguments size and then the frame size. On 64 157176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // bit, we pass the stack frame size in r10 and the argument size in r11. 157276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola if (Is64Bit) { 157376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // Functions with nested arguments use R10, so it needs to be saved across 157476927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // the call to _morestack 157576927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 157676927d758657b3a511c73467ec5a7288795c1513Rafael Espindola if (IsNested) 157776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola BuildMI(allocMBB, DL, TII.get(X86::MOV64rr), X86::RAX).addReg(X86::R10); 157876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 157976927d758657b3a511c73467ec5a7288795c1513Rafael Espindola BuildMI(allocMBB, DL, TII.get(X86::MOV64ri), X86::R10) 158076927d758657b3a511c73467ec5a7288795c1513Rafael Espindola .addImm(StackSize); 158176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola BuildMI(allocMBB, DL, TII.get(X86::MOV64ri), X86::R11) 158276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola .addImm(X86FI->getArgumentStackSize()); 158376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola MF.getRegInfo().setPhysRegUsed(X86::R10); 158476927d758657b3a511c73467ec5a7288795c1513Rafael Espindola MF.getRegInfo().setPhysRegUsed(X86::R11); 158576927d758657b3a511c73467ec5a7288795c1513Rafael Espindola } else { 158676927d758657b3a511c73467ec5a7288795c1513Rafael Espindola BuildMI(allocMBB, DL, TII.get(X86::PUSHi32)) 158776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola .addImm(X86FI->getArgumentStackSize()); 158876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola BuildMI(allocMBB, DL, TII.get(X86::PUSHi32)) 158976927d758657b3a511c73467ec5a7288795c1513Rafael Espindola .addImm(StackSize); 159076927d758657b3a511c73467ec5a7288795c1513Rafael Espindola } 159176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 159276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // __morestack is in libgcc 159376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola if (Is64Bit) 159476927d758657b3a511c73467ec5a7288795c1513Rafael Espindola BuildMI(allocMBB, DL, TII.get(X86::CALL64pcrel32)) 159576927d758657b3a511c73467ec5a7288795c1513Rafael Espindola .addExternalSymbol("__morestack"); 159676927d758657b3a511c73467ec5a7288795c1513Rafael Espindola else 159776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola BuildMI(allocMBB, DL, TII.get(X86::CALLpcrel32)) 159876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola .addExternalSymbol("__morestack"); 159976927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 16004e68054b20725f6ec1cac33630258f749fe5debeBill Wendling if (IsNested) 1601e840e88239cf92a065cbf5f5b9c7d18bc139c0e1Rafael Espindola BuildMI(allocMBB, DL, TII.get(X86::MORESTACK_RET_RESTORE_R10)); 1602e840e88239cf92a065cbf5f5b9c7d18bc139c0e1Rafael Espindola else 1603e840e88239cf92a065cbf5f5b9c7d18bc139c0e1Rafael Espindola BuildMI(allocMBB, DL, TII.get(X86::MORESTACK_RET)); 160476927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 1605e840e88239cf92a065cbf5f5b9c7d18bc139c0e1Rafael Espindola allocMBB->addSuccessor(&prologueMBB); 160682222c20be24adda7c218f3fdaf2e0ae049c955bBill Wendling 160776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola checkMBB->addSuccessor(allocMBB); 160876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola checkMBB->addSuccessor(&prologueMBB); 160976927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 161051f0c7641983469cbd29f8862a121645471a885aJakob Stoklund Olesen#ifdef XDEBUG 161176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola MF.verify(); 161276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola#endif 161376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola} 161498fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer 16152d1035def15030ae404b227747d0a28454ea32a9Yiannis Tsiouris/// Erlang programs may need a special prologue to handle the stack size they 16162d1035def15030ae404b227747d0a28454ea32a9Yiannis Tsiouris/// might need at runtime. That is because Erlang/OTP does not implement a C 16172d1035def15030ae404b227747d0a28454ea32a9Yiannis Tsiouris/// stack but uses a custom implementation of hybrid stack/heap architecture. 16182d1035def15030ae404b227747d0a28454ea32a9Yiannis Tsiouris/// (for more information see Eric Stenman's Ph.D. thesis: 16192d1035def15030ae404b227747d0a28454ea32a9Yiannis Tsiouris/// http://publications.uu.se/uu/fulltext/nbn_se_uu_diva-2688.pdf) 16202d1035def15030ae404b227747d0a28454ea32a9Yiannis Tsiouris/// 16212d1035def15030ae404b227747d0a28454ea32a9Yiannis Tsiouris/// CheckStack: 16222d1035def15030ae404b227747d0a28454ea32a9Yiannis Tsiouris/// temp0 = sp - MaxStack 16232d1035def15030ae404b227747d0a28454ea32a9Yiannis Tsiouris/// if( temp0 < SP_LIMIT(P) ) goto IncStack else goto OldStart 16242d1035def15030ae404b227747d0a28454ea32a9Yiannis Tsiouris/// OldStart: 16252d1035def15030ae404b227747d0a28454ea32a9Yiannis Tsiouris/// ... 16262d1035def15030ae404b227747d0a28454ea32a9Yiannis Tsiouris/// IncStack: 16272d1035def15030ae404b227747d0a28454ea32a9Yiannis Tsiouris/// call inc_stack # doubles the stack space 16282d1035def15030ae404b227747d0a28454ea32a9Yiannis Tsiouris/// temp0 = sp - MaxStack 16292d1035def15030ae404b227747d0a28454ea32a9Yiannis Tsiouris/// if( temp0 < SP_LIMIT(P) ) goto IncStack else goto OldStart 163098fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramervoid X86FrameLowering::adjustForHiPEPrologue(MachineFunction &MF) const { 163198fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer const X86InstrInfo &TII = *TM.getInstrInfo(); 163298fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer MachineFrameInfo *MFI = MF.getFrameInfo(); 1633b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer const unsigned SlotSize = TM.getRegisterInfo()->getSlotSize(); 163498fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer const bool Is64Bit = STI.is64Bit(); 163598fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer DebugLoc DL; 163698fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // HiPE-specific values 163798fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer const unsigned HipeLeafWords = 24; 163898fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer const unsigned CCRegisteredArgs = Is64Bit ? 6 : 5; 163998fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer const unsigned Guaranteed = HipeLeafWords * SlotSize; 1640b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer unsigned CallerStkArity = MF.getFunction()->arg_size() > CCRegisteredArgs ? 1641b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer MF.getFunction()->arg_size() - CCRegisteredArgs : 0; 1642b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer unsigned MaxStack = MFI->getStackSize() + CallerStkArity*SlotSize + SlotSize; 164398fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer 1644b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer assert(STI.isTargetLinux() && 164598fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer "HiPE prologue is only supported on Linux operating systems."); 164698fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer 164798fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // Compute the largest caller's frame that is needed to fit the callees' 164898fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // frames. This 'MaxStack' is computed from: 164998fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // 165098fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // a) the fixed frame size, which is the space needed for all spilled temps, 165198fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // b) outgoing on-stack parameter areas, and 165298fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // c) the minimum stack space this function needs to make available for the 165398fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // functions it calls (a tunable ABI property). 165498fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer if (MFI->hasCalls()) { 165598fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer unsigned MoreStackForCalls = 0; 165698fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer 165798fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer for (MachineFunction::iterator MBBI = MF.begin(), MBBE = MF.end(); 165898fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer MBBI != MBBE; ++MBBI) 165998fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer for (MachineBasicBlock::iterator MI = MBBI->begin(), ME = MBBI->end(); 1660b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer MI != ME; ++MI) { 1661b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer if (!MI->isCall()) 1662b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer continue; 1663b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer 1664b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer // Get callee operand. 1665b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer const MachineOperand &MO = MI->getOperand(0); 1666b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer 1667b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer // Only take account of global function calls (no closures etc.). 1668b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer if (!MO.isGlobal()) 1669b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer continue; 1670b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer 1671b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer const Function *F = dyn_cast<Function>(MO.getGlobal()); 1672b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer if (!F) 1673b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer continue; 1674b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer 1675b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer // Do not update 'MaxStack' for primitive and built-in functions 1676b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer // (encoded with names either starting with "erlang."/"bif_" or not 1677b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer // having a ".", such as a simple <Module>.<Function>.<Arity>, or an 1678b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer // "_", such as the BIF "suspend_0") as they are executed on another 1679b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer // stack. 1680b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer if (F->getName().find("erlang.") != StringRef::npos || 1681b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer F->getName().find("bif_") != StringRef::npos || 1682b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer F->getName().find_first_of("._") == StringRef::npos) 1683b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer continue; 1684b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer 1685b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer unsigned CalleeStkArity = 1686b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer F->arg_size() > CCRegisteredArgs ? F->arg_size()-CCRegisteredArgs : 0; 1687b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer if (HipeLeafWords - 1 > CalleeStkArity) 1688b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer MoreStackForCalls = std::max(MoreStackForCalls, 1689b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer (HipeLeafWords - 1 - CalleeStkArity) * SlotSize); 1690b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer } 169198fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer MaxStack += MoreStackForCalls; 169298fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer } 169398fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer 169498fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // If the stack frame needed is larger than the guaranteed then runtime checks 169598fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // and calls to "inc_stack_0" BIF should be inserted in the assembly prologue. 169698fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer if (MaxStack > Guaranteed) { 169798fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer MachineBasicBlock &prologueMBB = MF.front(); 169898fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer MachineBasicBlock *stackCheckMBB = MF.CreateMachineBasicBlock(); 169998fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer MachineBasicBlock *incStackMBB = MF.CreateMachineBasicBlock(); 170098fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer 170198fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer for (MachineBasicBlock::livein_iterator I = prologueMBB.livein_begin(), 170298fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer E = prologueMBB.livein_end(); I != E; I++) { 170398fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer stackCheckMBB->addLiveIn(*I); 170498fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer incStackMBB->addLiveIn(*I); 170598fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer } 170698fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer 170798fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer MF.push_front(incStackMBB); 170898fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer MF.push_front(stackCheckMBB); 170998fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer 171098fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer unsigned ScratchReg, SPReg, PReg, SPLimitOffset; 171198fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer unsigned LEAop, CMPop, CALLop; 171298fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer if (Is64Bit) { 171398fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer SPReg = X86::RSP; 171498fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer PReg = X86::RBP; 171598fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer LEAop = X86::LEA64r; 171698fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer CMPop = X86::CMP64rm; 171798fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer CALLop = X86::CALL64pcrel32; 171898fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer SPLimitOffset = 0x90; 171998fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer } else { 172098fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer SPReg = X86::ESP; 172198fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer PReg = X86::EBP; 172298fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer LEAop = X86::LEA32r; 172398fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer CMPop = X86::CMP32rm; 172498fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer CALLop = X86::CALLpcrel32; 172598fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer SPLimitOffset = 0x4c; 172698fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer } 172798fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer 172898fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer ScratchReg = GetScratchRegister(Is64Bit, MF, true); 172998fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer assert(!MF.getRegInfo().isLiveIn(ScratchReg) && 173098fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer "HiPE prologue scratch register is live-in"); 173198fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer 173298fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // Create new MBB for StackCheck: 173398fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer addRegOffset(BuildMI(stackCheckMBB, DL, TII.get(LEAop), ScratchReg), 173498fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer SPReg, false, -MaxStack); 173598fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // SPLimitOffset is in a fixed heap location (pointed by BP). 173698fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer addRegOffset(BuildMI(stackCheckMBB, DL, TII.get(CMPop)) 173798fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer .addReg(ScratchReg), PReg, false, SPLimitOffset); 173898fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer BuildMI(stackCheckMBB, DL, TII.get(X86::JAE_4)).addMBB(&prologueMBB); 173998fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer 174098fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // Create new MBB for IncStack: 174198fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer BuildMI(incStackMBB, DL, TII.get(CALLop)). 174298fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer addExternalSymbol("inc_stack_0"); 174398fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer addRegOffset(BuildMI(incStackMBB, DL, TII.get(LEAop), ScratchReg), 174498fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer SPReg, false, -MaxStack); 174598fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer addRegOffset(BuildMI(incStackMBB, DL, TII.get(CMPop)) 174698fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer .addReg(ScratchReg), PReg, false, SPLimitOffset); 174798fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer BuildMI(incStackMBB, DL, TII.get(X86::JLE_4)).addMBB(incStackMBB); 174898fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer 174998fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer stackCheckMBB->addSuccessor(&prologueMBB, 99); 175098fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer stackCheckMBB->addSuccessor(incStackMBB, 1); 175198fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer incStackMBB->addSuccessor(&prologueMBB, 99); 175298fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer incStackMBB->addSuccessor(incStackMBB, 1); 175398fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer } 175498fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer#ifdef XDEBUG 175598fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer MF.verify(); 175698fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer#endif 175798fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer} 1758700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 1759700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Benderskyvoid X86FrameLowering:: 1760700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli BenderskyeliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 1761700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MachineBasicBlock::iterator I) const { 1762700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky const X86InstrInfo &TII = *TM.getInstrInfo(); 1763700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky const X86RegisterInfo &RegInfo = *TM.getRegisterInfo(); 1764700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky unsigned StackPtr = RegInfo.getStackRegister(); 1765700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky bool reseveCallFrame = hasReservedCallFrame(MF); 1766700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky int Opcode = I->getOpcode(); 1767700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky bool isDestroy = Opcode == TII.getCallFrameDestroyOpcode(); 1768700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky bool IsLP64 = STI.isTarget64BitLP64(); 1769700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky DebugLoc DL = I->getDebugLoc(); 1770700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky uint64_t Amount = !reseveCallFrame ? I->getOperand(0).getImm() : 0; 1771700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky uint64_t CalleeAmt = isDestroy ? I->getOperand(1).getImm() : 0; 1772700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky I = MBB.erase(I); 1773700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 1774700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (!reseveCallFrame) { 1775700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // If the stack pointer can be changed after prologue, turn the 1776700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // adjcallstackup instruction into a 'sub ESP, <amt>' and the 1777700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // adjcallstackdown instruction into 'add ESP, <amt>' 1778700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // TODO: consider using push / pop instead of sub + store / add 1779700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (Amount == 0) 1780700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky return; 1781700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 1782700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // We need to keep the stack aligned properly. To do this, we round the 1783700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // amount of space needed for the outgoing arguments up to the next 1784700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // alignment boundary. 1785700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky unsigned StackAlign = TM.getFrameLowering()->getStackAlignment(); 1786700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky Amount = (Amount + StackAlign - 1) / StackAlign * StackAlign; 1787700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 1788700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MachineInstr *New = 0; 1789700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (Opcode == TII.getCallFrameSetupOpcode()) { 1790700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky New = BuildMI(MF, DL, TII.get(getSUBriOpcode(IsLP64, Amount)), 1791700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky StackPtr) 1792700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky .addReg(StackPtr) 1793700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky .addImm(Amount); 1794700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } else { 1795700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky assert(Opcode == TII.getCallFrameDestroyOpcode()); 1796700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 1797700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // Factor out the amount the callee already popped. 1798700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky Amount -= CalleeAmt; 1799700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 1800700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (Amount) { 1801700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky unsigned Opc = getADDriOpcode(IsLP64, Amount); 1802700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky New = BuildMI(MF, DL, TII.get(Opc), StackPtr) 1803700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky .addReg(StackPtr).addImm(Amount); 1804700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } 1805700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } 1806700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 1807700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (New) { 1808700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // The EFLAGS implicit def is dead. 1809700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky New->getOperand(3).setIsDead(); 1810700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 1811700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // Replace the pseudo instruction with a new instruction. 1812700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MBB.insert(I, New); 1813700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } 1814700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 1815700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky return; 1816700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } 1817700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 1818700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (Opcode == TII.getCallFrameDestroyOpcode() && CalleeAmt) { 1819700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // If we are performing frame pointer elimination and if the callee pops 1820700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // something off the stack pointer, add it back. We do this until we have 1821700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // more advanced stack pointer tracking ability. 1822700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky unsigned Opc = getSUBriOpcode(IsLP64, CalleeAmt); 1823700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MachineInstr *New = BuildMI(MF, DL, TII.get(Opc), StackPtr) 1824700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky .addReg(StackPtr).addImm(CalleeAmt); 1825700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 1826700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // The EFLAGS implicit def is dead. 1827700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky New->getOperand(3).setIsDead(); 1828700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 1829700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // We are not tracking the stack pointer adjustment by the callee, so make 1830700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // sure we restore the stack pointer immediately after the call, there may 1831700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // be spill code inserted between the CALL and ADJCALLSTACKUP instructions. 1832700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MachineBasicBlock::iterator B = MBB.begin(); 1833700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky while (I != B && !llvm::prior(I)->isCall()) 1834700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky --I; 1835700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MBB.insert(I, New); 1836700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } 1837700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky} 1838700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 1839