1 /* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_PROEPILOG_H 17 #define MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_PROEPILOG_H 18 19 #include "proepilog.h" 20 #include "cg.h" 21 #include "operand.h" 22 #include "aarch64_cgfunc.h" 23 #include "aarch64_operand.h" 24 #include "aarch64_insn.h" 25 26 namespace maplebe { 27 using namespace maple; 28 29 class AArch64GenProEpilog : public GenProEpilog { 30 public: AArch64GenProEpilog(CGFunc & func,MemPool & memPool)31 AArch64GenProEpilog(CGFunc &func, MemPool &memPool) : GenProEpilog(func), tmpAlloc(&memPool) 32 { 33 useFP = func.UseFP(); 34 if (func.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { 35 stackBaseReg = RFP; 36 } else { 37 stackBaseReg = useFP ? R29 : RSP; 38 } 39 AArch64CGFunc &aarchCGFunc = static_cast<AArch64CGFunc &>(func); 40 const MapleVector<AArch64reg> &calleeSavedRegs = aarchCGFunc.GetCalleeSavedRegs(); 41 if (useFP) { 42 storeFP = true; 43 } else if (find(calleeSavedRegs.begin(), calleeSavedRegs.end(), RFP) != calleeSavedRegs.end()) { 44 storeFP = true; 45 } else if (find(calleeSavedRegs.begin(), calleeSavedRegs.end(), R29) != calleeSavedRegs.end()) { 46 storeFP = true; 47 } 48 aarchCGFunc.SetStoreFP(storeFP); 49 } 50 ~AArch64GenProEpilog() override = default; 51 52 bool NeedProEpilog() override; 53 static MemOperand *SplitStpLdpOffsetForCalleeSavedWithAddInstruction(CGFunc &cgFunc, const MemOperand &mo, 54 uint32 bitLen, 55 AArch64reg baseRegNum = AArch64reg::kRinvalid); 56 static void AppendInstructionPushPair(CGFunc &cgFunc, AArch64reg reg0, AArch64reg reg1, RegType rty, int32 offset); 57 static void AppendInstructionPushSingle(CGFunc &cgFunc, AArch64reg reg, RegType rty, int32 offset); 58 static void AppendInstructionPopSingle(CGFunc &cgFunc, AArch64reg reg, RegType rty, int32 offset); 59 static void AppendInstructionPopPair(CGFunc &cgFunc, AArch64reg reg0, AArch64reg reg1, RegType rty, int32 offset); 60 void Run() override; 61 62 private: 63 AArch64reg GetStackGuardRegister(const BB &bb) const; 64 std::pair<AArch64reg, AArch64reg> GetStackGuardCheckRegister(const BB &bb) const; 65 MemOperand *GetDownStack(); 66 RegOperand &GenStackGuard(AArch64reg regNO); 67 void AddStackGuard(BB &bb); 68 void GenStackGuardCheckInsn(BB &bb); 69 BB &GetOrGenStackGuardCheckFailBB(BB &bb); 70 void AppendInstructionAllocateCallFrame(AArch64reg reg0, AArch64reg reg1, RegType rty); 71 void AppendInstructionAllocateCallFrameDebug(AArch64reg reg0, AArch64reg reg1, RegType rty); 72 void GeneratePushRegs(); 73 void GeneratePushUnnamedVarargRegs(); 74 void AppendInstructionStackCheck(AArch64reg reg, RegType rty, int32 offset); 75 void GenerateProlog(BB &bb); 76 77 void GenerateRet(BB &bb); 78 bool TestPredsOfRetBB(const BB &exitBB); 79 void AppendInstructionDeallocateCallFrame(AArch64reg reg0, AArch64reg reg1, RegType rty); 80 void AppendInstructionDeallocateCallFrameDebug(AArch64reg reg0, AArch64reg reg1, RegType rty); 81 void GeneratePopRegs(); 82 void AppendJump(const MIRSymbol &funcSymbol); 83 void GenerateEpilog(BB &bb); 84 void GenerateEpilogForCleanup(BB &bb); 85 void AppendBBtoEpilog(BB &epilogBB, BB &newBB); 86 Insn &CreateAndAppendInstructionForAllocateCallFrame(int64 fpToSpDistance, AArch64reg reg0, AArch64reg reg1, 87 RegType rty); 88 Insn &AppendInstructionForAllocateOrDeallocateCallFrame(int64 fpToSpDistance, AArch64reg reg0, AArch64reg reg1, 89 RegType rty, bool isAllocate); 90 MapleAllocator tmpAlloc; 91 static constexpr const int32 kOffset8MemPos = 8; 92 static constexpr const int32 kOffset16MemPos = 16; 93 bool useFP = false; 94 // To be compatible with previous code more easily,we use storeFP boolean to indicate the case 95 // (1) use FP to address 96 // (2) FP is clobbered 97 // need to delete this and optimize the callee save process. 98 bool storeFP = false; 99 /* frame pointer(x29) is available as a general-purpose register if useFP is set as false */ 100 AArch64reg stackBaseReg = RFP; 101 BB *stackChkFailBB = nullptr; // only one stack check fail BB is need 102 }; 103 } /* namespace maplebe */ 104 105 #endif /* MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_PROEPILOG_H */ 106