• 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 #include "aarch64_cfi_generator.h"
16 #include "aarch64_memlayout.h"
17 #include "aarch64_cgfunc.h"
18 namespace maplebe {
GenerateRegisterSaveDirective(BB & bb,Insn & stackDefInsn)19 void AArch64GenCfi::GenerateRegisterSaveDirective(BB &bb, Insn &stackDefInsn)
20 {
21     auto stackFrameSize =
22         static_cast<int32>(static_cast<AArch64MemLayout *>(cgFunc.GetMemlayout())->RealStackFrameSize());
23     auto argsToStkPassSize = static_cast<int32>(cgFunc.GetMemlayout()->SizeOfArgsToStackPass());
24     int32 cfiOffset = stackFrameSize;
25     auto *curInsn = InsertCFIDefCfaOffset(bb, stackDefInsn, cfiOffset);
26     cfiOffset = static_cast<int32>(GetOffsetFromCFA() - argsToStkPassSize);
27     auto &aarchCGFunc = static_cast<AArch64CGFunc &>(cgFunc);
28 
29     if (useFP) {
30         curInsn = bb.InsertInsnAfter(*curInsn, aarchCGFunc.CreateCfiOffsetInsn(stackBaseReg, -cfiOffset, k64BitSize));
31     }
32     int32 RLROffset = static_cast<AArch64CGFunc &>(cgFunc).GetStoreFP() ? kOffset8MemPos : 0;
33     curInsn = bb.InsertInsnAfter(
34         *curInsn, aarchCGFunc.CreateCfiOffsetInsn(RLR, static_cast<int64>(-cfiOffset + RLROffset), k64BitSize));
35 
36     /* change CFA register and offset */
37     if (useFP) {
38         bool isLmbc = cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc;
39         if ((argsToStkPassSize > 0) || isLmbc) {
40             curInsn = bb.InsertInsnAfter(
41                 *curInsn, aarchCGFunc.CreateCfiDefCfaInsn(stackBaseReg,
42                     static_cast<AArch64MemLayout *>(cgFunc.GetMemlayout())->RealStackFrameSize() -
43                     static_cast<uint32>(argsToStkPassSize) + cgFunc.GetFunction().GetFrameReseverdSlot(),
44                     k64BitSize));
45         } else {
46             curInsn =
47                 bb.InsertInsnAfter(*curInsn, cgFunc.GetInsnBuilder()
48                                                  ->BuildCfiInsn(cfi::OP_CFI_def_cfa_register)
49                                                  .AddOpndChain(cgFunc.CreateCfiRegOperand(stackBaseReg, k64BitSize)));
50         }
51     }
52 
53     if (CGOptions::IsNoCalleeCFI()) {
54         return;
55     }
56 
57     /* callee save register cfi offset */
58     auto &regsToSave = (aarchCGFunc.GetProEpilogSavedRegs().empty()) ? aarchCGFunc.GetCalleeSavedRegs()
59                                                                      : aarchCGFunc.GetProEpilogSavedRegs();
60     if (regsToSave.empty()) {
61         return;
62     }
63 
64     auto it = regsToSave.begin();
65     // skip the RFP
66     if (*it == RFP) {
67         ++it;
68     }
69     CHECK_FATAL(*it == RLR, "The second callee saved reg is expected to be RLR");
70     ++it;
71     int32 offset = cgFunc.GetMemlayout()->GetCalleeSaveBaseLoc();
72     for (; it != regsToSave.end(); ++it) {
73         AArch64reg reg = *it;
74         stackFrameSize -= static_cast<int32>(cgFunc.GetMemlayout()->SizeOfArgsToStackPass());
75         cfiOffset = stackFrameSize - offset;
76         curInsn = bb.InsertInsnAfter(*curInsn, aarchCGFunc.CreateCfiOffsetInsn(reg, -cfiOffset, k64BitSize));
77         /* On AArch64, kIntregBytelen == 8 */
78         offset += static_cast<int32>(kAarch64IntregBytelen);
79     }
80 }
81 
GenerateRegisterRestoreDirective(BB & bb,Insn & stackRevertInsn)82 void AArch64GenCfi::GenerateRegisterRestoreDirective(BB &bb, Insn &stackRevertInsn)
83 {
84     auto &aarchCGFunc = static_cast<AArch64CGFunc &>(cgFunc);
85     auto &regsToSave = (aarchCGFunc.GetProEpilogSavedRegs().empty()) ? aarchCGFunc.GetCalleeSavedRegs()
86                                                                      : aarchCGFunc.GetProEpilogSavedRegs();
87     auto *curInsn = &stackRevertInsn;
88 
89     if (!regsToSave.empty()) {
90         auto it = regsToSave.begin();
91         // skip the RFP
92         if (*it == RFP) {
93             ++it;
94         }
95         CHECK_FATAL(*it == RLR, "The second callee saved reg is expected to be RLR");
96         ++it;
97 
98         if (!CGOptions::IsNoCalleeCFI()) {
99             for (; it != regsToSave.end(); ++it) {
100                 AArch64reg reg = *it;
101                 curInsn = bb.InsertInsnAfter(*curInsn, aarchCGFunc.CreateCfiRestoreInsn(reg, k64BitSize));
102             }
103         }
104 
105         if (useFP) {
106             curInsn = bb.InsertInsnAfter(*curInsn, aarchCGFunc.CreateCfiRestoreInsn(stackBaseReg, k64BitSize));
107         }
108         curInsn = bb.InsertInsnAfter(*curInsn, aarchCGFunc.CreateCfiRestoreInsn(RLR, k64BitSize));
109     }
110     // in aarch64 R31 is sp
111     bb.InsertInsnAfter(*curInsn, aarchCGFunc.CreateCfiDefCfaInsn(R31, 0, k64BitSize));
112 }
113 }  // namespace maplebe
114