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_AARCH64_AARCH64_CALL_CONV_H 17 #define MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_CALL_CONV_H 18 19 #include "types_def.h" 20 #include "becommon.h" 21 #include "call_conv.h" 22 #include "aarch64_abi.h" 23 #include "abi.h" 24 25 namespace maplebe { 26 using namespace maple; 27 28 /* 29 * We use the names used in Procedure Call Standard for the Arm 64-bit 30 * Architecture (AArch64) 2022Q3. $6.8.2 31 * nextGeneralRegNO (= _int_parm_num) : Next General-purpose Register number 32 * nextFloatRegNO (= _float_parm_num): Next SIMD and Floating-point Register Number 33 * nextStackArgAdress (= _last_memOffset): Next Stacked Argument Address 34 * for processing an incoming or outgoing parameter list 35 */ 36 37 class AArch64CallConvImpl : public CCImpl { 38 public: AArch64CallConvImpl(BECommon & be)39 explicit AArch64CallConvImpl(BECommon &be) : CCImpl(), beCommon(be) {} 40 41 ~AArch64CallConvImpl() = default; 42 43 /* Return size of aggregate structure copy on stack. */ 44 uint64 LocateNextParm(const MIRType &mirType, CCLocInfo &pLoc, bool isFirst = false, 45 MIRFuncType *tFunc = nullptr) override; 46 47 void LocateRetVal(const MIRType &retType, CCLocInfo &ploc) override; 48 49 /* for lmbc */ 50 uint32 FloatParamRegRequired(const MIRStructType &structType, uint32 &fpSize); 51 52 void SetupSecondRetReg(const MIRType &retTy2, CCLocInfo &pLoc) const override; 53 SetupToReturnThroughMemory(CCLocInfo & pLoc)54 void SetupToReturnThroughMemory(CCLocInfo &pLoc) const 55 { 56 pLoc.regCount = 1; 57 pLoc.reg0 = R8; 58 pLoc.primTypeOfReg0 = GetExactPtrPrimType(); 59 } 60 Init()61 void Init() override 62 { 63 nextGeneralRegNO = 0; 64 nextFloatRegNO = 0; 65 nextStackArgAdress = 0; 66 } 67 68 private: 69 BECommon &beCommon; 70 uint32 nextGeneralRegNO = 0; /* number of integer parameters processed so far */ 71 uint32 nextFloatRegNO = 0; /* number of float parameters processed so far */ 72 AllocateGPRegister()73 AArch64reg AllocateGPRegister() 74 { 75 DEBUG_ASSERT(nextGeneralRegNO >= 0, "nextGeneralRegNO can not be neg"); 76 return (nextGeneralRegNO < AArch64Abi::kNumIntParmRegs) ? AArch64Abi::intParmRegs[nextGeneralRegNO++] 77 : kRinvalid; 78 } 79 80 void AllocateGPRegister(const MIRType &mirType, CCLocInfo &pLoc, uint64 size, uint64 align); 81 AllocateSIMDFPRegister()82 AArch64reg AllocateSIMDFPRegister() 83 { 84 return (nextFloatRegNO < AArch64Abi::kNumFloatParmRegs) ? AArch64Abi::floatParmRegs[nextFloatRegNO++] 85 : kRinvalid; 86 } 87 88 uint64 AllocateRegisterForAgg(const MIRType &mirType, CCLocInfo &pLoc, uint64 size, uint64 &align); 89 }; 90 91 class AArch64WebKitJSCC : public CCImpl { 92 public: AArch64WebKitJSCC(BECommon & be)93 explicit AArch64WebKitJSCC(BECommon &be) : CCImpl(), beCommon(be) {} 94 95 ~AArch64WebKitJSCC() = default; 96 97 /* Return size of aggregate structure copy on stack. */ 98 uint64 LocateNextParm(const MIRType &mirType, CCLocInfo &pLoc, bool isFirst = false, 99 MIRFuncType *func = nullptr) override; 100 101 void LocateRetVal(const MIRType &retType, CCLocInfo &ploc) override; 102 103 /* return value related */ 104 void InitReturnInfo(MIRType &retTy, CCLocInfo &pLoc); 105 106 // invalid interface 107 void SetupSecondRetReg(const MIRType &retTy2, CCLocInfo &pLoc) const override; 108 Init()109 void Init() override 110 { 111 nextGeneralRegNO = 0; 112 nextFloatRegNO = 0; 113 nextStackArgAdress = 0; 114 } 115 116 private: 117 BECommon &beCommon; 118 int32 nextGeneralRegNO = 0; /* number of integer parameters processed so far */ 119 uint32 nextFloatRegNO = 0; /* number of float parameters processed so far */ 120 static constexpr int32 kNumIntRetRegs = 8; 121 static constexpr int32 kNumFloatRetRegs = 8; 122 static constexpr int32 kNumIntParmRegs = 1; 123 static constexpr int32 kNumFloatParmRegs = 0; 124 static constexpr AArch64reg intReturnRegs[kNumIntRetRegs] = {R0, R1, R2, R3, R4, R5, R6, R7}; 125 static constexpr AArch64reg floatReturnRegs[kNumFloatRetRegs] = {V0, V1, V2, V3, V4, V5, V6, V7}; 126 static constexpr AArch64reg intParmRegs[kNumIntParmRegs] = {R0}; 127 static constexpr AArch64reg floatParmRegs[kNumFloatParmRegs] = {}; 128 129 int32 ClassificationArg(const BECommon &be, const MIRType &mirType, std::vector<ArgumentClass> &classes) const; 130 131 int32 ClassificationRet(const BECommon &be, const MIRType &mirType, std::vector<ArgumentClass> &classes) const; 132 AllocateGPParmRegister()133 AArch64reg AllocateGPParmRegister() 134 { 135 DEBUG_ASSERT(nextGeneralRegNO >= 0, "nextGeneralRegNO can not be neg"); 136 return (nextGeneralRegNO < AArch64WebKitJSCC::kNumIntParmRegs) 137 ? AArch64WebKitJSCC::intParmRegs[nextGeneralRegNO++] 138 : kRinvalid; 139 } 140 AllocateGPRetRegister()141 AArch64reg AllocateGPRetRegister() 142 { 143 DEBUG_ASSERT(nextGeneralRegNO >= 0, "nextGeneralRegNO can not be neg"); 144 return (nextGeneralRegNO < AArch64WebKitJSCC::kNumIntRetRegs) 145 ? AArch64WebKitJSCC::intReturnRegs[nextGeneralRegNO++] 146 : kRinvalid; 147 } 148 AllocateSIMDFPRetRegister()149 AArch64reg AllocateSIMDFPRetRegister() 150 { 151 return (nextFloatRegNO < AArch64WebKitJSCC::kNumFloatRetRegs) 152 ? AArch64WebKitJSCC::floatReturnRegs[nextFloatRegNO++] 153 : kRinvalid; 154 } 155 }; 156 157 class GHCCC : public CCImpl { 158 public: GHCCC(BECommon & be)159 explicit GHCCC(BECommon &be) : CCImpl(), beCommon(be) {} 160 161 ~GHCCC() = default; 162 163 /* Return size of aggregate structure copy on stack. */ 164 uint64 LocateNextParm(const MIRType &mirType, CCLocInfo &pLoc, bool isFirst = false, 165 MIRFuncType *func = nullptr) override; 166 167 void LocateRetVal(const MIRType &retType, CCLocInfo &ploc) override; 168 169 /* return value related */ 170 void InitReturnInfo(MIRType &retTy, CCLocInfo &pLoc); 171 172 // invalid interface 173 void SetupSecondRetReg(const MIRType &retTy2, CCLocInfo &pLoc) const override; 174 Init()175 void Init() override 176 { 177 nextGeneralRegNO = 0; 178 nextFloatRegNOF32 = 0; 179 nextFloatRegNOF64 = 0; 180 nextFloatRegNOF128 = 0; 181 nextStackArgAdress = 0; 182 } 183 184 private: 185 BECommon &beCommon; 186 int32 nextGeneralRegNO = 0; /* number of integer parameters processed so far */ 187 uint32 nextFloatRegNOF32 = 0; 188 uint32 nextFloatRegNOF64 = 0; 189 uint32 nextFloatRegNOF128 = 0; 190 static constexpr int32 kNumIntParmRegs = 8; 191 static constexpr int32 kNumFloatParmRegsF32 = 4; 192 static constexpr int32 kNumFloatParmRegsF64 = 4; 193 static constexpr int32 kNumFloatParmRegsF128 = 2; 194 static constexpr AArch64reg intParmRegs[kNumIntParmRegs] = {R19, R20, R21, R22, R23, R24, R25, R26}; 195 static constexpr AArch64reg floatParmRegsF32[kNumFloatParmRegsF32] = {V8, V9, V10, V11}; 196 static constexpr AArch64reg floatParmRegsF64[kNumFloatParmRegsF64] = {V12, V13, V14, V15}; 197 static constexpr AArch64reg floatParmRegsF128[kNumFloatParmRegsF128] = {V4, V5}; 198 199 int32 ClassificationArg(const BECommon &be, const MIRType &mirType, std::vector<ArgumentClass> &classes) const; 200 AllocateGPParmRegister()201 AArch64reg AllocateGPParmRegister() 202 { 203 DEBUG_ASSERT(nextGeneralRegNO >= 0, "nextGeneralRegNO can not be neg"); 204 return (nextGeneralRegNO < GHCCC::kNumIntParmRegs) ? GHCCC::intParmRegs[nextGeneralRegNO++] : kRinvalid; 205 } 206 AllocateSIMDFPParmRegisterF32()207 AArch64reg AllocateSIMDFPParmRegisterF32() 208 { 209 return (nextFloatRegNOF32 < GHCCC::kNumFloatParmRegsF32) ? GHCCC::floatParmRegsF32[nextFloatRegNOF32++] 210 : kRinvalid; 211 } 212 AllocateSIMDFPParmRegisterF64()213 AArch64reg AllocateSIMDFPParmRegisterF64() 214 { 215 return (nextFloatRegNOF64 < GHCCC::kNumFloatParmRegsF64) ? GHCCC::floatParmRegsF64[nextFloatRegNOF64++] 216 : kRinvalid; 217 } 218 AllocateSIMDFPParmRegisterF128()219 AArch64reg AllocateSIMDFPParmRegisterF128() 220 { 221 return (nextFloatRegNOF128 < GHCCC::kNumFloatParmRegsF128) ? GHCCC::floatParmRegsF128[nextFloatRegNOF128++] 222 : kRinvalid; 223 } 224 }; 225 226 } /* namespace maplebe */ 227 228 #endif /* MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_CALL_CONV_H */ 229