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