X86FrameLowering.cpp revision 5b2c4978ce56455689c515c9d74cc1d92871f3bb
13c2f0a11cce5a1e828e20675fa8467b624795e0aNick Lewycky//=======- X86FrameLowering.cpp - X86 Frame Information --------*- C++ -*-====// 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" 2033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/Function.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" 26f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola#include "llvm/MC/MCAsmInfo.h" 276a6b8c3e96b9e1ca7092eafd0cfb219cbbfbdfc4Bill Wendling#include "llvm/MC/MCSymbol.h" 2833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/Target/TargetData.h" 2933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/Target/TargetOptions.h" 3033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/Support/CommandLine.h" 317158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng#include "llvm/ADT/SmallSet.h" 3233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 3333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovusing namespace llvm; 3433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 3533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// FIXME: completely move here. 3633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovextern cl::opt<bool> ForceStackAlign; 3733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 3816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovbool X86FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 39d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov return !MF.getFrameInfo()->hasVarSizedObjects(); 40d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov} 41d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 42d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov/// hasFP - Return true if the specified function should have a dedicated frame 43d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov/// pointer register. This is true if the function has variable sized allocas 44d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov/// or if frame pointer elimination is disabled. 4516c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovbool X86FrameLowering::hasFP(const MachineFunction &MF) const { 46d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov const MachineFrameInfo *MFI = MF.getFrameInfo(); 47d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov const MachineModuleInfo &MMI = MF.getMMI(); 48d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov const TargetRegisterInfo *RI = TM.getRegisterInfo(); 49d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 508a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky return (MF.getTarget().Options.DisableFramePointerElim(MF) || 51d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov RI->needsStackRealignment(MF) || 52d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov MFI->hasVarSizedObjects() || 53d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov MFI->isFrameAddressTaken() || 54d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov MF.getInfo<X86MachineFunctionInfo>()->getForceFramePointer() || 55d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov MMI.callsUnwindInit()); 56d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov} 57d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 5833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovstatic unsigned getSUBriOpcode(unsigned is64Bit, int64_t Imm) { 5933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (is64Bit) { 6033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (isInt<8>(Imm)) 6133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::SUB64ri8; 6233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::SUB64ri32; 6333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 6433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (isInt<8>(Imm)) 6533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::SUB32ri8; 6633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::SUB32ri; 6733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 6833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 6933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 7033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovstatic unsigned getADDriOpcode(unsigned is64Bit, int64_t Imm) { 7133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (is64Bit) { 7233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (isInt<8>(Imm)) 7333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::ADD64ri8; 7433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::ADD64ri32; 7533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 7633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (isInt<8>(Imm)) 7733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::ADD32ri8; 7833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::ADD32ri; 7933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 8033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 8133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 827158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng/// findDeadCallerSavedReg - Return a caller-saved register that isn't live 837158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng/// when it reaches the "return" instruction. We can then pop a stack object 847158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng/// to this register without worry about clobbering it. 857158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Chengstatic unsigned findDeadCallerSavedReg(MachineBasicBlock &MBB, 867158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng MachineBasicBlock::iterator &MBBI, 877158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng const TargetRegisterInfo &TRI, 887158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng bool Is64Bit) { 897158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng const MachineFunction *MF = MBB.getParent(); 907158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng const Function *F = MF->getFunction(); 917158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng if (!F || MF->getMMI().callsEHReturn()) 927158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng return 0; 937158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 947158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng static const unsigned CallerSavedRegs32Bit[] = { 9532a183c84ad0cbe492119c37f1a7941ace61dd79Andrew Trick X86::EAX, X86::EDX, X86::ECX, 0 967158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng }; 977158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 987158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng static const unsigned CallerSavedRegs64Bit[] = { 997158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng X86::RAX, X86::RDX, X86::RCX, X86::RSI, X86::RDI, 10032a183c84ad0cbe492119c37f1a7941ace61dd79Andrew Trick X86::R8, X86::R9, X86::R10, X86::R11, 0 1017158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng }; 1027158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 1037158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng unsigned Opc = MBBI->getOpcode(); 1047158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng switch (Opc) { 1057158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng default: return 0; 1067158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::RET: 1077158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::RETI: 1087158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::TCRETURNdi: 1097158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::TCRETURNri: 1107158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::TCRETURNmi: 1117158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::TCRETURNdi64: 1127158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::TCRETURNri64: 1137158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::TCRETURNmi64: 1147158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::EH_RETURN: 1157158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::EH_RETURN64: { 1167158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng SmallSet<unsigned, 8> Uses; 1177158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng for (unsigned i = 0, e = MBBI->getNumOperands(); i != e; ++i) { 1187158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng MachineOperand &MO = MBBI->getOperand(i); 1197158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng if (!MO.isReg() || MO.isDef()) 1207158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng continue; 1217158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng unsigned Reg = MO.getReg(); 1227158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng if (!Reg) 1237158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng continue; 1247158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng for (const unsigned *AsI = TRI.getOverlaps(Reg); *AsI; ++AsI) 1257158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng Uses.insert(*AsI); 1267158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng } 1277158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 1287158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng const unsigned *CS = Is64Bit ? CallerSavedRegs64Bit : CallerSavedRegs32Bit; 1297158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng for (; *CS; ++CS) 1307158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng if (!Uses.count(*CS)) 1317158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng return *CS; 1327158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng } 1337158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng } 1347158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 1357158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng return 0; 1367158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng} 1377158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 1387158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 13933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// emitSPUpdate - Emit a series of instructions to increment / decrement the 14033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// stack pointer by a constant value. 14133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovstatic 14233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovvoid emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, 1437158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng unsigned StackPtr, int64_t NumBytes, 1447158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng bool Is64Bit, const TargetInstrInfo &TII, 1457158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng const TargetRegisterInfo &TRI) { 14633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool isSub = NumBytes < 0; 14733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t Offset = isSub ? -NumBytes : NumBytes; 14833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Opc = isSub ? 14933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov getSUBriOpcode(Is64Bit, Offset) : 15033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov getADDriOpcode(Is64Bit, Offset); 15133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t Chunk = (1LL << 31) - 1; 15233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DebugLoc DL = MBB.findDebugLoc(MBBI); 15333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 15433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov while (Offset) { 15533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t ThisVal = (Offset > Chunk) ? Chunk : Offset; 1567158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng if (ThisVal == (Is64Bit ? 8 : 4)) { 1577158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng // Use push / pop instead. 1587158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng unsigned Reg = isSub 1591e08cd1eaef8acbcfaf7db48d859a29583c29897Dale Johannesen ? (unsigned)(Is64Bit ? X86::RAX : X86::EAX) 1607158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng : findDeadCallerSavedReg(MBB, MBBI, TRI, Is64Bit); 1617158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng if (Reg) { 1627158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng Opc = isSub 1637158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng ? (Is64Bit ? X86::PUSH64r : X86::PUSH32r) 1647158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng : (Is64Bit ? X86::POP64r : X86::POP32r); 165aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis MachineInstr *MI = BuildMI(MBB, MBBI, DL, TII.get(Opc)) 1667158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng .addReg(Reg, getDefRegState(!isSub) | getUndefRegState(isSub)); 167aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis if (isSub) 168aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis MI->setFlag(MachineInstr::FrameSetup); 1697158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng Offset -= ThisVal; 1707158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng continue; 1717158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng } 1727158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng } 1737158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 17433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineInstr *MI = 17533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr) 1767158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng .addReg(StackPtr) 1777158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng .addImm(ThisVal); 178aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis if (isSub) 179aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis MI->setFlag(MachineInstr::FrameSetup); 18033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MI->getOperand(3).setIsDead(); // The EFLAGS implicit def is dead. 18133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Offset -= ThisVal; 18233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 18333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 18433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 18533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// mergeSPUpdatesUp - Merge two stack-manipulating instructions upper iterator. 18633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovstatic 18733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovvoid mergeSPUpdatesUp(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, 18833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackPtr, uint64_t *NumBytes = NULL) { 18933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MBBI == MBB.begin()) return; 19033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 19133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator PI = prior(MBBI); 19233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Opc = PI->getOpcode(); 19333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 || 19433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Opc == X86::ADD32ri || Opc == X86::ADD32ri8) && 19533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PI->getOperand(0).getReg() == StackPtr) { 19633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (NumBytes) 19733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *NumBytes += PI->getOperand(2).getImm(); 19833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBB.erase(PI); 19933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 || 20033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Opc == X86::SUB32ri || Opc == X86::SUB32ri8) && 20133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PI->getOperand(0).getReg() == StackPtr) { 20233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (NumBytes) 20333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *NumBytes -= PI->getOperand(2).getImm(); 20433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBB.erase(PI); 20533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 20633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 20733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 20833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// mergeSPUpdatesDown - Merge two stack-manipulating instructions lower iterator. 20933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovstatic 21033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovvoid mergeSPUpdatesDown(MachineBasicBlock &MBB, 21133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator &MBBI, 21233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackPtr, uint64_t *NumBytes = NULL) { 213fc9261279aa140542cf9b7c2c384d000ad97aca0Sanjoy Das // FIXME: THIS ISN'T RUN!!! 21433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return; 21533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 21633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MBBI == MBB.end()) return; 21733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 21833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator NI = llvm::next(MBBI); 21933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (NI == MBB.end()) return; 22033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 22133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Opc = NI->getOpcode(); 22233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 || 22333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Opc == X86::ADD32ri || Opc == X86::ADD32ri8) && 22433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov NI->getOperand(0).getReg() == StackPtr) { 22533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (NumBytes) 22633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *NumBytes -= NI->getOperand(2).getImm(); 22733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBB.erase(NI); 22833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBBI = NI; 22933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 || 23033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Opc == X86::SUB32ri || Opc == X86::SUB32ri8) && 23133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov NI->getOperand(0).getReg() == StackPtr) { 23233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (NumBytes) 23333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *NumBytes += NI->getOperand(2).getImm(); 23433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBB.erase(NI); 23533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBBI = NI; 23633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 23733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 23833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 23933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// mergeSPUpdates - Checks the instruction before/after the passed 24033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// instruction. If it is an ADD/SUB instruction it is deleted argument and the 24133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// stack adjustment is returned as a positive value for ADD and a negative for 24233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// SUB. 24333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovstatic int mergeSPUpdates(MachineBasicBlock &MBB, 24433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator &MBBI, 24533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackPtr, 24633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool doMergeWithPrevious) { 24733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if ((doMergeWithPrevious && MBBI == MBB.begin()) || 24833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov (!doMergeWithPrevious && MBBI == MBB.end())) 24933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return 0; 25033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 25133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator PI = doMergeWithPrevious ? prior(MBBI) : MBBI; 25233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator NI = doMergeWithPrevious ? 0 : llvm::next(MBBI); 25333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Opc = PI->getOpcode(); 25433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int Offset = 0; 25533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 25633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 || 25733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Opc == X86::ADD32ri || Opc == X86::ADD32ri8) && 25833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PI->getOperand(0).getReg() == StackPtr){ 25933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Offset += PI->getOperand(2).getImm(); 26033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBB.erase(PI); 26133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!doMergeWithPrevious) MBBI = NI; 26233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 || 26333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Opc == X86::SUB32ri || Opc == X86::SUB32ri8) && 26433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PI->getOperand(0).getReg() == StackPtr) { 26533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Offset -= PI->getOperand(2).getImm(); 26633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBB.erase(PI); 26733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!doMergeWithPrevious) MBBI = NI; 26833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 26933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 27033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return Offset; 27133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 27233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 27333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovstatic bool isEAXLiveIn(MachineFunction &MF) { 27433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (MachineRegisterInfo::livein_iterator II = MF.getRegInfo().livein_begin(), 27533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov EE = MF.getRegInfo().livein_end(); II != EE; ++II) { 27633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Reg = II->first; 27733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 27833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (Reg == X86::EAX || Reg == X86::AX || 27933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Reg == X86::AH || Reg == X86::AL) 28033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return true; 28133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 28233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 28333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return false; 28433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 28533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 28616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid X86FrameLowering::emitCalleeSavedFrameMoves(MachineFunction &MF, 28709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling MCSymbol *Label, 28809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned FramePtr) const { 28933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 29033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineModuleInfo &MMI = MF.getMMI(); 29133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 29233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Add callee saved registers to move list. 29333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 29433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (CSI.empty()) return; 29533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 29633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov std::vector<MachineMove> &Moves = MMI.getFrameMoves(); 297d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov const TargetData *TD = TM.getTargetData(); 298d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov bool HasFP = hasFP(MF); 29933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 30033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Calculate amount of bytes used for return address storing. 301e749911372c75e4e68f83a32b4092f4ffb0d2793Anton Korobeynikov int stackGrowth = -TD->getPointerSize(); 30233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 30333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // FIXME: This is dirty hack. The code itself is pretty mess right now. 30433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // It should be rewritten from scratch and generalized sometimes. 30533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 3067a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // Determine maximum offset (minimum due to stack growth). 30733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int64_t MaxOffset = 0; 30833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (std::vector<CalleeSavedInfo>::const_iterator 30933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov I = CSI.begin(), E = CSI.end(); I != E; ++I) 31033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MaxOffset = std::min(MaxOffset, 31133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MFI->getObjectOffset(I->getFrameIdx())); 31233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 31333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Calculate offsets. 31433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int64_t saveAreaOffset = (HasFP ? 3 : 2) * stackGrowth; 31533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (std::vector<CalleeSavedInfo>::const_iterator 31633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov I = CSI.begin(), E = CSI.end(); I != E; ++I) { 31733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int64_t Offset = MFI->getObjectOffset(I->getFrameIdx()); 31833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Reg = I->getReg(); 31933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Offset = MaxOffset - Offset + saveAreaOffset; 32033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 32133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Don't output a new machine move if we're re-saving the frame 32233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // pointer. This happens when the PrologEpilogInserter has inserted an extra 32333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // "PUSH" of the frame pointer -- the "emitPrologue" method automatically 32433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // generates one when frame pointers are used. If we generate a "machine 32533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // move" for this extra "PUSH", the linker will lose track of the fact that 32633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // the frame pointer should have the value of the first "PUSH" when it's 32733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // trying to unwind. 3282763538609fd455d63c192b320c73fb5d48c3e47NAKAMURA Takumi // 32933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // FIXME: This looks inelegant. It's possibly correct, but it's covering up 33033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // another bug. I.e., one where we generate a prolog like this: 33133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // 33233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // pushl %ebp 33333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // movl %esp, %ebp 33433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // pushl %ebp 33533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // pushl %esi 33633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // ... 33733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // 33833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // The immediate re-push of EBP is unnecessary. At the least, it's an 33933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // optimization bug. EBP can be used as a scratch register in certain 34033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // cases, but probably not when we have a frame pointer. 34133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP && FramePtr == Reg) 34233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov continue; 34333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 34433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation CSDst(MachineLocation::VirtualFP, Offset); 34533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation CSSrc(Reg); 34633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(Label, CSDst, CSSrc)); 34733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 34833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 34933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 35009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling/// getCompactUnwindRegNum - Get the compact unwind number for a given 35109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling/// register. The number corresponds to the enum lists in 35209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling/// compact_unwind_encoding.h. 35309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendlingstatic int getCompactUnwindRegNum(const unsigned *CURegs, unsigned Reg) { 35409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling int Idx = 1; 35509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling for (; *CURegs; ++CURegs, ++Idx) 35609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling if (*CURegs == Reg) 35709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling return Idx; 35809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 35909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling return -1; 36009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling} 36109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 36209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling/// encodeCompactUnwindRegistersWithoutFrame - Create the permutation encoding 36309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling/// used with frameless stacks. It is passed the number of registers to be saved 36409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling/// and an array of the registers saved. 36509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendlingstatic uint32_t encodeCompactUnwindRegistersWithoutFrame(unsigned SavedRegs[6], 36609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned RegCount, 36709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling bool Is64Bit) { 36809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // The saved registers are numbered from 1 to 6. In order to encode the order 36909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // in which they were saved, we re-number them according to their place in the 37009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // register order. The re-numbering is relative to the last re-numbered 37109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // register. E.g., if we have registers {6, 2, 4, 5} saved in that order: 37209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // 37309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // Orig Re-Num 37409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // ---- ------ 37509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // 6 6 37609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // 2 2 37709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // 4 3 37809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // 5 3 37909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // 38009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling static const unsigned CU32BitRegs[] = { 38109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling X86::EBX, X86::ECX, X86::EDX, X86::EDI, X86::ESI, X86::EBP, 0 38209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling }; 38309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling static const unsigned CU64BitRegs[] = { 38409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0 38509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling }; 38609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling const unsigned *CURegs = (Is64Bit ? CU64BitRegs : CU32BitRegs); 38709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 38809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling for (unsigned i = 6 - RegCount; i < 6; ++i) { 38909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling int CUReg = getCompactUnwindRegNum(CURegs, SavedRegs[i]); 39009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling if (CUReg == -1) return ~0U; 39109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling SavedRegs[i] = CUReg; 39279df986c60094e9ea29f081295aea08b1680a999Bill Wendling } 39309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 39479df986c60094e9ea29f081295aea08b1680a999Bill Wendling uint32_t RenumRegs[6]; 39579df986c60094e9ea29f081295aea08b1680a999Bill Wendling for (unsigned i = 6 - RegCount; i < 6; ++i) { 39609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned Countless = 0; 39709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling for (unsigned j = 6 - RegCount; j < i; ++j) 39809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling if (SavedRegs[j] < SavedRegs[i]) 39909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling ++Countless; 40009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 40109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling RenumRegs[i] = SavedRegs[i] - Countless - 1; 40209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling } 40309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 40409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // Take the renumbered values and encode them into a 10-bit number. 40509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling uint32_t permutationEncoding = 0; 40609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling switch (RegCount) { 40709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling case 6: 40809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling permutationEncoding |= 120 * RenumRegs[0] + 24 * RenumRegs[1] 40909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling + 6 * RenumRegs[2] + 2 * RenumRegs[3] 41009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling + RenumRegs[4]; 41109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling break; 41209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling case 5: 41309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling permutationEncoding |= 120 * RenumRegs[1] + 24 * RenumRegs[2] 41409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling + 6 * RenumRegs[3] + 2 * RenumRegs[4] 41509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling + RenumRegs[5]; 41609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling break; 41709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling case 4: 41809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling permutationEncoding |= 60 * RenumRegs[2] + 12 * RenumRegs[3] 41909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling + 3 * RenumRegs[4] + RenumRegs[5]; 42009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling break; 42109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling case 3: 42209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling permutationEncoding |= 20 * RenumRegs[3] + 4 * RenumRegs[4] 42309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling + RenumRegs[5]; 42409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling break; 42509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling case 2: 42609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling permutationEncoding |= 5 * RenumRegs[4] + RenumRegs[5]; 42709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling break; 42809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling case 1: 42909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling permutationEncoding |= RenumRegs[5]; 43009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling break; 43109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling } 43209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 43309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling assert((permutationEncoding & 0x3FF) == permutationEncoding && 43409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling "Invalid compact register encoding!"); 43509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling return permutationEncoding; 43609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling} 43709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 43809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling/// encodeCompactUnwindRegistersWithFrame - Return the registers encoded for a 43909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling/// compact encoding with a frame pointer. 44009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendlingstatic uint32_t encodeCompactUnwindRegistersWithFrame(unsigned SavedRegs[6], 44109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling bool Is64Bit) { 44209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling static const unsigned CU32BitRegs[] = { 44309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling X86::EBX, X86::ECX, X86::EDX, X86::EDI, X86::ESI, X86::EBP, 0 44409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling }; 44509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling static const unsigned CU64BitRegs[] = { 44609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0 44709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling }; 44809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling const unsigned *CURegs = (Is64Bit ? CU64BitRegs : CU32BitRegs); 44909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 45009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // Encode the registers in the order they were saved, 3-bits per register. The 45109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // registers are numbered from 1 to 6. 45209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling uint32_t RegEnc = 0; 45309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling for (int I = 5; I >= 0; --I) { 45409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned Reg = SavedRegs[I]; 45509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling if (Reg == 0) break; 45609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling int CURegNum = getCompactUnwindRegNum(CURegs, Reg); 45709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling if (CURegNum == -1) 45809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling return ~0U; 45980caf9c2737d4f1bf5bae3a283fe9d538f5e2970Bill Wendling 46080caf9c2737d4f1bf5bae3a283fe9d538f5e2970Bill Wendling // Encode the 3-bit register number in order, skipping over 3-bits for each 46180caf9c2737d4f1bf5bae3a283fe9d538f5e2970Bill Wendling // register. 46279df986c60094e9ea29f081295aea08b1680a999Bill Wendling RegEnc |= (CURegNum & 0x7) << ((5 - I) * 3); 46309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling } 46409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 46509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling assert((RegEnc & 0x7FFF) == RegEnc && "Invalid compact register encoding!"); 46609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling return RegEnc; 46709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling} 46809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 46909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendlinguint32_t X86FrameLowering::getCompactUnwindEncoding(MachineFunction &MF) const { 47009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling const X86RegisterInfo *RegInfo = TM.getRegisterInfo(); 47109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned FramePtr = RegInfo->getFrameRegister(MF); 47209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned StackPtr = RegInfo->getStackRegister(); 47309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 47409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>(); 47509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling int TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta(); 47609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 47709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling bool Is64Bit = STI.is64Bit(); 47809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling bool HasFP = hasFP(MF); 47909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 48009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned SavedRegs[6] = { 0, 0, 0, 0, 0, 0 }; 48109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling int SavedRegIdx = 6; 48209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 48309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned OffsetSize = (Is64Bit ? 8 : 4); 48409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 48509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned PushInstr = (Is64Bit ? X86::PUSH64r : X86::PUSH32r); 48609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned PushInstrSize = 1; 48709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned MoveInstr = (Is64Bit ? X86::MOV64rr : X86::MOV32rr); 48809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned MoveInstrSize = (Is64Bit ? 3 : 2); 48909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned SubtractInstr = getSUBriOpcode(Is64Bit, -TailCallReturnAddrDelta); 49009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned SubtractInstrIdx = (Is64Bit ? 3 : 2); 49109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 492de77055a68a3fc495e01b682f00059af3e38822eBill Wendling unsigned StackDivide = (Is64Bit ? 8 : 4); 493de77055a68a3fc495e01b682f00059af3e38822eBill Wendling 49409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned InstrOffset = 0; 49509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned CFAOffset = 0; 49609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned StackAdjust = 0; 49709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 49809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling MachineBasicBlock &MBB = MF.front(); // Prologue is in entry BB. 49909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling bool ExpectEnd = false; 50009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling for (MachineBasicBlock::iterator 50109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling MBBI = MBB.begin(), MBBE = MBB.end(); MBBI != MBBE; ++MBBI) { 50209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling MachineInstr &MI = *MBBI; 50309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned Opc = MI.getOpcode(); 50409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling if (Opc == X86::PROLOG_LABEL) continue; 50509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling if (!MI.getFlag(MachineInstr::FrameSetup)) break; 50609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 50709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // We don't exect any more prolog instructions. 50809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling if (ExpectEnd) return 0; 50909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 51009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling if (Opc == PushInstr) { 51109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // If there are too many saved registers, we cannot use compact encoding. 51209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling if (--SavedRegIdx < 0) return 0; 51309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 51409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling SavedRegs[SavedRegIdx] = MI.getOperand(0).getReg(); 51509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling CFAOffset += OffsetSize; 51609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling InstrOffset += PushInstrSize; 51709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling } else if (Opc == MoveInstr) { 51809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned SrcReg = MI.getOperand(1).getReg(); 51909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned DstReg = MI.getOperand(0).getReg(); 52009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 52109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling if (DstReg != FramePtr || SrcReg != StackPtr) 52209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling return 0; 52309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 52409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling CFAOffset = 0; 52509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling memset(SavedRegs, 0, sizeof(SavedRegs)); 526c739577d3c2e5ee47baaf8b4ba259718ec2db4ccBill Wendling SavedRegIdx = 6; 52709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling InstrOffset += MoveInstrSize; 52809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling } else if (Opc == SubtractInstr) { 52909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling if (StackAdjust) 53009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // We all ready have a stack pointer adjustment. 53109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling return 0; 53209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 53309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling if (!MI.getOperand(0).isReg() || 53409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling MI.getOperand(0).getReg() != MI.getOperand(1).getReg() || 53509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling MI.getOperand(0).getReg() != StackPtr || !MI.getOperand(2).isImm()) 53609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // We need this to be a stack adjustment pointer. Something like: 53709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // 53809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // %RSP<def> = SUB64ri8 %RSP, 48 53909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling return 0; 54009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 541de77055a68a3fc495e01b682f00059af3e38822eBill Wendling StackAdjust = MI.getOperand(2).getImm() / StackDivide; 54209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling SubtractInstrIdx += InstrOffset; 54309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling ExpectEnd = true; 54409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling } 54509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling } 54609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 54709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // Encode that we are using EBP/RBP as the frame pointer. 54809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling uint32_t CompactUnwindEncoding = 0; 549de77055a68a3fc495e01b682f00059af3e38822eBill Wendling CFAOffset /= StackDivide; 55009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling if (HasFP) { 55109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling if ((CFAOffset & 0xFF) != CFAOffset) 55209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // Offset was too big for compact encoding. 55309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling return 0; 55409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 55509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // Get the encoding of the saved registers when we have a frame pointer. 55609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling uint32_t RegEnc = encodeCompactUnwindRegistersWithFrame(SavedRegs, Is64Bit); 5575b2c4978ce56455689c515c9d74cc1d92871f3bbBill Wendling if (RegEnc == ~0U) return 0; 55809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 55909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling CompactUnwindEncoding |= 0x01000000; 56009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling CompactUnwindEncoding |= (CFAOffset & 0xFF) << 16; 56109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling CompactUnwindEncoding |= RegEnc & 0x7FFF; 56209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling } else { 5635b2c4978ce56455689c515c9d74cc1d92871f3bbBill Wendling if ((CFAOffset & 0xFF) == CFAOffset) { 5645b2c4978ce56455689c515c9d74cc1d92871f3bbBill Wendling // Frameless stack with a small stack size. 56509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling CompactUnwindEncoding |= 0x02000000; 5665b2c4978ce56455689c515c9d74cc1d92871f3bbBill Wendling 5675b2c4978ce56455689c515c9d74cc1d92871f3bbBill Wendling // Encode the stack size. 56875e14e0ebd29bb2b1893948037c0ae5df4e09a41Bill Wendling CompactUnwindEncoding |= (CFAOffset & 0xFF) << 16; 56909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling } else { 57009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling if ((CFAOffset & 0x7) != CFAOffset) 57109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // The extra stack adjustments are too big for us to handle. 57209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling return 0; 57309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 57409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // Frameless stack with an offset too large for us to encode compactly. 57509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling CompactUnwindEncoding |= 0x03000000; 57609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 57709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // Encode the offset to the nnnnnn value in the 'subl $nnnnnn, ESP' 57809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // instruction. 57909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling CompactUnwindEncoding |= (SubtractInstrIdx & 0xFF) << 16; 58009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 58109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // Encode any extra stack stack changes (done via push instructions). 58209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling CompactUnwindEncoding |= (CFAOffset & 0x7) << 13; 58309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling } 58409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 5855b2c4978ce56455689c515c9d74cc1d92871f3bbBill Wendling // Encode the number of registers saved. 58675e14e0ebd29bb2b1893948037c0ae5df4e09a41Bill Wendling CompactUnwindEncoding |= ((6 - SavedRegIdx) & 0x7) << 10; 58775e14e0ebd29bb2b1893948037c0ae5df4e09a41Bill Wendling 58809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // Get the encoding of the saved registers when we don't have a frame 58909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // pointer. 59009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling uint32_t RegEnc = encodeCompactUnwindRegistersWithoutFrame(SavedRegs, 59109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 6 - SavedRegIdx, 59209b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling Is64Bit); 59309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling if (RegEnc == ~0U) return 0; 5945b2c4978ce56455689c515c9d74cc1d92871f3bbBill Wendling 5955b2c4978ce56455689c515c9d74cc1d92871f3bbBill Wendling // Encode the register encoding. 59609b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling CompactUnwindEncoding |= RegEnc & 0x3FF; 59709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling } 59809b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 59909b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling return CompactUnwindEncoding; 60009b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling} 60109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 60233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// emitPrologue - Push callee-saved registers onto the stack, which 60333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// automatically adjust the stack pointer. Adjust the stack pointer to allocate 60433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// space for local variables. Also emit labels used by the exception handler to 60533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// generate the exception handling frames. 60616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid X86FrameLowering::emitPrologue(MachineFunction &MF) const { 60733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock &MBB = MF.front(); // Prologue goes in entry BB. 60833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator MBBI = MBB.begin(); 60933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 61033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const Function *Fn = MF.getFunction(); 611d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov const X86RegisterInfo *RegInfo = TM.getRegisterInfo(); 612d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov const X86InstrInfo &TII = *TM.getInstrInfo(); 61333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineModuleInfo &MMI = MF.getMMI(); 61433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>(); 61533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool needsFrameMoves = MMI.hasDebugInfo() || 616fc2bb8c4448fa884d79e437cc2d2627a7d7740a8Rafael Espindola Fn->needsUnwindTableEntry(); 61733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t MaxAlign = MFI->getMaxAlignment(); // Desired stack alignment. 61833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t StackSize = MFI->getStackSize(); // Number of bytes to allocate. 619d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov bool HasFP = hasFP(MF); 62033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool Is64Bit = STI.is64Bit(); 62133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool IsWin64 = STI.isTargetWin64(); 62233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackAlign = getStackAlignment(); 62333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned SlotSize = RegInfo->getSlotSize(); 62433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned FramePtr = RegInfo->getFrameRegister(MF); 62533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackPtr = RegInfo->getStackRegister(); 62633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DebugLoc DL; 62733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 62833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If we're forcing a stack realignment we can't rely on just the frame 62933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // info, we need to know the ABI stack alignment as well in case we 63033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // have a call out. Otherwise just make sure we have some alignment - we'll 63133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // go with the minimum SlotSize. 63233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (ForceStackAlign) { 63333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MFI->hasCalls()) 63433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MaxAlign = (StackAlign > MaxAlign) ? StackAlign : MaxAlign; 63533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov else if (MaxAlign < SlotSize) 63633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MaxAlign = SlotSize; 63733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 63833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 63933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Add RETADDR move area to callee saved frame size. 64033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta(); 64133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (TailCallReturnAddrDelta < 0) 64233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov X86FI->setCalleeSavedFrameSize( 64333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov X86FI->getCalleeSavedFrameSize() - TailCallReturnAddrDelta); 64433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 64533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If this is x86-64 and the Red Zone is not disabled, if we are a leaf 64633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // function, and use up to 128 bytes of stack space, don't have a frame 64733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // pointer, calls, or dynamic alloca then we do not need to adjust the 64833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // stack pointer (we fit in the Red Zone). 64933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (Is64Bit && !Fn->hasFnAttr(Attribute::NoRedZone) && 65033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov !RegInfo->needsStackRealignment(MF) && 6518a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky !MFI->hasVarSizedObjects() && // No dynamic alloca. 6528a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky !MFI->adjustsStack() && // No calls. 6538a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky !IsWin64 && // Win64 has no Red Zone 6548a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky !MF.getTarget().Options.EnableSegmentedStacks) { // Regular stack 65533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t MinSize = X86FI->getCalleeSavedFrameSize(); 65633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) MinSize += SlotSize; 65733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov StackSize = std::max(MinSize, StackSize > 128 ? StackSize - 128 : 0); 65833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MFI->setStackSize(StackSize); 65933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 66033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 66133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Insert stack pointer adjustment for later moving of return addr. Only 66233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // applies to tail call optimized functions where the callee argument stack 66333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // size is bigger than the callers. 66433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (TailCallReturnAddrDelta < 0) { 66533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineInstr *MI = 66633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, 66733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov TII.get(getSUBriOpcode(Is64Bit, -TailCallReturnAddrDelta)), 66833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov StackPtr) 66933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(StackPtr) 670aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis .addImm(-TailCallReturnAddrDelta) 671aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis .setMIFlag(MachineInstr::FrameSetup); 67233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MI->getOperand(3).setIsDead(); // The EFLAGS implicit def is dead. 67333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 67433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 67533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Mapping for machine moves: 67633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // 67733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // DST: VirtualFP AND 67833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // SRC: VirtualFP => DW_CFA_def_cfa_offset 67933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // ELSE => DW_CFA_def_cfa 68033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // 68133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // SRC: VirtualFP AND 68233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // DST: Register => DW_CFA_def_cfa_register 68333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // 68433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // ELSE 68533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // OFFSET < 0 => DW_CFA_offset_extended_sf 68633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // REG < 64 => DW_CFA_offset + Reg 68733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // ELSE => DW_CFA_offset_extended 68833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 68933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov std::vector<MachineMove> &Moves = MMI.getFrameMoves(); 69033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const TargetData *TD = MF.getTarget().getTargetData(); 69133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t NumBytes = 0; 69233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int stackGrowth = -TD->getPointerSize(); 69333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 69433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) { 69533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Calculate required stack adjustment. 69633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t FrameSize = StackSize - SlotSize; 69733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (RegInfo->needsStackRealignment(MF)) 69833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov FrameSize = (FrameSize + MaxAlign - 1) / MaxAlign * MaxAlign; 69933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 70033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov NumBytes = FrameSize - X86FI->getCalleeSavedFrameSize(); 70133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 70233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get the offset of the stack slot for the EBP register, which is 70333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // guaranteed to be the last slot by processFunctionBeforeFrameFinalized. 70433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Update the frame offset adjustment. 70533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MFI->setOffsetAdjustment(-NumBytes); 70633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 70733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Save EBP/RBP into the appropriate stack slot. 70833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::PUSH64r : X86::PUSH32r)) 709aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis .addReg(FramePtr, RegState::Kill) 710aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis .setMIFlag(MachineInstr::FrameSetup); 71133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 71233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (needsFrameMoves) { 71333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Mark the place where EBP/RBP was saved. 71433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MCSymbol *FrameLabel = MMI.getContext().CreateTempSymbol(); 715fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling BuildMI(MBB, MBBI, DL, TII.get(X86::PROLOG_LABEL)) 716fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .addSym(FrameLabel); 71733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 71833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Define the current CFA rule to use the provided offset. 71933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (StackSize) { 72033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPDst(MachineLocation::VirtualFP); 72133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPSrc(MachineLocation::VirtualFP, 2 * stackGrowth); 72233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc)); 72333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 72433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPDst(StackPtr); 72533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPSrc(StackPtr, stackGrowth); 72633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc)); 72733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 72833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 72933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Change the rule for the FramePtr to be an "offset" rule. 73033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation FPDst(MachineLocation::VirtualFP, 2 * stackGrowth); 73133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation FPSrc(FramePtr); 73233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(FrameLabel, FPDst, FPSrc)); 73333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 73433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 73509b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // Update EBP with the new base value. 73633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, 73733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr), FramePtr) 738aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis .addReg(StackPtr) 739aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis .setMIFlag(MachineInstr::FrameSetup); 74033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 74133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (needsFrameMoves) { 74233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Mark effective beginning of when frame pointer becomes valid. 74333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MCSymbol *FrameLabel = MMI.getContext().CreateTempSymbol(); 744fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling BuildMI(MBB, MBBI, DL, TII.get(X86::PROLOG_LABEL)) 745fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .addSym(FrameLabel); 74633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 74733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Define the current CFA to use the EBP/RBP register. 74833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation FPDst(FramePtr); 74933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation FPSrc(MachineLocation::VirtualFP); 75033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(FrameLabel, FPDst, FPSrc)); 75133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 75233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 75333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Mark the FramePtr as live-in in every block except the entry. 75433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (MachineFunction::iterator I = llvm::next(MF.begin()), E = MF.end(); 75533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov I != E; ++I) 75633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov I->addLiveIn(FramePtr); 75733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 75833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Realign stack 75933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (RegInfo->needsStackRealignment(MF)) { 76033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineInstr *MI = 76133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, 762fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling TII.get(Is64Bit ? X86::AND64ri32 : X86::AND32ri), StackPtr) 763fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .addReg(StackPtr) 764fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .addImm(-MaxAlign) 765fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .setMIFlag(MachineInstr::FrameSetup); 76633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 76733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // The EFLAGS implicit def is dead. 76833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MI->getOperand(3).setIsDead(); 76933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 77033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 77133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov NumBytes = StackSize - X86FI->getCalleeSavedFrameSize(); 77233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 77333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 77433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Skip the callee-saved push instructions. 77533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool PushedRegs = false; 77633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int StackOffset = 2 * stackGrowth; 77733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 77833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov while (MBBI != MBB.end() && 77933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov (MBBI->getOpcode() == X86::PUSH32r || 78033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBBI->getOpcode() == X86::PUSH64r)) { 78133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PushedRegs = true; 782fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling MBBI->setFlag(MachineInstr::FrameSetup); 78333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov ++MBBI; 78433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 78533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!HasFP && needsFrameMoves) { 78633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Mark callee-saved push instruction. 78733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MCSymbol *Label = MMI.getContext().CreateTempSymbol(); 78833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(X86::PROLOG_LABEL)).addSym(Label); 78933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 79033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Define the current CFA rule to use the provided offset. 79109b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling unsigned Ptr = StackSize ? MachineLocation::VirtualFP : StackPtr; 79233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPDst(Ptr); 79333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPSrc(Ptr, StackOffset); 79433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(Label, SPDst, SPSrc)); 79533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov StackOffset += stackGrowth; 79633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 79733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 79833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 79933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DL = MBB.findDebugLoc(MBBI); 80033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 80133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If there is an SUB32ri of ESP immediately before this instruction, merge 80233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // the two. This can be the case when tail call elimination is enabled and 80333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // the callee has more arguments then the caller. 80433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov NumBytes -= mergeSPUpdates(MBB, MBBI, StackPtr, true); 80533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 80633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If there is an ADD32ri or SUB32ri of ESP immediately after this 80733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // instruction, merge the two instructions. 80833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov mergeSPUpdatesDown(MBB, MBBI, StackPtr, &NumBytes); 80933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 81033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Adjust stack pointer: ESP -= numbytes. 81133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 81233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Windows and cygwin/mingw require a prologue helper routine when allocating 81333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // more than 4K bytes on the stack. Windows uses __chkstk and cygwin/mingw 81433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // uses __alloca. __alloca and the 32-bit version of __chkstk will probe the 81533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // stack and adjust the stack pointer in one go. The 64-bit version of 81633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // __chkstk is only responsible for probing the stack. The 64-bit prologue is 81733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // responsible for adjusting the stack pointer. Touching the stack at 4K 81833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // increments is necessary to ensure that the guard pages used by the OS 81933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // virtual memory manager are allocated in correct sequence. 820a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi if (NumBytes >= 4096 && STI.isTargetCOFF() && !STI.isTargetEnvMacho()) { 821a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi const char *StackProbeSymbol; 822a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi bool isSPUpdateNeeded = false; 823a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi 824a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi if (Is64Bit) { 825a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi if (STI.isTargetCygMing()) 826a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi StackProbeSymbol = "___chkstk"; 827a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi else { 828a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi StackProbeSymbol = "__chkstk"; 829a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi isSPUpdateNeeded = true; 830a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi } 831a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi } else if (STI.isTargetCygMing()) 832a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi StackProbeSymbol = "_alloca"; 833a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi else 834a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi StackProbeSymbol = "_chkstk"; 835a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi 83633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Check whether EAX is livein for this function. 83733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool isEAXAlive = isEAXLiveIn(MF); 83833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 839a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi if (isEAXAlive) { 840a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // Sanity check that EAX is not livein for this function. 841a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // It should not be, so throw an assert. 842a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi assert(!Is64Bit && "EAX is livein in x64 case!"); 843a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi 84433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Save EAX 84533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(X86::PUSH32r)) 846fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .addReg(X86::EAX, RegState::Kill) 847fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .setMIFlag(MachineInstr::FrameSetup); 848a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi } 84933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 850a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi if (Is64Bit) { 851a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // Handle the 64-bit Windows ABI case where we need to call __chkstk. 852a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // Function prologue is responsible for adjusting the stack pointer. 853a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi BuildMI(MBB, MBBI, DL, TII.get(X86::MOV64ri), X86::RAX) 854fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .addImm(NumBytes) 855fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .setMIFlag(MachineInstr::FrameSetup); 856a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi } else { 857a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // Allocate NumBytes-4 bytes on stack in case of isEAXAlive. 858a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // We'll also use 4 already allocated bytes for EAX. 85933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX) 860fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .addImm(isEAXAlive ? NumBytes - 4 : NumBytes) 861fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .setMIFlag(MachineInstr::FrameSetup); 862a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi } 863a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi 864a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi BuildMI(MBB, MBBI, DL, 865a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi TII.get(Is64Bit ? X86::W64ALLOCA : X86::CALLpcrel32)) 866a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi .addExternalSymbol(StackProbeSymbol) 867a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi .addReg(StackPtr, RegState::Define | RegState::Implicit) 868fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .addReg(X86::EFLAGS, RegState::Define | RegState::Implicit) 869fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .setMIFlag(MachineInstr::FrameSetup); 870a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi 871a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // MSVC x64's __chkstk needs to adjust %rsp. 872a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // FIXME: %rax preserves the offset and should be available. 873a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi if (isSPUpdateNeeded) 874a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi emitSPUpdate(MBB, MBBI, StackPtr, -(int64_t)NumBytes, Is64Bit, 875a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi TII, *RegInfo); 876a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi 877a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi if (isEAXAlive) { 878a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // Restore EAX 879a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi MachineInstr *MI = addRegOffset(BuildMI(MF, DL, TII.get(X86::MOV32rm), 880a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi X86::EAX), 881a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi StackPtr, false, NumBytes - 4); 882fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling MI->setFlag(MachineInstr::FrameSetup); 883a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi MBB.insert(MBBI, MI); 88433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 88533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (NumBytes) 8867158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng emitSPUpdate(MBB, MBBI, StackPtr, -(int64_t)NumBytes, Is64Bit, 8877158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng TII, *RegInfo); 88833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 889f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola if (( (!HasFP && NumBytes) || PushedRegs) && needsFrameMoves) { 89033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Mark end of stack pointer adjustment. 89133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MCSymbol *Label = MMI.getContext().CreateTempSymbol(); 892fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling BuildMI(MBB, MBBI, DL, TII.get(X86::PROLOG_LABEL)) 893fb4eb165d66b8ca5ae09c37d98d3ed937454b6afBill Wendling .addSym(Label); 89433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 89533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!HasFP && NumBytes) { 89633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Define the current CFA rule to use the provided offset. 89733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (StackSize) { 89833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPDst(MachineLocation::VirtualFP); 89933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPSrc(MachineLocation::VirtualFP, 90033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov -StackSize + stackGrowth); 90133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(Label, SPDst, SPSrc)); 90233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 90333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPDst(StackPtr); 90433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPSrc(StackPtr, stackGrowth); 90533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(Label, SPDst, SPSrc)); 90633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 90733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 90833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 90933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Emit DWARF info specifying the offsets of the callee-saved registers. 91033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (PushedRegs) 91133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov emitCalleeSavedFrameMoves(MF, Label, HasFP ? FramePtr : StackPtr); 91233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 91309b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling 91409b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling // Darwin 10.7 and greater has support for compact unwind encoding. 915c8725d11f8756c57bdbceccc61062a9d560261c5Bill Wendling if (STI.getTargetTriple().isMacOSX() && 916ac86d43eae8bbfe5284d8e5fa17c141d1a7b1194Eli Friedman !STI.getTargetTriple().isMacOSXVersionLT(10, 7)) 91709b02c8dddf822e84c30cc08e7759d6ceebb2334Bill Wendling MMI.setCompactUnwindEncoding(getCompactUnwindEncoding(MF)); 91833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 91933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 92016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid X86FrameLowering::emitEpilogue(MachineFunction &MF, 9213c2f0a11cce5a1e828e20675fa8467b624795e0aNick Lewycky MachineBasicBlock &MBB) const { 92233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const MachineFrameInfo *MFI = MF.getFrameInfo(); 92333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>(); 924d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov const X86RegisterInfo *RegInfo = TM.getRegisterInfo(); 925d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov const X86InstrInfo &TII = *TM.getInstrInfo(); 9264f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 9274f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen assert(MBBI != MBB.end() && "Returning block has no instructions"); 92833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned RetOpcode = MBBI->getOpcode(); 92933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DebugLoc DL = MBBI->getDebugLoc(); 93033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool Is64Bit = STI.is64Bit(); 93133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackAlign = getStackAlignment(); 93233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned SlotSize = RegInfo->getSlotSize(); 93333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned FramePtr = RegInfo->getFrameRegister(MF); 93433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackPtr = RegInfo->getStackRegister(); 93533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 93633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov switch (RetOpcode) { 93733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov default: 93833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov llvm_unreachable("Can only insert epilog into returning blocks"); 93933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::RET: 94033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::RETI: 94133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::TCRETURNdi: 94233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::TCRETURNri: 94333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::TCRETURNmi: 94433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::TCRETURNdi64: 94533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::TCRETURNri64: 94633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::TCRETURNmi64: 94733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::EH_RETURN: 94833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::EH_RETURN64: 94933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov break; // These are ok 95033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 95133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 95233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get the number of bytes to allocate from the FrameInfo. 95333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t StackSize = MFI->getStackSize(); 95433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t MaxAlign = MFI->getMaxAlignment(); 95533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned CSSize = X86FI->getCalleeSavedFrameSize(); 95633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t NumBytes = 0; 95733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 95833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If we're forcing a stack realignment we can't rely on just the frame 95933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // info, we need to know the ABI stack alignment as well in case we 96033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // have a call out. Otherwise just make sure we have some alignment - we'll 96133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // go with the minimum. 96233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (ForceStackAlign) { 96333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MFI->hasCalls()) 96433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MaxAlign = (StackAlign > MaxAlign) ? StackAlign : MaxAlign; 96533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov else 96633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MaxAlign = MaxAlign ? MaxAlign : 4; 96733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 96833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 969d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (hasFP(MF)) { 97033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Calculate required stack adjustment. 97133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t FrameSize = StackSize - SlotSize; 97233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (RegInfo->needsStackRealignment(MF)) 97333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov FrameSize = (FrameSize + MaxAlign - 1)/MaxAlign*MaxAlign; 97433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 97533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov NumBytes = FrameSize - CSSize; 97633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 97733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Pop EBP. 97833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, 97933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov TII.get(Is64Bit ? X86::POP64r : X86::POP32r), FramePtr); 98033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 98133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov NumBytes = StackSize - CSSize; 98233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 98333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 98433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Skip the callee-saved pop instructions. 98533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator LastCSPop = MBBI; 98633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov while (MBBI != MBB.begin()) { 98733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator PI = prior(MBBI); 98833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Opc = PI->getOpcode(); 98933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 9904f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen if (Opc != X86::POP32r && Opc != X86::POP64r && Opc != X86::DBG_VALUE && 99133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov !PI->getDesc().isTerminator()) 99233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov break; 99333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 99433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov --MBBI; 99533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 99633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 99733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DL = MBBI->getDebugLoc(); 99833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 99933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If there is an ADD32ri or SUB32ri of ESP immediately before this 100033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // instruction, merge the two instructions. 100133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (NumBytes || MFI->hasVarSizedObjects()) 100233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes); 100333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 100433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If dynamic alloca is used, then reset esp to point to the last callee-saved 100533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // slot before popping them off! Same applies for the case, when stack was 100633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // realigned. 100733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (RegInfo->needsStackRealignment(MF)) { 100833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // We cannot use LEA here, because stack pointer was realigned. We need to 100933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // deallocate local frame back. 101033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (CSSize) { 10117158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng emitSPUpdate(MBB, MBBI, StackPtr, NumBytes, Is64Bit, TII, *RegInfo); 101233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBBI = prior(LastCSPop); 101333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 101433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 101533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, 101633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr), 101733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov StackPtr).addReg(FramePtr); 101833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (MFI->hasVarSizedObjects()) { 101933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (CSSize) { 102033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Opc = Is64Bit ? X86::LEA64r : X86::LEA32r; 102133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineInstr *MI = 102233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov addRegOffset(BuildMI(MF, DL, TII.get(Opc), StackPtr), 102333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov FramePtr, false, -CSSize); 102433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBB.insert(MBBI, MI); 102533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 102633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, 102733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr), StackPtr) 102833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(FramePtr); 102933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 103033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (NumBytes) { 103133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Adjust stack pointer back: ESP += numbytes. 10327158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng emitSPUpdate(MBB, MBBI, StackPtr, NumBytes, Is64Bit, TII, *RegInfo); 103333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 103433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 103533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // We're returning from function via eh_return. 103633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (RetOpcode == X86::EH_RETURN || RetOpcode == X86::EH_RETURN64) { 10374f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MBBI = MBB.getLastNonDebugInstr(); 103833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineOperand &DestAddr = MBBI->getOperand(0); 103933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(DestAddr.isReg() && "Offset should be in register!"); 104033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, 104133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr), 104233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov StackPtr).addReg(DestAddr.getReg()); 104333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (RetOpcode == X86::TCRETURNri || RetOpcode == X86::TCRETURNdi || 104433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RetOpcode == X86::TCRETURNmi || 104533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RetOpcode == X86::TCRETURNri64 || RetOpcode == X86::TCRETURNdi64 || 104633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RetOpcode == X86::TCRETURNmi64) { 104733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool isMem = RetOpcode == X86::TCRETURNmi || RetOpcode == X86::TCRETURNmi64; 104833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Tail call return: adjust the stack pointer and jump to callee. 1049f7ca976e74eafeeab0e9097f0fb07d6bb447415bJakob Stoklund Olesen MBBI = MBB.getLastNonDebugInstr(); 105033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineOperand &JumpTarget = MBBI->getOperand(0); 105133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineOperand &StackAdjust = MBBI->getOperand(isMem ? 5 : 1); 105233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(StackAdjust.isImm() && "Expecting immediate value."); 105333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 105433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Adjust stack pointer. 105533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int StackAdj = StackAdjust.getImm(); 105633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int MaxTCDelta = X86FI->getTCReturnAddrDelta(); 105733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int Offset = 0; 105833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(MaxTCDelta <= 0 && "MaxTCDelta should never be positive"); 105933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 106033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Incoporate the retaddr area. 106133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Offset = StackAdj-MaxTCDelta; 106233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(Offset >= 0 && "Offset should never be negative"); 106333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 106433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (Offset) { 10657a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // Check for possible merge with preceding ADD instruction. 106633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Offset += mergeSPUpdates(MBB, MBBI, StackPtr, true); 10677158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng emitSPUpdate(MBB, MBBI, StackPtr, Offset, Is64Bit, TII, *RegInfo); 106833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 106933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 107033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Jump to label or value in register. 107133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (RetOpcode == X86::TCRETURNdi || RetOpcode == X86::TCRETURNdi64) { 10723d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng MachineInstrBuilder MIB = 10733d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng BuildMI(MBB, MBBI, DL, TII.get((RetOpcode == X86::TCRETURNdi) 10743d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng ? X86::TAILJMPd : X86::TAILJMPd64)); 10753d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng if (JumpTarget.isGlobal()) 10763d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng MIB.addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset(), 10773d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng JumpTarget.getTargetFlags()); 10783d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng else { 10793d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng assert(JumpTarget.isSymbol()); 10803d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng MIB.addExternalSymbol(JumpTarget.getSymbolName(), 10813d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng JumpTarget.getTargetFlags()); 10823d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng } 108333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (RetOpcode == X86::TCRETURNmi || RetOpcode == X86::TCRETURNmi64) { 108433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineInstrBuilder MIB = 108533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get((RetOpcode == X86::TCRETURNmi) 108633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov ? X86::TAILJMPm : X86::TAILJMPm64)); 108733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (unsigned i = 0; i != 5; ++i) 108833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MIB.addOperand(MBBI->getOperand(i)); 108933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (RetOpcode == X86::TCRETURNri64) { 109033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(X86::TAILJMPr64)). 109133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov addReg(JumpTarget.getReg(), RegState::Kill); 109233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 109333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(X86::TAILJMPr)). 109433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov addReg(JumpTarget.getReg(), RegState::Kill); 109533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 109633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 109733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineInstr *NewMI = prior(MBBI); 109833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (unsigned i = 2, e = MBBI->getNumOperands(); i != e; ++i) 109933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov NewMI->addOperand(MBBI->getOperand(i)); 110033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 110133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Delete the pseudo instruction TCRETURN. 110233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBB.erase(MBBI); 110333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if ((RetOpcode == X86::RET || RetOpcode == X86::RETI) && 110433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov (X86FI->getTCReturnAddrDelta() < 0)) { 110533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Add the return addr area delta back since we are not tail calling. 110633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int delta = -1*X86FI->getTCReturnAddrDelta(); 11074f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MBBI = MBB.getLastNonDebugInstr(); 110833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 11097a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // Check for possible merge with preceding ADD instruction. 111033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov delta += mergeSPUpdates(MBB, MBBI, StackPtr, true); 11117158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng emitSPUpdate(MBB, MBBI, StackPtr, delta, Is64Bit, TII, *RegInfo); 111233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 111333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 1114d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov 111516c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovint X86FrameLowering::getFrameIndexOffset(const MachineFunction &MF, int FI) const { 111682f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov const X86RegisterInfo *RI = 111782f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov static_cast<const X86RegisterInfo*>(MF.getTarget().getRegisterInfo()); 111882f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov const MachineFrameInfo *MFI = MF.getFrameInfo(); 111982f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov int Offset = MFI->getObjectOffset(FI) - getOffsetOfLocalArea(); 112082f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov uint64_t StackSize = MFI->getStackSize(); 112182f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov 112282f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov if (RI->needsStackRealignment(MF)) { 112382f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov if (FI < 0) { 112482f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov // Skip the saved EBP. 112582f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov Offset += RI->getSlotSize(); 112682f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov } else { 112717001ce25cc205ac1cd2604492c2bce310964220Duncan Sands assert((-(Offset + StackSize)) % MFI->getObjectAlignment(FI) == 0); 112882f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov return Offset + StackSize; 112982f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov } 113082f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov // FIXME: Support tail calls 113182f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov } else { 113282f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov if (!hasFP(MF)) 113382f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov return Offset + StackSize; 113482f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov 113582f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov // Skip the saved EBP. 113682f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov Offset += RI->getSlotSize(); 113782f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov 113882f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov // Skip the RETADDR move area 113982f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov const X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>(); 114082f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov int TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta(); 114182f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov if (TailCallReturnAddrDelta < 0) 114282f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov Offset -= TailCallReturnAddrDelta; 114382f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov } 114482f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov 114582f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov return Offset; 114682f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov} 1147cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 114816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovbool X86FrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB, 1149cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov MachineBasicBlock::iterator MI, 1150cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov const std::vector<CalleeSavedInfo> &CSI, 1151cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov const TargetRegisterInfo *TRI) const { 1152cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov if (CSI.empty()) 1153cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov return false; 1154cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 1155cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov DebugLoc DL = MBB.findDebugLoc(MI); 1156cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 1157cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov MachineFunction &MF = *MBB.getParent(); 1158cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 1159cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov unsigned SlotSize = STI.is64Bit() ? 8 : 4; 1160cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov unsigned FPReg = TRI->getFrameRegister(MF); 1161cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov unsigned CalleeFrameSize = 0; 1162cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 1163cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 1164cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>(); 1165cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 1166419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi // Push GPRs. It increases frame size. 1167cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov unsigned Opc = STI.is64Bit() ? X86::PUSH64r : X86::PUSH32r; 1168cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov for (unsigned i = CSI.size(); i != 0; --i) { 1169cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov unsigned Reg = CSI[i-1].getReg(); 1170419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi if (!X86::GR64RegClass.contains(Reg) && 1171419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi !X86::GR32RegClass.contains(Reg)) 1172419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi continue; 1173cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov // Add the callee-saved register as live-in. It's killed at the spill. 1174cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov MBB.addLiveIn(Reg); 1175cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov if (Reg == FPReg) 1176cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov // X86RegisterInfo::emitPrologue will handle spilling of frame register. 1177cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov continue; 1178419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi CalleeFrameSize += SlotSize; 1179aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis BuildMI(MBB, MI, DL, TII.get(Opc)).addReg(Reg, RegState::Kill) 1180aff232a5941c9ffb7ad52e08f81ad53794fed56bCharles Davis .setMIFlag(MachineInstr::FrameSetup); 1181cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov } 1182cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 1183cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov X86FI->setCalleeSavedFrameSize(CalleeFrameSize); 1184419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi 1185419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi // Make XMM regs spilled. X86 does not have ability of push/pop XMM. 1186419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi // It can be done by spilling XMMs to stack frame. 1187419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi // Note that only Win64 ABI might spill XMMs. 1188419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi for (unsigned i = CSI.size(); i != 0; --i) { 1189419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi unsigned Reg = CSI[i-1].getReg(); 1190419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi if (X86::GR64RegClass.contains(Reg) || 1191419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi X86::GR32RegClass.contains(Reg)) 1192419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi continue; 1193419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi // Add the callee-saved register as live-in. It's killed at the spill. 1194419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi MBB.addLiveIn(Reg); 1195419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 1196419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi TII.storeRegToStackSlot(MBB, MI, Reg, true, CSI[i-1].getFrameIdx(), 1197419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi RC, TRI); 1198419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi } 1199419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi 1200cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov return true; 1201cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov} 1202cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 120316c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovbool X86FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 1204cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov MachineBasicBlock::iterator MI, 1205cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov const std::vector<CalleeSavedInfo> &CSI, 1206cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov const TargetRegisterInfo *TRI) const { 1207cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov if (CSI.empty()) 1208cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov return false; 1209cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 1210cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov DebugLoc DL = MBB.findDebugLoc(MI); 1211cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 1212cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov MachineFunction &MF = *MBB.getParent(); 1213cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 1214419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi 1215419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi // Reload XMMs from stack frame. 1216419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 1217419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi unsigned Reg = CSI[i].getReg(); 1218419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi if (X86::GR64RegClass.contains(Reg) || 1219419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi X86::GR32RegClass.contains(Reg)) 1220419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi continue; 1221419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 1222419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi TII.loadRegFromStackSlot(MBB, MI, Reg, CSI[i].getFrameIdx(), 1223419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi RC, TRI); 1224419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi } 1225419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi 1226419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi // POP GPRs. 1227cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov unsigned FPReg = TRI->getFrameRegister(MF); 1228cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov unsigned Opc = STI.is64Bit() ? X86::POP64r : X86::POP32r; 1229cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 1230cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov unsigned Reg = CSI[i].getReg(); 1231419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi if (!X86::GR64RegClass.contains(Reg) && 1232419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi !X86::GR32RegClass.contains(Reg)) 1233419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi continue; 1234cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov if (Reg == FPReg) 1235cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov // X86RegisterInfo::emitEpilogue will handle restoring of frame register. 1236cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov continue; 1237419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi BuildMI(MBB, MI, DL, TII.get(Opc), Reg); 1238cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov } 1239cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov return true; 1240cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov} 124194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 124294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikovvoid 124316c29b5f285f375be53dabaa73e3e91107485fe4Anton KorobeynikovX86FrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, 124494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov RegScavenger *RS) const { 124594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 124694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov const X86RegisterInfo *RegInfo = TM.getRegisterInfo(); 124794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned SlotSize = RegInfo->getSlotSize(); 124894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 124994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>(); 125094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int32_t TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta(); 125194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 125294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (TailCallReturnAddrDelta < 0) { 125394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // create RETURNADDR area 125494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // arg 125594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // arg 125694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // RETADDR 125794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // { ... 125894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // RETADDR area 125994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // ... 126094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // } 126194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // [EBP] 126294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MFI->CreateFixedObject(-TailCallReturnAddrDelta, 126394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov (-1U*SlotSize)+TailCallReturnAddrDelta, true); 126494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 126594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 126694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (hasFP(MF)) { 126794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov assert((TailCallReturnAddrDelta <= 0) && 126894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov "The Delta should always be zero or negative"); 126916c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering &TFI = *MF.getTarget().getFrameLowering(); 127094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 127194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Create a frame entry for the EBP register that must be saved. 127294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int FrameIdx = MFI->CreateFixedObject(SlotSize, 127394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov -(int)SlotSize + 127494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov TFI.getOffsetOfLocalArea() + 127594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov TailCallReturnAddrDelta, 127694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov true); 127794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov assert(FrameIdx == MFI->getObjectIndexBegin() && 127894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov "Slot for EBP register must be last in order to be found!"); 127917001ce25cc205ac1cd2604492c2bce310964220Duncan Sands (void)FrameIdx; 128094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 128194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov} 128276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 128376927d758657b3a511c73467ec5a7288795c1513Rafael Espindolastatic bool 128476927d758657b3a511c73467ec5a7288795c1513Rafael EspindolaHasNestArgument(const MachineFunction *MF) { 128576927d758657b3a511c73467ec5a7288795c1513Rafael Espindola const Function *F = MF->getFunction(); 128676927d758657b3a511c73467ec5a7288795c1513Rafael Espindola for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end(); 128776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola I != E; I++) { 128876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola if (I->hasNestAttr()) 128976927d758657b3a511c73467ec5a7288795c1513Rafael Espindola return true; 129076927d758657b3a511c73467ec5a7288795c1513Rafael Espindola } 129176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola return false; 129276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola} 129376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 129476927d758657b3a511c73467ec5a7288795c1513Rafael Espindolastatic unsigned 129576927d758657b3a511c73467ec5a7288795c1513Rafael EspindolaGetScratchRegister(bool Is64Bit, const MachineFunction &MF) { 129676927d758657b3a511c73467ec5a7288795c1513Rafael Espindola if (Is64Bit) { 129776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola return X86::R11; 129876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola } else { 129976927d758657b3a511c73467ec5a7288795c1513Rafael Espindola CallingConv::ID CallingConvention = MF.getFunction()->getCallingConv(); 130076927d758657b3a511c73467ec5a7288795c1513Rafael Espindola bool IsNested = HasNestArgument(&MF); 130176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 130276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola if (CallingConvention == CallingConv::X86_FastCall) { 130376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola if (IsNested) { 1304e81abfd30b7c81735e9f3d79006c2653690aa592Rafael Espindola report_fatal_error("Segmented stacks does not support fastcall with " 1305e81abfd30b7c81735e9f3d79006c2653690aa592Rafael Espindola "nested function."); 130676927d758657b3a511c73467ec5a7288795c1513Rafael Espindola return -1; 130776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola } else { 130876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola return X86::EAX; 130976927d758657b3a511c73467ec5a7288795c1513Rafael Espindola } 131076927d758657b3a511c73467ec5a7288795c1513Rafael Espindola } else { 131176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola if (IsNested) 131276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola return X86::EDX; 131376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola else 131476927d758657b3a511c73467ec5a7288795c1513Rafael Espindola return X86::ECX; 131576927d758657b3a511c73467ec5a7288795c1513Rafael Espindola } 131676927d758657b3a511c73467ec5a7288795c1513Rafael Espindola } 131776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola} 131876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 1319199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das// The stack limit in the TCB is set to this many bytes above the actual stack 1320199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das// limit. 1321199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Dasstatic const uint64_t kSplitStackAvailable = 256; 1322199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das 132376927d758657b3a511c73467ec5a7288795c1513Rafael Espindolavoid 132476927d758657b3a511c73467ec5a7288795c1513Rafael EspindolaX86FrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const { 132576927d758657b3a511c73467ec5a7288795c1513Rafael Espindola MachineBasicBlock &prologueMBB = MF.front(); 132676927d758657b3a511c73467ec5a7288795c1513Rafael Espindola MachineFrameInfo *MFI = MF.getFrameInfo(); 132776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola const X86InstrInfo &TII = *TM.getInstrInfo(); 132876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola uint64_t StackSize; 132976927d758657b3a511c73467ec5a7288795c1513Rafael Espindola bool Is64Bit = STI.is64Bit(); 133076927d758657b3a511c73467ec5a7288795c1513Rafael Espindola unsigned TlsReg, TlsOffset; 133176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola DebugLoc DL; 133276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola const X86Subtarget *ST = &MF.getTarget().getSubtarget<X86Subtarget>(); 133376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 133476927d758657b3a511c73467ec5a7288795c1513Rafael Espindola unsigned ScratchReg = GetScratchRegister(Is64Bit, MF); 133576927d758657b3a511c73467ec5a7288795c1513Rafael Espindola assert(!MF.getRegInfo().isLiveIn(ScratchReg) && 133676927d758657b3a511c73467ec5a7288795c1513Rafael Espindola "Scratch register is live-in"); 133776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 133876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola if (MF.getFunction()->isVarArg()) 133976927d758657b3a511c73467ec5a7288795c1513Rafael Espindola report_fatal_error("Segmented stacks do not support vararg functions."); 134076927d758657b3a511c73467ec5a7288795c1513Rafael Espindola if (!ST->isTargetLinux()) 134176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola report_fatal_error("Segmented stacks supported only on linux."); 134276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 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 136776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // Eventually StackSize will be calculated by a link-time pass; which will 136876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // also decide whether checking code needs to be injected into this particular 136976927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // prologue. 137076927d758657b3a511c73467ec5a7288795c1513Rafael Espindola StackSize = MFI->getStackSize(); 137176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 137276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // Read the limit off the current stacklet off the stack_guard location. 137376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola if (Is64Bit) { 137476927d758657b3a511c73467ec5a7288795c1513Rafael Espindola TlsReg = X86::FS; 137576927d758657b3a511c73467ec5a7288795c1513Rafael Espindola TlsOffset = 0x70; 137676927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 1377199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das if (StackSize < kSplitStackAvailable) 1378199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das ScratchReg = X86::RSP; 1379199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das else 1380199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das BuildMI(checkMBB, DL, TII.get(X86::LEA64r), ScratchReg).addReg(X86::RSP) 1381199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das .addImm(0).addReg(0).addImm(-StackSize).addReg(0); 1382199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das 138376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola BuildMI(checkMBB, DL, TII.get(X86::CMP64rm)).addReg(ScratchReg) 138476927d758657b3a511c73467ec5a7288795c1513Rafael Espindola .addReg(0).addImm(0).addReg(0).addImm(TlsOffset).addReg(TlsReg); 138576927d758657b3a511c73467ec5a7288795c1513Rafael Espindola } else { 138676927d758657b3a511c73467ec5a7288795c1513Rafael Espindola TlsReg = X86::GS; 138776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola TlsOffset = 0x30; 138876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 1389199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das if (StackSize < kSplitStackAvailable) 1390199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das ScratchReg = X86::ESP; 1391199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das else 1392199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das BuildMI(checkMBB, DL, TII.get(X86::LEA32r), ScratchReg).addReg(X86::ESP) 1393199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das .addImm(0).addReg(0).addImm(-StackSize).addReg(0); 1394199ce33b3bfa0b6293946c1b835da2a1fbc8cab4Sanjoy Das 139576927d758657b3a511c73467ec5a7288795c1513Rafael Espindola BuildMI(checkMBB, DL, TII.get(X86::CMP32rm)).addReg(ScratchReg) 139676927d758657b3a511c73467ec5a7288795c1513Rafael Espindola .addReg(0).addImm(0).addReg(0).addImm(TlsOffset).addReg(TlsReg); 139776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola } 139876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 139976927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // This jump is taken if SP >= (Stacklet Limit + Stack Space required). 140076927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // It jumps to normal execution of the function body. 140176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola BuildMI(checkMBB, DL, TII.get(X86::JG_4)).addMBB(&prologueMBB); 140276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 140376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // On 32 bit we first push the arguments size and then the frame size. On 64 140476927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // bit, we pass the stack frame size in r10 and the argument size in r11. 140576927d758657b3a511c73467ec5a7288795c1513Rafael Espindola if (Is64Bit) { 140676927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // Functions with nested arguments use R10, so it needs to be saved across 140776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // the call to _morestack 140876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 140976927d758657b3a511c73467ec5a7288795c1513Rafael Espindola if (IsNested) 141076927d758657b3a511c73467ec5a7288795c1513Rafael Espindola BuildMI(allocMBB, DL, TII.get(X86::MOV64rr), X86::RAX).addReg(X86::R10); 141176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 141276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola BuildMI(allocMBB, DL, TII.get(X86::MOV64ri), X86::R10) 141376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola .addImm(StackSize); 141476927d758657b3a511c73467ec5a7288795c1513Rafael Espindola BuildMI(allocMBB, DL, TII.get(X86::MOV64ri), X86::R11) 141576927d758657b3a511c73467ec5a7288795c1513Rafael Espindola .addImm(X86FI->getArgumentStackSize()); 141676927d758657b3a511c73467ec5a7288795c1513Rafael Espindola MF.getRegInfo().setPhysRegUsed(X86::R10); 141776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola MF.getRegInfo().setPhysRegUsed(X86::R11); 141876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola } else { 141976927d758657b3a511c73467ec5a7288795c1513Rafael Espindola BuildMI(allocMBB, DL, TII.get(X86::PUSHi32)) 142076927d758657b3a511c73467ec5a7288795c1513Rafael Espindola .addImm(X86FI->getArgumentStackSize()); 142176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola BuildMI(allocMBB, DL, TII.get(X86::PUSHi32)) 142276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola .addImm(StackSize); 142376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola } 142476927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 142576927d758657b3a511c73467ec5a7288795c1513Rafael Espindola // __morestack is in libgcc 142676927d758657b3a511c73467ec5a7288795c1513Rafael Espindola if (Is64Bit) 142776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola BuildMI(allocMBB, DL, TII.get(X86::CALL64pcrel32)) 142876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola .addExternalSymbol("__morestack"); 142976927d758657b3a511c73467ec5a7288795c1513Rafael Espindola else 143076927d758657b3a511c73467ec5a7288795c1513Rafael Espindola BuildMI(allocMBB, DL, TII.get(X86::CALLpcrel32)) 143176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola .addExternalSymbol("__morestack"); 143276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 14334e68054b20725f6ec1cac33630258f749fe5debeBill Wendling if (IsNested) 1434e840e88239cf92a065cbf5f5b9c7d18bc139c0e1Rafael Espindola BuildMI(allocMBB, DL, TII.get(X86::MORESTACK_RET_RESTORE_R10)); 1435e840e88239cf92a065cbf5f5b9c7d18bc139c0e1Rafael Espindola else 1436e840e88239cf92a065cbf5f5b9c7d18bc139c0e1Rafael Espindola BuildMI(allocMBB, DL, TII.get(X86::MORESTACK_RET)); 143776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 1438e840e88239cf92a065cbf5f5b9c7d18bc139c0e1Rafael Espindola allocMBB->addSuccessor(&prologueMBB); 143982222c20be24adda7c218f3fdaf2e0ae049c955bBill Wendling 144076927d758657b3a511c73467ec5a7288795c1513Rafael Espindola checkMBB->addSuccessor(allocMBB); 144176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola checkMBB->addSuccessor(&prologueMBB); 144276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 144351f0c7641983469cbd29f8862a121645471a885aJakob Stoklund Olesen#ifdef XDEBUG 144476927d758657b3a511c73467ec5a7288795c1513Rafael Espindola MF.verify(); 144576927d758657b3a511c73467ec5a7288795c1513Rafael Espindola#endif 144676927d758657b3a511c73467ec5a7288795c1513Rafael Espindola} 1447