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 SetupToReturnThroughMemory(CCLocInfo & pLoc)49 void SetupToReturnThroughMemory(CCLocInfo &pLoc) const 50 { 51 pLoc.regCount = 1; 52 pLoc.reg0 = R8; 53 pLoc.primTypeOfReg0 = GetExactPtrPrimType(); 54 } 55 Init()56 void Init() override 57 { 58 nextGeneralRegNO = 0; 59 nextFloatRegNO = 0; 60 nextStackArgAdress = 0; 61 } 62 63 private: 64 BECommon &beCommon; 65 uint32 nextGeneralRegNO = 0; /* number of integer parameters processed so far */ 66 uint32 nextFloatRegNO = 0; /* number of float parameters processed so far */ 67 AllocateGPRegister()68 AArch64reg AllocateGPRegister() 69 { 70 DEBUG_ASSERT(nextGeneralRegNO >= 0, "nextGeneralRegNO can not be neg"); 71 return (nextGeneralRegNO < AArch64Abi::kNumIntParmRegs) ? AArch64Abi::intParmRegs[nextGeneralRegNO++] 72 : kRinvalid; 73 } 74 75 void AllocateGPRegister(const MIRType &mirType, CCLocInfo &pLoc, uint64 size, uint64 align); 76 AllocateSIMDFPRegister()77 AArch64reg AllocateSIMDFPRegister() 78 { 79 return (nextFloatRegNO < AArch64Abi::kNumFloatParmRegs) ? AArch64Abi::floatParmRegs[nextFloatRegNO++] 80 : kRinvalid; 81 } 82 }; 83 84 class AArch64WebKitJSCC : public CCImpl { 85 public: AArch64WebKitJSCC(BECommon & be)86 explicit AArch64WebKitJSCC(BECommon &be) : CCImpl(), beCommon(be) {} 87 88 ~AArch64WebKitJSCC() = default; 89 90 /* Return size of aggregate structure copy on stack. */ 91 uint64 LocateNextParm(const MIRType &mirType, CCLocInfo &pLoc, bool isFirst = false, 92 MIRFuncType *func = nullptr) override; 93 94 void LocateRetVal(const MIRType &retType, CCLocInfo &ploc) override; 95 96 /* return value related */ 97 void InitReturnInfo(MIRType &retTy, CCLocInfo &pLoc); 98 Init()99 void Init() override 100 { 101 nextGeneralRegNO = 0; 102 nextFloatRegNO = 0; 103 nextStackArgAdress = 0; 104 } 105 106 private: 107 BECommon &beCommon; 108 int32 nextGeneralRegNO = 0; /* number of integer parameters processed so far */ 109 uint32 nextFloatRegNO = 0; /* number of float parameters processed so far */ 110 static constexpr int32 kNumIntRetRegs = 8; 111 static constexpr int32 kNumFloatRetRegs = 8; 112 static constexpr int32 kNumIntParmRegs = 1; 113 static constexpr int32 kNumFloatParmRegs = 0; 114 static constexpr AArch64reg intReturnRegs[kNumIntRetRegs] = {R0, R1, R2, R3, R4, R5, R6, R7}; 115 static constexpr AArch64reg floatReturnRegs[kNumFloatRetRegs] = {V0, V1, V2, V3, V4, V5, V6, V7}; 116 static constexpr AArch64reg intParmRegs[kNumIntParmRegs] = {R0}; 117 static constexpr AArch64reg floatParmRegs[kNumFloatParmRegs] = {}; 118 119 int32 ClassificationArg(const BECommon &be, const MIRType &mirType, std::vector<ArgumentClass> &classes) const; 120 121 int32 ClassificationRet(const BECommon &be, const MIRType &mirType, std::vector<ArgumentClass> &classes) const; 122 AllocateGPParmRegister()123 AArch64reg AllocateGPParmRegister() 124 { 125 DEBUG_ASSERT(nextGeneralRegNO >= 0, "nextGeneralRegNO can not be neg"); 126 return (nextGeneralRegNO < AArch64WebKitJSCC::kNumIntParmRegs) 127 ? AArch64WebKitJSCC::intParmRegs[nextGeneralRegNO++] 128 : kRinvalid; 129 } 130 AllocateGPRetRegister()131 AArch64reg AllocateGPRetRegister() 132 { 133 DEBUG_ASSERT(nextGeneralRegNO >= 0, "nextGeneralRegNO can not be neg"); 134 return (nextGeneralRegNO < AArch64WebKitJSCC::kNumIntRetRegs) 135 ? AArch64WebKitJSCC::intReturnRegs[nextGeneralRegNO++] 136 : kRinvalid; 137 } 138 AllocateSIMDFPRetRegister()139 AArch64reg AllocateSIMDFPRetRegister() 140 { 141 return (nextFloatRegNO < AArch64WebKitJSCC::kNumFloatRetRegs) 142 ? AArch64WebKitJSCC::floatReturnRegs[nextFloatRegNO++] 143 : kRinvalid; 144 } 145 }; 146 } /* namespace maplebe */ 147 148 #endif /* MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_CALL_CONV_H */ 149