• 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 #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