15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//==- AArch64FrameLowering.h - Define frame lowering for AArch64 -*- C++ -*--=//
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                     The LLVM Compiler Infrastructure
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details.
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===//
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class implements the AArch64-specific parts of the TargetFrameLowering
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// class.
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===//
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef LLVM_AARCH64_FRAMEINFO_H
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LLVM_AARCH64_FRAMEINFO_H
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "AArch64Subtarget.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Target/TargetFrameLowering.h"
203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace llvm {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AArch64Subtarget;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AArch64FrameLowering : public TargetFrameLowering {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)private:
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In order to unify the spilling and restoring of callee-saved registers into
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // emitFrameMemOps, we need to be able to specify which instructions to use
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for the relevant memory operations on each register class. An array of the
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // following struct is populated and passed in to achieve this.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct LoadStoreMethod {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const TargetRegisterClass *RegClass; // E.g. GPR64RegClass
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The preferred instruction.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned PairOpcode; // E.g. LSPair64_STR
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sometimes only a single register can be handled at once.
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned SingleOpcode; // E.g. LS64_STR
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)protected:
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const AArch64Subtarget &STI;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public:
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit AArch64FrameLowering(const AArch64Subtarget &sti)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 16, 0, 16),
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      STI(sti) {
463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  /// emitProlog/emitEpilog - These methods insert prolog and epilog code into
493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  /// the function.
503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void emitPrologue(MachineFunction &MF) const;
513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// Decides how much stack adjustment to perform in each phase of the prologue
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// and epilogue.
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void splitSPAdjustments(uint64_t Total, uint64_t &Initial,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          uint64_t &Residual) const;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64_t resolveFrameIndexReference(MachineFunction &MF, int FrameIndex,
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     unsigned &FrameReg, int SPAdj,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     bool IsCalleeSaveOp) const;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    RegScavenger *RS) const;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        MachineBasicBlock::iterator MI,
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        const std::vector<CalleeSavedInfo> &CSI,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        const TargetRegisterInfo *TRI) const;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                        MachineBasicBlock::iterator MI,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        const std::vector<CalleeSavedInfo> &CSI,
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        const TargetRegisterInfo *TRI) const;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void eliminateCallFramePseudoInstr(MachineFunction &MF,
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     MachineBasicBlock &MBB,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     MachineBasicBlock::iterator MI) const;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// If the register is X30 (i.e. LR) and the return address is used in the
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// function then the callee-save store doesn't actually kill the register,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// otherwise it does.
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool determinePrologueDeath(MachineBasicBlock &MBB, unsigned Reg) const;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// This function emits the loads or stores required during prologue and
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// epilogue as efficiently as possible.
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ///
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// The operations involved in setting up and tearing down the frame are
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// similar enough to warrant a shared function, particularly as discrepancies
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// between the two would be disastrous.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void emitFrameMemOps(bool isStore, MachineBasicBlock &MBB,
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       MachineBasicBlock::iterator MI,
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const std::vector<CalleeSavedInfo> &CSI,
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const TargetRegisterInfo *TRI,
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const LoadStoreMethod PossibleClasses[],
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       unsigned NumClasses) const;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool hasFP(const MachineFunction &MF) const;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool useFPForAddressing(const MachineFunction &MF) const;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// On AA
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool hasReservedCallFrame(const MachineFunction &MF) const;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
105
106} // End llvm namespace
107
108#endif
109