• 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 MergeReturn() override;
43     void SelectDassign(DassignNode &stmt, Operand &opnd0) override;
44     void SelectRegassign(RegassignNode &stmt, Operand &opnd0) override;
45     void SelectIassign(IassignNode &stmt) override;
46     void SelectReturn(Operand *opnd) override;
47     void SelectCondGoto(CondGotoNode &stmt, Operand &opnd0, Operand &opnd1) override;
48     void SelectCondSpecialCase1(CondGotoNode &stmt, BaseNode &opnd0) override;
49     void SelectCondSpecialCase2(const CondGotoNode &stmt, BaseNode &opnd0) override;
50     void SelectGoto(GotoNode &stmt) override;
51     void SelectCall(CallNode &callNode) override;
52     void SelectIcall(IcallNode &icallNode) override;
53     void SelectIntrinsicCall(IntrinsiccallNode &intrinsiccallNode) override;
54     void SelectDeoptCall(CallNode &callNode) override;
55     void SelectTailICall(IcallNode &icallNode) override;
56     Operand *SelectCclz(IntrinsicopNode &intrinopNode) override;
57     RegOperand *SelectHeapConstant(IntrinsicopNode &node, Operand &opnd0, Operand &opnd1) override;
58     RegOperand *SelectTaggedIsHeapObject(IntrinsicopNode &node, Operand &opnd0, Operand &opnd1) override;
59     RegOperand *SelectIsStableElements(IntrinsicopNode &node, Operand &opnd0, Operand &opnd1, Operand &opnd2) override;
60     RegOperand *SelectHasPendingException(IntrinsicopNode &node, Operand &opnd0,
61                                           Operand &opnd1, Operand &opnd2) override;
62     RegOperand *SelectGetHeapConstantTable(
63         IntrinsicopNode &node, Operand &opnd0, Operand &opnd1, Operand &opnd2) override;
64     RegOperand *SelectTaggedObjectIsString(IntrinsicopNode &node, Operand &opnd0, Operand &opnd1,
65                                           Operand &opnd2, Operand &opnd3, Operand &opnd4) override;
66     RegOperand *SelectIsCOWArray(IntrinsicopNode &node, Operand &opnd0, Operand &opnd1,
67                                  Operand &opnd2, Operand &opnd3, Operand &opnd4, Operand &opnd5) override;
68     void SelectComment(CommentNode &comment) override;
69     Operand *SelectDread(const BaseNode &parent, AddrofNode &expr) override;
70     RegOperand *SelectRegread(RegreadNode &expr) override;
71     Operand *SelectIread(const BaseNode &parent, IreadNode &expr, int extraOffset = 0,
72                          PrimType finalBitFieldDestType = kPtyInvalid) override;
73     Operand *SelectIntConst(const MIRIntConst &intConst, const BaseNode &parent) override;
74     Operand *SelectFloatConst(MIRFloatConst &floatConst, const BaseNode &parent) override;
75     Operand *SelectDoubleConst(MIRDoubleConst &doubleConst, const BaseNode &parent) override;
76     void SelectAdd(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) override;
77     Operand *SelectAdd(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) override;
78     Operand *SelectShift(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) override;
79     void SelectMpy(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) override;
80     Operand *SelectMpy(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) override;
81     Operand *SelectRem(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) override;
82     void SelectDiv(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) override;
83     Operand *SelectDiv(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) override;
84     Operand *SelectSub(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) override;
85     void SelectSub(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) override;
86     Operand *SelectBand(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) override;
87     void SelectBand(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) override;
88     void SelectMin(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) override;
89     Operand *SelectMin(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) override;
90     void SelectMax(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) override;
91     Operand *SelectMax(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) override;
92     Operand *SelectCmpOp(CompareNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) override;
93     Operand *SelectBior(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) override;
94     void SelectBior(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) override;
95     Operand *SelectBxor(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) override;
96     void SelectBxor(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) override;
97     Operand *SelectAbs(UnaryNode &node, Operand &opnd0) override;
98     Operand *SelectBnot(UnaryNode &node, Operand &opnd0, const BaseNode &parent) override;
99     Operand *SelectExtractbits(ExtractbitsNode &node, Operand &opnd0, const BaseNode &parent) override;
100     Operand *SelectRegularBitFieldLoad(ExtractbitsNode &node, const BaseNode &parent) override;
101     Operand *SelectLnot(UnaryNode &node, Operand &opnd0, const BaseNode &parent) override;
102     Operand *SelectNeg(UnaryNode &node, Operand &opnd0, const BaseNode &parent) override;
103     Operand *SelectSqrt(UnaryNode &node, Operand &opnd0, const BaseNode &parent) override;
104     Operand *SelectCeil(TypeCvtNode &node, Operand &opnd0, const BaseNode &parent) override;
105     Operand *SelectFloor(TypeCvtNode &node, Operand &opnd0, const BaseNode &parent) override;
106     Operand *SelectRetype(TypeCvtNode &node, Operand &opnd0) override;
107     Operand *SelectCvt(const BaseNode &parent, TypeCvtNode &node, Operand &opnd0) override;
108     Operand *SelectTrunc(TypeCvtNode &node, Operand &opnd0, const BaseNode &parent) override;
109     RegOperand &SelectCopy(Operand &src, PrimType srcType, PrimType dstType) override;
110     void SelectRangeGoto(RangeGotoNode &rangeGotoNode, Operand &opnd0) override;
111     Operand &GetOrCreateRflag() override;
112     const Operand *GetRflag() const override;
113     const LabelOperand *GetLabelOperand(LabelIdx labIdx) const override;
114     LabelOperand &GetOrCreateLabelOperand(LabelIdx labIdx) override;
115     LabelOperand &GetOrCreateLabelOperand(BB &bb) override;
116     RegOperand &CreateVirtualRegisterOperand(regno_t vRegNO) override;
117     RegOperand &GetOrCreateVirtualRegisterOperand(regno_t vRegNO) override;
118     RegOperand &GetOrCreateFramePointerRegOperand() override;
119     RegOperand &GetOrCreateStackBaseRegOperand() override;
120     RegOperand &GetZeroOpnd(uint32 size) override;
121     Operand &CreateCfiRegOperand(uint32 reg, uint32 size) override;
122     Operand &CreateImmOperand(PrimType primType, int64 val) override;
123     MemOperand *GetOrCreatSpillMem(regno_t vrNum, uint32 bitSize) override;
124     MemOperand *GetPseudoRegisterSpillMemoryOperand(PregIdx idx) override;
125 
126     int32 GetBaseOffset(const SymbolAlloc &symbolAlloc) override;
127     RegOperand *GetBaseReg(const SymbolAlloc &symAlloc) override;
128 
AddtoCalleeSaved(regno_t reg)129     void AddtoCalleeSaved(regno_t reg) override
130     {
131         const auto &[_, flag] = calleeSavedRegs.insert(static_cast<X64reg>(reg));
132         DEBUG_ASSERT((IsGPRegister(static_cast<X64reg>(reg)) || IsFPSIMDRegister(static_cast<X64reg>(reg))),
133                      "Int or FP registers are expected");
134         if (flag) {
135             if (IsGPRegister(static_cast<X64reg>(reg))) {
136                 ++numIntregToCalleeSave;
137             } else {
138                 ++numFpregToCalleeSave;
139             }
140         }
141     }
142 
GetCalleeSavedRegs()143     const MapleSet<x64::X64reg> &GetCalleeSavedRegs() const
144     {
145         return calleeSavedRegs;
146     }
147 
SizeOfCalleeSaved()148     uint32 SizeOfCalleeSaved() const
149     {
150         uint32 size = numIntregToCalleeSave * kX64IntregBytelen + numFpregToCalleeSave * kX64FpregBytelen;
151         return RoundUp(size, GetMemlayout()->GetStackPtrAlignment());
152     }
153 
154     void FreeSpillRegMem(regno_t vrNum);
155 
156 private:
157     MapleSet<x64::X64reg> calleeSavedRegs;
158     uint32 numIntregToCalleeSave = 0;
159     uint32 numFpregToCalleeSave = 0;
160 };
161 
162 class X64OpndDumpVisitor : public OpndDumpVisitor {
163 public:
X64OpndDumpVisitor(const OpndDesc & operandDesc)164     explicit X64OpndDumpVisitor(const OpndDesc &operandDesc) : OpndDumpVisitor(operandDesc) {};
165     ~X64OpndDumpVisitor() override = default;
166 
167 private:
168     void Visit(RegOperand *v) final;
169     void Visit(ImmOperand *v) final;
170     void Visit(MemOperand *v) final;
171     void Visit(ListOperand *v) final;
172     void Visit(CondOperand *v) final;
173     void Visit(CommentOperand *v) final;
174     void Visit(StImmOperand *v) final;
175     void Visit(BitShiftOperand *v) final;
176     void Visit(ExtendShiftOperand *v) final;
177     void Visit(LabelOperand *v) final;
178     void Visit(FuncNameOperand *v) final;
179     void Visit(PhiOperand *v) final;
180     void DumpRegInfo(RegOperand &v);
181 };
182 } /* namespace maplebe */
183 #endif /* MAPLEBE_INCLUDE_CG_X86_64_CGFUNC_H */
184