//
//===----------------------------------------------------------------------===//
-#ifndef MIPS_MACHINE_FUNCTION_INFO_H
-#define MIPS_MACHINE_FUNCTION_INFO_H
+#ifndef LLVM_LIB_TARGET_MIPS_MIPSMACHINEFUNCTION_H
+#define LLVM_LIB_TARGET_MIPS_MIPSMACHINEFUNCTION_H
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/VectorExtras.h"
-#include "llvm/CodeGen/MachineFunction.h"
+#include "Mips16HardFloatInfo.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineMemOperand.h"
+#include "llvm/CodeGen/PseudoSourceValue.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/ValueMap.h"
+#include "llvm/Target/TargetFrameLowering.h"
+#include "llvm/Target/TargetMachine.h"
+#include <map>
+#include <string>
+#include <utility>
namespace llvm {
+/// \brief A class derived from PseudoSourceValue that represents a GOT entry
+/// resolved by lazy-binding.
+class MipsCallEntry : public PseudoSourceValue {
+public:
+ explicit MipsCallEntry(StringRef N);
+ explicit MipsCallEntry(const GlobalValue *V);
+ bool isConstant(const MachineFrameInfo *) const override;
+ bool isAliased(const MachineFrameInfo *) const override;
+ bool mayAlias(const MachineFrameInfo *) const override;
+
+private:
+ void printCustom(raw_ostream &O) const override;
+#ifndef NDEBUG
+ std::string Name;
+ const GlobalValue *Val;
+#endif
+};
+
/// MipsFunctionInfo - This class is derived from MachineFunction private
/// Mips target-specific information for each MachineFunction.
class MipsFunctionInfo : public MachineFunctionInfo {
+public:
+ MipsFunctionInfo(MachineFunction &MF)
+ : MF(MF), SRetReturnReg(0), GlobalBaseReg(0), Mips16SPAliasReg(0),
+ VarArgsFrameIndex(0), CallsEhReturn(false), SaveS2(false),
+ MoveF64ViaSpillFI(-1) {}
+
+ ~MipsFunctionInfo();
+
+ unsigned getSRetReturnReg() const { return SRetReturnReg; }
+ void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; }
+
+ bool globalBaseRegSet() const;
+ unsigned getGlobalBaseReg();
+
+ bool mips16SPAliasRegSet() const;
+ unsigned getMips16SPAliasReg();
+
+ int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
+ void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
+
+ bool hasByvalArg() const { return HasByvalArg; }
+ void setFormalArgInfo(unsigned Size, bool HasByval) {
+ IncomingArgSize = Size;
+ HasByvalArg = HasByval;
+ }
+
+ unsigned getIncomingArgSize() const { return IncomingArgSize; }
+
+ bool callsEhReturn() const { return CallsEhReturn; }
+ void setCallsEhReturn() { CallsEhReturn = true; }
+
+ void createEhDataRegsFI();
+ int getEhDataRegFI(unsigned Reg) const { return EhDataRegFI[Reg]; }
+ bool isEhDataRegFI(int FI) const;
+
+ /// \brief Create a MachinePointerInfo that has a MipsCallEntr object
+ /// representing a GOT entry for an external function.
+ MachinePointerInfo callPtrInfo(StringRef Name);
+
+ /// \brief Create a MachinePointerInfo that has a MipsCallEntr object
+ /// representing a GOT entry for a global function.
+ MachinePointerInfo callPtrInfo(const GlobalValue *Val);
+
+ void setSaveS2() { SaveS2 = true; }
+ bool hasSaveS2() const { return SaveS2; }
+
+ int getMoveF64ViaSpillFI(const TargetRegisterClass *RC);
+
+ std::map<const char *, const llvm::Mips16HardFloatInfo::FuncSignature *>
+ StubsNeeded;
private:
- /// Holds for each function where on the stack the Frame Pointer must be
- /// saved. This is used on Prologue and Epilogue to emit FP save/restore
- int FPStackOffset;
-
- /// Holds for each function where on the stack the Return Address must be
- /// saved. This is used on Prologue and Epilogue to emit RA save/restore
- int RAStackOffset;
-
- /// At each function entry, two special bitmask directives must be emitted
- /// to help debugging, for CPU and FPU callee saved registers. Both need
- /// the negative offset from the final stack size and its higher registers
- /// location on the stack.
- int CPUTopSavedRegOff;
- int FPUTopSavedRegOff;
-
- /// MipsFIHolder - Holds a FrameIndex and it's Stack Pointer Offset
- struct MipsFIHolder {
-
- int FI;
- int SPOffset;
-
- MipsFIHolder(int FrameIndex, int StackPointerOffset)
- : FI(FrameIndex), SPOffset(StackPointerOffset) {}
- };
-
- /// When PIC is used the GP must be saved on the stack on the function
- /// prologue and must be reloaded from this stack location after every
- /// call. A reference to its stack location and frame index must be kept
- /// to be used on emitPrologue and processFunctionBeforeFrameFinalized.
- MipsFIHolder GPHolder;
-
- /// On LowerFORMAL_ARGUMENTS the stack size is unknown, so the Stack
- /// Pointer Offset calculation of "not in register arguments" must be
- /// postponed to emitPrologue.
- SmallVector<MipsFIHolder, 16> FnLoadArgs;
- bool HasLoadArgs;
-
- // When VarArgs, we must write registers back to caller stack, preserving
- // on register arguments. Since the stack size is unknown on
- // LowerFORMAL_ARGUMENTS, the Stack Pointer Offset calculation must be
- // postponed to emitPrologue.
- SmallVector<MipsFIHolder, 4> FnStoreVarArgs;
- bool HasStoreVarArgs;
+ virtual void anchor();
+ MachineFunction& MF;
/// SRetReturnReg - Some subtargets require that sret lowering includes
/// returning the value of the returned struct in a register. This field
/// holds the virtual register into which the sret argument is passed.
unsigned SRetReturnReg;
-public:
- MipsFunctionInfo(MachineFunction& MF)
- : FPStackOffset(0), RAStackOffset(0), CPUTopSavedRegOff(0),
- FPUTopSavedRegOff(0), GPHolder(-1,-1), HasLoadArgs(false),
- HasStoreVarArgs(false), SRetReturnReg(0)
- {}
+ /// GlobalBaseReg - keeps track of the virtual register initialized for
+ /// use as the global base register. This is used for PIC in some PIC
+ /// relocation models.
+ unsigned GlobalBaseReg;
- int getFPStackOffset() const { return FPStackOffset; }
- void setFPStackOffset(int Off) { FPStackOffset = Off; }
+ /// Mips16SPAliasReg - keeps track of the virtual register initialized for
+ /// use as an alias for SP for use in load/store of halfword/byte from/to
+ /// the stack
+ unsigned Mips16SPAliasReg;
- int getRAStackOffset() const { return RAStackOffset; }
- void setRAStackOffset(int Off) { RAStackOffset = Off; }
+ /// VarArgsFrameIndex - FrameIndex for start of varargs area.
+ int VarArgsFrameIndex;
- int getCPUTopSavedRegOff() const { return CPUTopSavedRegOff; }
- void setCPUTopSavedRegOff(int Off) { CPUTopSavedRegOff = Off; }
+ /// True if function has a byval argument.
+ bool HasByvalArg;
- int getFPUTopSavedRegOff() const { return FPUTopSavedRegOff; }
- void setFPUTopSavedRegOff(int Off) { FPUTopSavedRegOff = Off; }
+ /// Size of incoming argument area.
+ unsigned IncomingArgSize;
- int getGPStackOffset() const { return GPHolder.SPOffset; }
- int getGPFI() const { return GPHolder.FI; }
- void setGPStackOffset(int Off) { GPHolder.SPOffset = Off; }
- void setGPFI(int FI) { GPHolder.FI = FI; }
+ /// CallsEhReturn - Whether the function calls llvm.eh.return.
+ bool CallsEhReturn;
- bool hasLoadArgs() const { return HasLoadArgs; }
- bool hasStoreVarArgs() const { return HasStoreVarArgs; }
+ /// Frame objects for spilling eh data registers.
+ int EhDataRegFI[4];
- void recordLoadArgsFI(int FI, int SPOffset) {
- if (!HasLoadArgs) HasLoadArgs=true;
- FnLoadArgs.push_back(MipsFIHolder(FI, SPOffset));
- }
- void recordStoreVarArgsFI(int FI, int SPOffset) {
- if (!HasStoreVarArgs) HasStoreVarArgs=true;
- FnStoreVarArgs.push_back(MipsFIHolder(FI, SPOffset));
- }
+ // saveS2
+ bool SaveS2;
- void adjustLoadArgsFI(MachineFrameInfo *MFI) const {
- if (!hasLoadArgs()) return;
- for (unsigned i = 0, e = FnLoadArgs.size(); i != e; ++i)
- MFI->setObjectOffset( FnLoadArgs[i].FI, FnLoadArgs[i].SPOffset );
- }
- void adjustStoreVarArgsFI(MachineFrameInfo *MFI) const {
- if (!hasStoreVarArgs()) return;
- for (unsigned i = 0, e = FnStoreVarArgs.size(); i != e; ++i)
- MFI->setObjectOffset( FnStoreVarArgs[i].FI, FnStoreVarArgs[i].SPOffset );
- }
+ /// FrameIndex for expanding BuildPairF64 nodes to spill and reload when the
+ /// O32 FPXX ABI is enabled. -1 is used to denote invalid index.
+ int MoveF64ViaSpillFI;
- unsigned getSRetReturnReg() const { return SRetReturnReg; }
- void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; }
+ /// MipsCallEntry maps.
+ StringMap<std::unique_ptr<const MipsCallEntry>> ExternalCallEntries;
+ ValueMap<const GlobalValue *, std::unique_ptr<const MipsCallEntry>>
+ GlobalCallEntries;
};
} // end of namespace llvm
-#endif // MIPS_MACHINE_FUNCTION_INFO_H
+#endif