• 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 #include "aarch64_cgfunc.h"
17 #include "becommon.h"
18 
19 namespace maplebe {
20 using namespace maple;
21 
22 namespace AArch64Abi {
IsAvailableReg(AArch64reg reg)23 bool IsAvailableReg(AArch64reg reg)
24 {
25     switch (reg) {
26 /* integer registers */
27 #define INT_REG(ID, PREF32, PREF64, canBeAssigned, isCalleeSave, isParam, isSpill, isExtraSpill) \
28     case R##ID: {                                                                                \
29         return canBeAssigned;                                                                    \
30     }
31 #define INT_REG_ALIAS(ALIAS, ID, PREF32, PREF64)
32 #include "aarch64_int_regs.def"
33 #undef INT_REG
34 #undef INT_REG_ALIAS
35 /* fp-simd registers */
36 #define FP_SIMD_REG(ID, PV, P8, P16, P32, P64, P128, canBeAssigned, isCalleeSave, isParam, isSpill, isExtraSpill) \
37     case V##ID: {                                                                                                 \
38         return canBeAssigned;                                                                                     \
39     }
40 #define FP_SIMD_REG_ALIAS(ID)
41 #include "aarch64_fp_simd_regs.def"
42 #undef FP_SIMD_REG
43 #undef FP_SIMD_REG_ALIAS
44         default:
45             return false;
46     }
47 }
48 
IsCallerSaveReg(AArch64reg regNO)49 bool IsCallerSaveReg(AArch64reg regNO)
50 {
51     return (R0 <= regNO && regNO <= R18) || (V0 <= regNO && regNO <= V7) || (V16 <= regNO && regNO <= V31) ||
52            (regNO == kRFLAG);
53 }
54 
IsCalleeSavedReg(AArch64reg reg)55 bool IsCalleeSavedReg(AArch64reg reg)
56 {
57     switch (reg) {
58 /* integer registers */
59 #define INT_REG(ID, PREF32, PREF64, canBeAssigned, isCalleeSave, isParam, isSpill, isExtraSpill) \
60     case R##ID: {                                                                                \
61         return isCalleeSave;                                                                     \
62     }
63 #define INT_REG_ALIAS(ALIAS, ID, PREF32, PREF64)
64 #include "aarch64_int_regs.def"
65 #undef INT_REG
66 #undef INT_REG_ALIAS
67 /* fp-simd registers */
68 #define FP_SIMD_REG(ID, PV, P8, P16, P32, P64, P128, canBeAssigned, isCalleeSave, isParam, isSpill, isExtraSpill) \
69     case V##ID: {                                                                                                 \
70         return isCalleeSave;                                                                                      \
71     }
72 #define FP_SIMD_REG_ALIAS(ID)
73 #include "aarch64_fp_simd_regs.def"
74 #undef FP_SIMD_REG
75 #undef FP_SIMD_REG_ALIAS
76         default:
77             return false;
78     }
79 }
80 
IsParamReg(AArch64reg reg)81 bool IsParamReg(AArch64reg reg)
82 {
83     switch (reg) {
84 /* integer registers */
85 #define INT_REG(ID, PREF32, PREF64, canBeAssigned, isCalleeSave, isParam, isSpill, isExtraSpill) \
86     case R##ID: {                                                                                \
87         return isParam;                                                                          \
88     }
89 #define INT_REG_ALIAS(ALIAS, ID, PREF32, PREF64)
90 #include "aarch64_int_regs.def"
91 #undef INT_REG
92 #undef INT_REG_ALIAS
93 /* fp-simd registers */
94 #define FP_SIMD_REG(ID, PV, P8, P16, P32, P64, P128, canBeAssigned, isCalleeSave, isParam, isSpill, isExtraSpill) \
95     case V##ID: {                                                                                                 \
96         return isParam;                                                                                           \
97     }
98 #define FP_SIMD_REG_ALIAS(ID)
99 #include "aarch64_fp_simd_regs.def"
100 #undef FP_SIMD_REG
101 #undef FP_SIMD_REG_ALIAS
102         default:
103             return false;
104     }
105 }
106 
IsSpillReg(AArch64reg reg)107 bool IsSpillReg(AArch64reg reg)
108 {
109     switch (reg) {
110 /* integer registers */
111 #define INT_REG(ID, PREF32, PREF64, canBeAssigned, isCalleeSave, isParam, isSpill, isExtraSpill) \
112     case R##ID: {                                                                                \
113         return isSpill;                                                                          \
114     }
115 #define INT_REG_ALIAS(ALIAS, ID, PREF32, PREF64)
116 #include "aarch64_int_regs.def"
117 #undef INT_REG
118 #undef INT_REG_ALIAS
119 /* fp-simd registers */
120 #define FP_SIMD_REG(ID, PV, P8, P16, P32, P64, P128, canBeAssigned, isCalleeSave, isParam, isSpill, isExtraSpill) \
121     case V##ID: {                                                                                                 \
122         return isSpill;                                                                                           \
123     }
124 #define FP_SIMD_REG_ALIAS(ID)
125 #include "aarch64_fp_simd_regs.def"
126 #undef FP_SIMD_REG
127 #undef FP_SIMD_REG_ALIAS
128         default:
129             return false;
130     }
131 }
132 
IsExtraSpillReg(AArch64reg reg)133 bool IsExtraSpillReg(AArch64reg reg)
134 {
135     switch (reg) {
136 /* integer registers */
137 #define INT_REG(ID, PREF32, PREF64, canBeAssigned, isCalleeSave, isParam, isSpill, isExtraSpill) \
138     case R##ID: {                                                                                \
139         return isExtraSpill;                                                                     \
140     }
141 #define INT_REG_ALIAS(ALIAS, ID, PREF32, PREF64)
142 #include "aarch64_int_regs.def"
143 #undef INT_REG
144 #undef INT_REG_ALIAS
145 /* fp-simd registers */
146 #define FP_SIMD_REG(ID, PV, P8, P16, P32, P64, P128, canBeAssigned, isCalleeSave, isParam, isSpill, isExtraSpill) \
147     case V##ID: {                                                                                                 \
148         return isExtraSpill;                                                                                      \
149     }
150 #define FP_SIMD_REG_ALIAS(ID)
151 #include "aarch64_fp_simd_regs.def"
152 #undef FP_SIMD_REG
153 #undef FP_SIMD_REG_ALIAS
154         default:
155             return false;
156     }
157 }
158 
IsSpillRegInRA(AArch64reg regNO,bool has3RegOpnd)159 bool IsSpillRegInRA(AArch64reg regNO, bool has3RegOpnd)
160 {
161     /* if has 3 RegOpnd, previous reg used to spill. */
162     if (has3RegOpnd) {
163         return AArch64Abi::IsSpillReg(regNO) || AArch64Abi::IsExtraSpillReg(regNO);
164     }
165     return AArch64Abi::IsSpillReg(regNO);
166 }
167 
IsVectorArrayType(MIRType * ty,uint32 & arraySize)168 PrimType IsVectorArrayType(MIRType *ty, uint32 &arraySize)
169 {
170     if (ty->GetKind() == kTypeStruct) {
171         MIRStructType *structTy = static_cast<MIRStructType *>(ty);
172         if (structTy->GetFields().size() == 1) {
173             auto fieldPair = structTy->GetFields()[0];
174             MIRType *fieldTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fieldPair.second.first);
175             if (fieldTy->GetKind() == kTypeArray) {
176                 MIRArrayType *arrayTy = static_cast<MIRArrayType *>(fieldTy);
177                 MIRType *arrayElemTy = arrayTy->GetElemType();
178                 arraySize = arrayTy->GetSizeArrayItem(0);
179                 if (arrayTy->GetDim() == k1BitSize && arraySize <= static_cast<int32>(k4BitSize) &&
180                     IsPrimitiveVector(arrayElemTy->GetPrimType())) {
181                     return arrayElemTy->GetPrimType();
182                 }
183             }
184         }
185     }
186     return PTY_void;
187 }
188 } /* namespace AArch64Abi */
189 } /* namespace maplebe */
190