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
18 namespace maplebe {
19 using namespace maple;
20
21 namespace AArch64Abi {
22 std::vector<AArch64reg> intReturnRegs = {R0, R1, R2, R3, R4, R5, R6, R7};
23 std::vector<AArch64reg> floatReturnRegs = {V0, V1, V2, V3, V4, V5, V6, V7};
24 std::vector<AArch64reg> intParmRegs = {R0, R1, R2, R3, R4, R5, R6, R7};
25 std::vector<AArch64reg> floatParmRegs = {V0, V1, V2, V3, V4, V5, V6, V7};
26
IsAvailableReg(AArch64reg reg)27 bool IsAvailableReg(AArch64reg reg)
28 {
29 switch (reg) {
30 /* integer registers */
31 #define INT_REG(ID, PREF32, PREF64, canBeAssigned, isCalleeSave, isParam, isSpill, isExtraSpill) \
32 case R##ID: { \
33 return canBeAssigned; \
34 }
35 #define INT_REG_ALIAS(ALIAS, ID, PREF32, PREF64)
36 #include "aarch64_int_regs.def"
37 #undef INT_REG
38 #undef INT_REG_ALIAS
39 /* fp-simd registers */
40 #define FP_SIMD_REG(ID, PV, P8, P16, P32, P64, P128, canBeAssigned, isCalleeSave, isParam, isSpill, isExtraSpill) \
41 case V##ID: { \
42 return canBeAssigned; \
43 }
44 #define FP_SIMD_REG_ALIAS(ID)
45 #include "aarch64_fp_simd_regs.def"
46 #undef FP_SIMD_REG
47 #undef FP_SIMD_REG_ALIAS
48 default:
49 return false;
50 }
51 }
52
IsCallerSaveReg(AArch64reg regNO)53 bool IsCallerSaveReg(AArch64reg regNO)
54 {
55 return (R0 <= regNO && regNO <= R18) || (V0 <= regNO && regNO <= V7) || (V16 <= regNO && regNO <= V31) ||
56 (regNO == kRFLAG);
57 }
58
IsCalleeSavedReg(AArch64reg reg)59 bool IsCalleeSavedReg(AArch64reg reg)
60 {
61 switch (reg) {
62 /* integer registers */
63 #define INT_REG(ID, PREF32, PREF64, canBeAssigned, isCalleeSave, isParam, isSpill, isExtraSpill) \
64 case R##ID: { \
65 return isCalleeSave; \
66 }
67 #define INT_REG_ALIAS(ALIAS, ID, PREF32, PREF64)
68 #include "aarch64_int_regs.def"
69 #undef INT_REG
70 #undef INT_REG_ALIAS
71 /* fp-simd registers */
72 #define FP_SIMD_REG(ID, PV, P8, P16, P32, P64, P128, canBeAssigned, isCalleeSave, isParam, isSpill, isExtraSpill) \
73 case V##ID: { \
74 return isCalleeSave; \
75 }
76 #define FP_SIMD_REG_ALIAS(ID)
77 #include "aarch64_fp_simd_regs.def"
78 #undef FP_SIMD_REG
79 #undef FP_SIMD_REG_ALIAS
80 default:
81 return false;
82 }
83 }
84
IsSpillReg(AArch64reg reg)85 bool IsSpillReg(AArch64reg reg)
86 {
87 switch (reg) {
88 /* integer registers */
89 #define INT_REG(ID, PREF32, PREF64, canBeAssigned, isCalleeSave, isParam, isSpill, isExtraSpill) \
90 case R##ID: { \
91 return isSpill; \
92 }
93 #define INT_REG_ALIAS(ALIAS, ID, PREF32, PREF64)
94 #include "aarch64_int_regs.def"
95 #undef INT_REG
96 #undef INT_REG_ALIAS
97 /* fp-simd registers */
98 #define FP_SIMD_REG(ID, PV, P8, P16, P32, P64, P128, canBeAssigned, isCalleeSave, isParam, isSpill, isExtraSpill) \
99 case V##ID: { \
100 return isSpill; \
101 }
102 #define FP_SIMD_REG_ALIAS(ID)
103 #include "aarch64_fp_simd_regs.def"
104 #undef FP_SIMD_REG
105 #undef FP_SIMD_REG_ALIAS
106 default:
107 return false;
108 }
109 }
110
IsExtraSpillReg(AArch64reg reg)111 bool IsExtraSpillReg(AArch64reg reg)
112 {
113 switch (reg) {
114 /* integer registers */
115 #define INT_REG(ID, PREF32, PREF64, canBeAssigned, isCalleeSave, isParam, isSpill, isExtraSpill) \
116 case R##ID: { \
117 return isExtraSpill; \
118 }
119 #define INT_REG_ALIAS(ALIAS, ID, PREF32, PREF64)
120 #include "aarch64_int_regs.def"
121 #undef INT_REG
122 #undef INT_REG_ALIAS
123 /* fp-simd registers */
124 #define FP_SIMD_REG(ID, PV, P8, P16, P32, P64, P128, canBeAssigned, isCalleeSave, isParam, isSpill, isExtraSpill) \
125 case V##ID: { \
126 return isExtraSpill; \
127 }
128 #define FP_SIMD_REG_ALIAS(ID)
129 #include "aarch64_fp_simd_regs.def"
130 #undef FP_SIMD_REG
131 #undef FP_SIMD_REG_ALIAS
132 default:
133 return false;
134 }
135 }
136
IsSpillRegInRA(AArch64reg regNO,bool has3RegOpnd)137 bool IsSpillRegInRA(AArch64reg regNO, bool has3RegOpnd)
138 {
139 /* if has 3 RegOpnd, previous reg used to spill. */
140 if (has3RegOpnd) {
141 return AArch64Abi::IsSpillReg(regNO) || AArch64Abi::IsExtraSpillReg(regNO);
142 }
143 return AArch64Abi::IsSpillReg(regNO);
144 }
145 } /* namespace AArch64Abi */
146 } /* namespace maplebe */
147