• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &regOpnd) 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 &regDest, RegOperand &regSrc, 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