• 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 #ifndef MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_CALL_CONV_H
17 #define MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_CALL_CONV_H
18 
19 #include "types_def.h"
20 #include "becommon.h"
21 #include "call_conv.h"
22 #include "aarch64_abi.h"
23 #include "abi.h"
24 
25 namespace maplebe {
26 using namespace maple;
27 
28 /*
29  * We use the names used in ARM IHI 0055C_beta. $ 5.4.2.
30  * nextGeneralRegNO (= _int_parm_num)  : Next General-purpose Register number
31  * nextFloatRegNO (= _float_parm_num): Next SIMD and Floating-point Register Number
32  * nextStackArgAdress (= _last_memOffset): Next Stacked Argument Address
33  * for processing an incoming or outgoing parameter list
34  */
35 
36 class AArch64CallConvImpl : public CCImpl {
37 public:
AArch64CallConvImpl(BECommon & be)38     explicit AArch64CallConvImpl(BECommon &be) : CCImpl(), beCommon(be) {}
39 
40     ~AArch64CallConvImpl() = default;
41 
42     /* Return size of aggregate structure copy on stack. */
43     int32 LocateNextParm(MIRType &mirType, CCLocInfo &pLoc, bool isFirst = false, MIRFunction *func = nullptr) override;
44 
45     int32 LocateRetVal(MIRType &retType, CCLocInfo &ploc) override;
46 
47     /* for lmbc */
48     uint32 FloatParamRegRequired(MIRStructType &structType, uint32 &fpSize);
49 
50     /*  return value related  */
51     void InitReturnInfo(MIRType &retTy, CCLocInfo &pLoc) override;
52 
53     void SetupSecondRetReg(const MIRType &retTy2, CCLocInfo &pLoc) const override;
54 
SetupToReturnThroughMemory(CCLocInfo & pLoc)55     void SetupToReturnThroughMemory(CCLocInfo &pLoc) const
56     {
57         pLoc.regCount = 1;
58         pLoc.reg0 = R8;
59         pLoc.primTypeOfReg0 = PTY_u64;
60     }
61 
Init()62     void Init() override
63     {
64         paramNum = 0;
65         nextGeneralRegNO = 0;
66         nextFloatRegNO = 0;
67         nextStackArgAdress = 0;
68     }
69 
70 private:
71     BECommon &beCommon;
72     uint64 paramNum = 0;        /* number of all types of parameters processed so far */
73     int32 nextGeneralRegNO = 0; /* number of integer parameters processed so far */
74     uint32 nextFloatRegNO = 0;  /* number of float parameters processed so far */
75 
AllocateGPRegister()76     AArch64reg AllocateGPRegister()
77     {
78         DEBUG_ASSERT(nextGeneralRegNO >= 0, "nextGeneralRegNO can not be neg");
79         return (nextGeneralRegNO < AArch64Abi::kNumIntParmRegs) ? AArch64Abi::intParmRegs[nextGeneralRegNO++]
80                                                                 : kRinvalid;
81     }
82 
AllocateTwoGPRegisters(CCLocInfo & pLoc)83     void AllocateTwoGPRegisters(CCLocInfo &pLoc)
84     {
85         if ((nextGeneralRegNO + 1) < AArch64Abi::kNumIntParmRegs) {
86             pLoc.reg0 = AArch64Abi::intParmRegs[nextGeneralRegNO++];
87             pLoc.reg1 = AArch64Abi::intParmRegs[nextGeneralRegNO++];
88         } else {
89             pLoc.reg0 = kRinvalid;
90         }
91     }
92 
AllocateSIMDFPRegister()93     AArch64reg AllocateSIMDFPRegister()
94     {
95         return (nextFloatRegNO < AArch64Abi::kNumFloatParmRegs) ? AArch64Abi::floatParmRegs[nextFloatRegNO++]
96                                                                 : kRinvalid;
97     }
98 
AllocateNSIMDFPRegisters(CCLocInfo & ploc,uint32 num)99     void AllocateNSIMDFPRegisters(CCLocInfo &ploc, uint32 num)
100     {
101         if ((nextFloatRegNO + num - 1) < AArch64Abi::kNumFloatParmRegs) {
102             switch (num) {
103                 case kOneRegister:
104                     ploc.reg0 = AArch64Abi::floatParmRegs[nextFloatRegNO++];
105                     break;
106                 case kTwoRegister:
107                     ploc.reg0 = AArch64Abi::floatParmRegs[nextFloatRegNO++];
108                     ploc.reg1 = AArch64Abi::floatParmRegs[nextFloatRegNO++];
109                     break;
110                 case kThreeRegister:
111                     ploc.reg0 = AArch64Abi::floatParmRegs[nextFloatRegNO++];
112                     ploc.reg1 = AArch64Abi::floatParmRegs[nextFloatRegNO++];
113                     ploc.reg2 = AArch64Abi::floatParmRegs[nextFloatRegNO++];
114                     break;
115                 case kFourRegister:
116                     ploc.reg0 = AArch64Abi::floatParmRegs[nextFloatRegNO++];
117                     ploc.reg1 = AArch64Abi::floatParmRegs[nextFloatRegNO++];
118                     ploc.reg2 = AArch64Abi::floatParmRegs[nextFloatRegNO++];
119                     ploc.reg3 = AArch64Abi::floatParmRegs[nextFloatRegNO++];
120                     break;
121                 default:
122                     CHECK_FATAL(0, "AllocateNSIMDFPRegisters: unsupported");
123             }
124         } else {
125             ploc.reg0 = kRinvalid;
126         }
127     }
128 
RoundNGRNUpToNextEven()129     void RoundNGRNUpToNextEven()
130     {
131         nextGeneralRegNO = static_cast<int32>((nextGeneralRegNO + 1) & ~static_cast<int32>(1));
132     }
133 
134     int32 ProcessPtyAggWhenLocateNextParm(MIRType &mirType, CCLocInfo &pLoc, uint64 &typeSize, int32 typeAlign);
135 };
136 
137 class AArch64WebKitJSCC : public CCImpl {
138 public:
AArch64WebKitJSCC(BECommon & be)139     explicit AArch64WebKitJSCC(BECommon &be) : CCImpl(), beCommon(be) {}
140 
141     ~AArch64WebKitJSCC() = default;
142 
143     /* Return size of aggregate structure copy on stack. */
144     int32 LocateNextParm(MIRType &mirType, CCLocInfo &pLoc, bool isFirst = false, MIRFunction *func = nullptr) override;
145 
146     int32 LocateRetVal(MIRType &retType, CCLocInfo &ploc) override;
147 
148     /*  return value related  */
149     void InitReturnInfo(MIRType &retTy, CCLocInfo &pLoc) override;
150 
151     // invalid interface
152     void SetupSecondRetReg(const MIRType &retTy2, CCLocInfo &pLoc) const override;
153 
Init()154     void Init() override
155     {
156         nextGeneralRegNO = 0;
157         nextFloatRegNO = 0;
158         nextStackArgAdress = 0;
159     }
160 
161 private:
162     BECommon &beCommon;
163     int32 nextGeneralRegNO = 0; /* number of integer parameters processed so far */
164     uint32 nextFloatRegNO = 0;  /* number of float parameters processed so far */
165     static constexpr int32 kNumIntRetRegs = 8;
166     static constexpr int32 kNumFloatRetRegs = 8;
167     static constexpr int32 kNumIntParmRegs = 1;
168     static constexpr int32 kNumFloatParmRegs = 0;
169     static constexpr AArch64reg intReturnRegs[kNumIntRetRegs] = {R0, R1, R2, R3, R4, R5, R6, R7};
170     static constexpr AArch64reg floatReturnRegs[kNumFloatRetRegs] = {V0, V1, V2, V3, V4, V5, V6, V7};
171     static constexpr AArch64reg intParmRegs[kNumIntParmRegs] = {R0};
172     static constexpr AArch64reg floatParmRegs[kNumFloatParmRegs] = {};
173 
174     int32 ClassificationArg(const BECommon &be, MIRType &mirType, std::vector<ArgumentClass> &classes) const;
175 
176     int32 ClassificationRet(const BECommon &be, MIRType &mirType, std::vector<ArgumentClass> &classes) const;
177 
AllocateGPParmRegister()178     AArch64reg AllocateGPParmRegister()
179     {
180         DEBUG_ASSERT(nextGeneralRegNO >= 0, "nextGeneralRegNO can not be neg");
181         return (nextGeneralRegNO < AArch64WebKitJSCC::kNumIntParmRegs)
182                    ? AArch64WebKitJSCC::intParmRegs[nextGeneralRegNO++]
183                    : kRinvalid;
184     }
185 
AllocateGPRetRegister()186     AArch64reg AllocateGPRetRegister()
187     {
188         DEBUG_ASSERT(nextGeneralRegNO >= 0, "nextGeneralRegNO can not be neg");
189         return (nextGeneralRegNO < AArch64WebKitJSCC::kNumIntRetRegs)
190                    ? AArch64WebKitJSCC::intReturnRegs[nextGeneralRegNO++]
191                    : kRinvalid;
192     }
193 
AllocateSIMDFPRetRegister()194     AArch64reg AllocateSIMDFPRetRegister()
195     {
196         return (nextFloatRegNO < AArch64WebKitJSCC::kNumFloatParmRegs)
197                    ? AArch64WebKitJSCC::floatReturnRegs[nextFloatRegNO++]
198                    : kRinvalid;
199     }
200 };
201 
202 class GHCCC : public CCImpl {
203 public:
GHCCC(BECommon & be)204     explicit GHCCC(BECommon &be) : CCImpl(), beCommon(be) {}
205 
206     ~GHCCC() = default;
207 
208     /* Return size of aggregate structure copy on stack. */
209     int32 LocateNextParm(MIRType &mirType, CCLocInfo &pLoc, bool isFirst = false, MIRFunction *func = nullptr) override;
210 
211     int32 LocateRetVal(MIRType &retType, CCLocInfo &ploc) override;
212 
213     /*  return value related  */
214     void InitReturnInfo(MIRType &retTy, CCLocInfo &pLoc) override;
215 
216     // invalid interface
217     void SetupSecondRetReg(const MIRType &retTy2, CCLocInfo &pLoc) const override;
218 
Init()219     void Init() override
220     {
221         nextGeneralRegNO = 0;
222         nextFloatRegNOF32 = 0;
223         nextFloatRegNOF64 = 0;
224         nextFloatRegNOF128 = 0;
225         nextStackArgAdress = 0;
226     }
227 
228 private:
229     BECommon &beCommon;
230     int32 nextGeneralRegNO = 0; /* number of integer parameters processed so far */
231     uint32 nextFloatRegNOF32 = 0;
232     uint32 nextFloatRegNOF64 = 0;
233     uint32 nextFloatRegNOF128 = 0;
234     static constexpr int32 kNumIntParmRegs = 8;
235     static constexpr int32 kNumFloatParmRegsF32 = 4;
236     static constexpr int32 kNumFloatParmRegsF64 = 4;
237     static constexpr int32 kNumFloatParmRegsF128 = 2;
238     static constexpr AArch64reg intParmRegs[kNumIntParmRegs] = {R19, R20, R21, R22, R23, R24, R25, R26};
239     static constexpr AArch64reg floatParmRegsF32[kNumFloatParmRegsF32] = {V8, V9, V10, V11};
240     static constexpr AArch64reg floatParmRegsF64[kNumFloatParmRegsF64] = {V12, V13, V14, V15};
241     static constexpr AArch64reg floatParmRegsF128[kNumFloatParmRegsF128] = {V4, V5};
242 
243     int32 ClassificationArg(const BECommon &be, MIRType &mirType, std::vector<ArgumentClass> &classes) const;
244 
AllocateGPParmRegister()245     AArch64reg AllocateGPParmRegister()
246     {
247         DEBUG_ASSERT(nextGeneralRegNO >= 0, "nextGeneralRegNO can not be neg");
248         return (nextGeneralRegNO < GHCCC::kNumIntParmRegs) ? GHCCC::intParmRegs[nextGeneralRegNO++] : kRinvalid;
249     }
250 
AllocateSIMDFPParmRegisterF32()251     AArch64reg AllocateSIMDFPParmRegisterF32()
252     {
253         return (nextFloatRegNOF32 < GHCCC::kNumFloatParmRegsF32) ? GHCCC::floatParmRegsF32[nextFloatRegNOF32++]
254                                                                  : kRinvalid;
255     }
256 
AllocateSIMDFPParmRegisterF64()257     AArch64reg AllocateSIMDFPParmRegisterF64()
258     {
259         return (nextFloatRegNOF64 < GHCCC::kNumFloatParmRegsF64) ? GHCCC::floatParmRegsF64[nextFloatRegNOF64++]
260                                                                  : kRinvalid;
261     }
262 
AllocateSIMDFPParmRegisterF128()263     AArch64reg AllocateSIMDFPParmRegisterF128()
264     {
265         return (nextFloatRegNOF128 < GHCCC::kNumFloatParmRegsF128) ? GHCCC::floatParmRegsF128[nextFloatRegNOF128++]
266                                                                    : kRinvalid;
267     }
268 };
269 
270 } /* namespace maplebe */
271 
272 #endif /* MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_CALL_CONV_H */
273