• 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_X64_X64_CALL_CONV_H
17 #define MAPLEBE_INCLUDE_CG_X64_X64_CALL_CONV_H
18 
19 #include "types_def.h"
20 #include "becommon.h"
21 #include "call_conv.h"
22 #include "abi.h"
23 #include "x64_abi.h"
24 #include "x64_isa.h"
25 #include <vector>
26 
27 namespace maplebe {
28 using namespace maple;
29 using namespace x64;
30 constexpr const uint32 kMaxStructParamByReg = 4;
31 
32 class CallConventionInfo {
33 public:
34     virtual const std::vector<X64reg> &GetIntParamRegs() const = 0;
35     virtual size_t GetIntParamRegsNum() const = 0;
36     virtual const std::vector<X64reg> &GetIntReturnRegs() const = 0;
37     virtual size_t GetIntReturnRegsNum() const = 0;
38     virtual const std::vector<X64reg> &GetFloatParamRegs() const = 0;
39     virtual size_t GetFloatParamRegsNum() const = 0;
40     virtual const std::vector<X64reg> &GetFloatReturnRegs() const = 0;
41     virtual size_t GetFloatReturnRegsNum() const = 0;
42     virtual int32 Classification(const BECommon &be, MIRType &mirType, std::vector<ArgumentClass> &classes) const = 0;
43 };
44 
45 #define CALL_CONVENTION_INFO_SUBCLASS_DECLARE_BEGIN(CLASSNAME)                    \
46     class CLASSNAME : public CallConventionInfo {                                 \
47     public:                                                                       \
48         const std::vector<X64reg> &GetIntParamRegs() const override               \
49         {                                                                         \
50             return intParmRegs;                                                   \
51         }                                                                         \
52         size_t GetIntParamRegsNum() const override                                \
53         {                                                                         \
54             return intParmRegs.size();                                            \
55         }                                                                         \
56         const std::vector<X64reg> &GetIntReturnRegs() const override              \
57         {                                                                         \
58             return intReturnRegs;                                                 \
59         }                                                                         \
60         size_t GetIntReturnRegsNum() const override                               \
61         {                                                                         \
62             return intReturnRegs.size();                                          \
63         }                                                                         \
64         const std::vector<X64reg> &GetFloatParamRegs() const override             \
65         {                                                                         \
66             return floatParmRegs;                                                 \
67         }                                                                         \
68         size_t GetFloatParamRegsNum() const override                              \
69         {                                                                         \
70             return floatParmRegs.size();                                          \
71         }                                                                         \
72         const std::vector<X64reg> &GetFloatReturnRegs() const override            \
73         {                                                                         \
74             return floatReturnRegs;                                               \
75         }                                                                         \
76         size_t GetFloatReturnRegsNum() const override                             \
77         {                                                                         \
78             return floatReturnRegs.size();                                        \
79         }                                                                         \
80         const static CLASSNAME &GetCallConvInfo()                                 \
81         {                                                                         \
82             static CLASSNAME callConvInfo;                                        \
83             return callConvInfo;                                                  \
84         }                                                                         \
85         int32 Classification(const BECommon &be, MIRType &mirType,                \
86                              std::vector<ArgumentClass> &classes) const override; \
87                                                                                   \
88     private:                                                                      \
89         CLASSNAME() {}                                                            \
90         ~CLASSNAME() {}                                                           \
91         CLASSNAME &operator=(const CLASSNAME &);                                  \
92         CLASSNAME(const CLASSNAME &);
93 
94 #define CALL_CONVENTION_INFO_SUBCLASS_DECLARE_END \
95     }                                             \
96     ;
97 
CALL_CONVENTION_INFO_SUBCLASS_DECLARE_BEGIN(WebKitJSCallConventionInfo)98 CALL_CONVENTION_INFO_SUBCLASS_DECLARE_BEGIN(WebKitJSCallConventionInfo)
99 
100 const std::vector<X64reg> intParmRegs {
101     RAX};
102 const std::vector<X64reg> intReturnRegs {
103     RAX};
104 const std::vector<X64reg> floatParmRegs{};
105 const std::vector<X64reg> floatReturnRegs{};
106 CALL_CONVENTION_INFO_SUBCLASS_DECLARE_END
107 
CALL_CONVENTION_INFO_SUBCLASS_DECLARE_BEGIN(CCallConventionInfo)108 CALL_CONVENTION_INFO_SUBCLASS_DECLARE_BEGIN(CCallConventionInfo)
109 const std::vector<X64reg> intParmRegs {
110     RDI, RSI, RDX, RCX, X64reg::R8, X64reg::R9};
111 const std::vector<X64reg> intReturnRegs {
112     RAX, RDX};
113 const std::vector<X64reg> floatParmRegs = {
114     X64reg::V0, X64reg::V1, X64reg::V2, X64reg::V3, X64reg::V4, X64reg::V5, X64reg::V6, X64reg::V7};
115 const std::vector<X64reg> floatReturnRegs = {
116     X64reg::V0, X64reg::V1 };
117 
118 int32 ClassifyAggregate(MIRType &mirType, uint64 sizeOfTy, std::vector<ArgumentClass> &classes) const;
119 CALL_CONVENTION_INFO_SUBCLASS_DECLARE_END
120 
CALL_CONVENTION_INFO_SUBCLASS_DECLARE_BEGIN(GHCCallConventionInfo)121 CALL_CONVENTION_INFO_SUBCLASS_DECLARE_BEGIN(GHCCallConventionInfo)
122 const std::vector<X64reg> intParmRegs {
123     X64reg::R13, RBP, X64reg::R12, RBX, X64reg::R14, RSI, RDI, X64reg::R8, X64reg::R9, X64reg::R15};
124 const std::vector<X64reg> intReturnRegs{};
125 const std::vector<X64reg> floatParmRegs{};
126 const std::vector<X64reg> floatReturnRegs{};
127 CALL_CONVENTION_INFO_SUBCLASS_DECLARE_END
128 
129 class X64CallConvImpl {
130 public:
X64CallConvImpl(BECommon & be)131     X64CallConvImpl(BECommon &be) : beCommon(be)
132     {
133         convKind = GetCallConvKind(*(be.GetMIRModule().CurFunction()));
134     }
X64CallConvImpl(BECommon & be,CallConvKind convKind)135     X64CallConvImpl(BECommon &be, CallConvKind convKind) : beCommon(be), convKind(convKind) {}
136 
137     ~X64CallConvImpl() = default;
138 
GetCallConvInfo()139     const CallConventionInfo &GetCallConvInfo() const
140     {
141         return GetCallConvInfo(convKind);
142     }
143 
GetCallConvInfo(CallConvKind convKind_)144     static const CallConventionInfo &GetCallConvInfo(CallConvKind convKind_)
145     {
146         switch (convKind_) {
147             case kCCall:
148                 return CCallConventionInfo::GetCallConvInfo();
149             case kWebKitJS:
150                 return WebKitJSCallConventionInfo::GetCallConvInfo();
151             case kGHC:
152                 return GHCCallConventionInfo::GetCallConvInfo();
153             default:
154                 return CCallConventionInfo::GetCallConvInfo();
155         }
156     }
157 
GetCallConvKind(MIRFunction & mirFunction)158     static CallConvKind GetCallConvKind(MIRFunction &mirFunction)
159     {
160         if (mirFunction.GetAttr(FUNCATTR_ccall)) {
161             return kCCall;
162         } else if (mirFunction.GetAttr(FUNCATTR_webkitjscall)) {
163             return kWebKitJS;
164         } else if (mirFunction.GetAttr(FUNCATTR_ghcall)) {
165             return kGHC;
166         } else {
167             return kCCall;
168         }
169     }
170 
GetCallConvKind(StmtNode & node)171     static CallConvKind GetCallConvKind(StmtNode &node)
172     {
173         if (node.GetAttr(STMTATTR_ccall)) {
174             return kCCall;
175         } else if (node.GetAttr(STMTATTR_webkitjscall)) {
176             return kWebKitJS;
177         } else if (node.GetAttr(STMTATTR_ghcall)) {
178             return kGHC;
179         } else {
180             return kCCall;
181         }
182     }
183 
184     void InitCCLocInfo(CCLocInfo &pLoc) const;
185 
186     /* Passing  value related */
187     int32 LocateNextParm(MIRType &mirType, CCLocInfo &pLoc, bool isFirst = false, MIRFunction *func = nullptr);
188 
189     /*  return value related  */
190     int32 LocateRetVal(MIRType &retType, CCLocInfo &ploc);
191 
192 private:
AllocateGPParmRegister()193     X64reg AllocateGPParmRegister()
194     {
195         const std::vector<X64reg> &intParamRegs = GetCallConvInfo().GetIntParamRegs();
196         return (nextGeneralParmRegNO < intParamRegs.size()) ? intParamRegs[nextGeneralParmRegNO++] : X64reg::kRinvalid;
197     }
198 
AllocateTwoGPParmRegisters(CCLocInfo & pLoc)199     void AllocateTwoGPParmRegisters(CCLocInfo &pLoc)
200     {
201         const std::vector<X64reg> &intParamRegs = GetCallConvInfo().GetIntParamRegs();
202         if ((nextGeneralParmRegNO + 1) < intParamRegs.size()) {
203             pLoc.reg0 = intParamRegs[nextGeneralParmRegNO++];
204             pLoc.reg1 = intParamRegs[nextGeneralParmRegNO++];
205         } else {
206             pLoc.reg0 = X64reg::kRinvalid;
207         }
208     }
209 
AllocateSIMDFPRegister()210     X64reg AllocateSIMDFPRegister()
211     {
212         return (nextFloatRegNO < kNumFloatParmRegs) ? kFloatParmRegs[nextFloatRegNO++] : X64reg::kRinvalid;
213     }
214 
AllocateGPReturnRegister()215     X64reg AllocateGPReturnRegister()
216     {
217         const std::vector<X64reg> &intReturnRegs = GetCallConvInfo().GetIntReturnRegs();
218         return (nextGeneralReturnRegNO < intReturnRegs.size()) ?
219             intReturnRegs[nextGeneralReturnRegNO++] : X64reg::kRinvalid;
220     }
221 
AllocateTwoGPReturnRegisters(CCLocInfo & pLoc)222     void AllocateTwoGPReturnRegisters(CCLocInfo &pLoc)
223     {
224         const std::vector<X64reg> &intReturnRegs = GetCallConvInfo().GetIntReturnRegs();
225         if ((nextGeneralReturnRegNO + 1) < intReturnRegs.size()) {
226             pLoc.reg0 = intReturnRegs[nextGeneralReturnRegNO++];
227             pLoc.reg1 = intReturnRegs[nextGeneralReturnRegNO++];
228         } else {
229             pLoc.reg0 = X64reg::kRinvalid;
230         }
231     }
232 
AllocateSIMDFPReturnRegister()233     X64reg AllocateSIMDFPReturnRegister()
234     {
235         return (nextFloatRetRegNO < kNumFloatReturnRegs) ? kFloatReturnRegs[nextFloatRetRegNO++] : X64reg::kRinvalid;
236     }
237 
238     BECommon &beCommon;
239     CallConvKind convKind = kCCall;
240     uint64 paramNum = 0;               /* number of all types of parameters processed so far */
241     uint32 nextGeneralParmRegNO = 0;   /* number of integer parameters processed so far */
242     uint32 nextGeneralReturnRegNO = 0; /* number of integer return processed so far */
243     uint32 nextStackArgAdress = 0;
244     uint32 nextFloatRegNO = 0;
245     uint32 nextFloatRetRegNO = 0;
246 };
247 } /* namespace maplebe */
248 
249 #endif /* MAPLEBE_INCLUDE_CG_X64_X64_CALL_CONV_H */
250