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_X86_64_CGFUNC_H 17 #define MAPLEBE_INCLUDE_CG_X86_64_CGFUNC_H 18 19 #include "cgfunc.h" 20 #include "x64_memlayout.h" 21 #include "x64_isa.h" 22 #include "x64_reg_info.h" 23 #include "x64_optimize_common.h" 24 25 namespace maplebe { 26 class X64CGFunc : public CGFunc { 27 public: X64CGFunc(MIRModule & mod,CG & c,MIRFunction & f,BECommon & b,MemPool & memPool,StackMemPool & stackMp,MapleAllocator & mallocator,uint32 funcId)28 X64CGFunc(MIRModule &mod, CG &c, MIRFunction &f, BECommon &b, MemPool &memPool, StackMemPool &stackMp, 29 MapleAllocator &mallocator, uint32 funcId) 30 : CGFunc(mod, c, f, b, memPool, stackMp, mallocator, funcId), calleeSavedRegs(mallocator.Adapter()) 31 { 32 CGFunc::SetMemlayout(*memPool.New<X64MemLayout>(b, f, mallocator)); 33 CGFunc::GetMemlayout()->SetCurrFunction(*this); 34 CGFunc::SetTargetRegInfo(*memPool.New<X64RegInfo>(mallocator, X64CallConvImpl::GetCallConvKind(f))); 35 CGFunc::GetTargetRegInfo()->SetCurrFunction(*this); 36 } 37 /* null implementation yet */ NewInsnModifier()38 InsnVisitor *NewInsnModifier() override 39 { 40 return memPool->New<X64InsnVisitor>(*this); 41 } 42 void GenSaveMethodInfoCode(BB &bb) override; 43 void GenerateCleanupCode(BB &bb) override; 44 bool NeedCleanup() override; 45 void GenerateCleanupCodeForExtEpilog(BB &bb) override; 46 uint32 FloatParamRegRequired(MIRStructType *structType, uint32 &fpSize) override; 47 void AssignLmbcFormalParams() override; 48 void LmbcGenSaveSpForAlloca() override; 49 void MergeReturn() override; 50 void HandleRCCall(bool begin, const MIRSymbol *retRef = nullptr) override; 51 void HandleRetCleanup(NaryStmtNode &retNode) override; 52 void SelectDassign(DassignNode &stmt, Operand &opnd0) override; 53 void SelectDassignoff(DassignoffNode &stmt, Operand &opnd0) override; 54 void SelectRegassign(RegassignNode &stmt, Operand &opnd0) override; 55 void SelectAbort() override; 56 void SelectAssertNull(UnaryStmtNode &stmt) override; 57 void SelectAsm(AsmNode &node) override; 58 void SelectAggDassign(DassignNode &stmt) override; 59 void SelectIassign(IassignNode &stmt) override; 60 void SelectIassignoff(IassignoffNode &stmt) override; 61 void SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) override; 62 void SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd) override; 63 void SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) override; 64 void SelectAggIassign(IassignNode &stmt, Operand &lhsAddrOpnd) override; 65 void SelectReturnSendOfStructInRegs(BaseNode *x) override; 66 void SelectReturn(Operand *opnd) override; 67 void SelectIgoto(Operand *opnd0) override; 68 void SelectCondGoto(CondGotoNode &stmt, Operand &opnd0, Operand &opnd1) override; 69 void SelectCondSpecialCase1(CondGotoNode &stmt, BaseNode &opnd0) override; 70 void SelectCondSpecialCase2(const CondGotoNode &stmt, BaseNode &opnd0) override; 71 void SelectGoto(GotoNode &stmt) override; 72 void SelectCall(CallNode &callNode) override; 73 void SelectIcall(IcallNode &icallNode) override; 74 void SelectIntrinsicCall(IntrinsiccallNode &intrinsiccallNode) override; 75 Operand *SelectIntrinsicOpWithOneParam(IntrinsicopNode &intrinopNode, std::string name) override; 76 Operand *SelectCclz(IntrinsicopNode &intrinopNode) override; 77 Operand *SelectCctz(IntrinsicopNode &intrinopNode) override; 78 Operand *SelectCpopcount(IntrinsicopNode &intrinopNode) override; 79 Operand *SelectCparity(IntrinsicopNode &intrinopNode) override; 80 Operand *SelectCclrsb(IntrinsicopNode &intrinopNode) override; 81 Operand *SelectCisaligned(IntrinsicopNode &intrinopNode) override; 82 Operand *SelectCalignup(IntrinsicopNode &intrinopNode) override; 83 Operand *SelectCaligndown(IntrinsicopNode &intrinopNode) override; 84 Operand *SelectCSyncFetch(IntrinsicopNode &intrinsicopNode, Opcode op, bool fetchBefore) override; 85 Operand *SelectCSyncSynchronize(IntrinsicopNode &intrinsicopNode) override; 86 Operand *SelectCAtomicLoadN(IntrinsicopNode &intrinsicopNode) override; 87 Operand *SelectCAtomicExchangeN(const IntrinsiccallNode &intrinsicopNode) override; 88 Operand *SelectCSyncBoolCmpSwap(IntrinsicopNode &intrinopNode) override; 89 Operand *SelectCSyncValCmpSwap(IntrinsicopNode &intrinopNode) override; 90 Operand *SelectCSyncLockTestSet(IntrinsicopNode &intrinopNode, PrimType pty) override; 91 Operand *SelectCReturnAddress(IntrinsicopNode &intrinopNode) override; 92 void SelectMembar(StmtNode &membar) override; 93 void SelectComment(CommentNode &comment) override; 94 void HandleCatch() override; 95 Operand *SelectDread(const BaseNode &parent, AddrofNode &expr) override; 96 RegOperand *SelectRegread(RegreadNode &expr) override; 97 Operand *SelectAddrof(AddrofNode &expr, const BaseNode &parent, bool isAddrofoff) override; 98 Operand *SelectAddrofoff(AddrofoffNode &expr, const BaseNode &parent) override; 99 Operand &SelectAddrofFunc(AddroffuncNode &expr, const BaseNode &parent) override; 100 Operand &SelectAddrofLabel(AddroflabelNode &expr, const BaseNode &parent) override; 101 Operand *SelectIread(const BaseNode &parent, IreadNode &expr, int extraOffset = 0, 102 PrimType finalBitFieldDestType = kPtyInvalid) override; 103 Operand *SelectIreadoff(const BaseNode &parent, IreadoffNode &ireadoff) override; 104 Operand *SelectIreadfpoff(const BaseNode &parent, IreadFPoffNode &ireadoff) override; 105 Operand *SelectIntConst(const MIRIntConst &intConst, const BaseNode &parent) override; 106 Operand *SelectFloatConst(MIRFloatConst &floatConst, const BaseNode &parent) override; 107 Operand *SelectDoubleConst(MIRDoubleConst &doubleConst, const BaseNode &parent) override; 108 Operand *SelectStrConst(MIRStrConst &strConst) override; 109 Operand *SelectStr16Const(MIRStr16Const &strConst) override; 110 void SelectAdd(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) override; 111 Operand *SelectAdd(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) override; 112 void SelectMadd(Operand &resOpnd, Operand &opndM0, Operand &opndM1, Operand &opnd1, PrimType primType) override; 113 Operand *SelectMadd(BinaryNode &node, Operand &opndM0, Operand &opndM1, Operand &opnd1, 114 const BaseNode &parent) override; 115 Operand *SelectRor(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) override; 116 Operand &SelectCGArrayElemAdd(BinaryNode &node, const BaseNode &parent) override; 117 Operand *SelectShift(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) override; 118 void SelectMpy(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) override; 119 Operand *SelectMpy(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) override; 120 Operand *SelectRem(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) override; 121 void SelectDiv(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) override; 122 Operand *SelectDiv(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) override; 123 Operand *SelectSub(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) override; 124 void SelectSub(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) override; 125 Operand *SelectBand(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) override; 126 void SelectBand(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) override; 127 Operand *SelectLand(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) override; 128 Operand *SelectLor(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent, 129 bool parentIsBr = false) override; 130 void SelectMin(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) override; 131 Operand *SelectMin(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) override; 132 void SelectMax(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) override; 133 Operand *SelectMax(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) override; 134 Operand *SelectCmpOp(CompareNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) override; 135 Operand *SelectBior(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) override; 136 void SelectBior(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) override; 137 Operand *SelectBxor(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) override; 138 void SelectBxor(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) override; 139 Operand *SelectAbs(UnaryNode &node, Operand &opnd0) override; 140 Operand *SelectBnot(UnaryNode &node, Operand &opnd0, const BaseNode &parent) override; 141 Operand *SelectExtractbits(ExtractbitsNode &node, Operand &opnd0, const BaseNode &parent) override; 142 Operand *SelectDepositBits(DepositbitsNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) override; 143 Operand *SelectRegularBitFieldLoad(ExtractbitsNode &node, const BaseNode &parent) override; 144 Operand *SelectLnot(UnaryNode &node, Operand &opnd0, const BaseNode &parent) override; 145 Operand *SelectNeg(UnaryNode &node, Operand &opnd0, const BaseNode &parent) override; 146 Operand *SelectRecip(UnaryNode &node, Operand &opnd0, const BaseNode &parent) override; 147 Operand *SelectSqrt(UnaryNode &node, Operand &opnd0, const BaseNode &parent) override; 148 Operand *SelectCeil(TypeCvtNode &node, Operand &opnd0, const BaseNode &parent) override; 149 Operand *SelectFloor(TypeCvtNode &node, Operand &opnd0, const BaseNode &parent) override; 150 Operand *SelectRetype(TypeCvtNode &node, Operand &opnd0) override; 151 Operand *SelectRound(TypeCvtNode &node, Operand &opnd0, const BaseNode &parent) override; 152 Operand *SelectCvt(const BaseNode &parent, TypeCvtNode &node, Operand &opnd0) override; 153 Operand *SelectBswap(IntrinsicopNode &node, Operand &opnd0, const BaseNode &parent) override; 154 Operand *SelectTrunc(TypeCvtNode &node, Operand &opnd0, const BaseNode &parent) override; 155 Operand *SelectSelect(TernaryNode &node, Operand &cond, Operand &opnd0, Operand &opnd1, const BaseNode &parent, 156 bool hasCompare = false) override; 157 Operand *SelectMalloc(UnaryNode &call, Operand &opnd0) override; 158 RegOperand &SelectCopy(Operand &src, PrimType srcType, PrimType dstType) override; 159 Operand *SelectAlloca(UnaryNode &call, Operand &opnd0) override; 160 Operand *SelectGCMalloc(GCMallocNode &call) override; 161 Operand *SelectJarrayMalloc(JarrayMallocNode &call, Operand &opnd0) override; 162 void SelectRangeGoto(RangeGotoNode &rangeGotoNode, Operand &opnd0) override; 163 Operand *SelectLazyLoad(Operand &opnd0, PrimType primType) override; 164 Operand *SelectLazyLoadStatic(MIRSymbol &st, int64 offset, PrimType primType) override; 165 Operand *SelectLoadArrayClassCache(MIRSymbol &st, int64 offset, PrimType primType) override; 166 void GenerateYieldpoint(BB &bb) override; 167 Operand &GetOrCreateRflag() override; 168 const Operand *GetRflag() const override; 169 const Operand *GetFloatRflag() const override; 170 const LabelOperand *GetLabelOperand(LabelIdx labIdx) const override; 171 LabelOperand &GetOrCreateLabelOperand(LabelIdx labIdx) override; 172 LabelOperand &GetOrCreateLabelOperand(BB &bb) override; 173 RegOperand &CreateVirtualRegisterOperand(regno_t vRegNO) override; 174 RegOperand &GetOrCreateVirtualRegisterOperand(regno_t vRegNO) override; 175 RegOperand &GetOrCreateVirtualRegisterOperand(RegOperand ®Opnd) override; 176 RegOperand &GetOrCreateFramePointerRegOperand() override; 177 RegOperand &GetOrCreateStackBaseRegOperand() override; 178 RegOperand &GetZeroOpnd(uint32 size) override; 179 Operand &CreateCfiRegOperand(uint32 reg, uint32 size) override; 180 Operand &GetTargetRetOperand(PrimType primType, int32 sReg) override; 181 Operand &CreateImmOperand(PrimType primType, int64 val) override; 182 void ReplaceOpndInInsn(RegOperand ®Dest, RegOperand ®Src, Insn &insn, regno_t regno) override; 183 void CleanupDeadMov(bool dump = false) override; 184 void GetRealCallerSaveRegs(const Insn &insn, std::set<regno_t> &realCallerSave) override; 185 bool IsFrameReg(const RegOperand &opnd) const override; 186 MemOperand *GetOrCreatSpillMem(regno_t vrNum, uint32 bitSize) override; 187 RegOperand *SelectVectorAddLong(PrimType rTy, Operand *o1, Operand *o2, PrimType oty, bool isLow) override; 188 RegOperand *SelectVectorAddWiden(Operand *o1, PrimType oty1, Operand *o2, PrimType oty2, bool isLow) override; 189 RegOperand *SelectVectorAbs(PrimType rType, Operand *o1) override; 190 RegOperand *SelectVectorBinOp(PrimType rType, Operand *o1, PrimType oTyp1, Operand *o2, PrimType oTyp2, 191 Opcode opc) override; 192 RegOperand *SelectVectorBitwiseOp(PrimType rType, Operand *o1, PrimType oty1, Operand *o2, PrimType oty2, 193 Opcode opc) override; 194 ; 195 RegOperand *SelectVectorCompareZero(Operand *o1, PrimType oty1, Operand *o2, Opcode opc) override; 196 RegOperand *SelectVectorCompare(Operand *o1, PrimType oty1, Operand *o2, PrimType oty2, Opcode opc) override; 197 RegOperand *SelectVectorFromScalar(PrimType pType, Operand *opnd, PrimType sType) override; 198 RegOperand *SelectVectorDup(PrimType rType, Operand *src, bool getLow) override; 199 RegOperand *SelectVectorGetElement(PrimType rType, Operand *src, PrimType sType, int32 lane) override; 200 RegOperand *SelectVectorAbsSubL(PrimType rType, Operand *o1, Operand *o2, PrimType oTy, bool isLow) override; 201 RegOperand *SelectVectorMadd(Operand *o1, PrimType oTyp1, Operand *o2, PrimType oTyp2, Operand *o3, 202 PrimType oTyp3) override; 203 RegOperand *SelectVectorMerge(PrimType rTyp, Operand *o1, Operand *o2, int32 iNum) override; 204 RegOperand *SelectVectorMull(PrimType rType, Operand *o1, PrimType oTyp1, Operand *o2, PrimType oTyp2, 205 bool isLow) override; 206 RegOperand *SelectVectorNarrow(PrimType rType, Operand *o1, PrimType otyp) override; 207 RegOperand *SelectVectorNarrow2(PrimType rType, Operand *o1, PrimType oty1, Operand *o2, PrimType oty2) override; 208 RegOperand *SelectVectorNeg(PrimType rType, Operand *o1) override; 209 RegOperand *SelectVectorNot(PrimType rType, Operand *o1) override; 210 RegOperand *SelectVectorPairwiseAdalp(Operand *src1, PrimType sty1, Operand *src2, PrimType sty2) override; 211 RegOperand *SelectVectorPairwiseAdd(PrimType rType, Operand *src, PrimType sType) override; 212 RegOperand *SelectVectorReverse(PrimType rtype, Operand *src, PrimType stype, uint32 size) override; 213 RegOperand *SelectVectorSetElement(Operand *eOp, PrimType eTyp, Operand *vOpd, PrimType vTyp, int32 lane) override; 214 RegOperand *SelectVectorShift(PrimType rType, Operand *o1, PrimType oty1, Operand *o2, PrimType oty2, 215 Opcode opc) override; 216 RegOperand *SelectVectorShiftImm(PrimType rType, Operand *o1, Operand *imm, int32 sVal, Opcode opc) override; 217 RegOperand *SelectVectorShiftRNarrow(PrimType rType, Operand *o1, PrimType oType, Operand *o2, bool isLow) override; 218 RegOperand *SelectVectorSubWiden(PrimType resType, Operand *o1, PrimType otyp1, Operand *o2, PrimType otyp2, 219 bool isLow, bool isWide) override; 220 RegOperand *SelectVectorSum(PrimType rtype, Operand *o1, PrimType oType) override; 221 RegOperand *SelectVectorTableLookup(PrimType rType, Operand *o1, Operand *o2) override; 222 RegOperand *SelectVectorWiden(PrimType rType, Operand *o1, PrimType otyp, bool isLow) override; 223 Operand *SelectIntrinsicOpWithNParams(IntrinsicopNode &intrinopNode, PrimType retType, 224 const std::string &name) override; 225 void ProcessLazyBinding() override; 226 void DBGFixCallFrameLocationOffsets() override; 227 MemOperand *GetPseudoRegisterSpillMemoryOperand(PregIdx idx) override; 228 229 int32 GetBaseOffset(const SymbolAlloc &symbolAlloc) override; 230 RegOperand *GetBaseReg(const SymbolAlloc &symAlloc) override; 231 AddtoCalleeSaved(regno_t reg)232 void AddtoCalleeSaved(regno_t reg) override 233 { 234 const auto &[_, flag] = calleeSavedRegs.insert(static_cast<X64reg>(reg)); 235 DEBUG_ASSERT((IsGPRegister(static_cast<X64reg>(reg)) || IsFPSIMDRegister(static_cast<X64reg>(reg))), 236 "Int or FP registers are expected"); 237 if (flag) { 238 if (IsGPRegister(static_cast<X64reg>(reg))) { 239 ++numIntregToCalleeSave; 240 } else { 241 ++numFpregToCalleeSave; 242 } 243 } 244 } 245 GetCalleeSavedRegs()246 const MapleSet<x64::X64reg> &GetCalleeSavedRegs() const 247 { 248 return calleeSavedRegs; 249 } 250 SizeOfCalleeSaved()251 uint32 SizeOfCalleeSaved() const 252 { 253 uint32 size = numIntregToCalleeSave * kX64IntregBytelen + numFpregToCalleeSave * kX64FpregBytelen; 254 return RoundUp(size, GetMemlayout()->GetStackPtrAlignment()); 255 } 256 257 void FreeSpillRegMem(regno_t vrNum); 258 259 private: 260 MapleSet<x64::X64reg> calleeSavedRegs; 261 uint32 numIntregToCalleeSave = 0; 262 uint32 numFpregToCalleeSave = 0; 263 }; 264 265 class X64OpndDumpVisitor : public OpndDumpVisitor { 266 public: X64OpndDumpVisitor(const OpndDesc & operandDesc)267 explicit X64OpndDumpVisitor(const OpndDesc &operandDesc) : OpndDumpVisitor(operandDesc) {}; 268 ~X64OpndDumpVisitor() override = default; 269 270 private: 271 void Visit(RegOperand *v) final; 272 void Visit(ImmOperand *v) final; 273 void Visit(MemOperand *v) final; 274 void Visit(ListOperand *v) final; 275 void Visit(CondOperand *v) final; 276 void Visit(CommentOperand *v) final; 277 void Visit(StImmOperand *v) final; 278 void Visit(BitShiftOperand *v) final; 279 void Visit(ExtendShiftOperand *v) final; 280 void Visit(LabelOperand *v) final; 281 void Visit(FuncNameOperand *v) final; 282 void Visit(PhiOperand *v) final; 283 void DumpRegInfo(RegOperand &v); 284 }; 285 } /* namespace maplebe */ 286 #endif /* MAPLEBE_INCLUDE_CG_X86_64_CGFUNC_H */ 287