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" 32cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "llvm/Support/Debug.h" 3333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 3433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovusing namespace llvm; 3533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 3633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// FIXME: completely move here. 3733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovextern cl::opt<bool> ForceStackAlign; 3833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 3916c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovbool X86FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 40d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov return !MF.getFrameInfo()->hasVarSizedObjects(); 41d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov} 42d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 43d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov/// hasFP - Return true if the specified function should have a dedicated frame 44d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov/// pointer register. This is true if the function has variable sized allocas 45d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov/// or if frame pointer elimination is disabled. 4616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovbool X86FrameLowering::hasFP(const MachineFunction &MF) const { 47d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov const MachineFrameInfo *MFI = MF.getFrameInfo(); 48d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov const MachineModuleInfo &MMI = MF.getMMI(); 49cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo(); 50d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 518a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky return (MF.getTarget().Options.DisableFramePointerElim(MF) || 523fb6eca0cd4c2b31b06543ca2ac60b9c91c2264dChad Rosier RegInfo->needsStackRealignment(MF) || 53d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov MFI->hasVarSizedObjects() || 5436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MFI->isFrameAddressTaken() || MFI->hasInlineAsmWithSPAdjust() || 55d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov MF.getInfo<X86MachineFunctionInfo>()->getForceFramePointer() || 56e208c491726bb1efbfc4fc05a9f73ad808432979Jakob Stoklund Olesen MMI.callsUnwindInit() || MMI.callsEHReturn()); 57d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov} 58d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 59700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Benderskystatic unsigned getSUBriOpcode(unsigned IsLP64, int64_t Imm) { 60700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (IsLP64) { 6133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (isInt<8>(Imm)) 6233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::SUB64ri8; 6333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::SUB64ri32; 6433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 6533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (isInt<8>(Imm)) 6633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::SUB32ri8; 6733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::SUB32ri; 6833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 6933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 7033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 7116221a60a00e52b078f6164ba4475c6e8e918e4bEli Benderskystatic unsigned getADDriOpcode(unsigned IsLP64, int64_t Imm) { 7216221a60a00e52b078f6164ba4475c6e8e918e4bEli Bendersky if (IsLP64) { 7333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (isInt<8>(Imm)) 7433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::ADD64ri8; 7533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::ADD64ri32; 7633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 7733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (isInt<8>(Imm)) 7833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::ADD32ri8; 7933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::ADD32ri; 8033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 8133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 8233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 8316221a60a00e52b078f6164ba4475c6e8e918e4bEli Benderskystatic unsigned getLEArOpcode(unsigned IsLP64) { 8416221a60a00e52b078f6164ba4475c6e8e918e4bEli Bendersky return IsLP64 ? X86::LEA64r : X86::LEA32r; 85de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng} 86de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng 877158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng/// findDeadCallerSavedReg - Return a caller-saved register that isn't live 887158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng/// when it reaches the "return" instruction. We can then pop a stack object 897158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng/// to this register without worry about clobbering it. 907158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Chengstatic unsigned findDeadCallerSavedReg(MachineBasicBlock &MBB, 917158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng MachineBasicBlock::iterator &MBBI, 927158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng const TargetRegisterInfo &TRI, 937158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng bool Is64Bit) { 947158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng const MachineFunction *MF = MBB.getParent(); 957158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng const Function *F = MF->getFunction(); 967158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng if (!F || MF->getMMI().callsEHReturn()) 977158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng return 0; 987158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 99e4fd907e72a599eddfa7a81eac4366b5b82523e3Craig Topper static const uint16_t CallerSavedRegs32Bit[] = { 10032a183c84ad0cbe492119c37f1a7941ace61dd79Andrew Trick X86::EAX, X86::EDX, X86::ECX, 0 1017158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng }; 1027158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 103e4fd907e72a599eddfa7a81eac4366b5b82523e3Craig Topper static const uint16_t CallerSavedRegs64Bit[] = { 1047158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng X86::RAX, X86::RDX, X86::RCX, X86::RSI, X86::RDI, 10532a183c84ad0cbe492119c37f1a7941ace61dd79Andrew Trick X86::R8, X86::R9, X86::R10, X86::R11, 0 1067158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng }; 1077158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 1087158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng unsigned Opc = MBBI->getOpcode(); 1097158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng switch (Opc) { 1107158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng default: return 0; 11136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case X86::RETL: 11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case X86::RETQ: 11336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case X86::RETIL: 11436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case X86::RETIQ: 1157158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::TCRETURNdi: 1167158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::TCRETURNri: 1177158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::TCRETURNmi: 1187158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::TCRETURNdi64: 1197158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::TCRETURNri64: 1207158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::TCRETURNmi64: 1217158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::EH_RETURN: 1227158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::EH_RETURN64: { 123e4fd907e72a599eddfa7a81eac4366b5b82523e3Craig Topper SmallSet<uint16_t, 8> Uses; 1247158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng for (unsigned i = 0, e = MBBI->getNumOperands(); i != e; ++i) { 1257158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng MachineOperand &MO = MBBI->getOperand(i); 1267158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng if (!MO.isReg() || MO.isDef()) 1277158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng continue; 1287158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng unsigned Reg = MO.getReg(); 1297158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng if (!Reg) 1307158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng continue; 131396618b43a85e12d290a90b181c6af5d7c0c5f11Jakob Stoklund Olesen for (MCRegAliasIterator AI(Reg, &TRI, true); AI.isValid(); ++AI) 132396618b43a85e12d290a90b181c6af5d7c0c5f11Jakob Stoklund Olesen Uses.insert(*AI); 1337158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng } 1347158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 135e4fd907e72a599eddfa7a81eac4366b5b82523e3Craig Topper const uint16_t *CS = Is64Bit ? CallerSavedRegs64Bit : CallerSavedRegs32Bit; 1367158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng for (; *CS; ++CS) 1377158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng if (!Uses.count(*CS)) 1387158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng return *CS; 1397158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng } 1407158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng } 1417158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 1427158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng return 0; 1437158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng} 1447158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 1457158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 14633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// emitSPUpdate - Emit a series of instructions to increment / decrement the 14733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// stack pointer by a constant value. 14833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovstatic 14933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovvoid emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, 1507158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng unsigned StackPtr, int64_t NumBytes, 1512a1b60d791522d73be91d4281c90d25bd5e3d117Eli Bendersky bool Is64Bit, bool IsLP64, bool UseLEA, 15276ad43c6e1619ed4c087b8ccb2cd573eb9d7093eEric Christopher const TargetInstrInfo &TII, const TargetRegisterInfo &TRI) { 15333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool isSub = NumBytes < 0; 15433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t Offset = isSub ? -NumBytes : NumBytes; 155de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng unsigned Opc; 156de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng if (UseLEA) 15716221a60a00e52b078f6164ba4475c6e8e918e4bEli Bendersky Opc = getLEArOpcode(IsLP64); 158de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng else 159de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng Opc = isSub 1602a1b60d791522d73be91d4281c90d25bd5e3d117Eli Bendersky ? getSUBriOpcode(IsLP64, Offset) 1612a1b60d791522d73be91d4281c90d25bd5e3d117Eli Bendersky : getADDriOpcode(IsLP64, Offset); 162de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng 16333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t Chunk = (1LL << 31) - 1; 16476ad43c6e1619ed4c087b8ccb2cd573eb9d7093eEric Christopher DebugLoc DL = MBB.findDebugLoc(MBBI); 16533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 16633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov while (Offset) { 16733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t ThisVal = (Offset > Chunk) ? Chunk : Offset; 1687158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng if (ThisVal == (Is64Bit ? 8 : 4)) { 1697158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng // Use push / pop instead. 1707158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng unsigned Reg = isSub 1711e08cd1eaef8acbcfaf7db48d859a29583c29897Dale Johannesen ? (unsigned)(Is64Bit ? X86::RAX : X86::EAX) 1727158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng : findDeadCallerSavedReg(MBB, MBBI, TRI, Is64Bit); 1737158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng if (Reg) { 1747158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng Opc = isSub 1757158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng ? (Is64Bit ? X86::PUSH64r : X86::PUSH32r) 1767158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng : (Is64Bit ? X86::POP64r : X86::POP32r); 177aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis MachineInstr *MI = BuildMI(MBB, MBBI, DL, TII.get(Opc)) 1787158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng .addReg(Reg, getDefRegState(!isSub) | getUndefRegState(isSub)); 179aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis if (isSub) 180aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis MI->setFlag(MachineInstr::FrameSetup); 1817158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng Offset -= ThisVal; 1827158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng continue; 1837158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng } 1847158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng } 1857158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 186dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachineInstr *MI = nullptr; 187de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng 188de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng if (UseLEA) { 189de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng MI = addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr), 190de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng StackPtr, false, isSub ? -ThisVal : ThisVal); 191de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng } else { 192de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng MI = BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr) 193de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng .addReg(StackPtr) 194de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng .addImm(ThisVal); 195de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng MI->getOperand(3).setIsDead(); // The EFLAGS implicit def is dead. 196de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng } 197de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng 198aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis if (isSub) 199aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis MI->setFlag(MachineInstr::FrameSetup); 200de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng 20133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Offset -= ThisVal; 20233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 20333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 20433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 20533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// mergeSPUpdatesUp - Merge two stack-manipulating instructions upper iterator. 20633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovstatic 20733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovvoid mergeSPUpdatesUp(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, 208dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned StackPtr, uint64_t *NumBytes = nullptr) { 20933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MBBI == MBB.begin()) return; 21033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 21136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachineBasicBlock::iterator PI = std::prev(MBBI); 21233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Opc = PI->getOpcode(); 21333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 || 214de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng Opc == X86::ADD32ri || Opc == X86::ADD32ri8 || 215de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng Opc == X86::LEA32r || Opc == X86::LEA64_32r) && 21633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PI->getOperand(0).getReg() == StackPtr) { 21733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (NumBytes) 21833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *NumBytes += PI->getOperand(2).getImm(); 21933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBB.erase(PI); 22033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 || 22133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Opc == X86::SUB32ri || Opc == X86::SUB32ri8) && 22233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PI->getOperand(0).getReg() == StackPtr) { 22333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (NumBytes) 22433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *NumBytes -= PI->getOperand(2).getImm(); 22533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBB.erase(PI); 22633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 22733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 22833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 229dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// mergeSPUpdatesDown - Merge two stack-manipulating instructions lower 230dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// iterator. 23133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovstatic 23233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovvoid mergeSPUpdatesDown(MachineBasicBlock &MBB, 23333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator &MBBI, 234dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned StackPtr, uint64_t *NumBytes = nullptr) { 235fc9261279aa140542cf9b7c2c384d000ad97aca0Sanjoy Das // FIXME: THIS ISN'T RUN!!! 23633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return; 23733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 23833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MBBI == MBB.end()) return; 23933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 24036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachineBasicBlock::iterator NI = std::next(MBBI); 24133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (NI == MBB.end()) return; 24233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 24333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Opc = NI->getOpcode(); 24433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 || 24533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Opc == X86::ADD32ri || Opc == X86::ADD32ri8) && 24633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov NI->getOperand(0).getReg() == StackPtr) { 24733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (NumBytes) 24833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *NumBytes -= NI->getOperand(2).getImm(); 24933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBB.erase(NI); 25033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBBI = NI; 25133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 || 25233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Opc == X86::SUB32ri || Opc == X86::SUB32ri8) && 25333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov NI->getOperand(0).getReg() == StackPtr) { 25433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (NumBytes) 25533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *NumBytes += NI->getOperand(2).getImm(); 25633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBB.erase(NI); 25733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBBI = NI; 25833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 25933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 26033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 26133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// mergeSPUpdates - Checks the instruction before/after the passed 262dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// instruction. If it is an ADD/SUB/LEA instruction it is deleted argument and 263dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// the stack adjustment is returned as a positive value for ADD/LEA and a 264dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// negative for SUB. 26533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovstatic int mergeSPUpdates(MachineBasicBlock &MBB, 266dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachineBasicBlock::iterator &MBBI, unsigned StackPtr, 267dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool doMergeWithPrevious) { 26833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if ((doMergeWithPrevious && MBBI == MBB.begin()) || 26933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov (!doMergeWithPrevious && MBBI == MBB.end())) 27033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return 0; 27133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 27236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachineBasicBlock::iterator PI = doMergeWithPrevious ? std::prev(MBBI) : MBBI; 273dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachineBasicBlock::iterator NI = doMergeWithPrevious ? nullptr 274dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines : std::next(MBBI); 27533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Opc = PI->getOpcode(); 27633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int Offset = 0; 27733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 27833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 || 279de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng Opc == X86::ADD32ri || Opc == X86::ADD32ri8 || 280de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng Opc == X86::LEA32r || Opc == X86::LEA64_32r) && 28133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PI->getOperand(0).getReg() == StackPtr){ 28233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Offset += PI->getOperand(2).getImm(); 28333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBB.erase(PI); 28433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!doMergeWithPrevious) MBBI = NI; 28533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 || 28633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Opc == X86::SUB32ri || Opc == X86::SUB32ri8) && 28733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PI->getOperand(0).getReg() == StackPtr) { 28833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Offset -= PI->getOperand(2).getImm(); 28933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBB.erase(PI); 29033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!doMergeWithPrevious) MBBI = NI; 29133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 29233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 29333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return Offset; 29433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 29533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 29633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovstatic bool isEAXLiveIn(MachineFunction &MF) { 29733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (MachineRegisterInfo::livein_iterator II = MF.getRegInfo().livein_begin(), 29833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov EE = MF.getRegInfo().livein_end(); II != EE; ++II) { 29933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Reg = II->first; 30033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 30133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (Reg == X86::EAX || Reg == X86::AX || 30233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Reg == X86::AH || Reg == X86::AL) 30333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return true; 30433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 30533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 30633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return false; 30733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 30833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 309cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid 310cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesX86FrameLowering::emitCalleeSavedFrameMoves(MachineBasicBlock &MBB, 311cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachineBasicBlock::iterator MBBI, 312cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines DebugLoc DL) const { 31336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachineFunction &MF = *MBB.getParent(); 31433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 31533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineModuleInfo &MMI = MF.getMMI(); 31699cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo(); 317cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 31833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 31933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Add callee saved registers to move list. 32033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 32133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (CSI.empty()) return; 32233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 32333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Calculate offsets. 32433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (std::vector<CalleeSavedInfo>::const_iterator 32533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov I = CSI.begin(), E = CSI.end(); I != E; ++I) { 32633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int64_t Offset = MFI->getObjectOffset(I->getFrameIdx()); 32733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Reg = I->getReg(); 32833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 32999cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned DwarfReg = MRI->getDwarfRegNum(Reg, true); 33036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned CFIIndex = 331dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MMI.addFrameInst(MCCFIInstruction::createOffset(nullptr, DwarfReg, 332dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Offset)); 333dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION)) 334dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines .addCFIIndex(CFIIndex); 33533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 33633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 33733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 338677689cf5dc65404645462464682a0696cc84532Nadav Rotem/// usesTheStack - This function checks if any of the users of EFLAGS 339d0696ef8c33b9b2504e89bc0aab2ea99a6c90756Nadav Rotem/// copies the EFLAGS. We know that the code that lowers COPY of EFLAGS has 340d0696ef8c33b9b2504e89bc0aab2ea99a6c90756Nadav Rotem/// to use the stack, and if we don't adjust the stack we clobber the first 341d0696ef8c33b9b2504e89bc0aab2ea99a6c90756Nadav Rotem/// frame index. 342677689cf5dc65404645462464682a0696cc84532Nadav Rotem/// See X86InstrInfo::copyPhysReg. 343e4272979978951bece0141cdd9f6a4481b34656fBill Wendlingstatic bool usesTheStack(const MachineFunction &MF) { 344e4272979978951bece0141cdd9f6a4481b34656fBill Wendling const MachineRegisterInfo &MRI = MF.getRegInfo(); 345d0696ef8c33b9b2504e89bc0aab2ea99a6c90756Nadav Rotem 34636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (MachineRegisterInfo::reg_instr_iterator 34736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ri = MRI.reg_instr_begin(X86::EFLAGS), re = MRI.reg_instr_end(); 34836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ri != re; ++ri) 349d0696ef8c33b9b2504e89bc0aab2ea99a6c90756Nadav Rotem if (ri->isCopy()) 350d0696ef8c33b9b2504e89bc0aab2ea99a6c90756Nadav Rotem return true; 351d0696ef8c33b9b2504e89bc0aab2ea99a6c90756Nadav Rotem 352d0696ef8c33b9b2504e89bc0aab2ea99a6c90756Nadav Rotem return false; 353d0696ef8c33b9b2504e89bc0aab2ea99a6c90756Nadav Rotem} 354d0696ef8c33b9b2504e89bc0aab2ea99a6c90756Nadav Rotem 35533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// emitPrologue - Push callee-saved registers onto the stack, which 35633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// automatically adjust the stack pointer. Adjust the stack pointer to allocate 35733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// space for local variables. Also emit labels used by the exception handler to 35833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// generate the exception handling frames. 359cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 360cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/* 361cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Here's a gist of what gets emitted: 362cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 363cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ; Establish frame pointer, if needed 364cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines [if needs FP] 365cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines push %rbp 366cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .cfi_def_cfa_offset 16 367cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .cfi_offset %rbp, -16 368cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .seh_pushreg %rpb 369cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines mov %rsp, %rbp 370cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .cfi_def_cfa_register %rbp 371cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 372cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ; Spill general-purpose registers 373cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines [for all callee-saved GPRs] 374cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines pushq %<reg> 375cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines [if not needs FP] 376cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .cfi_def_cfa_offset (offset from RETADDR) 377cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .seh_pushreg %<reg> 378cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 379cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ; If the required stack alignment > default stack alignment 380cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ; rsp needs to be re-aligned. This creates a "re-alignment gap" 381cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ; of unknown size in the stack frame. 382cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines [if stack needs re-alignment] 383cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines and $MASK, %rsp 384cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 385cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ; Allocate space for locals 386cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines [if target is Windows and allocated space > 4096 bytes] 387cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ; Windows needs special care for allocations larger 388cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ; than one page. 389cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines mov $NNN, %rax 390cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines call ___chkstk_ms/___chkstk 391cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines sub %rax, %rsp 392cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines [else] 393cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines sub $NNN, %rsp 394cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 395cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines [if needs FP] 396cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .seh_stackalloc (size of XMM spill slots) 397cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .seh_setframe %rbp, SEHFrameOffset ; = size of all spill slots 398cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines [else] 399cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .seh_stackalloc NNN 400cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 401cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ; Spill XMMs 402cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ; Note, that while only Windows 64 ABI specifies XMMs as callee-preserved, 403cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ; they may get spilled on any platform, if the current function 404cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ; calls @llvm.eh.unwind.init 405cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines [if needs FP] 406cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines [for all callee-saved XMM registers] 407cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines movaps %<xmm reg>, -MMM(%rbp) 408cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines [for all callee-saved XMM registers] 409cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .seh_savexmm %<xmm reg>, (-MMM + SEHFrameOffset) 410cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ; i.e. the offset relative to (%rbp - SEHFrameOffset) 411cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines [else] 412cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines [for all callee-saved XMM registers] 413cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines movaps %<xmm reg>, KKK(%rsp) 414cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines [for all callee-saved XMM registers] 415cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .seh_savexmm %<xmm reg>, KKK 416cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 417cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .seh_endprologue 418cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 419cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines [if needs base pointer] 420cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines mov %rsp, %rbx 421cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 422cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ; Emit CFI info 423cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines [if needs FP] 424cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines [for all callee-saved registers] 425cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .cfi_offset %<reg>, (offset from %rbp) 426cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines [else] 427cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .cfi_def_cfa_offset (offset from RETADDR) 428cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines [for all callee-saved registers] 429cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .cfi_offset %<reg>, (offset from %rsp) 430cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 431cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Notes: 432cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines - .seh directives are emitted only for Windows 64 ABI 433cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines - .cfi directives are emitted for all other ABIs 434cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines - for 32-bit code, substitute %e?? registers for %r?? 435cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines*/ 436cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 43716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid X86FrameLowering::emitPrologue(MachineFunction &MF) const { 43833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock &MBB = MF.front(); // Prologue goes in entry BB. 43933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator MBBI = MBB.begin(); 44033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 44133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const Function *Fn = MF.getFunction(); 442cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const X86RegisterInfo *RegInfo = 443cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines static_cast<const X86RegisterInfo *>(MF.getTarget().getRegisterInfo()); 444cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 44533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineModuleInfo &MMI = MF.getMMI(); 44633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>(); 44733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t MaxAlign = MFI->getMaxAlignment(); // Desired stack alignment. 44833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t StackSize = MFI->getStackSize(); // Number of bytes to allocate. 449d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov bool HasFP = hasFP(MF); 450cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const X86Subtarget &STI = MF.getTarget().getSubtarget<X86Subtarget>(); 45133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool Is64Bit = STI.is64Bit(); 4522a1b60d791522d73be91d4281c90d25bd5e3d117Eli Bendersky bool IsLP64 = STI.isTarget64BitLP64(); 45333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool IsWin64 = STI.isTargetWin64(); 454cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool IsWinEH = 455cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MF.getTarget().getMCAsmInfo()->getExceptionHandlingType() == 456cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ExceptionHandling::WinEH; // Not necessarily synonymous with IsWin64. 457cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool NeedsWinEH = IsWinEH && Fn->needsUnwindTableEntry(); 458cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool NeedsDwarfCFI = 459cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines !IsWinEH && (MMI.hasDebugInfo() || Fn->needsUnwindTableEntry()); 460de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng bool UseLEA = STI.useLeaForSP(); 46133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackAlign = getStackAlignment(); 46233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned SlotSize = RegInfo->getSlotSize(); 46333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned FramePtr = RegInfo->getFrameRegister(MF); 46433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackPtr = RegInfo->getStackRegister(); 4653f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier unsigned BasePtr = RegInfo->getBaseRegister(); 4669c7448c8d337fde57a75f58baab8fed6afad0a10Bill Wendling DebugLoc DL; 46733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 46833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If we're forcing a stack realignment we can't rely on just the frame 46933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // info, we need to know the ABI stack alignment as well in case we 47033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // have a call out. Otherwise just make sure we have some alignment - we'll 47133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // go with the minimum SlotSize. 47233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (ForceStackAlign) { 47333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MFI->hasCalls()) 47433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MaxAlign = (StackAlign > MaxAlign) ? StackAlign : MaxAlign; 47533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov else if (MaxAlign < SlotSize) 47633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MaxAlign = SlotSize; 47733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 47833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 47933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Add RETADDR move area to callee saved frame size. 48033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta(); 48133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (TailCallReturnAddrDelta < 0) 48233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov X86FI->setCalleeSavedFrameSize( 48333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov X86FI->getCalleeSavedFrameSize() - TailCallReturnAddrDelta); 48433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 48533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If this is x86-64 and the Red Zone is not disabled, if we are a leaf 48633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // function, and use up to 128 bytes of stack space, don't have a frame 48733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // pointer, calls, or dynamic alloca then we do not need to adjust the 488d0696ef8c33b9b2504e89bc0aab2ea99a6c90756Nadav Rotem // stack pointer (we fit in the Red Zone). We also check that we don't 489d0696ef8c33b9b2504e89bc0aab2ea99a6c90756Nadav Rotem // push and pop from the stack. 490831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling if (Is64Bit && !Fn->getAttributes().hasAttribute(AttributeSet::FunctionIndex, 491831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling Attribute::NoRedZone) && 49233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov !RegInfo->needsStackRealignment(MF) && 4938a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky !MFI->hasVarSizedObjects() && // No dynamic alloca. 4948a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky !MFI->adjustsStack() && // No calls. 4958a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky !IsWin64 && // Win64 has no Red Zone 496677689cf5dc65404645462464682a0696cc84532Nadav Rotem !usesTheStack(MF) && // Don't push and pop. 497dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines !MF.shouldSplitStack()) { // Regular stack 49833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t MinSize = X86FI->getCalleeSavedFrameSize(); 49933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) MinSize += SlotSize; 50033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov StackSize = std::max(MinSize, StackSize > 128 ? StackSize - 128 : 0); 50133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MFI->setStackSize(StackSize); 50233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 50333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 50433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Insert stack pointer adjustment for later moving of return addr. Only 50533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // applies to tail call optimized functions where the callee argument stack 50633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // size is bigger than the callers. 50733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (TailCallReturnAddrDelta < 0) { 50833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineInstr *MI = 50933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, 5102a1b60d791522d73be91d4281c90d25bd5e3d117Eli Bendersky TII.get(getSUBriOpcode(IsLP64, -TailCallReturnAddrDelta)), 51133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov StackPtr) 51233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(StackPtr) 513aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis .addImm(-TailCallReturnAddrDelta) 514aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis .setMIFlag(MachineInstr::FrameSetup); 51533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MI->getOperand(3).setIsDead(); // The EFLAGS implicit def is dead. 51633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 51733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 51833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Mapping for machine moves: 51933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // 52033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // DST: VirtualFP AND 52133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // SRC: VirtualFP => DW_CFA_def_cfa_offset 52233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // ELSE => DW_CFA_def_cfa 52333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // 52433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // SRC: VirtualFP AND 52533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // DST: Register => DW_CFA_def_cfa_register 52633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // 52733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // ELSE 52833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // OFFSET < 0 => DW_CFA_offset_extended_sf 52933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // REG < 64 => DW_CFA_offset + Reg 53033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // ELSE => DW_CFA_offset_extended 53133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 53233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t NumBytes = 0; 533aa3c2c09d9d5bc67c6ca2fbc6697257b15476684Michael Liao int stackGrowth = -SlotSize; 53433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 53533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) { 53633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Calculate required stack adjustment. 53733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t FrameSize = StackSize - SlotSize; 53899a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov if (RegInfo->needsStackRealignment(MF)) { 53999a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov // Callee-saved registers are pushed on stack before the stack 54099a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov // is realigned. 54199a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov FrameSize -= X86FI->getCalleeSavedFrameSize(); 54299a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov NumBytes = (FrameSize + MaxAlign - 1) / MaxAlign * MaxAlign; 54399a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov } else { 54499a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov NumBytes = FrameSize - X86FI->getCalleeSavedFrameSize(); 54599a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov } 54633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 54733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get the offset of the stack slot for the EBP register, which is 54833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // guaranteed to be the last slot by processFunctionBeforeFrameFinalized. 54933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Update the frame offset adjustment. 55033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MFI->setOffsetAdjustment(-NumBytes); 55133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 55233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Save EBP/RBP into the appropriate stack slot. 55333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::PUSH64r : X86::PUSH32r)) 554aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis .addReg(FramePtr, RegState::Kill) 555aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis .setMIFlag(MachineInstr::FrameSetup); 55633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 557cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (NeedsDwarfCFI) { 55833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Mark the place where EBP/RBP was saved. 55933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Define the current CFA rule to use the provided offset. 560377b2270124f6f566c0f291bcb02f7755b642c2cRafael Espindola assert(StackSize); 56136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned CFIIndex = MMI.addFrameInst( 562dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MCCFIInstruction::createDefCfaOffset(nullptr, 2 * stackGrowth)); 563dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION)) 56436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .addCFIIndex(CFIIndex); 56533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 56633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Change the rule for the FramePtr to be an "offset" rule. 5676b67ffd68bb2e555b1b512a809f3c82c68f3debeRafael Espindola unsigned DwarfFramePtr = RegInfo->getDwarfRegNum(FramePtr, true); 56836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CFIIndex = MMI.addFrameInst( 569dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MCCFIInstruction::createOffset(nullptr, 570dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DwarfFramePtr, 2 * stackGrowth)); 571dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION)) 57236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .addCFIIndex(CFIIndex); 57333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 57433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 575cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (NeedsWinEH) { 576cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines BuildMI(MBB, MBBI, DL, TII.get(X86::SEH_PushReg)) 577cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .addImm(FramePtr) 578cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .setMIFlag(MachineInstr::FrameSetup); 579cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 580cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 58109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // Update EBP with the new base value. 58233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, 58333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr), FramePtr) 584aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis .addReg(StackPtr) 585aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis .setMIFlag(MachineInstr::FrameSetup); 58633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 587cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (NeedsDwarfCFI) { 58833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Mark effective beginning of when frame pointer becomes valid. 58933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Define the current CFA to use the EBP/RBP register. 5906b67ffd68bb2e555b1b512a809f3c82c68f3debeRafael Espindola unsigned DwarfFramePtr = RegInfo->getDwarfRegNum(FramePtr, true); 59136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned CFIIndex = MMI.addFrameInst( 592dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MCCFIInstruction::createDefCfaRegister(nullptr, DwarfFramePtr)); 593dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION)) 59436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .addCFIIndex(CFIIndex); 59533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 59633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 597cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Mark the FramePtr as live-in in every block. 598cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) 59933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov I->addLiveIn(FramePtr); 60033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 60133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov NumBytes = StackSize - X86FI->getCalleeSavedFrameSize(); 60233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 60333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 60433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Skip the callee-saved push instructions. 60533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool PushedRegs = false; 60633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int StackOffset = 2 * stackGrowth; 60733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 60833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov while (MBBI != MBB.end() && 60933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov (MBBI->getOpcode() == X86::PUSH32r || 61033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBBI->getOpcode() == X86::PUSH64r)) { 61133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PushedRegs = true; 612cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned Reg = MBBI->getOperand(0).getReg(); 61333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov ++MBBI; 61433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 615cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!HasFP && NeedsDwarfCFI) { 61633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Mark callee-saved push instruction. 61733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Define the current CFA rule to use the provided offset. 6180ed9f1fd8687ad32364b56898e6ebe1515e0e41cRafael Espindola assert(StackSize); 61936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned CFIIndex = MMI.addFrameInst( 62036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCCFIInstruction::createDefCfaOffset(nullptr, StackOffset)); 621dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION)) 62236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .addCFIIndex(CFIIndex); 62333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov StackOffset += stackGrowth; 62433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 625cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 626cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (NeedsWinEH) { 627cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines BuildMI(MBB, MBBI, DL, TII.get(X86::SEH_PushReg)).addImm(Reg).setMIFlag( 628cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachineInstr::FrameSetup); 629cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 63033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 63133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 63299a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov // Realign stack after we pushed callee-saved registers (so that we'll be 63399a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov // able to calculate their offsets from the frame pointer). 63499a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov if (RegInfo->needsStackRealignment(MF)) { 63599a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov assert(HasFP && "There should be a frame pointer if stack is realigned."); 63699a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov MachineInstr *MI = 63799a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov BuildMI(MBB, MBBI, DL, 63899a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov TII.get(Is64Bit ? X86::AND64ri32 : X86::AND32ri), StackPtr) 63999a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov .addReg(StackPtr) 64099a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov .addImm(-MaxAlign) 64199a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov .setMIFlag(MachineInstr::FrameSetup); 64299a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov 64399a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov // The EFLAGS implicit def is dead. 64499a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov MI->getOperand(3).setIsDead(); 64599a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov } 64699a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov 64733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If there is an SUB32ri of ESP immediately before this instruction, merge 64833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // the two. This can be the case when tail call elimination is enabled and 64933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // the callee has more arguments then the caller. 65033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov NumBytes -= mergeSPUpdates(MBB, MBBI, StackPtr, true); 65133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 65233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If there is an ADD32ri or SUB32ri of ESP immediately after this 65333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // instruction, merge the two instructions. 65433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov mergeSPUpdatesDown(MBB, MBBI, StackPtr, &NumBytes); 65533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 65633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Adjust stack pointer: ESP -= numbytes. 65733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 65833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Windows and cygwin/mingw require a prologue helper routine when allocating 65933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // more than 4K bytes on the stack. Windows uses __chkstk and cygwin/mingw 66033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // uses __alloca. __alloca and the 32-bit version of __chkstk will probe the 66133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // stack and adjust the stack pointer in one go. The 64-bit version of 66233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // __chkstk is only responsible for probing the stack. The 64-bit prologue is 66333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // responsible for adjusting the stack pointer. Touching the stack at 4K 66433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // increments is necessary to ensure that the guard pages used by the OS 66533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // virtual memory manager are allocated in correct sequence. 66636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (NumBytes >= 4096 && STI.isOSWindows() && !STI.isTargetMacho()) { 667a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi const char *StackProbeSymbol; 668a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi 669a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi if (Is64Bit) { 67036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (STI.isTargetCygMing()) { 67136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StackProbeSymbol = "___chkstk_ms"; 67236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 673a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi StackProbeSymbol = "__chkstk"; 674a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi } 675a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi } else if (STI.isTargetCygMing()) 676a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi StackProbeSymbol = "_alloca"; 677a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi else 678a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi StackProbeSymbol = "_chkstk"; 679a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi 68033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Check whether EAX is livein for this function. 68133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool isEAXAlive = isEAXLiveIn(MF); 68233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 683a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi if (isEAXAlive) { 684a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // Sanity check that EAX is not livein for this function. 685a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // It should not be, so throw an assert. 686a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi assert(!Is64Bit && "EAX is livein in x64 case!"); 687a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi 68833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Save EAX 68933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(X86::PUSH32r)) 690fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .addReg(X86::EAX, RegState::Kill) 691fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .setMIFlag(MachineInstr::FrameSetup); 692a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi } 69333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 694a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi if (Is64Bit) { 695a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // Handle the 64-bit Windows ABI case where we need to call __chkstk. 696a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // Function prologue is responsible for adjusting the stack pointer. 697a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi BuildMI(MBB, MBBI, DL, TII.get(X86::MOV64ri), X86::RAX) 698fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .addImm(NumBytes) 699fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .setMIFlag(MachineInstr::FrameSetup); 700a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi } else { 701a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // Allocate NumBytes-4 bytes on stack in case of isEAXAlive. 702a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // We'll also use 4 already allocated bytes for EAX. 70333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX) 704fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .addImm(isEAXAlive ? NumBytes - 4 : NumBytes) 705fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .setMIFlag(MachineInstr::FrameSetup); 706a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi } 707a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi 708a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi BuildMI(MBB, MBBI, DL, 709a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi TII.get(Is64Bit ? X86::W64ALLOCA : X86::CALLpcrel32)) 710a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi .addExternalSymbol(StackProbeSymbol) 711a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi .addReg(StackPtr, RegState::Define | RegState::Implicit) 712fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .addReg(X86::EFLAGS, RegState::Define | RegState::Implicit) 713fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .setMIFlag(MachineInstr::FrameSetup); 714a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi 71536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Is64Bit) { 71636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // MSVC x64's __chkstk and cygwin/mingw's ___chkstk_ms do not adjust %rsp 71736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // themself. It also does not clobber %rax so we can reuse it when 71836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // adjusting %rsp. 7194010110ccf21be0517034b6ccf9493628afaad77Nico Rieck BuildMI(MBB, MBBI, DL, TII.get(X86::SUB64rr), StackPtr) 7204010110ccf21be0517034b6ccf9493628afaad77Nico Rieck .addReg(StackPtr) 7214010110ccf21be0517034b6ccf9493628afaad77Nico Rieck .addReg(X86::RAX) 7224010110ccf21be0517034b6ccf9493628afaad77Nico Rieck .setMIFlag(MachineInstr::FrameSetup); 7234010110ccf21be0517034b6ccf9493628afaad77Nico Rieck } 724a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi if (isEAXAlive) { 725a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // Restore EAX 726a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi MachineInstr *MI = addRegOffset(BuildMI(MF, DL, TII.get(X86::MOV32rm), 727a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi X86::EAX), 728a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi StackPtr, false, NumBytes - 4); 729fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling MI->setFlag(MachineInstr::FrameSetup); 730a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi MBB.insert(MBBI, MI); 73133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 732cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else if (NumBytes) { 7332a1b60d791522d73be91d4281c90d25bd5e3d117Eli Bendersky emitSPUpdate(MBB, MBBI, StackPtr, -(int64_t)NumBytes, Is64Bit, IsLP64, 73476ad43c6e1619ed4c087b8ccb2cd573eb9d7093eEric Christopher UseLEA, TII, *RegInfo); 735cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 736cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 737cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines int SEHFrameOffset = 0; 738cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (NeedsWinEH) { 739cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (HasFP) { 740cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // We need to set frame base offset low enough such that all saved 741cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // register offsets would be positive relative to it, but we can't 742cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // just use NumBytes, because .seh_setframe offset must be <=240. 743cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // So we pretend to have only allocated enough space to spill the 744cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // non-volatile registers. 745cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // We don't care about the rest of stack allocation, because unwinder 746cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // will restore SP to (BP - SEHFrameOffset) 747cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (const CalleeSavedInfo &Info : MFI->getCalleeSavedInfo()) { 748cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines int offset = MFI->getObjectOffset(Info.getFrameIdx()); 749cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines SEHFrameOffset = std::max(SEHFrameOffset, abs(offset)); 750cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 751cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines SEHFrameOffset += SEHFrameOffset % 16; // ensure alignmant 752cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 753cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // This only needs to account for XMM spill slots, GPR slots 754cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // are covered by the .seh_pushreg's emitted above. 755cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned Size = SEHFrameOffset - X86FI->getCalleeSavedFrameSize(); 756cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Size) { 757cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines BuildMI(MBB, MBBI, DL, TII.get(X86::SEH_StackAlloc)) 758cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .addImm(Size) 759cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .setMIFlag(MachineInstr::FrameSetup); 760cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 761cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 762cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines BuildMI(MBB, MBBI, DL, TII.get(X86::SEH_SetFrame)) 763cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .addImm(FramePtr) 764cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .addImm(SEHFrameOffset) 765cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .setMIFlag(MachineInstr::FrameSetup); 766cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else { 767cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // SP will be the base register for restoring XMMs 768cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (NumBytes) { 769cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines BuildMI(MBB, MBBI, DL, TII.get(X86::SEH_StackAlloc)) 770cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .addImm(NumBytes) 771cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .setMIFlag(MachineInstr::FrameSetup); 772cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 773cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 774cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 775cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 776cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Skip the rest of register spilling code 777cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines while (MBBI != MBB.end() && MBBI->getFlag(MachineInstr::FrameSetup)) 778cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ++MBBI; 779cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 780cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Emit SEH info for non-GPRs 781cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (NeedsWinEH) { 782cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (const CalleeSavedInfo &Info : MFI->getCalleeSavedInfo()) { 783cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned Reg = Info.getReg(); 784cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (X86::GR64RegClass.contains(Reg) || X86::GR32RegClass.contains(Reg)) 785cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines continue; 786cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines assert(X86::FR64RegClass.contains(Reg) && "Unexpected register class"); 787cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 788cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines int Offset = getFrameIndexOffset(MF, Info.getFrameIdx()); 789cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Offset += SEHFrameOffset; 790cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 791cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines BuildMI(MBB, MBBI, DL, TII.get(X86::SEH_SaveXMM)) 792cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .addImm(Reg) 793cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .addImm(Offset) 794cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .setMIFlag(MachineInstr::FrameSetup); 795cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 796cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 797cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines BuildMI(MBB, MBBI, DL, TII.get(X86::SEH_EndPrologue)) 798cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .setMIFlag(MachineInstr::FrameSetup); 799cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 80033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 8013f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier // If we need a base pointer, set it up here. It's whatever the value 8023f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier // of the stack pointer is at this point. Any variable size objects 8033f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier // will be allocated after this, so we can still use the base pointer 8043f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier // to reference locals. 8053f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier if (RegInfo->hasBasePointer(MF)) { 806cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Update the base pointer with the current stack pointer. 8073f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier unsigned Opc = Is64Bit ? X86::MOV64rr : X86::MOV32rr; 8083f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier BuildMI(MBB, MBBI, DL, TII.get(Opc), BasePtr) 8093f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier .addReg(StackPtr) 8103f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier .setMIFlag(MachineInstr::FrameSetup); 8113f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier } 8123f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier 813cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (((!HasFP && NumBytes) || PushedRegs) && NeedsDwarfCFI) { 81433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Mark end of stack pointer adjustment. 81533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!HasFP && NumBytes) { 81633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Define the current CFA rule to use the provided offset. 817377b2270124f6f566c0f291bcb02f7755b642c2cRafael Espindola assert(StackSize); 81836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned CFIIndex = MMI.addFrameInst( 819dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MCCFIInstruction::createDefCfaOffset(nullptr, 820dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines -StackSize + stackGrowth)); 82136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 822dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION)) 82336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .addCFIIndex(CFIIndex); 82433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 82533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 82633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Emit DWARF info specifying the offsets of the callee-saved registers. 82733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (PushedRegs) 828cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines emitCalleeSavedFrameMoves(MBB, MBBI, DL); 82933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 83033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 83133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 83216c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid X86FrameLowering::emitEpilogue(MachineFunction &MF, 8333c2f0a11cce5a1e828e20675fa8467b624795e0aNick Lewycky MachineBasicBlock &MBB) const { 83433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const MachineFrameInfo *MFI = MF.getFrameInfo(); 83533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>(); 836cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const X86RegisterInfo *RegInfo = 837cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines static_cast<const X86RegisterInfo *>(MF.getTarget().getRegisterInfo()); 838cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 8394f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 8404f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen assert(MBBI != MBB.end() && "Returning block has no instructions"); 84133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned RetOpcode = MBBI->getOpcode(); 84233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DebugLoc DL = MBBI->getDebugLoc(); 843cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const X86Subtarget &STI = MF.getTarget().getSubtarget<X86Subtarget>(); 84433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool Is64Bit = STI.is64Bit(); 8452a1b60d791522d73be91d4281c90d25bd5e3d117Eli Bendersky bool IsLP64 = STI.isTarget64BitLP64(); 846de1df103b9c578d0a1609054a5944342c5d0ba23Evan Cheng bool UseLEA = STI.useLeaForSP(); 84733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackAlign = getStackAlignment(); 84833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned SlotSize = RegInfo->getSlotSize(); 84933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned FramePtr = RegInfo->getFrameRegister(MF); 85033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackPtr = RegInfo->getStackRegister(); 85133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 85233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov switch (RetOpcode) { 85333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov default: 85433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov llvm_unreachable("Can only insert epilog into returning blocks"); 85536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case X86::RETQ: 85636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case X86::RETL: 85736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case X86::RETIL: 85836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case X86::RETIQ: 85933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::TCRETURNdi: 86033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::TCRETURNri: 86133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::TCRETURNmi: 86233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::TCRETURNdi64: 86333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::TCRETURNri64: 86433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::TCRETURNmi64: 86533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::EH_RETURN: 86633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::EH_RETURN64: 86733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov break; // These are ok 86833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 86933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 87033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get the number of bytes to allocate from the FrameInfo. 87133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t StackSize = MFI->getStackSize(); 87233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t MaxAlign = MFI->getMaxAlignment(); 87333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned CSSize = X86FI->getCalleeSavedFrameSize(); 87433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t NumBytes = 0; 87533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 87633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If we're forcing a stack realignment we can't rely on just the frame 87733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // info, we need to know the ABI stack alignment as well in case we 87833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // have a call out. Otherwise just make sure we have some alignment - we'll 87933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // go with the minimum. 88033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (ForceStackAlign) { 88133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MFI->hasCalls()) 88233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MaxAlign = (StackAlign > MaxAlign) ? StackAlign : MaxAlign; 88333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov else 88433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MaxAlign = MaxAlign ? MaxAlign : 4; 88533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 88633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 887d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (hasFP(MF)) { 88833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Calculate required stack adjustment. 88933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t FrameSize = StackSize - SlotSize; 89099a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov if (RegInfo->needsStackRealignment(MF)) { 89199a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov // Callee-saved registers were pushed on stack before the stack 89299a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov // was realigned. 89399a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov FrameSize -= CSSize; 89499a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov NumBytes = (FrameSize + MaxAlign - 1) / MaxAlign * MaxAlign; 89599a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov } else { 89699a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov NumBytes = FrameSize - CSSize; 89799a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov } 89833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 89933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Pop EBP. 90033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, 90133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov TII.get(Is64Bit ? X86::POP64r : X86::POP32r), FramePtr); 90233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 90333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov NumBytes = StackSize - CSSize; 90433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 90533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 90633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Skip the callee-saved pop instructions. 90733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov while (MBBI != MBB.begin()) { 90836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachineBasicBlock::iterator PI = std::prev(MBBI); 90933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Opc = PI->getOpcode(); 91033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 9114f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen if (Opc != X86::POP32r && Opc != X86::POP64r && Opc != X86::DBG_VALUE && 9125a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng !PI->isTerminator()) 91333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov break; 91433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 91533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov --MBBI; 91633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 91799a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov MachineBasicBlock::iterator FirstCSPop = MBBI; 91833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 91933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DL = MBBI->getDebugLoc(); 92033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 92133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If there is an ADD32ri or SUB32ri of ESP immediately before this 92233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // instruction, merge the two instructions. 92333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (NumBytes || MFI->hasVarSizedObjects()) 92433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes); 92533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 92633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If dynamic alloca is used, then reset esp to point to the last callee-saved 92733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // slot before popping them off! Same applies for the case, when stack was 92833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // realigned. 92999a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov if (RegInfo->needsStackRealignment(MF) || MFI->hasVarSizedObjects()) { 93099a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov if (RegInfo->needsStackRealignment(MF)) 93199a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov MBBI = FirstCSPop; 93299a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov if (CSSize != 0) { 93316221a60a00e52b078f6164ba4475c6e8e918e4bEli Bendersky unsigned Opc = getLEArOpcode(IsLP64); 93499a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr), 93599a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov FramePtr, false, -CSSize); 93633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 93799a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov unsigned Opc = (Is64Bit ? X86::MOV64rr : X86::MOV32rr); 93899a92f269d4ea6f13a9858bb883e13382d021120Alexey Samsonov BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr) 93933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(FramePtr); 94033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 94133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (NumBytes) { 94233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Adjust stack pointer back: ESP += numbytes. 9432a1b60d791522d73be91d4281c90d25bd5e3d117Eli Bendersky emitSPUpdate(MBB, MBBI, StackPtr, NumBytes, Is64Bit, IsLP64, UseLEA, 9442a1b60d791522d73be91d4281c90d25bd5e3d117Eli Bendersky TII, *RegInfo); 94533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 94633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 94733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // We're returning from function via eh_return. 94833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (RetOpcode == X86::EH_RETURN || RetOpcode == X86::EH_RETURN64) { 9494f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MBBI = MBB.getLastNonDebugInstr(); 95033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineOperand &DestAddr = MBBI->getOperand(0); 95133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(DestAddr.isReg() && "Offset should be in register!"); 95233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, 95333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr), 95433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov StackPtr).addReg(DestAddr.getReg()); 95533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (RetOpcode == X86::TCRETURNri || RetOpcode == X86::TCRETURNdi || 95633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RetOpcode == X86::TCRETURNmi || 95733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RetOpcode == X86::TCRETURNri64 || RetOpcode == X86::TCRETURNdi64 || 95833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RetOpcode == X86::TCRETURNmi64) { 95933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool isMem = RetOpcode == X86::TCRETURNmi || RetOpcode == X86::TCRETURNmi64; 96033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Tail call return: adjust the stack pointer and jump to callee. 961f7ca976e74eafeeab0e9097f0fb07d6bb447415bJakob Stoklund Olesen MBBI = MBB.getLastNonDebugInstr(); 96233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineOperand &JumpTarget = MBBI->getOperand(0); 96333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineOperand &StackAdjust = MBBI->getOperand(isMem ? 5 : 1); 96433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(StackAdjust.isImm() && "Expecting immediate value."); 96533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 96633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Adjust stack pointer. 96733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int StackAdj = StackAdjust.getImm(); 96833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int MaxTCDelta = X86FI->getTCReturnAddrDelta(); 96933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int Offset = 0; 97033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(MaxTCDelta <= 0 && "MaxTCDelta should never be positive"); 97133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 97233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Incoporate the retaddr area. 97333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Offset = StackAdj-MaxTCDelta; 97433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(Offset >= 0 && "Offset should never be negative"); 97533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 97633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (Offset) { 9777a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // Check for possible merge with preceding ADD instruction. 97833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Offset += mergeSPUpdates(MBB, MBBI, StackPtr, true); 9792a1b60d791522d73be91d4281c90d25bd5e3d117Eli Bendersky emitSPUpdate(MBB, MBBI, StackPtr, Offset, Is64Bit, IsLP64, 9802a1b60d791522d73be91d4281c90d25bd5e3d117Eli Bendersky UseLEA, TII, *RegInfo); 98133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 98233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 98333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Jump to label or value in register. 98433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (RetOpcode == X86::TCRETURNdi || RetOpcode == X86::TCRETURNdi64) { 9853d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng MachineInstrBuilder MIB = 9863d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng BuildMI(MBB, MBBI, DL, TII.get((RetOpcode == X86::TCRETURNdi) 9873d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng ? X86::TAILJMPd : X86::TAILJMPd64)); 9883d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng if (JumpTarget.isGlobal()) 9893d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng MIB.addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset(), 9903d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng JumpTarget.getTargetFlags()); 9913d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng else { 9923d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng assert(JumpTarget.isSymbol()); 9933d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng MIB.addExternalSymbol(JumpTarget.getSymbolName(), 9943d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng JumpTarget.getTargetFlags()); 9953d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng } 99633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (RetOpcode == X86::TCRETURNmi || RetOpcode == X86::TCRETURNmi64) { 99733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineInstrBuilder MIB = 99833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get((RetOpcode == X86::TCRETURNmi) 99933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov ? X86::TAILJMPm : X86::TAILJMPm64)); 100033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (unsigned i = 0; i != 5; ++i) 100133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MIB.addOperand(MBBI->getOperand(i)); 100233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (RetOpcode == X86::TCRETURNri64) { 100333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(X86::TAILJMPr64)). 100433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov addReg(JumpTarget.getReg(), RegState::Kill); 100533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 100633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(X86::TAILJMPr)). 100733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov addReg(JumpTarget.getReg(), RegState::Kill); 100833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 100933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 101036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachineInstr *NewMI = std::prev(MBBI); 1011be06aacaa9a270384599bbfa850b967e9996b9fbJakob Stoklund Olesen NewMI->copyImplicitOps(MF, MBBI); 101233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 101333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Delete the pseudo instruction TCRETURN. 101433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBB.erase(MBBI); 101536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if ((RetOpcode == X86::RETQ || RetOpcode == X86::RETL || 101636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RetOpcode == X86::RETIQ || RetOpcode == X86::RETIL) && 101733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov (X86FI->getTCReturnAddrDelta() < 0)) { 101833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Add the return addr area delta back since we are not tail calling. 101933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int delta = -1*X86FI->getTCReturnAddrDelta(); 10204f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MBBI = MBB.getLastNonDebugInstr(); 102133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 10227a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // Check for possible merge with preceding ADD instruction. 102333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov delta += mergeSPUpdates(MBB, MBBI, StackPtr, true); 10242a1b60d791522d73be91d4281c90d25bd5e3d117Eli Bendersky emitSPUpdate(MBB, MBBI, StackPtr, delta, Is64Bit, IsLP64, UseLEA, TII, 10252a1b60d791522d73be91d4281c90d25bd5e3d117Eli Bendersky *RegInfo); 102633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 102733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 1028d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov 1029dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesint X86FrameLowering::getFrameIndexOffset(const MachineFunction &MF, 1030dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines int FI) const { 10313fb6eca0cd4c2b31b06543ca2ac60b9c91c2264dChad Rosier const X86RegisterInfo *RegInfo = 103282f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov static_cast<const X86RegisterInfo*>(MF.getTarget().getRegisterInfo()); 103382f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov const MachineFrameInfo *MFI = MF.getFrameInfo(); 103482f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov int Offset = MFI->getObjectOffset(FI) - getOffsetOfLocalArea(); 103582f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov uint64_t StackSize = MFI->getStackSize(); 103682f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov 10373f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier if (RegInfo->hasBasePointer(MF)) { 10383f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier assert (hasFP(MF) && "VLAs and dynamic stack realign, but no FP?!"); 10393f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier if (FI < 0) { 10403f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier // Skip the saved EBP. 10413f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier return Offset + RegInfo->getSlotSize(); 10423f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier } else { 10433f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier assert((-(Offset + StackSize)) % MFI->getObjectAlignment(FI) == 0); 10443f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier return Offset + StackSize; 10453f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier } 10463f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier } else if (RegInfo->needsStackRealignment(MF)) { 104782f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov if (FI < 0) { 104882f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov // Skip the saved EBP. 10493fb6eca0cd4c2b31b06543ca2ac60b9c91c2264dChad Rosier return Offset + RegInfo->getSlotSize(); 105082f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov } else { 105117001ce25cc205ac1cd2604492c2bce310964220Duncan Sands assert((-(Offset + StackSize)) % MFI->getObjectAlignment(FI) == 0); 105282f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov return Offset + StackSize; 105382f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov } 105482f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov // FIXME: Support tail calls 105582f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov } else { 105682f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov if (!hasFP(MF)) 105782f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov return Offset + StackSize; 105882f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov 105982f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov // Skip the saved EBP. 10603fb6eca0cd4c2b31b06543ca2ac60b9c91c2264dChad Rosier Offset += RegInfo->getSlotSize(); 106182f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov 106282f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov // Skip the RETADDR move area 106382f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov const X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>(); 106482f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov int TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta(); 106582f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov if (TailCallReturnAddrDelta < 0) 106682f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov Offset -= TailCallReturnAddrDelta; 106782f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov } 106882f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov 106982f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov return Offset; 107082f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov} 1071cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 1072d07d06ceef942c478c0f75a4c4d7442e61ddff1dAlexey Samsonovint X86FrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI, 1073d07d06ceef942c478c0f75a4c4d7442e61ddff1dAlexey Samsonov unsigned &FrameReg) const { 10743fb6eca0cd4c2b31b06543ca2ac60b9c91c2264dChad Rosier const X86RegisterInfo *RegInfo = 1075d07d06ceef942c478c0f75a4c4d7442e61ddff1dAlexey Samsonov static_cast<const X86RegisterInfo*>(MF.getTarget().getRegisterInfo()); 1076d07d06ceef942c478c0f75a4c4d7442e61ddff1dAlexey Samsonov // We can't calculate offset from frame pointer if the stack is realigned, 10773f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier // so enforce usage of stack/base pointer. The base pointer is used when we 10783f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier // have dynamic allocas in addition to dynamic realignment. 10793f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier if (RegInfo->hasBasePointer(MF)) 10803f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier FrameReg = RegInfo->getBaseRegister(); 10813f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier else if (RegInfo->needsStackRealignment(MF)) 10823f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier FrameReg = RegInfo->getStackRegister(); 10833f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier else 10843f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier FrameReg = RegInfo->getFrameRegister(MF); 1085d07d06ceef942c478c0f75a4c4d7442e61ddff1dAlexey Samsonov return getFrameIndexOffset(MF, FI); 1086d07d06ceef942c478c0f75a4c4d7442e61ddff1dAlexey Samsonov} 1087d07d06ceef942c478c0f75a4c4d7442e61ddff1dAlexey Samsonov 1088cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool X86FrameLowering::assignCalleeSavedSpillSlots( 1089cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachineFunction &MF, const TargetRegisterInfo *TRI, 1090cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::vector<CalleeSavedInfo> &CSI) const { 1091cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachineFrameInfo *MFI = MF.getFrameInfo(); 1092cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const X86RegisterInfo *RegInfo = 1093cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines static_cast<const X86RegisterInfo *>(MF.getTarget().getRegisterInfo()); 1094cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned SlotSize = RegInfo->getSlotSize(); 1095cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>(); 1096cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 1097cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned CalleeSavedFrameSize = 0; 1098cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines int SpillSlotOffset = getOffsetOfLocalArea() + X86FI->getTCReturnAddrDelta(); 1099cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 1100cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (hasFP(MF)) { 1101cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // emitPrologue always spills frame register the first thing. 1102cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines SpillSlotOffset -= SlotSize; 1103cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MFI->CreateFixedSpillStackObject(SlotSize, SpillSlotOffset); 1104cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1105cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Since emitPrologue and emitEpilogue will handle spilling and restoring of 1106cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // the frame register, we can delete it from CSI list and not have to worry 1107cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // about avoiding it later. 1108cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned FPReg = RegInfo->getFrameRegister(MF); 1109cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (unsigned i = 0; i < CSI.size(); ++i) { 1110cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (CSI[i].getReg() == FPReg) { 1111cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines CSI.erase(CSI.begin() + i); 1112cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines break; 1113cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 1114cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 1115cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 1116cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1117cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Assign slots for GPRs. It increases frame size. 1118cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (unsigned i = CSI.size(); i != 0; --i) { 1119cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned Reg = CSI[i - 1].getReg(); 1120cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1121cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!X86::GR64RegClass.contains(Reg) && !X86::GR32RegClass.contains(Reg)) 1122cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines continue; 1123cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 1124cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines SpillSlotOffset -= SlotSize; 1125cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines CalleeSavedFrameSize += SlotSize; 1126cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1127cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines int SlotIndex = MFI->CreateFixedSpillStackObject(SlotSize, SpillSlotOffset); 1128cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines CSI[i - 1].setFrameIdx(SlotIndex); 1129cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 1130cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1131cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines X86FI->setCalleeSavedFrameSize(CalleeSavedFrameSize); 1132cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1133cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Assign slots for XMMs. 1134cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (unsigned i = CSI.size(); i != 0; --i) { 1135cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned Reg = CSI[i - 1].getReg(); 1136cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (X86::GR64RegClass.contains(Reg) || X86::GR32RegClass.contains(Reg)) 1137cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines continue; 1138cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1139cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const TargetRegisterClass *RC = RegInfo->getMinimalPhysRegClass(Reg); 1140cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // ensure alignment 1141cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines SpillSlotOffset -= abs(SpillSlotOffset) % RC->getAlignment(); 1142cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // spill into slot 1143cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines SpillSlotOffset -= RC->getSize(); 1144cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines int SlotIndex = 1145cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MFI->CreateFixedSpillStackObject(RC->getSize(), SpillSlotOffset); 1146cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines CSI[i - 1].setFrameIdx(SlotIndex); 1147cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MFI->ensureMaxAlignment(RC->getAlignment()); 1148cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 1149cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1150cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return true; 1151cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 1152cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 1153cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool X86FrameLowering::spillCalleeSavedRegisters( 1154cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, 1155cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const std::vector<CalleeSavedInfo> &CSI, 1156cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const TargetRegisterInfo *TRI) const { 1157cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines DebugLoc DL = MBB.findDebugLoc(MI); 1158cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1159cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachineFunction &MF = *MBB.getParent(); 1160cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 1161cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const X86Subtarget &STI = MF.getTarget().getSubtarget<X86Subtarget>(); 1162cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 1163419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi // Push GPRs. It increases frame size. 1164cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov unsigned Opc = STI.is64Bit() ? X86::PUSH64r : X86::PUSH32r; 1165cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov for (unsigned i = CSI.size(); i != 0; --i) { 1166cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned Reg = CSI[i - 1].getReg(); 1167cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1168cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!X86::GR64RegClass.contains(Reg) && !X86::GR32RegClass.contains(Reg)) 1169419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi continue; 1170cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov // Add the callee-saved register as live-in. It's killed at the spill. 1171cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov MBB.addLiveIn(Reg); 1172cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1173aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis BuildMI(MBB, MI, DL, TII.get(Opc)).addReg(Reg, RegState::Kill) 1174aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis .setMIFlag(MachineInstr::FrameSetup); 1175cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov } 1176cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 1177419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi // Make XMM regs spilled. X86 does not have ability of push/pop XMM. 1178419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi // It can be done by spilling XMMs to stack frame. 1179419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi for (unsigned i = CSI.size(); i != 0; --i) { 1180419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi unsigned Reg = CSI[i-1].getReg(); 1181419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi if (X86::GR64RegClass.contains(Reg) || 1182419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi X86::GR32RegClass.contains(Reg)) 1183419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi continue; 1184419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi // Add the callee-saved register as live-in. It's killed at the spill. 1185419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi MBB.addLiveIn(Reg); 1186419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 1187cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1188cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines TII.storeRegToStackSlot(MBB, MI, Reg, true, CSI[i - 1].getFrameIdx(), RC, 1189cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines TRI); 1190cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines --MI; 1191cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MI->setFlag(MachineInstr::FrameSetup); 1192cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ++MI; 1193419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi } 1194419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi 1195cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov return true; 1196cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov} 1197cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 119816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovbool X86FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 1199cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov MachineBasicBlock::iterator MI, 1200cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov const std::vector<CalleeSavedInfo> &CSI, 1201cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov const TargetRegisterInfo *TRI) const { 1202cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov if (CSI.empty()) 1203cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov return false; 1204cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 1205cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov DebugLoc DL = MBB.findDebugLoc(MI); 1206cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 1207cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov MachineFunction &MF = *MBB.getParent(); 1208cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 1209cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const X86Subtarget &STI = MF.getTarget().getSubtarget<X86Subtarget>(); 1210419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi 1211419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi // Reload XMMs from stack frame. 1212419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 1213419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi unsigned Reg = CSI[i].getReg(); 1214419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi if (X86::GR64RegClass.contains(Reg) || 1215419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi X86::GR32RegClass.contains(Reg)) 1216419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi continue; 1217cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1218419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 1219cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines TII.loadRegFromStackSlot(MBB, MI, Reg, CSI[i].getFrameIdx(), RC, TRI); 1220419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi } 1221419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi 1222419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi // POP GPRs. 1223cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov unsigned Opc = STI.is64Bit() ? X86::POP64r : X86::POP32r; 1224cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 1225cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov unsigned Reg = CSI[i].getReg(); 1226419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi if (!X86::GR64RegClass.contains(Reg) && 1227419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi !X86::GR32RegClass.contains(Reg)) 1228419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi continue; 1229cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1230419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi BuildMI(MBB, MI, DL, TII.get(Opc), Reg); 1231cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov } 1232cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov return true; 1233cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov} 123494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 123594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikovvoid 123616c29b5f285f375be53dabaa73e3e91107485fe4Anton KorobeynikovX86FrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, 1237cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RegScavenger *RS) const { 123894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 1239cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const X86RegisterInfo *RegInfo = 1240cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines static_cast<const X86RegisterInfo *>(MF.getTarget().getRegisterInfo()); 124194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned SlotSize = RegInfo->getSlotSize(); 124294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 124394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>(); 1244a54b66277e5d4bdd55825eb9378f07334692020cTim Northover int64_t TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta(); 124594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 124694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (TailCallReturnAddrDelta < 0) { 124794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // create RETURNADDR area 124894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // arg 124994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // arg 125094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // RETADDR 125194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // { ... 125294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // RETADDR area 125394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // ... 125494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // } 125594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // [EBP] 125694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MFI->CreateFixedObject(-TailCallReturnAddrDelta, 1257a54b66277e5d4bdd55825eb9378f07334692020cTim Northover TailCallReturnAddrDelta - SlotSize, true); 125894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 125994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 12603f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier // Spill the BasePtr if it's used. 12613f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier if (RegInfo->hasBasePointer(MF)) 12623f0dbab963197cadb32f70e1ee1a106fe35f5c8eChad Rosier MF.getRegInfo().setPhysRegUsed(RegInfo->getBaseRegister()); 126394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov} 126476927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 126576927d758657b3a511c73467ec5a7288795c1513Rafael Espindolastatic bool 126676927d758657b3a511c73467ec5a7288795c1513Rafael EspindolaHasNestArgument(const MachineFunction *MF) { 126776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola const Function *F = MF->getFunction(); 126876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end(); 126976927d758657b3a511c73467ec5a7288795c1513Rafael Espindola I != E; I++) { 127076927d758657b3a511c73467ec5a7288795c1513Rafael Espindola if (I->hasNestAttr()) 127176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola return true; 127276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola } 127376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola return false; 127476927d758657b3a511c73467ec5a7288795c1513Rafael Espindola} 127576927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 127698fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer/// GetScratchRegister - Get a temp register for performing work in the 127798fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer/// segmented stack and the Erlang/HiPE stack prologue. Depending on platform 127898fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer/// and the properties of the function either one or two registers will be 127998fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer/// needed. Set primary to true for the first register, false for the second. 128076927d758657b3a511c73467ec5a7288795c1513Rafael Espindolastatic unsigned 12812028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael EspindolaGetScratchRegister(bool Is64Bit, const MachineFunction &MF, bool Primary) { 128298fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer CallingConv::ID CallingConvention = MF.getFunction()->getCallingConv(); 128398fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer 128498fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // Erlang stuff. 128598fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer if (CallingConvention == CallingConv::HiPE) { 128698fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer if (Is64Bit) 128798fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer return Primary ? X86::R14 : X86::R13; 128898fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer else 128998fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer return Primary ? X86::EBX : X86::EDI; 129098fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer } 129198fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer 12924d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie if (Is64Bit) 12932028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola return Primary ? X86::R11 : X86::R12; 12944d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie 12954d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie bool IsNested = HasNestArgument(&MF); 12964d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie 12974d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie if (CallingConvention == CallingConv::X86_FastCall || 12984d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie CallingConvention == CallingConv::Fast) { 12994d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie if (IsNested) 13004d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie report_fatal_error("Segmented stacks does not support fastcall with " 13014d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie "nested function."); 13024d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie return Primary ? X86::EAX : X86::ECX; 130376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola } 13044d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie if (IsNested) 13054d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie return Primary ? X86::EDX : X86::EAX; 13064d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie return Primary ? X86::ECX : X86::EAX; 130776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola} 130876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 1309199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das// The stack limit in the TCB is set to this many bytes above the actual stack 1310199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das// limit. 1311199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Dasstatic const uint64_t kSplitStackAvailable = 256; 1312199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das 131376927d758657b3a511c73467ec5a7288795c1513Rafael Espindolavoid 131476927d758657b3a511c73467ec5a7288795c1513Rafael EspindolaX86FrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const { 131576927d758657b3a511c73467ec5a7288795c1513Rafael Espindola MachineBasicBlock &prologueMBB = MF.front(); 131676927d758657b3a511c73467ec5a7288795c1513Rafael Espindola MachineFrameInfo *MFI = MF.getFrameInfo(); 1317cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 131876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola uint64_t StackSize; 1319cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const X86Subtarget &STI = MF.getTarget().getSubtarget<X86Subtarget>(); 132076927d758657b3a511c73467ec5a7288795c1513Rafael Espindola bool Is64Bit = STI.is64Bit(); 132176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola unsigned TlsReg, TlsOffset; 132276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola DebugLoc DL; 132376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 13242028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola unsigned ScratchReg = GetScratchRegister(Is64Bit, MF, true); 132576927d758657b3a511c73467ec5a7288795c1513Rafael Espindola assert(!MF.getRegInfo().isLiveIn(ScratchReg) && 132676927d758657b3a511c73467ec5a7288795c1513Rafael Espindola "Scratch register is live-in"); 132776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 132876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola if (MF.getFunction()->isVarArg()) 132976927d758657b3a511c73467ec5a7288795c1513Rafael Espindola report_fatal_error("Segmented stacks do not support vararg functions."); 1330b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer if (!STI.isTargetLinux() && !STI.isTargetDarwin() && 133136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines !STI.isTargetWin32() && !STI.isTargetWin64() && !STI.isTargetFreeBSD()) 133285b9d43d4c7a4a5e6e7da651a159353a9a00e227Rafael Espindola report_fatal_error("Segmented stacks not supported on this platform."); 133376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 1334dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Eventually StackSize will be calculated by a link-time pass; which will 1335dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // also decide whether checking code needs to be injected into this particular 1336dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // prologue. 1337dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines StackSize = MFI->getStackSize(); 1338dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 1339dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Do not generate a prologue for functions with a stack of size zero 1340dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (StackSize == 0) 1341dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return; 1342dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 134376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola MachineBasicBlock *allocMBB = MF.CreateMachineBasicBlock(); 134476927d758657b3a511c73467ec5a7288795c1513Rafael Espindola MachineBasicBlock *checkMBB = MF.CreateMachineBasicBlock(); 134576927d758657b3a511c73467ec5a7288795c1513Rafael Espindola X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>(); 134676927d758657b3a511c73467ec5a7288795c1513Rafael Espindola bool IsNested = false; 134776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 134876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // We need to know if the function has a nest argument only in 64 bit mode. 134976927d758657b3a511c73467ec5a7288795c1513Rafael Espindola if (Is64Bit) 135076927d758657b3a511c73467ec5a7288795c1513Rafael Espindola IsNested = HasNestArgument(&MF); 135176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 13524e68054b20725f6ec1cac33630258f749fe5debeBill Wendling // The MOV R10, RAX needs to be in a different block, since the RET we emit in 13534e68054b20725f6ec1cac33630258f749fe5debeBill Wendling // allocMBB needs to be last (terminating) instruction. 13544e68054b20725f6ec1cac33630258f749fe5debeBill Wendling 135576927d758657b3a511c73467ec5a7288795c1513Rafael Espindola for (MachineBasicBlock::livein_iterator i = prologueMBB.livein_begin(), 135676927d758657b3a511c73467ec5a7288795c1513Rafael Espindola e = prologueMBB.livein_end(); i != e; i++) { 135776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola allocMBB->addLiveIn(*i); 135876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola checkMBB->addLiveIn(*i); 135976927d758657b3a511c73467ec5a7288795c1513Rafael Espindola } 136076927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 1361e840e88239cf92a065cbf5f5b9c7d18bc139c0e1Rafael Espindola if (IsNested) 136276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola allocMBB->addLiveIn(X86::R10); 136376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 136476927d758657b3a511c73467ec5a7288795c1513Rafael Espindola MF.push_front(allocMBB); 136576927d758657b3a511c73467ec5a7288795c1513Rafael Espindola MF.push_front(checkMBB); 136676927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 13672028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola // When the frame size is less than 256 we just compare the stack 13682028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola // boundary directly to the value of the stack pointer, per gcc. 13692028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola bool CompareStackPointer = StackSize < kSplitStackAvailable; 13702028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola 137176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // Read the limit off the current stacklet off the stack_guard location. 137276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola if (Is64Bit) { 1373b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer if (STI.isTargetLinux()) { 13742028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola TlsReg = X86::FS; 13752028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola TlsOffset = 0x70; 1376b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer } else if (STI.isTargetDarwin()) { 13772028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola TlsReg = X86::GS; 13782028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola TlsOffset = 0x60 + 90*8; // See pthread_machdep.h. Steal TLS slot 90. 137936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (STI.isTargetWin64()) { 138036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TlsReg = X86::GS; 138136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TlsOffset = 0x28; // pvArbitrary, reserved for application use 1382b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer } else if (STI.isTargetFreeBSD()) { 138385b9d43d4c7a4a5e6e7da651a159353a9a00e227Rafael Espindola TlsReg = X86::FS; 138485b9d43d4c7a4a5e6e7da651a159353a9a00e227Rafael Espindola TlsOffset = 0x18; 1385e4d18de5d15c6c1d4d279788b35d0cd1ab237e82Rafael Espindola } else { 1386e4d18de5d15c6c1d4d279788b35d0cd1ab237e82Rafael Espindola report_fatal_error("Segmented stacks not supported on this platform."); 13872028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola } 138876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 13892028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola if (CompareStackPointer) 1390199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das ScratchReg = X86::RSP; 1391199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das else 1392199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das BuildMI(checkMBB, DL, TII.get(X86::LEA64r), ScratchReg).addReg(X86::RSP) 1393014f7a3b3798580d5aac80b83bcb67e03d302fa4Rafael Espindola .addImm(1).addReg(0).addImm(-StackSize).addReg(0); 1394199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das 139576927d758657b3a511c73467ec5a7288795c1513Rafael Espindola BuildMI(checkMBB, DL, TII.get(X86::CMP64rm)).addReg(ScratchReg) 1396014f7a3b3798580d5aac80b83bcb67e03d302fa4Rafael Espindola .addReg(0).addImm(1).addReg(0).addImm(TlsOffset).addReg(TlsReg); 139776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola } else { 1398b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer if (STI.isTargetLinux()) { 1399e4d18de5d15c6c1d4d279788b35d0cd1ab237e82Rafael Espindola TlsReg = X86::GS; 1400e4d18de5d15c6c1d4d279788b35d0cd1ab237e82Rafael Espindola TlsOffset = 0x30; 1401b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer } else if (STI.isTargetDarwin()) { 1402e4d18de5d15c6c1d4d279788b35d0cd1ab237e82Rafael Espindola TlsReg = X86::GS; 1403e4d18de5d15c6c1d4d279788b35d0cd1ab237e82Rafael Espindola TlsOffset = 0x48 + 90*4; 1404b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer } else if (STI.isTargetWin32()) { 1405e4d18de5d15c6c1d4d279788b35d0cd1ab237e82Rafael Espindola TlsReg = X86::FS; 1406e4d18de5d15c6c1d4d279788b35d0cd1ab237e82Rafael Espindola TlsOffset = 0x14; // pvArbitrary, reserved for application use 1407b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer } else if (STI.isTargetFreeBSD()) { 140885b9d43d4c7a4a5e6e7da651a159353a9a00e227Rafael Espindola report_fatal_error("Segmented stacks not supported on FreeBSD i386."); 1409e4d18de5d15c6c1d4d279788b35d0cd1ab237e82Rafael Espindola } else { 1410e4d18de5d15c6c1d4d279788b35d0cd1ab237e82Rafael Espindola report_fatal_error("Segmented stacks not supported on this platform."); 1411e4d18de5d15c6c1d4d279788b35d0cd1ab237e82Rafael Espindola } 141276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 14132028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola if (CompareStackPointer) 1414199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das ScratchReg = X86::ESP; 1415199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das else 1416199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das BuildMI(checkMBB, DL, TII.get(X86::LEA32r), ScratchReg).addReg(X86::ESP) 1417014f7a3b3798580d5aac80b83bcb67e03d302fa4Rafael Espindola .addImm(1).addReg(0).addImm(-StackSize).addReg(0); 1418199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das 141936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (STI.isTargetLinux() || STI.isTargetWin32() || STI.isTargetWin64()) { 14202028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola BuildMI(checkMBB, DL, TII.get(X86::CMP32rm)).addReg(ScratchReg) 14212028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola .addReg(0).addImm(0).addReg(0).addImm(TlsOffset).addReg(TlsReg); 1422b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer } else if (STI.isTargetDarwin()) { 14232028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola 1424dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // TlsOffset doesn't fit into a mod r/m byte so we need an extra register. 14252028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola unsigned ScratchReg2; 14262028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola bool SaveScratch2; 14272028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola if (CompareStackPointer) { 1428dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // The primary scratch register is available for holding the TLS offset. 14292028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola ScratchReg2 = GetScratchRegister(Is64Bit, MF, true); 14302028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola SaveScratch2 = false; 14312028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola } else { 14322028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola // Need to use a second register to hold the TLS offset 14332028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola ScratchReg2 = GetScratchRegister(Is64Bit, MF, false); 14342028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola 1435dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Unfortunately, with fastcc the second scratch register may hold an 1436dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // argument. 14372028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola SaveScratch2 = MF.getRegInfo().isLiveIn(ScratchReg2); 14382028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola } 14392028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola 1440dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // If Scratch2 is live-in then it needs to be saved. 14412028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola assert((!MF.getRegInfo().isLiveIn(ScratchReg2) || SaveScratch2) && 14422028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola "Scratch register is live-in and not saved"); 14432028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola 14442028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola if (SaveScratch2) 14452028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola BuildMI(checkMBB, DL, TII.get(X86::PUSH32r)) 14462028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola .addReg(ScratchReg2, RegState::Kill); 14472028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola 14482028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola BuildMI(checkMBB, DL, TII.get(X86::MOV32ri), ScratchReg2) 14492028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola .addImm(TlsOffset); 14502028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola BuildMI(checkMBB, DL, TII.get(X86::CMP32rm)) 14512028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola .addReg(ScratchReg) 14522028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola .addReg(ScratchReg2).addImm(1).addReg(0) 14532028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola .addImm(0) 14542028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola .addReg(TlsReg); 14552028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola 14562028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola if (SaveScratch2) 14572028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola BuildMI(checkMBB, DL, TII.get(X86::POP32r), ScratchReg2); 14582028b793e1fd1a8dd4d99b0b7c9972865d5e806aRafael Espindola } 145976927d758657b3a511c73467ec5a7288795c1513Rafael Espindola } 146076927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 146176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // This jump is taken if SP >= (Stacklet Limit + Stack Space required). 146276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // It jumps to normal execution of the function body. 1463313c7038319422cff0b2ea1015e180575cab4b7aRafael Espindola BuildMI(checkMBB, DL, TII.get(X86::JA_4)).addMBB(&prologueMBB); 146476927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 146576927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // On 32 bit we first push the arguments size and then the frame size. On 64 146676927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // bit, we pass the stack frame size in r10 and the argument size in r11. 146776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola if (Is64Bit) { 146876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // Functions with nested arguments use R10, so it needs to be saved across 146976927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // the call to _morestack 147076927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 147176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola if (IsNested) 147276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola BuildMI(allocMBB, DL, TII.get(X86::MOV64rr), X86::RAX).addReg(X86::R10); 147376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 147476927d758657b3a511c73467ec5a7288795c1513Rafael Espindola BuildMI(allocMBB, DL, TII.get(X86::MOV64ri), X86::R10) 147576927d758657b3a511c73467ec5a7288795c1513Rafael Espindola .addImm(StackSize); 147676927d758657b3a511c73467ec5a7288795c1513Rafael Espindola BuildMI(allocMBB, DL, TII.get(X86::MOV64ri), X86::R11) 147776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola .addImm(X86FI->getArgumentStackSize()); 147876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola MF.getRegInfo().setPhysRegUsed(X86::R10); 147976927d758657b3a511c73467ec5a7288795c1513Rafael Espindola MF.getRegInfo().setPhysRegUsed(X86::R11); 148076927d758657b3a511c73467ec5a7288795c1513Rafael Espindola } else { 148176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola BuildMI(allocMBB, DL, TII.get(X86::PUSHi32)) 148276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola .addImm(X86FI->getArgumentStackSize()); 148376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola BuildMI(allocMBB, DL, TII.get(X86::PUSHi32)) 148476927d758657b3a511c73467ec5a7288795c1513Rafael Espindola .addImm(StackSize); 148576927d758657b3a511c73467ec5a7288795c1513Rafael Espindola } 148676927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 148776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // __morestack is in libgcc 148876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola if (Is64Bit) 148976927d758657b3a511c73467ec5a7288795c1513Rafael Espindola BuildMI(allocMBB, DL, TII.get(X86::CALL64pcrel32)) 149076927d758657b3a511c73467ec5a7288795c1513Rafael Espindola .addExternalSymbol("__morestack"); 149176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola else 149276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola BuildMI(allocMBB, DL, TII.get(X86::CALLpcrel32)) 149376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola .addExternalSymbol("__morestack"); 149476927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 14954e68054b20725f6ec1cac33630258f749fe5debeBill Wendling if (IsNested) 1496e840e88239cf92a065cbf5f5b9c7d18bc139c0e1Rafael Espindola BuildMI(allocMBB, DL, TII.get(X86::MORESTACK_RET_RESTORE_R10)); 1497e840e88239cf92a065cbf5f5b9c7d18bc139c0e1Rafael Espindola else 1498e840e88239cf92a065cbf5f5b9c7d18bc139c0e1Rafael Espindola BuildMI(allocMBB, DL, TII.get(X86::MORESTACK_RET)); 149976927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 1500e840e88239cf92a065cbf5f5b9c7d18bc139c0e1Rafael Espindola allocMBB->addSuccessor(&prologueMBB); 150182222c20be24adda7c218f3fdaf2e0ae049c955bBill Wendling 150276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola checkMBB->addSuccessor(allocMBB); 150376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola checkMBB->addSuccessor(&prologueMBB); 150476927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 150551f0c7641983469cbd29f8862a121645471a885aJakob Stoklund Olesen#ifdef XDEBUG 150676927d758657b3a511c73467ec5a7288795c1513Rafael Espindola MF.verify(); 150776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola#endif 150876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola} 150998fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer 15102d1035def15030ae404b227747d0a28454ea32a9Yiannis Tsiouris/// Erlang programs may need a special prologue to handle the stack size they 15112d1035def15030ae404b227747d0a28454ea32a9Yiannis Tsiouris/// might need at runtime. That is because Erlang/OTP does not implement a C 15122d1035def15030ae404b227747d0a28454ea32a9Yiannis Tsiouris/// stack but uses a custom implementation of hybrid stack/heap architecture. 15132d1035def15030ae404b227747d0a28454ea32a9Yiannis Tsiouris/// (for more information see Eric Stenman's Ph.D. thesis: 15142d1035def15030ae404b227747d0a28454ea32a9Yiannis Tsiouris/// http://publications.uu.se/uu/fulltext/nbn_se_uu_diva-2688.pdf) 15152d1035def15030ae404b227747d0a28454ea32a9Yiannis Tsiouris/// 15162d1035def15030ae404b227747d0a28454ea32a9Yiannis Tsiouris/// CheckStack: 1517dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// temp0 = sp - MaxStack 1518dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// if( temp0 < SP_LIMIT(P) ) goto IncStack else goto OldStart 15192d1035def15030ae404b227747d0a28454ea32a9Yiannis Tsiouris/// OldStart: 1520dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// ... 15212d1035def15030ae404b227747d0a28454ea32a9Yiannis Tsiouris/// IncStack: 1522dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// call inc_stack # doubles the stack space 1523dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// temp0 = sp - MaxStack 1524dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// if( temp0 < SP_LIMIT(P) ) goto IncStack else goto OldStart 152598fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramervoid X86FrameLowering::adjustForHiPEPrologue(MachineFunction &MF) const { 1526cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 152798fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer MachineFrameInfo *MFI = MF.getFrameInfo(); 1528cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const unsigned SlotSize = 1529cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines static_cast<const X86RegisterInfo *>(MF.getTarget().getRegisterInfo()) 1530cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ->getSlotSize(); 1531cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const X86Subtarget &STI = MF.getTarget().getSubtarget<X86Subtarget>(); 153298fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer const bool Is64Bit = STI.is64Bit(); 153398fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer DebugLoc DL; 153498fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // HiPE-specific values 153598fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer const unsigned HipeLeafWords = 24; 153698fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer const unsigned CCRegisteredArgs = Is64Bit ? 6 : 5; 153798fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer const unsigned Guaranteed = HipeLeafWords * SlotSize; 1538b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer unsigned CallerStkArity = MF.getFunction()->arg_size() > CCRegisteredArgs ? 1539b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer MF.getFunction()->arg_size() - CCRegisteredArgs : 0; 1540b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer unsigned MaxStack = MFI->getStackSize() + CallerStkArity*SlotSize + SlotSize; 154198fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer 1542b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer assert(STI.isTargetLinux() && 154398fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer "HiPE prologue is only supported on Linux operating systems."); 154498fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer 154598fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // Compute the largest caller's frame that is needed to fit the callees' 154698fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // frames. This 'MaxStack' is computed from: 154798fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // 154898fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // a) the fixed frame size, which is the space needed for all spilled temps, 154998fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // b) outgoing on-stack parameter areas, and 155098fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // c) the minimum stack space this function needs to make available for the 155198fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // functions it calls (a tunable ABI property). 155298fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer if (MFI->hasCalls()) { 155398fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer unsigned MoreStackForCalls = 0; 155498fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer 155598fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer for (MachineFunction::iterator MBBI = MF.begin(), MBBE = MF.end(); 155698fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer MBBI != MBBE; ++MBBI) 155798fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer for (MachineBasicBlock::iterator MI = MBBI->begin(), ME = MBBI->end(); 1558b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer MI != ME; ++MI) { 1559b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer if (!MI->isCall()) 1560b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer continue; 1561b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer 1562b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer // Get callee operand. 1563b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer const MachineOperand &MO = MI->getOperand(0); 1564b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer 1565b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer // Only take account of global function calls (no closures etc.). 1566b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer if (!MO.isGlobal()) 1567b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer continue; 1568b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer 1569b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer const Function *F = dyn_cast<Function>(MO.getGlobal()); 1570b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer if (!F) 1571b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer continue; 1572b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer 1573b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer // Do not update 'MaxStack' for primitive and built-in functions 1574b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer // (encoded with names either starting with "erlang."/"bif_" or not 1575b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer // having a ".", such as a simple <Module>.<Function>.<Arity>, or an 1576b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer // "_", such as the BIF "suspend_0") as they are executed on another 1577b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer // stack. 1578b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer if (F->getName().find("erlang.") != StringRef::npos || 1579b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer F->getName().find("bif_") != StringRef::npos || 1580b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer F->getName().find_first_of("._") == StringRef::npos) 1581b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer continue; 1582b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer 1583b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer unsigned CalleeStkArity = 1584b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer F->arg_size() > CCRegisteredArgs ? F->arg_size()-CCRegisteredArgs : 0; 1585b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer if (HipeLeafWords - 1 > CalleeStkArity) 1586b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer MoreStackForCalls = std::max(MoreStackForCalls, 1587b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer (HipeLeafWords - 1 - CalleeStkArity) * SlotSize); 1588b1e1d5d4a575f5e5b4ceb7af68f33e75695ee959Benjamin Kramer } 158998fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer MaxStack += MoreStackForCalls; 159098fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer } 159198fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer 159298fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // If the stack frame needed is larger than the guaranteed then runtime checks 159398fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // and calls to "inc_stack_0" BIF should be inserted in the assembly prologue. 159498fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer if (MaxStack > Guaranteed) { 159598fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer MachineBasicBlock &prologueMBB = MF.front(); 159698fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer MachineBasicBlock *stackCheckMBB = MF.CreateMachineBasicBlock(); 159798fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer MachineBasicBlock *incStackMBB = MF.CreateMachineBasicBlock(); 159898fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer 159998fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer for (MachineBasicBlock::livein_iterator I = prologueMBB.livein_begin(), 160098fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer E = prologueMBB.livein_end(); I != E; I++) { 160198fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer stackCheckMBB->addLiveIn(*I); 160298fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer incStackMBB->addLiveIn(*I); 160398fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer } 160498fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer 160598fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer MF.push_front(incStackMBB); 160698fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer MF.push_front(stackCheckMBB); 160798fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer 160898fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer unsigned ScratchReg, SPReg, PReg, SPLimitOffset; 160998fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer unsigned LEAop, CMPop, CALLop; 161098fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer if (Is64Bit) { 161198fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer SPReg = X86::RSP; 161298fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer PReg = X86::RBP; 161398fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer LEAop = X86::LEA64r; 161498fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer CMPop = X86::CMP64rm; 161598fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer CALLop = X86::CALL64pcrel32; 161698fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer SPLimitOffset = 0x90; 161798fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer } else { 161898fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer SPReg = X86::ESP; 161998fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer PReg = X86::EBP; 162098fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer LEAop = X86::LEA32r; 162198fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer CMPop = X86::CMP32rm; 162298fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer CALLop = X86::CALLpcrel32; 162398fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer SPLimitOffset = 0x4c; 162498fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer } 162598fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer 162698fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer ScratchReg = GetScratchRegister(Is64Bit, MF, true); 162798fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer assert(!MF.getRegInfo().isLiveIn(ScratchReg) && 162898fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer "HiPE prologue scratch register is live-in"); 162998fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer 163098fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // Create new MBB for StackCheck: 163198fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer addRegOffset(BuildMI(stackCheckMBB, DL, TII.get(LEAop), ScratchReg), 163298fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer SPReg, false, -MaxStack); 163398fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // SPLimitOffset is in a fixed heap location (pointed by BP). 163498fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer addRegOffset(BuildMI(stackCheckMBB, DL, TII.get(CMPop)) 163598fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer .addReg(ScratchReg), PReg, false, SPLimitOffset); 163698fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer BuildMI(stackCheckMBB, DL, TII.get(X86::JAE_4)).addMBB(&prologueMBB); 163798fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer 163898fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // Create new MBB for IncStack: 163998fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer BuildMI(incStackMBB, DL, TII.get(CALLop)). 164098fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer addExternalSymbol("inc_stack_0"); 164198fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer addRegOffset(BuildMI(incStackMBB, DL, TII.get(LEAop), ScratchReg), 164298fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer SPReg, false, -MaxStack); 164398fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer addRegOffset(BuildMI(incStackMBB, DL, TII.get(CMPop)) 164498fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer .addReg(ScratchReg), PReg, false, SPLimitOffset); 164598fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer BuildMI(incStackMBB, DL, TII.get(X86::JLE_4)).addMBB(incStackMBB); 164698fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer 164798fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer stackCheckMBB->addSuccessor(&prologueMBB, 99); 164898fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer stackCheckMBB->addSuccessor(incStackMBB, 1); 164998fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer incStackMBB->addSuccessor(&prologueMBB, 99); 165098fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer incStackMBB->addSuccessor(incStackMBB, 1); 165198fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer } 165298fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer#ifdef XDEBUG 165398fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer MF.verify(); 165498fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer#endif 165598fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer} 1656700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 1657700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Benderskyvoid X86FrameLowering:: 1658700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli BenderskyeliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 1659700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MachineBasicBlock::iterator I) const { 1660cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 1661cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const X86RegisterInfo &RegInfo = 1662cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines *static_cast<const X86RegisterInfo *>(MF.getTarget().getRegisterInfo()); 1663700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky unsigned StackPtr = RegInfo.getStackRegister(); 1664700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky bool reseveCallFrame = hasReservedCallFrame(MF); 1665700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky int Opcode = I->getOpcode(); 1666700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky bool isDestroy = Opcode == TII.getCallFrameDestroyOpcode(); 1667cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const X86Subtarget &STI = MF.getTarget().getSubtarget<X86Subtarget>(); 1668700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky bool IsLP64 = STI.isTarget64BitLP64(); 1669700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky DebugLoc DL = I->getDebugLoc(); 1670700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky uint64_t Amount = !reseveCallFrame ? I->getOperand(0).getImm() : 0; 1671700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky uint64_t CalleeAmt = isDestroy ? I->getOperand(1).getImm() : 0; 1672700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky I = MBB.erase(I); 1673700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 1674700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (!reseveCallFrame) { 1675700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // If the stack pointer can be changed after prologue, turn the 1676700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // adjcallstackup instruction into a 'sub ESP, <amt>' and the 1677700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // adjcallstackdown instruction into 'add ESP, <amt>' 1678700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // TODO: consider using push / pop instead of sub + store / add 1679700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (Amount == 0) 1680700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky return; 1681700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 1682700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // We need to keep the stack aligned properly. To do this, we round the 1683700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // amount of space needed for the outgoing arguments up to the next 1684700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // alignment boundary. 1685cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned StackAlign = 1686cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MF.getTarget().getFrameLowering()->getStackAlignment(); 1687700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky Amount = (Amount + StackAlign - 1) / StackAlign * StackAlign; 1688700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 1689dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachineInstr *New = nullptr; 1690700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (Opcode == TII.getCallFrameSetupOpcode()) { 1691700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky New = BuildMI(MF, DL, TII.get(getSUBriOpcode(IsLP64, Amount)), 1692700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky StackPtr) 1693700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky .addReg(StackPtr) 1694700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky .addImm(Amount); 1695700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } else { 1696700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky assert(Opcode == TII.getCallFrameDestroyOpcode()); 1697700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 1698700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // Factor out the amount the callee already popped. 1699700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky Amount -= CalleeAmt; 1700700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 1701700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (Amount) { 1702700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky unsigned Opc = getADDriOpcode(IsLP64, Amount); 1703700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky New = BuildMI(MF, DL, TII.get(Opc), StackPtr) 1704700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky .addReg(StackPtr).addImm(Amount); 1705700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } 1706700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } 1707700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 1708700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (New) { 1709700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // The EFLAGS implicit def is dead. 1710700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky New->getOperand(3).setIsDead(); 1711700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 1712700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // Replace the pseudo instruction with a new instruction. 1713700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MBB.insert(I, New); 1714700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } 1715700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 1716700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky return; 1717700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } 1718700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 1719700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (Opcode == TII.getCallFrameDestroyOpcode() && CalleeAmt) { 1720700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // If we are performing frame pointer elimination and if the callee pops 1721700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // something off the stack pointer, add it back. We do this until we have 1722700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // more advanced stack pointer tracking ability. 1723700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky unsigned Opc = getSUBriOpcode(IsLP64, CalleeAmt); 1724700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MachineInstr *New = BuildMI(MF, DL, TII.get(Opc), StackPtr) 1725700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky .addReg(StackPtr).addImm(CalleeAmt); 1726700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 1727700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // The EFLAGS implicit def is dead. 1728700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky New->getOperand(3).setIsDead(); 1729700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 1730700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // We are not tracking the stack pointer adjustment by the callee, so make 1731700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // sure we restore the stack pointer immediately after the call, there may 1732700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // be spill code inserted between the CALL and ADJCALLSTACKUP instructions. 1733700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MachineBasicBlock::iterator B = MBB.begin(); 173436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines while (I != B && !std::prev(I)->isCall()) 1735700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky --I; 1736700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MBB.insert(I, New); 1737700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } 1738700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky} 1739700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 1740