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 #include "aarch64_cgfunc.h"
17 #include "aarch64_cg.h"
18 #include "becommon.h"
19
20 namespace maplebe {
21 using namespace maple;
22
Init()23 void AArch64RegInfo::Init()
24 {
25 for (regno_t regNO = kRinvalid; regNO < kMaxRegNum; ++regNO) {
26 /* when yieldpoint is enabled, x19 is reserved. */
27 if (IsYieldPointReg(regNO) || IsReservedReg(regNO)) {
28 continue;
29 }
30 if (regNO == R29 && GetCurrFunction()->UseFP()) {
31 continue;
32 }
33 if (!AArch64Abi::IsAvailableReg(static_cast<AArch64reg>(regNO))) {
34 continue;
35 }
36 if (AArch64isa::IsGPRegister(static_cast<AArch64reg>(regNO))) {
37 AddToIntRegs(regNO);
38 } else {
39 AddToFpRegs(regNO);
40 }
41 AddToAllRegs(regNO);
42 }
43 return;
44 }
45
Fini()46 void AArch64RegInfo::Fini()
47 {
48 AArch64CGFunc *a64CGFunc = static_cast<AArch64CGFunc *>(GetCurrFunction());
49 a64CGFunc->AddtoCalleeSaved(RFP);
50 a64CGFunc->AddtoCalleeSaved(RLR);
51 a64CGFunc->NoteFPLRAddedToCalleeSavedList();
52 }
53
SaveCalleeSavedReg(MapleSet<regno_t> savedRegs)54 void AArch64RegInfo::SaveCalleeSavedReg(MapleSet<regno_t> savedRegs)
55 {
56 AArch64CGFunc *a64CGFunc = static_cast<AArch64CGFunc *>(GetCurrFunction());
57 for (auto reg : savedRegs) {
58 a64CGFunc->AddtoCalleeSaved(static_cast<AArch64reg>(reg));
59 }
60 }
61
IsSpillRegInRA(regno_t regNO,bool has3RegOpnd)62 bool AArch64RegInfo::IsSpillRegInRA(regno_t regNO, bool has3RegOpnd)
63 {
64 return AArch64Abi::IsSpillRegInRA(static_cast<AArch64reg>(regNO), has3RegOpnd);
65 }
IsCalleeSavedReg(regno_t regno) const66 bool AArch64RegInfo::IsCalleeSavedReg(regno_t regno) const
67 {
68 return AArch64Abi::IsCalleeSavedReg(static_cast<AArch64reg>(regno));
69 }
IsYieldPointReg(regno_t regno) const70 bool AArch64RegInfo::IsYieldPointReg(regno_t regno) const
71 {
72 /* when yieldpoint is enabled, x19 is reserved. */
73 if (CGOptions::GetInstance().GenYieldPoint()) {
74 return (static_cast<AArch64reg>(regno) == RYP);
75 }
76 return false;
77 }
IsUnconcernedReg(regno_t regNO) const78 bool AArch64RegInfo::IsUnconcernedReg(regno_t regNO) const
79 {
80 /* RFP = 32, RLR = 31, RSP = 33, RZR = 34, ccReg */
81 if ((regNO >= RLR && regNO <= RZR) || regNO == RFP || regNO == kRFLAG) {
82 return true;
83 }
84
85 /* when yieldpoint is enabled, the RYP(x19) can not be used. */
86 if (IsYieldPointReg(regNO)) {
87 return true;
88 }
89 return false;
90 }
91
IsUnconcernedReg(const RegOperand & regOpnd) const92 bool AArch64RegInfo::IsUnconcernedReg(const RegOperand ®Opnd) const
93 {
94 RegType regType = regOpnd.GetRegisterType();
95 if (regType == kRegTyCc || regType == kRegTyVary) {
96 return true;
97 }
98 uint32 regNO = regOpnd.GetRegisterNumber();
99 if (regNO == RZR) {
100 return true;
101 }
102 return IsUnconcernedReg(regNO);
103 }
104
GetOrCreatePhyRegOperand(regno_t regNO,uint32 size,maplebe::RegType kind,uint32 flag)105 RegOperand *AArch64RegInfo::GetOrCreatePhyRegOperand(regno_t regNO, uint32 size, maplebe::RegType kind, uint32 flag)
106 {
107 AArch64CGFunc *aarch64CgFunc = static_cast<AArch64CGFunc *>(GetCurrFunction());
108 return &aarch64CgFunc->GetOrCreatePhysicalRegisterOperand(static_cast<AArch64reg>(regNO), size, kind, flag);
109 }
110
BuildStrInsn(uint32 regSize,PrimType stype,RegOperand & phyOpnd,MemOperand & memOpnd)111 Insn *AArch64RegInfo::BuildStrInsn(uint32 regSize, PrimType stype, RegOperand &phyOpnd, MemOperand &memOpnd)
112 {
113 AArch64CGFunc *a64CGFunc = static_cast<AArch64CGFunc *>(GetCurrFunction());
114 return &a64CGFunc->GetInsnBuilder()->BuildInsn(a64CGFunc->PickStInsn(regSize, stype), phyOpnd, memOpnd);
115 }
116
BuildLdrInsn(uint32 regSize,PrimType stype,RegOperand & phyOpnd,MemOperand & memOpnd)117 Insn *AArch64RegInfo::BuildLdrInsn(uint32 regSize, PrimType stype, RegOperand &phyOpnd, MemOperand &memOpnd)
118 {
119 AArch64CGFunc *a64CGFunc = static_cast<AArch64CGFunc *>(GetCurrFunction());
120 return &a64CGFunc->GetInsnBuilder()->BuildInsn(a64CGFunc->PickLdInsn(regSize, stype), phyOpnd, memOpnd);
121 }
122
GetOrCreatSpillMem(regno_t vrNum,uint32 bitSize)123 MemOperand *AArch64RegInfo::GetOrCreatSpillMem(regno_t vrNum, uint32 bitSize)
124 {
125 AArch64CGFunc *a64CGFunc = static_cast<AArch64CGFunc *>(GetCurrFunction());
126 return a64CGFunc->GetOrCreatSpillMem(vrNum, bitSize);
127 }
AdjustMemOperandIfOffsetOutOfRange(MemOperand * memOpnd,const RegNoPair & regNoPair,bool isDest,Insn & insn,bool & isOutOfRange)128 MemOperand *AArch64RegInfo::AdjustMemOperandIfOffsetOutOfRange(MemOperand *memOpnd, const RegNoPair ®NoPair,
129 bool isDest, Insn &insn, bool &isOutOfRange)
130 {
131 AArch64CGFunc *a64CGFunc = static_cast<AArch64CGFunc *>(GetCurrFunction());
132 return a64CGFunc->AdjustMemOperandIfOffsetOutOfRange(memOpnd, static_cast<AArch64reg>(regNoPair.first), isDest,
133 insn, static_cast<AArch64reg>(regNoPair.second), isOutOfRange);
134 }
FreeSpillRegMem(regno_t vrNum)135 void AArch64RegInfo::FreeSpillRegMem(regno_t vrNum)
136 {
137 AArch64CGFunc *a64CGFunc = static_cast<AArch64CGFunc *>(GetCurrFunction());
138 return a64CGFunc->FreeSpillRegMem(vrNum);
139 }
140 } /* namespace maplebe */
141