mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 20:29:48 +00:00
700ed80d3d
to TargetFrameLowering, where it belongs. Incidentally, this allows us to delete some duplicated (and slightly different!) code in TRI. There are potentially other layering problems that can be cleaned up as a result, or in a similar manner. The refactoring was OK'd by Anton Korobeynikov on llvmdev. Note: this touches the target interfaces, so out-of-tree targets may be affected. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175788 91177308-0d34-0410-b5e6-96231b3b80d8
109 lines
4.2 KiB
C++
109 lines
4.2 KiB
C++
//==- AArch64FrameLowering.h - Define frame lowering for AArch64 -*- C++ -*--=//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This class implements the AArch64-specific parts of the TargetFrameLowering
|
|
// class.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_AARCH64_FRAMEINFO_H
|
|
#define LLVM_AARCH64_FRAMEINFO_H
|
|
|
|
#include "AArch64Subtarget.h"
|
|
#include "llvm/Target/TargetFrameLowering.h"
|
|
|
|
namespace llvm {
|
|
class AArch64Subtarget;
|
|
|
|
class AArch64FrameLowering : public TargetFrameLowering {
|
|
private:
|
|
// In order to unify the spilling and restoring of callee-saved registers into
|
|
// emitFrameMemOps, we need to be able to specify which instructions to use
|
|
// for the relevant memory operations on each register class. An array of the
|
|
// following struct is populated and passed in to achieve this.
|
|
struct LoadStoreMethod {
|
|
const TargetRegisterClass *RegClass; // E.g. GPR64RegClass
|
|
|
|
// The preferred instruction.
|
|
unsigned PairOpcode; // E.g. LSPair64_STR
|
|
|
|
// Sometimes only a single register can be handled at once.
|
|
unsigned SingleOpcode; // E.g. LS64_STR
|
|
};
|
|
protected:
|
|
const AArch64Subtarget &STI;
|
|
|
|
public:
|
|
explicit AArch64FrameLowering(const AArch64Subtarget &sti)
|
|
: TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 16, 0, 16),
|
|
STI(sti) {
|
|
}
|
|
|
|
/// emitProlog/emitEpilog - These methods insert prolog and epilog code into
|
|
/// the function.
|
|
virtual void emitPrologue(MachineFunction &MF) const;
|
|
virtual void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
|
|
|
|
/// Decides how much stack adjustment to perform in each phase of the prologue
|
|
/// and epilogue.
|
|
void splitSPAdjustments(uint64_t Total, uint64_t &Initial,
|
|
uint64_t &Residual) const;
|
|
|
|
int64_t resolveFrameIndexReference(MachineFunction &MF, int FrameIndex,
|
|
unsigned &FrameReg, int SPAdj,
|
|
bool IsCalleeSaveOp) const;
|
|
|
|
virtual void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
|
RegScavenger *RS) const;
|
|
|
|
virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
|
MachineBasicBlock::iterator MI,
|
|
const std::vector<CalleeSavedInfo> &CSI,
|
|
const TargetRegisterInfo *TRI) const;
|
|
virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
|
MachineBasicBlock::iterator MI,
|
|
const std::vector<CalleeSavedInfo> &CSI,
|
|
const TargetRegisterInfo *TRI) const;
|
|
|
|
void eliminateCallFramePseudoInstr(MachineFunction &MF,
|
|
MachineBasicBlock &MBB,
|
|
MachineBasicBlock::iterator MI) const;
|
|
|
|
/// If the register is X30 (i.e. LR) and the return address is used in the
|
|
/// function then the callee-save store doesn't actually kill the register,
|
|
/// otherwise it does.
|
|
bool determinePrologueDeath(MachineBasicBlock &MBB, unsigned Reg) const;
|
|
|
|
/// This function emits the loads or stores required during prologue and
|
|
/// epilogue as efficiently as possible.
|
|
///
|
|
/// The operations involved in setting up and tearing down the frame are
|
|
/// similar enough to warrant a shared function, particularly as discrepancies
|
|
/// between the two would be disastrous.
|
|
void emitFrameMemOps(bool isStore, MachineBasicBlock &MBB,
|
|
MachineBasicBlock::iterator MI,
|
|
const std::vector<CalleeSavedInfo> &CSI,
|
|
const TargetRegisterInfo *TRI,
|
|
LoadStoreMethod PossibleClasses[],
|
|
unsigned NumClasses) const;
|
|
|
|
|
|
virtual bool hasFP(const MachineFunction &MF) const;
|
|
|
|
virtual bool useFPForAddressing(const MachineFunction &MF) const;
|
|
|
|
/// On AA
|
|
virtual bool hasReservedCallFrame(const MachineFunction &MF) const;
|
|
|
|
};
|
|
|
|
} // End llvm namespace
|
|
|
|
#endif
|