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; GetRegCountCCLocInfo40 uint8 GetRegCount() const 41 { 42 return regCount; 43 } 44 GetPrimTypeOfReg0CCLocInfo45 PrimType GetPrimTypeOfReg0() const 46 { 47 return primTypeOfReg0; 48 } 49 GetPrimTypeOfReg1CCLocInfo50 PrimType GetPrimTypeOfReg1() const 51 { 52 return primTypeOfReg1; 53 } 54 GetPrimTypeOfReg2CCLocInfo55 PrimType GetPrimTypeOfReg2() const 56 { 57 return primTypeOfReg2; 58 } 59 GetPrimTypeOfReg3CCLocInfo60 PrimType GetPrimTypeOfReg3() const 61 { 62 return primTypeOfReg3; 63 } 64 GetReg0CCLocInfo65 regno_t GetReg0() const 66 { 67 return reg0; 68 } 69 GetReg1CCLocInfo70 regno_t GetReg1() const 71 { 72 return reg1; 73 } 74 GetReg2CCLocInfo75 regno_t GetReg2() const 76 { 77 return reg2; 78 } 79 GetReg3CCLocInfo80 regno_t GetReg3() const 81 { 82 return reg3; 83 } 84 DumpCCLocInfo85 void Dump() 86 { 87 std::cout << "reg: " 88 << "[" << reg0 << "], " 89 << "[" << reg1 << "]\n"; 90 std::cout << "memBase: " << memOffset << " memSize: " << memSize << std::endl; 91 } 92 }; 93 94 class LmbcFormalParamInfo { 95 public: LmbcFormalParamInfo(PrimType pType,uint32 ofst,uint32 sz)96 LmbcFormalParamInfo(PrimType pType, uint32 ofst, uint32 sz) 97 : type(nullptr), 98 primType(pType), 99 offset(ofst), 100 onStackOffset(0), 101 size(sz), 102 regNO(0), 103 vregNO(0), 104 numRegs(0), 105 fpSize(0), 106 isReturn(false), 107 isPureFloat(false), 108 isOnStack(false), 109 hasRegassign(false) 110 { 111 } 112 113 ~LmbcFormalParamInfo() = default; 114 GetType()115 MIRStructType *GetType() 116 { 117 return type; 118 } SetType(MIRStructType * ty)119 void SetType(MIRStructType *ty) 120 { 121 type = ty; 122 } GetPrimType()123 PrimType GetPrimType() const 124 { 125 return primType; 126 } SetPrimType(PrimType pType)127 void SetPrimType(PrimType pType) 128 { 129 primType = pType; 130 } GetOffset()131 uint32 GetOffset() const 132 { 133 return offset; 134 } SetOffset(uint32 ofs)135 void SetOffset(uint32 ofs) 136 { 137 offset = ofs; 138 } GetOnStackOffset()139 uint32 GetOnStackOffset() const 140 { 141 return onStackOffset; 142 } SetOnStackOffset(uint32 ofs)143 void SetOnStackOffset(uint32 ofs) 144 { 145 onStackOffset = ofs; 146 } GetSize()147 uint32 GetSize() const 148 { 149 return size; 150 } SetSize(uint32 sz)151 void SetSize(uint32 sz) 152 { 153 size = sz; 154 } GetRegNO()155 regno_t GetRegNO() const 156 { 157 return regNO; 158 } SetRegNO(regno_t reg)159 void SetRegNO(regno_t reg) 160 { 161 regNO = reg; 162 } GetVregNO()163 regno_t GetVregNO() const 164 { 165 return vregNO; 166 } SetVregNO(regno_t reg)167 void SetVregNO(regno_t reg) 168 { 169 vregNO = reg; 170 } GetNumRegs()171 uint32 GetNumRegs() const 172 { 173 return numRegs; 174 } SetNumRegs(uint32 num)175 void SetNumRegs(uint32 num) 176 { 177 numRegs = num; 178 } GetFpSize()179 uint32 GetFpSize() const 180 { 181 return fpSize; 182 } SetFpSize(uint32 sz)183 void SetFpSize(uint32 sz) 184 { 185 fpSize = sz; 186 } IsReturn()187 bool IsReturn() const 188 { 189 return isReturn; 190 } SetIsReturn()191 void SetIsReturn() 192 { 193 isReturn = true; 194 } IsPureFloat()195 bool IsPureFloat() const 196 { 197 return isPureFloat; 198 } SetIsPureFloat()199 void SetIsPureFloat() 200 { 201 isPureFloat = true; 202 } IsInReg()203 bool IsInReg() const 204 { 205 return !isOnStack; 206 } IsOnStack()207 bool IsOnStack() const 208 { 209 return isOnStack; 210 } SetIsOnStack()211 void SetIsOnStack() 212 { 213 isOnStack = true; 214 } HasRegassign()215 bool HasRegassign() const 216 { 217 return hasRegassign; 218 } SetHasRegassign()219 void SetHasRegassign() 220 { 221 hasRegassign = true; 222 } 223 224 private: 225 MIRStructType *type; 226 PrimType primType; 227 uint32 offset; 228 uint32 onStackOffset; /* stack location if isOnStack */ 229 uint32 size; /* size primtype or struct */ 230 regno_t regNO = 0; /* param reg num or starting reg num if numRegs > 0 */ 231 regno_t vregNO = 0; /* if no explicit regassing from IR, create move from param reg */ 232 uint32 numRegs = 0; /* number of regs for struct param */ 233 uint32 fpSize = 0; /* size of fp param if isPureFloat */ 234 bool isReturn; 235 bool isPureFloat = false; 236 bool isOnStack; /* large struct is passed by a copy on stack */ 237 bool hasRegassign; 238 }; 239 240 class CCImpl { 241 public: 242 CCImpl() = default; 243 244 ~CCImpl() = default; 245 246 virtual int32 LocateNextParm(MIRType &mirType, CCLocInfo &pLoc, bool isFirst = false, 247 MIRFunction *func = nullptr) = 0; 248 249 virtual int32 LocateRetVal(MIRType &retType, CCLocInfo &ploc) = 0; 250 InitCCLocInfo(CCLocInfo & pLoc)251 void InitCCLocInfo(CCLocInfo &pLoc) const 252 { 253 pLoc.reg0 = kInvalidRegNO; 254 pLoc.reg1 = kInvalidRegNO; 255 pLoc.reg2 = kInvalidRegNO; 256 pLoc.reg3 = kInvalidRegNO; 257 pLoc.memOffset = nextStackArgAdress; 258 pLoc.fpSize = 0; 259 pLoc.numFpPureRegs = 0; 260 return; 261 }; 262 263 virtual void InitReturnInfo(MIRType &retTy, CCLocInfo &pLoc) = 0; 264 265 virtual void SetupSecondRetReg(const MIRType &retTy2, CCLocInfo &pLoc) const = 0; 266 267 virtual void Init() = 0; 268 GetCallConvKind(MIRFunction & mirFunction)269 static CallConvKind GetCallConvKind(MIRFunction &mirFunction) 270 { 271 if (mirFunction.GetAttr(FUNCATTR_ccall)) { 272 return kCCall; 273 } else if (mirFunction.GetAttr(FUNCATTR_webkitjscall)) { 274 return kWebKitJS; 275 } else if (mirFunction.GetAttr(FUNCATTR_ghcall)) { 276 return kGHC; 277 } else { 278 return kCCall; 279 } 280 } 281 GetCallConvKind(StmtNode & node)282 static CallConvKind GetCallConvKind(StmtNode &node) 283 { 284 if (node.GetAttr(STMTATTR_ccall)) { 285 return kCCall; 286 } else if (node.GetAttr(STMTATTR_webkitjscall)) { 287 return kWebKitJS; 288 } else if (node.GetAttr(STMTATTR_ghcall)) { 289 return kGHC; 290 } else { 291 return kCCall; 292 } 293 } 294 295 protected: 296 int32 nextStackArgAdress = 0; 297 }; 298 } /* namespace maplebe */ 299 300 #endif /* MAPLEBE_INCLUDE_CG_CALL_CONV_H */ 301