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 "x64_cgfunc.h"
17 #include "x64_call_conv.h"
18 namespace maplebe {
19 using namespace maple;
20 using namespace x64;
21
Classification(const BECommon & be,MIRType & mirType,std::vector<ArgumentClass> & classes) const22 int32 CCallConventionInfo::Classification(const BECommon &be, MIRType &mirType,
23 std::vector<ArgumentClass> &classes) const
24 {
25 switch (mirType.GetPrimType()) {
26 /*
27 * Arguments of types void, (signed and unsigned) _Bool, char, short, int,
28 * long, long long, and pointers are in the INTEGER class.
29 */
30 case PTY_void:
31 case PTY_u1:
32 case PTY_u8:
33 case PTY_i8:
34 case PTY_u16:
35 case PTY_i16:
36 case PTY_u32:
37 case PTY_i32:
38 case PTY_a64:
39 case PTY_ptr:
40 case PTY_ref:
41 case PTY_u64:
42 case PTY_i64:
43 classes.push_back(kIntegerClass);
44 return k8ByteSize;
45 case PTY_f32:
46 case PTY_f64:
47 classes.push_back(kFloatClass);
48 return k8ByteSize;
49 default:
50 CHECK_FATAL(false, "NYI");
51 }
52 return 0;
53 }
54
Classification(const BECommon & be,MIRType & mirType,std::vector<ArgumentClass> & classes) const55 int32 WebKitJSCallConventionInfo::Classification(const BECommon &be, MIRType &mirType,
56 std::vector<ArgumentClass> &classes) const
57 {
58 switch (mirType.GetPrimType()) {
59 /*
60 * Arguments of types void, (signed and unsigned) _Bool, char, short, int,
61 * long, long long, and pointers are in the INTEGER class.
62 */
63 case PTY_void:
64 case PTY_u1:
65 case PTY_u8:
66 case PTY_i8:
67 case PTY_u16:
68 case PTY_i16:
69 case PTY_u32:
70 case PTY_i32:
71 classes.push_back(kIntegerClass);
72 return k4ByteSize;
73 case PTY_a64:
74 case PTY_ptr:
75 case PTY_ref:
76 case PTY_u64:
77 case PTY_i64:
78 classes.push_back(kIntegerClass);
79 return k8ByteSize;
80 case PTY_f32:
81 classes.push_back(kFloatClass);
82 return k4ByteSize;
83 case PTY_f64:
84 classes.push_back(kFloatClass);
85 return k8ByteSize;
86 default:
87 CHECK_FATAL(false, "NYI");
88 }
89 return 0;
90 }
91
Classification(const BECommon & be,MIRType & mirType,std::vector<ArgumentClass> & classes) const92 int32 GHCCallConventionInfo::Classification(const BECommon &be, MIRType &mirType,
93 std::vector<ArgumentClass> &classes) const
94 {
95 switch (mirType.GetPrimType()) {
96 case PTY_u1:
97 case PTY_u8:
98 case PTY_i8:
99 case PTY_u16:
100 case PTY_i16:
101 case PTY_u32:
102 case PTY_i32:
103 case PTY_a64:
104 case PTY_ptr:
105 case PTY_ref:
106 case PTY_u64:
107 case PTY_i64:
108 classes.push_back(kIntegerClass);
109 return k8ByteSize;
110 default:
111 CHECK_FATAL(false, "NYI");
112 }
113 return 0;
114 }
115
InitCCLocInfo(CCLocInfo & pLoc) const116 void X64CallConvImpl::InitCCLocInfo(CCLocInfo &pLoc) const
117 {
118 pLoc.reg0 = kRinvalid;
119 pLoc.reg1 = kRinvalid;
120 pLoc.reg2 = kRinvalid;
121 pLoc.reg3 = kRinvalid;
122 pLoc.memOffset = nextStackArgAdress;
123 pLoc.fpSize = 0;
124 pLoc.numFpPureRegs = 0;
125 }
126
LocateNextParm(MIRType & mirType,CCLocInfo & pLoc,bool isFirst,MIRFunction * tFunc)127 int32 X64CallConvImpl::LocateNextParm(MIRType &mirType, CCLocInfo &pLoc, bool isFirst, MIRFunction *tFunc)
128 {
129 InitCCLocInfo(pLoc);
130 std::vector<ArgumentClass> classes {};
131 int32 alignedTySize = GetCallConvInfo().Classification(beCommon, mirType, classes);
132 if (alignedTySize == 0) {
133 return 0;
134 }
135 pLoc.memSize = alignedTySize;
136 ++paramNum;
137 if (classes[0] == kIntegerClass) {
138 CHECK_FATAL((alignedTySize == k4ByteSize) || (alignedTySize == k8ByteSize), "NIY");
139 pLoc.reg0 = AllocateGPParmRegister();
140 DEBUG_ASSERT(nextGeneralParmRegNO <= GetCallConvInfo().GetIntParamRegsNum(), "RegNo should be pramRegNO");
141 } else if (classes[0] == kFloatClass) {
142 CHECK_FATAL(alignedTySize == k8ByteSize, "NIY");
143 pLoc.reg0 = AllocateSIMDFPRegister();
144 DEBUG_ASSERT(nextGeneralParmRegNO <= kNumFloatParmRegs, "RegNo should be pramRegNO");
145 }
146 if (pLoc.reg0 == kRinvalid || classes[0] == kMemoryClass) {
147 /* being passed in memory */
148 nextStackArgAdress = pLoc.memOffset + alignedTySize;
149 }
150 return 0;
151 }
152
LocateRetVal(MIRType & retType,CCLocInfo & pLoc)153 int32 X64CallConvImpl::LocateRetVal(MIRType &retType, CCLocInfo &pLoc)
154 {
155 InitCCLocInfo(pLoc);
156 std::vector<ArgumentClass> classes {}; /* Max of four Regs. */
157 uint32 alignedTySize = static_cast<uint32>(GetCallConvInfo().Classification(beCommon, retType, classes));
158 if (alignedTySize == 0) {
159 return 0; /* size 0 ret val */
160 }
161 if (classes[0] == kIntegerClass) {
162 /* If the class is INTEGER, the next available register of the sequence %rax, */
163 /* %rdx is used. */
164 CHECK_FATAL((alignedTySize == k4ByteSize) || (alignedTySize == k8ByteSize),
165 "LocateRetVal: illegal number of regs");
166 pLoc.regCount = kOneRegister;
167 pLoc.reg0 = AllocateGPReturnRegister();
168 DEBUG_ASSERT(nextGeneralReturnRegNO <= GetCallConvInfo().GetIntReturnRegsNum(), "RegNo should be pramRegNO");
169 CHECK_FATAL(nextGeneralReturnRegNO == kOneRegister, "RegNo should be pramRegNO");
170 pLoc.primTypeOfReg0 = retType.GetPrimType();
171 return 0;
172 } else if (classes[0] == kFloatClass) {
173 /* If the class is SSE, the next available vector register of the sequence %xmm0, */
174 /* %xmm1 is used. */
175 CHECK_FATAL(alignedTySize == k8ByteSize, "LocateRetVal: illegal number of regs");
176 pLoc.regCount = 1;
177 pLoc.reg0 = AllocateSIMDFPReturnRegister();
178 CHECK_FATAL(nextFloatRetRegNO == kOneRegister, "RegNo should be pramRegNO");
179 pLoc.primTypeOfReg0 = retType.GetPrimType();
180 return 0;
181 }
182 CHECK_FATAL(false, "NYI");
183 return 0;
184 }
185 } /* namespace maplebe */
186