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 static MemOperand *SplitStpLdpOffsetForCalleeSavedWithAddInstruction(CGFunc &cgFunc, const MemOperand &mo, 52 uint32 bitLen, 53 AArch64reg baseRegNum = AArch64reg::kRinvalid); 54 static void AppendInstructionPushPair(CGFunc &cgFunc, AArch64reg reg0, AArch64reg reg1, RegType rty, int32 offset); 55 static void AppendInstructionPushSingle(CGFunc &cgFunc, AArch64reg reg, RegType rty, int32 offset); 56 static void AppendInstructionPopSingle(CGFunc &cgFunc, AArch64reg reg, RegType rty, int32 offset); 57 static void AppendInstructionPopPair(CGFunc &cgFunc, AArch64reg reg0, AArch64reg reg1, RegType rty, int32 offset); 58 void Run() override; 59 60 private: 61 void AppendInstructionAllocateCallFrame(AArch64reg reg0, AArch64reg reg1, RegType rty); 62 void AppendInstructionAllocateCallFrameDebug(AArch64reg reg0, AArch64reg reg1, RegType rty); 63 void GeneratePushRegs(); 64 void GenerateProlog(BB &bb); 65 void GenerateSave(); 66 void GenerateFrameTypeSave(SaveInfo &frameInfo, int32 stackSize, int64 fpToSpDistance); 67 void GenerateFunctionSave(SaveInfo &funcInfo, int32 stackSize, int64 fpToSpDistance); 68 void GenerateRet(BB &bb); 69 void AppendInstructionDeallocateCallFrame(AArch64reg reg0, AArch64reg reg1, RegType rty); 70 void AppendInstructionDeallocateCallFrameDebug(AArch64reg reg0, AArch64reg reg1, RegType rty); 71 void GeneratePopRegs(); 72 void GenerateEpilog(BB &bb); 73 void AppendBBtoEpilog(BB &epilogBB, BB &newBB); 74 Insn &CreateAndAppendInstructionForAllocateCallFrame(int64 fpToSpDistance, AArch64reg reg0, AArch64reg reg1, 75 RegType rty); 76 Insn &AppendInstructionForAllocateOrDeallocateCallFrame(int64 fpToSpDistance, AArch64reg reg0, AArch64reg reg1, 77 RegType rty, bool isAllocate); 78 MapleAllocator tmpAlloc; 79 static constexpr const int32 kOffset8MemPos = 8; 80 static constexpr const int32 kOffset16MemPos = 16; 81 bool useFP = false; 82 // To be compatible with previous code more easily,we use storeFP boolean to indicate the case 83 // (1) use FP to address 84 // (2) FP is clobbered 85 // need to delete this and optimize the callee save process. 86 bool storeFP = false; 87 /* frame pointer(x29) is available as a general-purpose register if useFP is set as false */ 88 AArch64reg stackBaseReg = RFP; 89 }; 90 } /* namespace maplebe */ 91 92 #endif /* MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_PROEPILOG_H */ 93