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