• 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 Procedure Call Standard for the Arm 64-bit
30  * Architecture (AArch64) 2022Q3.  $6.8.2
31  * nextGeneralRegNO (= _int_parm_num)  : Next General-purpose Register number
32  * nextFloatRegNO (= _float_parm_num): Next SIMD and Floating-point Register Number
33  * nextStackArgAdress (= _last_memOffset): Next Stacked Argument Address
34  * for processing an incoming or outgoing parameter list
35  */
36 
37 class AArch64CallConvImpl : public CCImpl {
38 public:
AArch64CallConvImpl(BECommon & be)39     explicit AArch64CallConvImpl(BECommon &be) : CCImpl(), beCommon(be) {}
40 
41     ~AArch64CallConvImpl() = default;
42 
43     /* Return size of aggregate structure copy on stack. */
44     uint64 LocateNextParm(const MIRType &mirType, CCLocInfo &pLoc, bool isFirst = false,
45                           MIRFuncType *tFunc = nullptr) override;
46 
47     void LocateRetVal(const MIRType &retType, CCLocInfo &ploc) override;
48 
49     /* for lmbc */
50     uint32 FloatParamRegRequired(const MIRStructType &structType, uint32 &fpSize);
51 
52     void SetupSecondRetReg(const MIRType &retTy2, CCLocInfo &pLoc) const override;
53 
SetupToReturnThroughMemory(CCLocInfo & pLoc)54     void SetupToReturnThroughMemory(CCLocInfo &pLoc) const
55     {
56         pLoc.regCount = 1;
57         pLoc.reg0 = R8;
58         pLoc.primTypeOfReg0 = GetExactPtrPrimType();
59     }
60 
Init()61     void Init() override
62     {
63         nextGeneralRegNO = 0;
64         nextFloatRegNO = 0;
65         nextStackArgAdress = 0;
66     }
67 
68 private:
69     BECommon &beCommon;
70     uint32 nextGeneralRegNO = 0; /* number of integer parameters processed so far */
71     uint32 nextFloatRegNO = 0;   /* number of float parameters processed so far */
72 
AllocateGPRegister()73     AArch64reg AllocateGPRegister()
74     {
75         DEBUG_ASSERT(nextGeneralRegNO >= 0, "nextGeneralRegNO can not be neg");
76         return (nextGeneralRegNO < AArch64Abi::kNumIntParmRegs) ? AArch64Abi::intParmRegs[nextGeneralRegNO++]
77                                                                 : kRinvalid;
78     }
79 
80     void AllocateGPRegister(const MIRType &mirType, CCLocInfo &pLoc, uint64 size, uint64 align);
81 
AllocateSIMDFPRegister()82     AArch64reg AllocateSIMDFPRegister()
83     {
84         return (nextFloatRegNO < AArch64Abi::kNumFloatParmRegs) ? AArch64Abi::floatParmRegs[nextFloatRegNO++]
85                                                                 : kRinvalid;
86     }
87 
88     uint64 AllocateRegisterForAgg(const MIRType &mirType, CCLocInfo &pLoc, uint64 size, uint64 &align);
89 };
90 
91 class AArch64WebKitJSCC : public CCImpl {
92 public:
AArch64WebKitJSCC(BECommon & be)93     explicit AArch64WebKitJSCC(BECommon &be) : CCImpl(), beCommon(be) {}
94 
95     ~AArch64WebKitJSCC() = default;
96 
97     /* Return size of aggregate structure copy on stack. */
98     uint64 LocateNextParm(const MIRType &mirType, CCLocInfo &pLoc, bool isFirst = false,
99                           MIRFuncType *func = nullptr) override;
100 
101     void LocateRetVal(const MIRType &retType, CCLocInfo &ploc) override;
102 
103     /*  return value related  */
104     void InitReturnInfo(MIRType &retTy, CCLocInfo &pLoc);
105 
106     // invalid interface
107     void SetupSecondRetReg(const MIRType &retTy2, CCLocInfo &pLoc) const override;
108 
Init()109     void Init() override
110     {
111         nextGeneralRegNO = 0;
112         nextFloatRegNO = 0;
113         nextStackArgAdress = 0;
114     }
115 
116 private:
117     BECommon &beCommon;
118     int32 nextGeneralRegNO = 0; /* number of integer parameters processed so far */
119     uint32 nextFloatRegNO = 0;  /* number of float parameters processed so far */
120     static constexpr int32 kNumIntRetRegs = 8;
121     static constexpr int32 kNumFloatRetRegs = 8;
122     static constexpr int32 kNumIntParmRegs = 1;
123     static constexpr int32 kNumFloatParmRegs = 0;
124     static constexpr AArch64reg intReturnRegs[kNumIntRetRegs] = {R0, R1, R2, R3, R4, R5, R6, R7};
125     static constexpr AArch64reg floatReturnRegs[kNumFloatRetRegs] = {V0, V1, V2, V3, V4, V5, V6, V7};
126     static constexpr AArch64reg intParmRegs[kNumIntParmRegs] = {R0};
127     static constexpr AArch64reg floatParmRegs[kNumFloatParmRegs] = {};
128 
129     int32 ClassificationArg(const BECommon &be, const MIRType &mirType, std::vector<ArgumentClass> &classes) const;
130 
131     int32 ClassificationRet(const BECommon &be, const MIRType &mirType, std::vector<ArgumentClass> &classes) const;
132 
AllocateGPParmRegister()133     AArch64reg AllocateGPParmRegister()
134     {
135         DEBUG_ASSERT(nextGeneralRegNO >= 0, "nextGeneralRegNO can not be neg");
136         return (nextGeneralRegNO < AArch64WebKitJSCC::kNumIntParmRegs)
137                    ? AArch64WebKitJSCC::intParmRegs[nextGeneralRegNO++]
138                    : kRinvalid;
139     }
140 
AllocateGPRetRegister()141     AArch64reg AllocateGPRetRegister()
142     {
143         DEBUG_ASSERT(nextGeneralRegNO >= 0, "nextGeneralRegNO can not be neg");
144         return (nextGeneralRegNO < AArch64WebKitJSCC::kNumIntRetRegs)
145                    ? AArch64WebKitJSCC::intReturnRegs[nextGeneralRegNO++]
146                    : kRinvalid;
147     }
148 
AllocateSIMDFPRetRegister()149     AArch64reg AllocateSIMDFPRetRegister()
150     {
151         return (nextFloatRegNO < AArch64WebKitJSCC::kNumFloatRetRegs)
152                    ? AArch64WebKitJSCC::floatReturnRegs[nextFloatRegNO++]
153                    : kRinvalid;
154     }
155 };
156 
157 class GHCCC : public CCImpl {
158 public:
GHCCC(BECommon & be)159     explicit GHCCC(BECommon &be) : CCImpl(), beCommon(be) {}
160 
161     ~GHCCC() = default;
162 
163     /* Return size of aggregate structure copy on stack. */
164     uint64 LocateNextParm(const MIRType &mirType, CCLocInfo &pLoc, bool isFirst = false,
165                           MIRFuncType *func = nullptr) override;
166 
167     void LocateRetVal(const MIRType &retType, CCLocInfo &ploc) override;
168 
169     /*  return value related  */
170     void InitReturnInfo(MIRType &retTy, CCLocInfo &pLoc);
171 
172     // invalid interface
173     void SetupSecondRetReg(const MIRType &retTy2, CCLocInfo &pLoc) const override;
174 
Init()175     void Init() override
176     {
177         nextGeneralRegNO = 0;
178         nextFloatRegNOF32 = 0;
179         nextFloatRegNOF64 = 0;
180         nextFloatRegNOF128 = 0;
181         nextStackArgAdress = 0;
182     }
183 
184 private:
185     BECommon &beCommon;
186     int32 nextGeneralRegNO = 0; /* number of integer parameters processed so far */
187     uint32 nextFloatRegNOF32 = 0;
188     uint32 nextFloatRegNOF64 = 0;
189     uint32 nextFloatRegNOF128 = 0;
190     static constexpr int32 kNumIntParmRegs = 8;
191     static constexpr int32 kNumFloatParmRegsF32 = 4;
192     static constexpr int32 kNumFloatParmRegsF64 = 4;
193     static constexpr int32 kNumFloatParmRegsF128 = 2;
194     static constexpr AArch64reg intParmRegs[kNumIntParmRegs] = {R19, R20, R21, R22, R23, R24, R25, R26};
195     static constexpr AArch64reg floatParmRegsF32[kNumFloatParmRegsF32] = {V8, V9, V10, V11};
196     static constexpr AArch64reg floatParmRegsF64[kNumFloatParmRegsF64] = {V12, V13, V14, V15};
197     static constexpr AArch64reg floatParmRegsF128[kNumFloatParmRegsF128] = {V4, V5};
198 
199     int32 ClassificationArg(const BECommon &be, const MIRType &mirType, std::vector<ArgumentClass> &classes) const;
200 
AllocateGPParmRegister()201     AArch64reg AllocateGPParmRegister()
202     {
203         DEBUG_ASSERT(nextGeneralRegNO >= 0, "nextGeneralRegNO can not be neg");
204         return (nextGeneralRegNO < GHCCC::kNumIntParmRegs) ? GHCCC::intParmRegs[nextGeneralRegNO++] : kRinvalid;
205     }
206 
AllocateSIMDFPParmRegisterF32()207     AArch64reg AllocateSIMDFPParmRegisterF32()
208     {
209         return (nextFloatRegNOF32 < GHCCC::kNumFloatParmRegsF32) ? GHCCC::floatParmRegsF32[nextFloatRegNOF32++]
210                                                                  : kRinvalid;
211     }
212 
AllocateSIMDFPParmRegisterF64()213     AArch64reg AllocateSIMDFPParmRegisterF64()
214     {
215         return (nextFloatRegNOF64 < GHCCC::kNumFloatParmRegsF64) ? GHCCC::floatParmRegsF64[nextFloatRegNOF64++]
216                                                                  : kRinvalid;
217     }
218 
AllocateSIMDFPParmRegisterF128()219     AArch64reg AllocateSIMDFPParmRegisterF128()
220     {
221         return (nextFloatRegNOF128 < GHCCC::kNumFloatParmRegsF128) ? GHCCC::floatParmRegsF128[nextFloatRegNOF128++]
222                                                                    : kRinvalid;
223     }
224 };
225 
226 } /* namespace maplebe */
227 
228 #endif /* MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_CALL_CONV_H */
229