X86FrameLowering.cpp revision fc2bb8c4448fa884d79e437cc2d2627a7d7740a8
116c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov//=======- 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" 18d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov#include "X86TargetMachine.h" 1933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/Function.h" 2033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineFrameInfo.h" 2133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineFunction.h" 2233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineInstrBuilder.h" 2333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineModuleInfo.h" 2433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineRegisterInfo.h" 25f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola#include "llvm/MC/MCAsmInfo.h" 2633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/Target/TargetData.h" 2733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/Target/TargetOptions.h" 2833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/Support/CommandLine.h" 297158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng#include "llvm/ADT/SmallSet.h" 3033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 3133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovusing namespace llvm; 3233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 3333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// FIXME: completely move here. 3433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovextern cl::opt<bool> ForceStackAlign; 3533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 3616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovbool X86FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 37d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov return !MF.getFrameInfo()->hasVarSizedObjects(); 38d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov} 39d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 40d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov/// hasFP - Return true if the specified function should have a dedicated frame 41d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov/// pointer register. This is true if the function has variable sized allocas 42d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov/// or if frame pointer elimination is disabled. 4316c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovbool X86FrameLowering::hasFP(const MachineFunction &MF) const { 44d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov const MachineFrameInfo *MFI = MF.getFrameInfo(); 45d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov const MachineModuleInfo &MMI = MF.getMMI(); 46d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov const TargetRegisterInfo *RI = TM.getRegisterInfo(); 47d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 48d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov return (DisableFramePointerElim(MF) || 49d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov RI->needsStackRealignment(MF) || 50d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov MFI->hasVarSizedObjects() || 51d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov MFI->isFrameAddressTaken() || 52d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov MF.getInfo<X86MachineFunctionInfo>()->getForceFramePointer() || 53d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov MMI.callsUnwindInit()); 54d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov} 55d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 5633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovstatic unsigned getSUBriOpcode(unsigned is64Bit, int64_t Imm) { 5733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (is64Bit) { 5833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (isInt<8>(Imm)) 5933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::SUB64ri8; 6033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::SUB64ri32; 6133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 6233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (isInt<8>(Imm)) 6333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::SUB32ri8; 6433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::SUB32ri; 6533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 6633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 6733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 6833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovstatic unsigned getADDriOpcode(unsigned is64Bit, int64_t Imm) { 6933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (is64Bit) { 7033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (isInt<8>(Imm)) 7133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::ADD64ri8; 7233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::ADD64ri32; 7333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 7433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (isInt<8>(Imm)) 7533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::ADD32ri8; 7633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return X86::ADD32ri; 7733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 7833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 7933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 807158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng/// findDeadCallerSavedReg - Return a caller-saved register that isn't live 817158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng/// when it reaches the "return" instruction. We can then pop a stack object 827158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng/// to this register without worry about clobbering it. 837158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Chengstatic unsigned findDeadCallerSavedReg(MachineBasicBlock &MBB, 847158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng MachineBasicBlock::iterator &MBBI, 857158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng const TargetRegisterInfo &TRI, 867158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng bool Is64Bit) { 877158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng const MachineFunction *MF = MBB.getParent(); 887158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng const Function *F = MF->getFunction(); 897158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng if (!F || MF->getMMI().callsEHReturn()) 907158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng return 0; 917158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 927158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng static const unsigned CallerSavedRegs32Bit[] = { 937158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng X86::EAX, X86::EDX, X86::ECX 947158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng }; 957158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 967158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng static const unsigned CallerSavedRegs64Bit[] = { 977158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng X86::RAX, X86::RDX, X86::RCX, X86::RSI, X86::RDI, 987158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng X86::R8, X86::R9, X86::R10, X86::R11 997158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng }; 1007158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 1017158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng unsigned Opc = MBBI->getOpcode(); 1027158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng switch (Opc) { 1037158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng default: return 0; 1047158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::RET: 1057158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::RETI: 1067158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::TCRETURNdi: 1077158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::TCRETURNri: 1087158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::TCRETURNmi: 1097158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::TCRETURNdi64: 1107158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::TCRETURNri64: 1117158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::TCRETURNmi64: 1127158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::EH_RETURN: 1137158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng case X86::EH_RETURN64: { 1147158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng SmallSet<unsigned, 8> Uses; 1157158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng for (unsigned i = 0, e = MBBI->getNumOperands(); i != e; ++i) { 1167158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng MachineOperand &MO = MBBI->getOperand(i); 1177158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng if (!MO.isReg() || MO.isDef()) 1187158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng continue; 1197158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng unsigned Reg = MO.getReg(); 1207158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng if (!Reg) 1217158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng continue; 1227158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng for (const unsigned *AsI = TRI.getOverlaps(Reg); *AsI; ++AsI) 1237158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng Uses.insert(*AsI); 1247158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng } 1257158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 1267158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng const unsigned *CS = Is64Bit ? CallerSavedRegs64Bit : CallerSavedRegs32Bit; 1277158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng for (; *CS; ++CS) 1287158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng if (!Uses.count(*CS)) 1297158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng return *CS; 1307158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng } 1317158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng } 1327158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 1337158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng return 0; 1347158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng} 1357158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 1367158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 13733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// emitSPUpdate - Emit a series of instructions to increment / decrement the 13833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// stack pointer by a constant value. 13933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovstatic 14033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovvoid emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, 1417158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng unsigned StackPtr, int64_t NumBytes, 1427158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng bool Is64Bit, const TargetInstrInfo &TII, 1437158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng const TargetRegisterInfo &TRI) { 14433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool isSub = NumBytes < 0; 14533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t Offset = isSub ? -NumBytes : NumBytes; 14633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Opc = isSub ? 14733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov getSUBriOpcode(Is64Bit, Offset) : 14833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov getADDriOpcode(Is64Bit, Offset); 14933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t Chunk = (1LL << 31) - 1; 15033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DebugLoc DL = MBB.findDebugLoc(MBBI); 15133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 15233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov while (Offset) { 15333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t ThisVal = (Offset > Chunk) ? Chunk : Offset; 1547158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng if (ThisVal == (Is64Bit ? 8 : 4)) { 1557158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng // Use push / pop instead. 1567158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng unsigned Reg = isSub 1571e08cd1eaef8acbcfaf7db48d859a29583c29897Dale Johannesen ? (unsigned)(Is64Bit ? X86::RAX : X86::EAX) 1587158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng : findDeadCallerSavedReg(MBB, MBBI, TRI, Is64Bit); 1597158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng if (Reg) { 1607158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng Opc = isSub 1617158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng ? (Is64Bit ? X86::PUSH64r : X86::PUSH32r) 1627158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng : (Is64Bit ? X86::POP64r : X86::POP32r); 1637158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng BuildMI(MBB, MBBI, DL, TII.get(Opc)) 1647158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng .addReg(Reg, getDefRegState(!isSub) | getUndefRegState(isSub)); 1657158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng Offset -= ThisVal; 1667158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng continue; 1677158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng } 1687158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng } 1697158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng 17033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineInstr *MI = 17133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr) 1727158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng .addReg(StackPtr) 1737158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng .addImm(ThisVal); 17433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MI->getOperand(3).setIsDead(); // The EFLAGS implicit def is dead. 17533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Offset -= ThisVal; 17633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 17733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 17833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 17933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// mergeSPUpdatesUp - Merge two stack-manipulating instructions upper iterator. 18033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovstatic 18133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovvoid mergeSPUpdatesUp(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, 18233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackPtr, uint64_t *NumBytes = NULL) { 18333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MBBI == MBB.begin()) return; 18433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 18533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator PI = prior(MBBI); 18633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Opc = PI->getOpcode(); 18733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 || 18833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Opc == X86::ADD32ri || Opc == X86::ADD32ri8) && 18933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PI->getOperand(0).getReg() == StackPtr) { 19033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (NumBytes) 19133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *NumBytes += PI->getOperand(2).getImm(); 19233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBB.erase(PI); 19333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 || 19433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Opc == X86::SUB32ri || Opc == X86::SUB32ri8) && 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 } 20033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 20133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 20233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// mergeSPUpdatesDown - Merge two stack-manipulating instructions lower iterator. 20333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovstatic 20433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovvoid mergeSPUpdatesDown(MachineBasicBlock &MBB, 20533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator &MBBI, 20633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackPtr, uint64_t *NumBytes = NULL) { 20733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // FIXME: THIS ISN'T RUN!!! 20833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return; 20933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 21033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MBBI == MBB.end()) return; 21133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 21233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator NI = llvm::next(MBBI); 21333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (NI == MBB.end()) return; 21433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 21533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Opc = NI->getOpcode(); 21633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 || 21733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Opc == X86::ADD32ri || Opc == X86::ADD32ri8) && 21833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov NI->getOperand(0).getReg() == StackPtr) { 21933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (NumBytes) 22033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *NumBytes -= NI->getOperand(2).getImm(); 22133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBB.erase(NI); 22233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBBI = NI; 22333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 || 22433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Opc == X86::SUB32ri || Opc == X86::SUB32ri8) && 22533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov NI->getOperand(0).getReg() == StackPtr) { 22633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (NumBytes) 22733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *NumBytes += NI->getOperand(2).getImm(); 22833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBB.erase(NI); 22933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBBI = NI; 23033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 23133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 23233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 23333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// mergeSPUpdates - Checks the instruction before/after the passed 23433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// instruction. If it is an ADD/SUB instruction it is deleted argument and the 23533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// stack adjustment is returned as a positive value for ADD and a negative for 23633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// SUB. 23733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovstatic int mergeSPUpdates(MachineBasicBlock &MBB, 23833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator &MBBI, 23933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackPtr, 24033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool doMergeWithPrevious) { 24133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if ((doMergeWithPrevious && MBBI == MBB.begin()) || 24233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov (!doMergeWithPrevious && MBBI == MBB.end())) 24333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return 0; 24433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 24533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator PI = doMergeWithPrevious ? prior(MBBI) : MBBI; 24633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator NI = doMergeWithPrevious ? 0 : llvm::next(MBBI); 24733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Opc = PI->getOpcode(); 24833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int Offset = 0; 24933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 25033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 || 25133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Opc == X86::ADD32ri || Opc == X86::ADD32ri8) && 25233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PI->getOperand(0).getReg() == StackPtr){ 25333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Offset += PI->getOperand(2).getImm(); 25433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBB.erase(PI); 25533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!doMergeWithPrevious) MBBI = NI; 25633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 || 25733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Opc == X86::SUB32ri || Opc == X86::SUB32ri8) && 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 } 26333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 26433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return Offset; 26533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 26633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 26733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovstatic bool isEAXLiveIn(MachineFunction &MF) { 26833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (MachineRegisterInfo::livein_iterator II = MF.getRegInfo().livein_begin(), 26933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov EE = MF.getRegInfo().livein_end(); II != EE; ++II) { 27033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Reg = II->first; 27133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 27233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (Reg == X86::EAX || Reg == X86::AX || 27333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Reg == X86::AH || Reg == X86::AL) 27433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return true; 27533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 27633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 27733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov return false; 27833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 27933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 28016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid X86FrameLowering::emitCalleeSavedFrameMoves(MachineFunction &MF, 28133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MCSymbol *Label, 28233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned FramePtr) const { 28333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 28433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineModuleInfo &MMI = MF.getMMI(); 28533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 28633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Add callee saved registers to move list. 28733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 28833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (CSI.empty()) return; 28933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 29033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov std::vector<MachineMove> &Moves = MMI.getFrameMoves(); 291d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov const TargetData *TD = TM.getTargetData(); 292d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov bool HasFP = hasFP(MF); 29333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 29433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Calculate amount of bytes used for return address storing. 295e749911372c75e4e68f83a32b4092f4ffb0d2793Anton Korobeynikov int stackGrowth = -TD->getPointerSize(); 29633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 29733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // FIXME: This is dirty hack. The code itself is pretty mess right now. 29833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // It should be rewritten from scratch and generalized sometimes. 29933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 3007a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // Determine maximum offset (minimum due to stack growth). 30133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int64_t MaxOffset = 0; 30233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (std::vector<CalleeSavedInfo>::const_iterator 30333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov I = CSI.begin(), E = CSI.end(); I != E; ++I) 30433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MaxOffset = std::min(MaxOffset, 30533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MFI->getObjectOffset(I->getFrameIdx())); 30633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 30733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Calculate offsets. 30833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int64_t saveAreaOffset = (HasFP ? 3 : 2) * stackGrowth; 30933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (std::vector<CalleeSavedInfo>::const_iterator 31033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov I = CSI.begin(), E = CSI.end(); I != E; ++I) { 31133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int64_t Offset = MFI->getObjectOffset(I->getFrameIdx()); 31233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Reg = I->getReg(); 31333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Offset = MaxOffset - Offset + saveAreaOffset; 31433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 31533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Don't output a new machine move if we're re-saving the frame 31633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // pointer. This happens when the PrologEpilogInserter has inserted an extra 31733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // "PUSH" of the frame pointer -- the "emitPrologue" method automatically 31833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // generates one when frame pointers are used. If we generate a "machine 31933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // move" for this extra "PUSH", the linker will lose track of the fact that 32033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // the frame pointer should have the value of the first "PUSH" when it's 32133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // trying to unwind. 3222763538609fd455d63c192b320c73fb5d48c3e47NAKAMURA Takumi // 32333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // FIXME: This looks inelegant. It's possibly correct, but it's covering up 32433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // another bug. I.e., one where we generate a prolog like this: 32533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // 32633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // pushl %ebp 32733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // movl %esp, %ebp 32833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // pushl %ebp 32933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // pushl %esi 33033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // ... 33133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // 33233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // The immediate re-push of EBP is unnecessary. At the least, it's an 33333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // optimization bug. EBP can be used as a scratch register in certain 33433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // cases, but probably not when we have a frame pointer. 33533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP && FramePtr == Reg) 33633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov continue; 33733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 33833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation CSDst(MachineLocation::VirtualFP, Offset); 33933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation CSSrc(Reg); 34033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(Label, CSDst, CSSrc)); 34133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 34233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 34333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 34433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// emitPrologue - Push callee-saved registers onto the stack, which 34533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// automatically adjust the stack pointer. Adjust the stack pointer to allocate 34633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// space for local variables. Also emit labels used by the exception handler to 34733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov/// generate the exception handling frames. 34816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid X86FrameLowering::emitPrologue(MachineFunction &MF) const { 34933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock &MBB = MF.front(); // Prologue goes in entry BB. 35033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator MBBI = MBB.begin(); 35133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 35233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const Function *Fn = MF.getFunction(); 353d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov const X86RegisterInfo *RegInfo = TM.getRegisterInfo(); 354d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov const X86InstrInfo &TII = *TM.getInstrInfo(); 35533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineModuleInfo &MMI = MF.getMMI(); 35633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>(); 35733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool needsFrameMoves = MMI.hasDebugInfo() || 358fc2bb8c4448fa884d79e437cc2d2627a7d7740a8Rafael Espindola Fn->needsUnwindTableEntry(); 35933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t MaxAlign = MFI->getMaxAlignment(); // Desired stack alignment. 36033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t StackSize = MFI->getStackSize(); // Number of bytes to allocate. 361d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov bool HasFP = hasFP(MF); 36233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool Is64Bit = STI.is64Bit(); 36333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool IsWin64 = STI.isTargetWin64(); 36433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackAlign = getStackAlignment(); 36533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned SlotSize = RegInfo->getSlotSize(); 36633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned FramePtr = RegInfo->getFrameRegister(MF); 36733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackPtr = RegInfo->getStackRegister(); 36833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 36933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DebugLoc DL; 37033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 37133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If we're forcing a stack realignment we can't rely on just the frame 37233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // info, we need to know the ABI stack alignment as well in case we 37333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // have a call out. Otherwise just make sure we have some alignment - we'll 37433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // go with the minimum SlotSize. 37533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (ForceStackAlign) { 37633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MFI->hasCalls()) 37733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MaxAlign = (StackAlign > MaxAlign) ? StackAlign : MaxAlign; 37833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov else if (MaxAlign < SlotSize) 37933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MaxAlign = SlotSize; 38033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 38133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 38233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Add RETADDR move area to callee saved frame size. 38333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta(); 38433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (TailCallReturnAddrDelta < 0) 38533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov X86FI->setCalleeSavedFrameSize( 38633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov X86FI->getCalleeSavedFrameSize() - TailCallReturnAddrDelta); 38733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 38833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If this is x86-64 and the Red Zone is not disabled, if we are a leaf 38933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // function, and use up to 128 bytes of stack space, don't have a frame 39033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // pointer, calls, or dynamic alloca then we do not need to adjust the 39133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // stack pointer (we fit in the Red Zone). 39233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (Is64Bit && !Fn->hasFnAttr(Attribute::NoRedZone) && 39333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov !RegInfo->needsStackRealignment(MF) && 39433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov !MFI->hasVarSizedObjects() && // No dynamic alloca. 39533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov !MFI->adjustsStack() && // No calls. 39633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov !IsWin64) { // Win64 has no Red Zone 39733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t MinSize = X86FI->getCalleeSavedFrameSize(); 39833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) MinSize += SlotSize; 39933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov StackSize = std::max(MinSize, StackSize > 128 ? StackSize - 128 : 0); 40033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MFI->setStackSize(StackSize); 40133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 40233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 40333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Insert stack pointer adjustment for later moving of return addr. Only 40433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // applies to tail call optimized functions where the callee argument stack 40533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // size is bigger than the callers. 40633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (TailCallReturnAddrDelta < 0) { 40733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineInstr *MI = 40833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, 40933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov TII.get(getSUBriOpcode(Is64Bit, -TailCallReturnAddrDelta)), 41033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov StackPtr) 41133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(StackPtr) 41233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addImm(-TailCallReturnAddrDelta); 41333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MI->getOperand(3).setIsDead(); // The EFLAGS implicit def is dead. 41433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 41533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 41633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Mapping for machine moves: 41733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // 41833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // DST: VirtualFP AND 41933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // SRC: VirtualFP => DW_CFA_def_cfa_offset 42033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // ELSE => DW_CFA_def_cfa 42133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // 42233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // SRC: VirtualFP AND 42333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // DST: Register => DW_CFA_def_cfa_register 42433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // 42533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // ELSE 42633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // OFFSET < 0 => DW_CFA_offset_extended_sf 42733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // REG < 64 => DW_CFA_offset + Reg 42833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // ELSE => DW_CFA_offset_extended 42933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 43033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov std::vector<MachineMove> &Moves = MMI.getFrameMoves(); 43133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const TargetData *TD = MF.getTarget().getTargetData(); 43233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t NumBytes = 0; 43333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int stackGrowth = -TD->getPointerSize(); 43433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 43533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (HasFP) { 43633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Calculate required stack adjustment. 43733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t FrameSize = StackSize - SlotSize; 43833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (RegInfo->needsStackRealignment(MF)) 43933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov FrameSize = (FrameSize + MaxAlign - 1) / MaxAlign * MaxAlign; 44033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 44133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov NumBytes = FrameSize - X86FI->getCalleeSavedFrameSize(); 44233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 44333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get the offset of the stack slot for the EBP register, which is 44433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // guaranteed to be the last slot by processFunctionBeforeFrameFinalized. 44533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Update the frame offset adjustment. 44633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MFI->setOffsetAdjustment(-NumBytes); 44733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 44833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Save EBP/RBP into the appropriate stack slot. 44933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::PUSH64r : X86::PUSH32r)) 45033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(FramePtr, RegState::Kill); 45133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 45233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (needsFrameMoves) { 45333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Mark the place where EBP/RBP was saved. 45433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MCSymbol *FrameLabel = MMI.getContext().CreateTempSymbol(); 45533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(X86::PROLOG_LABEL)).addSym(FrameLabel); 45633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 45733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Define the current CFA rule to use the provided offset. 45833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (StackSize) { 45933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPDst(MachineLocation::VirtualFP); 46033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPSrc(MachineLocation::VirtualFP, 2 * stackGrowth); 46133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc)); 46233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 46333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPDst(StackPtr); 46433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPSrc(StackPtr, stackGrowth); 46533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc)); 46633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 46733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 46833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Change the rule for the FramePtr to be an "offset" rule. 46933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation FPDst(MachineLocation::VirtualFP, 2 * stackGrowth); 47033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation FPSrc(FramePtr); 47133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(FrameLabel, FPDst, FPSrc)); 47233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 47333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 47433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Update EBP with the new base value... 47533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, 47633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr), FramePtr) 47733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(StackPtr); 47833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 47933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (needsFrameMoves) { 48033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Mark effective beginning of when frame pointer becomes valid. 48133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MCSymbol *FrameLabel = MMI.getContext().CreateTempSymbol(); 48233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(X86::PROLOG_LABEL)).addSym(FrameLabel); 48333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 48433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Define the current CFA to use the EBP/RBP register. 48533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation FPDst(FramePtr); 48633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation FPSrc(MachineLocation::VirtualFP); 48733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(FrameLabel, FPDst, FPSrc)); 48833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 48933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 49033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Mark the FramePtr as live-in in every block except the entry. 49133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (MachineFunction::iterator I = llvm::next(MF.begin()), E = MF.end(); 49233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov I != E; ++I) 49333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov I->addLiveIn(FramePtr); 49433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 49533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Realign stack 49633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (RegInfo->needsStackRealignment(MF)) { 49733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineInstr *MI = 49833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, 49933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov TII.get(Is64Bit ? X86::AND64ri32 : X86::AND32ri), 50033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov StackPtr).addReg(StackPtr).addImm(-MaxAlign); 50133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 50233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // The EFLAGS implicit def is dead. 50333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MI->getOperand(3).setIsDead(); 50433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 50533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 50633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov NumBytes = StackSize - X86FI->getCalleeSavedFrameSize(); 50733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 50833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 50933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Skip the callee-saved push instructions. 51033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool PushedRegs = false; 51133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int StackOffset = 2 * stackGrowth; 51233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 51333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov while (MBBI != MBB.end() && 51433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov (MBBI->getOpcode() == X86::PUSH32r || 51533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBBI->getOpcode() == X86::PUSH64r)) { 51633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov PushedRegs = true; 51733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov ++MBBI; 51833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 51933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!HasFP && needsFrameMoves) { 52033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Mark callee-saved push instruction. 52133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MCSymbol *Label = MMI.getContext().CreateTempSymbol(); 52233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(X86::PROLOG_LABEL)).addSym(Label); 52333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 52433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Define the current CFA rule to use the provided offset. 52533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Ptr = StackSize ? 52633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation::VirtualFP : StackPtr; 52733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPDst(Ptr); 52833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPSrc(Ptr, StackOffset); 52933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(Label, SPDst, SPSrc)); 53033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov StackOffset += stackGrowth; 53133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 53233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 53333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 53433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DL = MBB.findDebugLoc(MBBI); 53533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 53633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If there is an SUB32ri of ESP immediately before this instruction, merge 53733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // the two. This can be the case when tail call elimination is enabled and 53833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // the callee has more arguments then the caller. 53933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov NumBytes -= mergeSPUpdates(MBB, MBBI, StackPtr, true); 54033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 54133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If there is an ADD32ri or SUB32ri of ESP immediately after this 54233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // instruction, merge the two instructions. 54333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov mergeSPUpdatesDown(MBB, MBBI, StackPtr, &NumBytes); 54433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 54533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Adjust stack pointer: ESP -= numbytes. 54633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 54733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Windows and cygwin/mingw require a prologue helper routine when allocating 54833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // more than 4K bytes on the stack. Windows uses __chkstk and cygwin/mingw 54933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // uses __alloca. __alloca and the 32-bit version of __chkstk will probe the 55033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // stack and adjust the stack pointer in one go. The 64-bit version of 55133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // __chkstk is only responsible for probing the stack. The 64-bit prologue is 55233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // responsible for adjusting the stack pointer. Touching the stack at 4K 55333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // increments is necessary to ensure that the guard pages used by the OS 55433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // virtual memory manager are allocated in correct sequence. 555a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi if (NumBytes >= 4096 && STI.isTargetCOFF() && !STI.isTargetEnvMacho()) { 556a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi const char *StackProbeSymbol; 557a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi bool isSPUpdateNeeded = false; 558a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi 559a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi if (Is64Bit) { 560a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi if (STI.isTargetCygMing()) 561a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi StackProbeSymbol = "___chkstk"; 562a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi else { 563a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi StackProbeSymbol = "__chkstk"; 564a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi isSPUpdateNeeded = true; 565a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi } 566a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi } else if (STI.isTargetCygMing()) 567a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi StackProbeSymbol = "_alloca"; 568a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi else 569a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi StackProbeSymbol = "_chkstk"; 570a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi 57133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Check whether EAX is livein for this function. 57233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool isEAXAlive = isEAXLiveIn(MF); 57333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 574a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi if (isEAXAlive) { 575a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // Sanity check that EAX is not livein for this function. 576a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // It should not be, so throw an assert. 577a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi assert(!Is64Bit && "EAX is livein in x64 case!"); 578a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi 57933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Save EAX 58033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(X86::PUSH32r)) 58133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(X86::EAX, RegState::Kill); 582a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi } 58333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 584a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi if (Is64Bit) { 585a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // Handle the 64-bit Windows ABI case where we need to call __chkstk. 586a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // Function prologue is responsible for adjusting the stack pointer. 587a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi BuildMI(MBB, MBBI, DL, TII.get(X86::MOV64ri), X86::RAX) 588a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi .addImm(NumBytes); 589a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi } else { 590a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // Allocate NumBytes-4 bytes on stack in case of isEAXAlive. 591a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // We'll also use 4 already allocated bytes for EAX. 59233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX) 593a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi .addImm(isEAXAlive ? NumBytes - 4 : NumBytes); 594a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi } 595a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi 596a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi BuildMI(MBB, MBBI, DL, 597a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi TII.get(Is64Bit ? X86::W64ALLOCA : X86::CALLpcrel32)) 598a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi .addExternalSymbol(StackProbeSymbol) 599a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi .addReg(StackPtr, RegState::Define | RegState::Implicit) 600a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi .addReg(X86::EFLAGS, RegState::Define | RegState::Implicit); 601a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi 602a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // MSVC x64's __chkstk needs to adjust %rsp. 603a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // FIXME: %rax preserves the offset and should be available. 604a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi if (isSPUpdateNeeded) 605a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi emitSPUpdate(MBB, MBBI, StackPtr, -(int64_t)NumBytes, Is64Bit, 606a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi TII, *RegInfo); 607a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi 608a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi if (isEAXAlive) { 609a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi // Restore EAX 610a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi MachineInstr *MI = addRegOffset(BuildMI(MF, DL, TII.get(X86::MOV32rm), 611a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi X86::EAX), 612a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi StackPtr, false, NumBytes - 4); 613a2e0762fae050464494a50c8b5d53ac2f4ba738cNAKAMURA Takumi MBB.insert(MBBI, MI); 61433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 61533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (NumBytes) 6167158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng emitSPUpdate(MBB, MBBI, StackPtr, -(int64_t)NumBytes, Is64Bit, 6177158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng TII, *RegInfo); 61833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 619f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola if (( (!HasFP && NumBytes) || PushedRegs) && needsFrameMoves) { 62033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Mark end of stack pointer adjustment. 62133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MCSymbol *Label = MMI.getContext().CreateTempSymbol(); 62233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(X86::PROLOG_LABEL)).addSym(Label); 62333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 62433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!HasFP && NumBytes) { 62533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Define the current CFA rule to use the provided offset. 62633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (StackSize) { 62733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPDst(MachineLocation::VirtualFP); 62833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPSrc(MachineLocation::VirtualFP, 62933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov -StackSize + stackGrowth); 63033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(Label, SPDst, SPSrc)); 63133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 63233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPDst(StackPtr); 63333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineLocation SPSrc(StackPtr, stackGrowth); 63433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Moves.push_back(MachineMove(Label, SPDst, SPSrc)); 63533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 63633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 63733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 63833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Emit DWARF info specifying the offsets of the callee-saved registers. 63933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (PushedRegs) 64033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov emitCalleeSavedFrameMoves(MF, Label, HasFP ? FramePtr : StackPtr); 64133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 64233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 64333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 64416c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid X86FrameLowering::emitEpilogue(MachineFunction &MF, 64533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock &MBB) const { 64633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const MachineFrameInfo *MFI = MF.getFrameInfo(); 64733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>(); 648d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov const X86RegisterInfo *RegInfo = TM.getRegisterInfo(); 649d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov const X86InstrInfo &TII = *TM.getInstrInfo(); 6504f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 6514f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen assert(MBBI != MBB.end() && "Returning block has no instructions"); 65233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned RetOpcode = MBBI->getOpcode(); 65333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DebugLoc DL = MBBI->getDebugLoc(); 65433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool Is64Bit = STI.is64Bit(); 65533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackAlign = getStackAlignment(); 65633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned SlotSize = RegInfo->getSlotSize(); 65733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned FramePtr = RegInfo->getFrameRegister(MF); 65833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned StackPtr = RegInfo->getStackRegister(); 65933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 66033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov switch (RetOpcode) { 66133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov default: 66233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov llvm_unreachable("Can only insert epilog into returning blocks"); 66333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::RET: 66433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::RETI: 66533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::TCRETURNdi: 66633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::TCRETURNri: 66733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::TCRETURNmi: 66833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::TCRETURNdi64: 66933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::TCRETURNri64: 67033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::TCRETURNmi64: 67133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::EH_RETURN: 67233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case X86::EH_RETURN64: 67333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov break; // These are ok 67433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 67533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 67633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get the number of bytes to allocate from the FrameInfo. 67733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t StackSize = MFI->getStackSize(); 67833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t MaxAlign = MFI->getMaxAlignment(); 67933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned CSSize = X86FI->getCalleeSavedFrameSize(); 68033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t NumBytes = 0; 68133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 68233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If we're forcing a stack realignment we can't rely on just the frame 68333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // info, we need to know the ABI stack alignment as well in case we 68433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // have a call out. Otherwise just make sure we have some alignment - we'll 68533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // go with the minimum. 68633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (ForceStackAlign) { 68733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MFI->hasCalls()) 68833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MaxAlign = (StackAlign > MaxAlign) ? StackAlign : MaxAlign; 68933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov else 69033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MaxAlign = MaxAlign ? MaxAlign : 4; 69133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 69233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 693d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (hasFP(MF)) { 69433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Calculate required stack adjustment. 69533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t FrameSize = StackSize - SlotSize; 69633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (RegInfo->needsStackRealignment(MF)) 69733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov FrameSize = (FrameSize + MaxAlign - 1)/MaxAlign*MaxAlign; 69833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 69933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov NumBytes = FrameSize - CSSize; 70033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 70133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Pop EBP. 70233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, 70333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov TII.get(Is64Bit ? X86::POP64r : X86::POP32r), FramePtr); 70433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 70533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov NumBytes = StackSize - CSSize; 70633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 70733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 70833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Skip the callee-saved pop instructions. 70933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator LastCSPop = MBBI; 71033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov while (MBBI != MBB.begin()) { 71133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator PI = prior(MBBI); 71233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Opc = PI->getOpcode(); 71333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 7144f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen if (Opc != X86::POP32r && Opc != X86::POP64r && Opc != X86::DBG_VALUE && 71533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov !PI->getDesc().isTerminator()) 71633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov break; 71733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 71833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov --MBBI; 71933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 72033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 72133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DL = MBBI->getDebugLoc(); 72233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 72333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If there is an ADD32ri or SUB32ri of ESP immediately before this 72433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // instruction, merge the two instructions. 72533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (NumBytes || MFI->hasVarSizedObjects()) 72633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes); 72733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 72833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If dynamic alloca is used, then reset esp to point to the last callee-saved 72933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // slot before popping them off! Same applies for the case, when stack was 73033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // realigned. 73133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (RegInfo->needsStackRealignment(MF)) { 73233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // We cannot use LEA here, because stack pointer was realigned. We need to 73333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // deallocate local frame back. 73433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (CSSize) { 7357158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng emitSPUpdate(MBB, MBBI, StackPtr, NumBytes, Is64Bit, TII, *RegInfo); 73633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBBI = prior(LastCSPop); 73733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 73833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 73933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, 74033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr), 74133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov StackPtr).addReg(FramePtr); 74233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (MFI->hasVarSizedObjects()) { 74333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (CSSize) { 74433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Opc = Is64Bit ? X86::LEA64r : X86::LEA32r; 74533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineInstr *MI = 74633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov addRegOffset(BuildMI(MF, DL, TII.get(Opc), StackPtr), 74733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov FramePtr, false, -CSSize); 74833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBB.insert(MBBI, MI); 74933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 75033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, 75133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr), StackPtr) 75233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(FramePtr); 75333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 75433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (NumBytes) { 75533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Adjust stack pointer back: ESP += numbytes. 7567158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng emitSPUpdate(MBB, MBBI, StackPtr, NumBytes, Is64Bit, TII, *RegInfo); 75733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 75833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 75933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // We're returning from function via eh_return. 76033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (RetOpcode == X86::EH_RETURN || RetOpcode == X86::EH_RETURN64) { 7614f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MBBI = MBB.getLastNonDebugInstr(); 76233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineOperand &DestAddr = MBBI->getOperand(0); 76333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(DestAddr.isReg() && "Offset should be in register!"); 76433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, 76533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr), 76633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov StackPtr).addReg(DestAddr.getReg()); 76733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (RetOpcode == X86::TCRETURNri || RetOpcode == X86::TCRETURNdi || 76833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RetOpcode == X86::TCRETURNmi || 76933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RetOpcode == X86::TCRETURNri64 || RetOpcode == X86::TCRETURNdi64 || 77033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov RetOpcode == X86::TCRETURNmi64) { 77133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool isMem = RetOpcode == X86::TCRETURNmi || RetOpcode == X86::TCRETURNmi64; 77233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Tail call return: adjust the stack pointer and jump to callee. 773f7ca976e74eafeeab0e9097f0fb07d6bb447415bJakob Stoklund Olesen MBBI = MBB.getLastNonDebugInstr(); 77433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineOperand &JumpTarget = MBBI->getOperand(0); 77533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineOperand &StackAdjust = MBBI->getOperand(isMem ? 5 : 1); 77633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(StackAdjust.isImm() && "Expecting immediate value."); 77733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 77833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Adjust stack pointer. 77933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int StackAdj = StackAdjust.getImm(); 78033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int MaxTCDelta = X86FI->getTCReturnAddrDelta(); 78133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int Offset = 0; 78233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(MaxTCDelta <= 0 && "MaxTCDelta should never be positive"); 78333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 78433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Incoporate the retaddr area. 78533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Offset = StackAdj-MaxTCDelta; 78633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov assert(Offset >= 0 && "Offset should never be negative"); 78733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 78833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (Offset) { 7897a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // Check for possible merge with preceding ADD instruction. 79033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov Offset += mergeSPUpdates(MBB, MBBI, StackPtr, true); 7917158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng emitSPUpdate(MBB, MBBI, StackPtr, Offset, Is64Bit, TII, *RegInfo); 79233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 79333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 79433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Jump to label or value in register. 79533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (RetOpcode == X86::TCRETURNdi || RetOpcode == X86::TCRETURNdi64) { 7963d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng MachineInstrBuilder MIB = 7973d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng BuildMI(MBB, MBBI, DL, TII.get((RetOpcode == X86::TCRETURNdi) 7983d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng ? X86::TAILJMPd : X86::TAILJMPd64)); 7993d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng if (JumpTarget.isGlobal()) 8003d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng MIB.addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset(), 8013d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng JumpTarget.getTargetFlags()); 8023d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng else { 8033d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng assert(JumpTarget.isSymbol()); 8043d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng MIB.addExternalSymbol(JumpTarget.getSymbolName(), 8053d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng JumpTarget.getTargetFlags()); 8063d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng } 80733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (RetOpcode == X86::TCRETURNmi || RetOpcode == X86::TCRETURNmi64) { 80833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineInstrBuilder MIB = 80933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get((RetOpcode == X86::TCRETURNmi) 81033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov ? X86::TAILJMPm : X86::TAILJMPm64)); 81133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (unsigned i = 0; i != 5; ++i) 81233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MIB.addOperand(MBBI->getOperand(i)); 81333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if (RetOpcode == X86::TCRETURNri64) { 81433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(X86::TAILJMPr64)). 81533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov addReg(JumpTarget.getReg(), RegState::Kill); 81633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 81733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(X86::TAILJMPr)). 81833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov addReg(JumpTarget.getReg(), RegState::Kill); 81933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 82033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 82133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineInstr *NewMI = prior(MBBI); 82233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov for (unsigned i = 2, e = MBBI->getNumOperands(); i != e; ++i) 82333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov NewMI->addOperand(MBBI->getOperand(i)); 82433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 82533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Delete the pseudo instruction TCRETURN. 82633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MBB.erase(MBBI); 82733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else if ((RetOpcode == X86::RET || RetOpcode == X86::RETI) && 82833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov (X86FI->getTCReturnAddrDelta() < 0)) { 82933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Add the return addr area delta back since we are not tail calling. 83033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov int delta = -1*X86FI->getTCReturnAddrDelta(); 8314f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MBBI = MBB.getLastNonDebugInstr(); 83233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 8337a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // Check for possible merge with preceding ADD instruction. 83433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov delta += mergeSPUpdates(MBB, MBBI, StackPtr, true); 8357158e08b8e619f4dcac9834c57f5f8afd6eea2ebEvan Cheng emitSPUpdate(MBB, MBBI, StackPtr, delta, Is64Bit, TII, *RegInfo); 83633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 83733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 838d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov 839d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikovvoid 84016c29b5f285f375be53dabaa73e3e91107485fe4Anton KorobeynikovX86FrameLowering::getInitialFrameState(std::vector<MachineMove> &Moves) const { 841d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov // Calculate amount of bytes used for return address storing 842d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov int stackGrowth = (STI.is64Bit() ? -8 : -4); 843d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov const X86RegisterInfo *RI = TM.getRegisterInfo(); 844d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov 845d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov // Initial state of the frame pointer is esp+stackGrowth. 846d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov MachineLocation Dst(MachineLocation::VirtualFP); 847d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov MachineLocation Src(RI->getStackRegister(), stackGrowth); 848d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov Moves.push_back(MachineMove(0, Dst, Src)); 849d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov 850d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov // Add return address to move list 851d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov MachineLocation CSDst(RI->getStackRegister(), stackGrowth); 852d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov MachineLocation CSSrc(RI->getRARegister()); 853d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov Moves.push_back(MachineMove(0, CSDst, CSSrc)); 854d9e3385ced2dc887e2fe8e1c071bd2611e4d3edeAnton Korobeynikov} 85582f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov 85616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovint X86FrameLowering::getFrameIndexOffset(const MachineFunction &MF, int FI) const { 85782f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov const X86RegisterInfo *RI = 85882f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov static_cast<const X86RegisterInfo*>(MF.getTarget().getRegisterInfo()); 85982f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov const MachineFrameInfo *MFI = MF.getFrameInfo(); 86082f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov int Offset = MFI->getObjectOffset(FI) - getOffsetOfLocalArea(); 86182f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov uint64_t StackSize = MFI->getStackSize(); 86282f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov 86382f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov if (RI->needsStackRealignment(MF)) { 86482f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov if (FI < 0) { 86582f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov // Skip the saved EBP. 86682f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov Offset += RI->getSlotSize(); 86782f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov } else { 86882f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov unsigned Align = MFI->getObjectAlignment(FI); 86982f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov assert((-(Offset + StackSize)) % Align == 0); 87082f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov Align = 0; 87182f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov return Offset + StackSize; 87282f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov } 87382f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov // FIXME: Support tail calls 87482f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov } else { 87582f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov if (!hasFP(MF)) 87682f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov return Offset + StackSize; 87782f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov 87882f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov // Skip the saved EBP. 87982f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov Offset += RI->getSlotSize(); 88082f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov 88182f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov // Skip the RETADDR move area 88282f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov const X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>(); 88382f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov int TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta(); 88482f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov if (TailCallReturnAddrDelta < 0) 88582f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov Offset -= TailCallReturnAddrDelta; 88682f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov } 88782f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov 88882f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov return Offset; 88982f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov} 890cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 89116c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovbool X86FrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB, 892cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov MachineBasicBlock::iterator MI, 893cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov const std::vector<CalleeSavedInfo> &CSI, 894cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov const TargetRegisterInfo *TRI) const { 895cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov if (CSI.empty()) 896cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov return false; 897cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 898cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov DebugLoc DL = MBB.findDebugLoc(MI); 899cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 900cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov MachineFunction &MF = *MBB.getParent(); 901cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 902cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov unsigned SlotSize = STI.is64Bit() ? 8 : 4; 903cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov unsigned FPReg = TRI->getFrameRegister(MF); 904cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov unsigned CalleeFrameSize = 0; 905cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 906cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 907cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>(); 908cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 909419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi // Push GPRs. It increases frame size. 910cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov unsigned Opc = STI.is64Bit() ? X86::PUSH64r : X86::PUSH32r; 911cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov for (unsigned i = CSI.size(); i != 0; --i) { 912cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov unsigned Reg = CSI[i-1].getReg(); 913419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi if (!X86::GR64RegClass.contains(Reg) && 914419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi !X86::GR32RegClass.contains(Reg)) 915419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi continue; 916cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov // Add the callee-saved register as live-in. It's killed at the spill. 917cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov MBB.addLiveIn(Reg); 918cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov if (Reg == FPReg) 919cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov // X86RegisterInfo::emitPrologue will handle spilling of frame register. 920cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov continue; 921419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi CalleeFrameSize += SlotSize; 922419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi BuildMI(MBB, MI, DL, TII.get(Opc)).addReg(Reg, RegState::Kill); 923cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov } 924cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 925cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov X86FI->setCalleeSavedFrameSize(CalleeFrameSize); 926419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi 927419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi // Make XMM regs spilled. X86 does not have ability of push/pop XMM. 928419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi // It can be done by spilling XMMs to stack frame. 929419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi // Note that only Win64 ABI might spill XMMs. 930419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi for (unsigned i = CSI.size(); i != 0; --i) { 931419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi unsigned Reg = CSI[i-1].getReg(); 932419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi if (X86::GR64RegClass.contains(Reg) || 933419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi X86::GR32RegClass.contains(Reg)) 934419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi continue; 935419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi // Add the callee-saved register as live-in. It's killed at the spill. 936419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi MBB.addLiveIn(Reg); 937419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 938419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi TII.storeRegToStackSlot(MBB, MI, Reg, true, CSI[i-1].getFrameIdx(), 939419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi RC, TRI); 940419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi } 941419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi 942cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov return true; 943cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov} 944cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 94516c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovbool X86FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 946cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov MachineBasicBlock::iterator MI, 947cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov const std::vector<CalleeSavedInfo> &CSI, 948cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov const TargetRegisterInfo *TRI) const { 949cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov if (CSI.empty()) 950cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov return false; 951cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 952cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov DebugLoc DL = MBB.findDebugLoc(MI); 953cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 954cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov MachineFunction &MF = *MBB.getParent(); 955cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 956419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi 957419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi // Reload XMMs from stack frame. 958419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 959419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi unsigned Reg = CSI[i].getReg(); 960419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi if (X86::GR64RegClass.contains(Reg) || 961419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi X86::GR32RegClass.contains(Reg)) 962419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi continue; 963419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 964419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi TII.loadRegFromStackSlot(MBB, MI, Reg, CSI[i].getFrameIdx(), 965419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi RC, TRI); 966419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi } 967419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi 968419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi // POP GPRs. 969cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov unsigned FPReg = TRI->getFrameRegister(MF); 970cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov unsigned Opc = STI.is64Bit() ? X86::POP64r : X86::POP32r; 971cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 972cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov unsigned Reg = CSI[i].getReg(); 973419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi if (!X86::GR64RegClass.contains(Reg) && 974419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi !X86::GR32RegClass.contains(Reg)) 975419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi continue; 976cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov if (Reg == FPReg) 977cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov // X86RegisterInfo::emitEpilogue will handle restoring of frame register. 978cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov continue; 979419f23278388a8999b5c0bbe73ce823f63747f28NAKAMURA Takumi BuildMI(MBB, MI, DL, TII.get(Opc), Reg); 980cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov } 981cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov return true; 982cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov} 98394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 98494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikovvoid 98516c29b5f285f375be53dabaa73e3e91107485fe4Anton KorobeynikovX86FrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, 98694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov RegScavenger *RS) const { 98794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 98894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov const X86RegisterInfo *RegInfo = TM.getRegisterInfo(); 98994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov unsigned SlotSize = RegInfo->getSlotSize(); 99094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 99194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>(); 99294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int32_t TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta(); 99394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 99494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (TailCallReturnAddrDelta < 0) { 99594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // create RETURNADDR area 99694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // arg 99794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // arg 99894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // RETADDR 99994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // { ... 100094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // RETADDR area 100194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // ... 100294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // } 100394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // [EBP] 100494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov MFI->CreateFixedObject(-TailCallReturnAddrDelta, 100594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov (-1U*SlotSize)+TailCallReturnAddrDelta, true); 100694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 100794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 100894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov if (hasFP(MF)) { 100994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov assert((TailCallReturnAddrDelta <= 0) && 101094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov "The Delta should always be zero or negative"); 101116c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering &TFI = *MF.getTarget().getFrameLowering(); 101294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 101394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov // Create a frame entry for the EBP register that must be saved. 101494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov int FrameIdx = MFI->CreateFixedObject(SlotSize, 101594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov -(int)SlotSize + 101694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov TFI.getOffsetOfLocalArea() + 101794c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov TailCallReturnAddrDelta, 101894c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov true); 101994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov assert(FrameIdx == MFI->getObjectIndexBegin() && 102094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov "Slot for EBP register must be last in order to be found!"); 102194c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov FrameIdx = 0; 102294c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov } 102394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov} 1024