• 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     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