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_CALL_CONV_H 17 #define MAPLEBE_INCLUDE_CG_CALL_CONV_H 18 19 #include "types_def.h" 20 #include "becommon.h" 21 22 namespace maplebe { 23 using namespace maple; 24 enum CallConvKind { kCCall, kWebKitJS, kGHC }; 25 /* for specifying how a parameter is passed */ 26 struct CCLocInfo { 27 regno_t reg0 = 0; /* 0 means parameter is stored on the stack */ 28 regno_t reg1 = 0; 29 regno_t reg2 = 0; /* can have up to 4 single precision fp registers */ 30 regno_t reg3 = 0; /* for small structure return. */ 31 int32 memOffset = 0; 32 int32 memSize = 0; 33 uint32 fpSize = 0; 34 uint32 numFpPureRegs = 0; 35 uint8 regCount = 0; /* number of registers <= 2 storing the return value */ 36 PrimType primTypeOfReg0; /* the primitive type stored in reg0 */ 37 PrimType primTypeOfReg1; /* the primitive type stored in reg1 */ 38 PrimType primTypeOfReg2; 39 PrimType primTypeOfReg3; 40 ClearCCLocInfo41 void Clear() 42 { 43 reg0 = kInvalidRegNO; 44 reg1 = kInvalidRegNO; 45 reg2 = kInvalidRegNO; 46 reg3 = kInvalidRegNO; 47 memOffset = 0; 48 memSize = 0; 49 fpSize = 0; 50 numFpPureRegs = 0; 51 regCount = 0; 52 primTypeOfReg0 = PTY_begin; 53 primTypeOfReg1 = PTY_begin; 54 primTypeOfReg2 = PTY_begin; 55 primTypeOfReg3 = PTY_begin; 56 } 57 GetRegCountCCLocInfo58 uint8 GetRegCount() const 59 { 60 return regCount; 61 } 62 GetPrimTypeOfReg0CCLocInfo63 PrimType GetPrimTypeOfReg0() const 64 { 65 return primTypeOfReg0; 66 } 67 GetPrimTypeOfReg1CCLocInfo68 PrimType GetPrimTypeOfReg1() const 69 { 70 return primTypeOfReg1; 71 } 72 GetPrimTypeOfReg2CCLocInfo73 PrimType GetPrimTypeOfReg2() const 74 { 75 return primTypeOfReg2; 76 } 77 GetPrimTypeOfReg3CCLocInfo78 PrimType GetPrimTypeOfReg3() const 79 { 80 return primTypeOfReg3; 81 } 82 GetReg0CCLocInfo83 regno_t GetReg0() const 84 { 85 return reg0; 86 } 87 GetReg1CCLocInfo88 regno_t GetReg1() const 89 { 90 return reg1; 91 } 92 GetReg2CCLocInfo93 regno_t GetReg2() const 94 { 95 return reg2; 96 } 97 GetReg3CCLocInfo98 regno_t GetReg3() const 99 { 100 return reg3; 101 } 102 DumpCCLocInfo103 void Dump() 104 { 105 std::cout << "reg: " 106 << "[" << reg0 << "], " 107 << "[" << reg1 << "]\n"; 108 std::cout << "memBase: " << memOffset << " memSize: " << memSize << std::endl; 109 } 110 }; 111 112 class LmbcFormalParamInfo { 113 public: LmbcFormalParamInfo(PrimType pType,uint32 ofst,uint32 sz)114 LmbcFormalParamInfo(PrimType pType, uint32 ofst, uint32 sz) 115 : type(nullptr), 116 primType(pType), 117 offset(ofst), 118 onStackOffset(0), 119 size(sz), 120 regNO(0), 121 vregNO(0), 122 numRegs(0), 123 fpSize(0), 124 isReturn(false), 125 isPureFloat(false), 126 isOnStack(false), 127 hasRegassign(false) 128 { 129 } 130 131 ~LmbcFormalParamInfo() = default; 132 GetType()133 MIRStructType *GetType() 134 { 135 return type; 136 } SetType(MIRStructType * ty)137 void SetType(MIRStructType *ty) 138 { 139 type = ty; 140 } GetPrimType()141 PrimType GetPrimType() const 142 { 143 return primType; 144 } SetPrimType(PrimType pType)145 void SetPrimType(PrimType pType) 146 { 147 primType = pType; 148 } GetOffset()149 uint32 GetOffset() const 150 { 151 return offset; 152 } SetOffset(uint32 ofs)153 void SetOffset(uint32 ofs) 154 { 155 offset = ofs; 156 } GetOnStackOffset()157 uint32 GetOnStackOffset() const 158 { 159 return onStackOffset; 160 } SetOnStackOffset(uint32 ofs)161 void SetOnStackOffset(uint32 ofs) 162 { 163 onStackOffset = ofs; 164 } GetSize()165 uint32 GetSize() const 166 { 167 return size; 168 } SetSize(uint32 sz)169 void SetSize(uint32 sz) 170 { 171 size = sz; 172 } GetRegNO()173 regno_t GetRegNO() const 174 { 175 return regNO; 176 } SetRegNO(regno_t reg)177 void SetRegNO(regno_t reg) 178 { 179 regNO = reg; 180 } GetVregNO()181 regno_t GetVregNO() const 182 { 183 return vregNO; 184 } SetVregNO(regno_t reg)185 void SetVregNO(regno_t reg) 186 { 187 vregNO = reg; 188 } GetNumRegs()189 uint32 GetNumRegs() const 190 { 191 return numRegs; 192 } SetNumRegs(uint32 num)193 void SetNumRegs(uint32 num) 194 { 195 numRegs = num; 196 } GetFpSize()197 uint32 GetFpSize() const 198 { 199 return fpSize; 200 } SetFpSize(uint32 sz)201 void SetFpSize(uint32 sz) 202 { 203 fpSize = sz; 204 } IsReturn()205 bool IsReturn() const 206 { 207 return isReturn; 208 } SetIsReturn()209 void SetIsReturn() 210 { 211 isReturn = true; 212 } IsPureFloat()213 bool IsPureFloat() const 214 { 215 return isPureFloat; 216 } SetIsPureFloat()217 void SetIsPureFloat() 218 { 219 isPureFloat = true; 220 } IsInReg()221 bool IsInReg() const 222 { 223 return !isOnStack; 224 } IsOnStack()225 bool IsOnStack() const 226 { 227 return isOnStack; 228 } SetIsOnStack()229 void SetIsOnStack() 230 { 231 isOnStack = true; 232 } HasRegassign()233 bool HasRegassign() const 234 { 235 return hasRegassign; 236 } SetHasRegassign()237 void SetHasRegassign() 238 { 239 hasRegassign = true; 240 } 241 242 private: 243 MIRStructType *type; 244 PrimType primType; 245 uint32 offset; 246 uint32 onStackOffset; /* stack location if isOnStack */ 247 uint32 size; /* size primtype or struct */ 248 regno_t regNO = 0; /* param reg num or starting reg num if numRegs > 0 */ 249 regno_t vregNO = 0; /* if no explicit regassing from IR, create move from param reg */ 250 uint32 numRegs = 0; /* number of regs for struct param */ 251 uint32 fpSize = 0; /* size of fp param if isPureFloat */ 252 bool isReturn; 253 bool isPureFloat = false; 254 bool isOnStack; /* large struct is passed by a copy on stack */ 255 bool hasRegassign; 256 }; 257 258 class CCImpl { 259 public: 260 CCImpl() = default; 261 262 ~CCImpl() = default; 263 264 virtual uint64 LocateNextParm(const MIRType &mirType, CCLocInfo &pLoc, bool isFirst = false, 265 MIRFuncType *tFunc = nullptr) = 0; 266 267 virtual void LocateRetVal(const MIRType &retType, CCLocInfo &ploc) = 0; 268 InitCCLocInfo(CCLocInfo & pLoc)269 void InitCCLocInfo(CCLocInfo &pLoc) const 270 { 271 pLoc.reg0 = kInvalidRegNO; 272 pLoc.reg1 = kInvalidRegNO; 273 pLoc.reg2 = kInvalidRegNO; 274 pLoc.reg3 = kInvalidRegNO; 275 pLoc.memOffset = nextStackArgAdress; 276 pLoc.fpSize = 0; 277 pLoc.numFpPureRegs = 0; 278 return; 279 }; 280 281 virtual void SetupSecondRetReg(const MIRType &retTy2, CCLocInfo &pLoc) const = 0; 282 283 virtual void Init() = 0; 284 GetCallConvKind(MIRFunction & mirFunction)285 static CallConvKind GetCallConvKind(MIRFunction &mirFunction) 286 { 287 if (mirFunction.GetAttr(FUNCATTR_ccall)) { 288 return kCCall; 289 } else if (mirFunction.GetAttr(FUNCATTR_webkitjscall)) { 290 return kWebKitJS; 291 } else if (mirFunction.GetAttr(FUNCATTR_ghcall)) { 292 return kGHC; 293 } else { 294 return kCCall; 295 } 296 } 297 GetCallConvKind(StmtNode & node)298 static CallConvKind GetCallConvKind(StmtNode &node) 299 { 300 if (node.GetAttr(STMTATTR_ccall)) { 301 return kCCall; 302 } else if (node.GetAttr(STMTATTR_webkitjscall)) { 303 return kWebKitJS; 304 } else if (node.GetAttr(STMTATTR_ghcall)) { 305 return kGHC; 306 } else { 307 return kCCall; 308 } 309 } 310 311 protected: 312 int32 nextStackArgAdress = 0; 313 }; 314 } /* namespace maplebe */ 315 316 #endif /* MAPLEBE_INCLUDE_CG_CALL_CONV_H */ 317