• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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