• 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_CFI_H
17 #define MAPLEBE_INCLUDE_CG_CFI_H
18 
19 #include "insn.h"
20 #include "mempool_allocator.h"
21 #include "mir_symbol.h"
22 #include "operand.h"
23 #include "common_utils.h"
24 
25 /*
26  * Reference:
27  * GNU Binutils. AS documentation
28  * https://sourceware.org/binutils/docs-2.28/as/index.html
29  *
30  * CFI blog
31  * https://www.imperialviolet.org/2017/01/18/cfi.html
32  *
33  * System V Application Binary Interface
34  * AMD64 Architecture Processor Supplement. Draft Version 0.99.7
35  * https://www.uclibc.org/docs/psABI-x86_64.pdf $ 3.7 Figure 3.36
36  * (RBP->6, RSP->7)
37  *
38  * System V Application Binary Interface
39  * Inte386 Architecture Processor Supplement. Version 1.0
40  * https://www.uclibc.org/docs/psABI-i386.pdf $ 2.5 Table 2.14
41  * (EBP->5, ESP->4)
42  *
43  * DWARF for ARM Architecture (ARM IHI 0040B)
44  * infocenter.arm.com/help/topic/com.arm.doc.ihi0040b/IHI0040B_aadwarf.pdf
45  * $ 3.1 Table 1
46  * (0-15 -> R0-R15)
47  */
48 namespace cfi {
49 using namespace maple;
50 
51 enum CfiOpcode : uint8 {
52 #define CFI_DEFINE(k, sub, n, o0, o1, o2) OP_CFI_##k##sub,
53 #define ARM_DIRECTIVES_DEFINE(k, sub, n, o0, o1, o2) OP_ARM_DIRECTIVES_##k##sub,
54 #include "cfi.def"
55 #undef CFI_DEFINE
56 #undef ARM_DIRECTIVES_DEFINE
57     kOpCfiLast
58 };
59 
60 class CfiInsn : public maplebe::Insn {
61 public:
CfiInsn(MemPool & memPool,maplebe::MOperator op)62     CfiInsn(MemPool &memPool, maplebe::MOperator op) : Insn(memPool, op) {}
63 
CfiInsn(const CfiInsn & other)64     CfiInsn(const CfiInsn &other) : maplebe::Insn(other) {}
65 
CfiInsn(MemPool & memPool,maplebe::MOperator op,maplebe::Operand & opnd0)66     CfiInsn(MemPool &memPool, maplebe::MOperator op, maplebe::Operand &opnd0) : Insn(memPool, op, opnd0) {}
67 
CfiInsn(MemPool & memPool,maplebe::MOperator op,maplebe::Operand & opnd0,maplebe::Operand & opnd1)68     CfiInsn(MemPool &memPool, maplebe::MOperator op, maplebe::Operand &opnd0, maplebe::Operand &opnd1)
69         : Insn(memPool, op, opnd0, opnd1)
70     {
71     }
72 
CfiInsn(MemPool & memPool,maplebe::MOperator op,maplebe::Operand & opnd0,maplebe::Operand & opnd1,maplebe::Operand & opnd2)73     CfiInsn(MemPool &memPool, maplebe::MOperator op, maplebe::Operand &opnd0, maplebe::Operand &opnd1,
74             maplebe::Operand &opnd2)
75         : Insn(memPool, op, opnd0, opnd1, opnd2)
76     {
77     }
78 
79     ~CfiInsn() = default;
80 
CloneTree(MapleAllocator & allocator)81     CfiInsn *CloneTree(MapleAllocator &allocator) const override
82     {
83         auto *insn = allocator.GetMemPool()->New<CfiInsn>(*this);
84         insn->DeepClone(*this, allocator);
85         return insn;
86     }
87 
IsMachineInstruction()88     bool IsMachineInstruction() const override
89     {
90         return false;
91     }
92 
93     void Dump() const override;
94 
95     bool CheckMD() const override;
96 
IsCfiInsn()97     bool IsCfiInsn() const override
98     {
99         return true;
100     }
101 
IsTargetInsn()102     bool IsTargetInsn() const override
103     {
104         return false;
105     }
106 
IsRegDefined(maplebe::regno_t regNO)107     bool IsRegDefined(maplebe::regno_t regNO) const override
108     {
109         CHECK_FATAL(false, "cfi do not def regs");
110         return false;
111     }
112 
GetDefRegs()113     std::set<uint32> GetDefRegs() const override
114     {
115         CHECK_FATAL(false, "cfi do not def regs");
116         return std::set<uint32>();
117     }
118 
119 private:
120     CfiInsn &operator=(const CfiInsn &);
121 };
122 
123 class RegOperand : public maplebe::OperandVisitable<RegOperand> {
124 public:
RegOperand(uint32 no,uint32 size)125     RegOperand(uint32 no, uint32 size) : OperandVisitable(kOpdRegister, size), regNO(no) {}
126 
127     ~RegOperand() = default;
128     using OperandVisitable<RegOperand>::OperandVisitable;
129 
GetRegisterNO()130     uint32 GetRegisterNO() const
131     {
132         return regNO;
133     }
134 
CloneTree(MapleAllocator & allocator)135     RegOperand *CloneTree(MapleAllocator &allocator) const override
136     {
137         return allocator.GetMemPool()->New<RegOperand>(*this);
138     }
139 
Clone(MemPool & memPool)140     Operand *Clone(MemPool &memPool) const override
141     {
142         Operand *opnd = memPool.Clone<RegOperand>(*this);
143         return opnd;
144     }
145 
146     void Dump() const override;
147 
Less(const Operand & right)148     bool Less(const Operand &right) const override
149     {
150         (void)right;
151         return false;
152     }
153 
154 private:
155     uint32 regNO;
156 };
157 
158 class ImmOperand : public maplebe::OperandVisitable<ImmOperand> {
159 public:
ImmOperand(int64 val,uint32 size)160     ImmOperand(int64 val, uint32 size) : OperandVisitable(kOpdImmediate, size), val(val) {}
161 
162     ~ImmOperand() = default;
163     using OperandVisitable<ImmOperand>::OperandVisitable;
164 
CloneTree(MapleAllocator & allocator)165     ImmOperand *CloneTree(MapleAllocator &allocator) const override
166     {
167         // const MIRSymbol is not changed in cg, so we can do shallow copy
168         return allocator.GetMemPool()->New<ImmOperand>(*this);
169     }
170 
Clone(MemPool & memPool)171     Operand *Clone(MemPool &memPool) const override
172     {
173         Operand *opnd = memPool.Clone<ImmOperand>(*this);
174         return opnd;
175     }
GetValue()176     int64 GetValue() const
177     {
178         return val;
179     }
180 
181     void Dump() const override;
182 
Less(const Operand & right)183     bool Less(const Operand &right) const override
184     {
185         (void)right;
186         return false;
187     }
188 
189 private:
190     int64 val;
191 };
192 
193 class SymbolOperand : public maplebe::OperandVisitable<SymbolOperand> {
194 public:
SymbolOperand(maple::MIRSymbol & mirSymbol,uint8 size)195     SymbolOperand(maple::MIRSymbol &mirSymbol, uint8 size) : OperandVisitable(kOpdStImmediate, size), symbol(&mirSymbol)
196     {
197     }
198     ~SymbolOperand() = default;
199     using OperandVisitable<SymbolOperand>::OperandVisitable;
200 
CloneTree(MapleAllocator & allocator)201     SymbolOperand *CloneTree(MapleAllocator &allocator) const override
202     {
203         // const MIRSymbol is not changed in cg, so we can do shallow copy
204         return allocator.GetMemPool()->New<SymbolOperand>(*this);
205     }
206 
Clone(MemPool & memPool)207     Operand *Clone(MemPool &memPool) const override
208     {
209         Operand *opnd = memPool.Clone<SymbolOperand>(*this);
210         return opnd;
211     }
212 
Less(const Operand & right)213     bool Less(const Operand &right) const override
214     {
215         (void)right;
216         return false;
217     }
218 
Dump()219     void Dump() const override
220     {
221         LogInfo::MapleLogger() << "symbol is  : " << symbol->GetName();
222     }
223 
224 private:
225     maple::MIRSymbol *symbol;
226 };
227 
228 class StrOperand : public maplebe::OperandVisitable<StrOperand> {
229 public:
StrOperand(const std::string & str,MemPool & memPool)230     StrOperand(const std::string &str, MemPool &memPool) : OperandVisitable(kOpdString, 0), str(str, &memPool) {}
231 
232     ~StrOperand() = default;
233     using OperandVisitable<StrOperand>::OperandVisitable;
234 
CloneTree(MapleAllocator & allocator)235     StrOperand *CloneTree(MapleAllocator &allocator) const override
236     {
237         return allocator.GetMemPool()->New<StrOperand>(*this);
238     }
239 
Clone(MemPool & memPool)240     Operand *Clone(MemPool &memPool) const override
241     {
242         Operand *opnd = memPool.Clone<StrOperand>(*this);
243         return opnd;
244     }
245 
Less(const Operand & right)246     bool Less(const Operand &right) const override
247     {
248         (void)right;
249         return false;
250     }
251 
GetStr()252     const MapleString &GetStr() const
253     {
254         return str;
255     }
256 
257     void Dump() const override;
258 
259 private:
260     const MapleString str;
261 };
262 
263 class LabelOperand : public maplebe::OperandVisitable<LabelOperand> {
264 public:
LabelOperand(const std::string & parent,LabelIdx labIdx,MemPool & memPool)265     LabelOperand(const std::string &parent, LabelIdx labIdx, MemPool &memPool)
266         : OperandVisitable(kOpdBBAddress, 0), parentFunc(parent, &memPool), labelIndex(labIdx)
267     {
268     }
269 
270     ~LabelOperand() = default;
271     using OperandVisitable<LabelOperand>::OperandVisitable;
272 
CloneTree(MapleAllocator & allocator)273     LabelOperand *CloneTree(MapleAllocator &allocator) const override
274     {
275         return allocator.GetMemPool()->New<LabelOperand>(*this);
276     }
277 
Clone(MemPool & memPool)278     Operand *Clone(MemPool &memPool) const override
279     {
280         Operand *opnd = memPool.Clone<LabelOperand>(*this);
281         return opnd;
282     }
283 
Less(const Operand & right)284     bool Less(const Operand &right) const override
285     {
286         (void)right;
287         return false;
288     }
289 
290     void Dump() const override;
291 
GetParentFunc()292     const MapleString &GetParentFunc() const
293     {
294         return parentFunc;
295     }
GetIabelIdx()296     LabelIdx GetIabelIdx() const
297     {
298         return labelIndex;
299     };
300 
301 private:
302     const MapleString parentFunc;
303     LabelIdx labelIndex;
304 };
305 
306 class CFIOpndEmitVisitor
307     : public maplebe::OperandVisitorBase,
308       public maplebe::OperandVisitors<RegOperand, ImmOperand, SymbolOperand, StrOperand, LabelOperand> {
309 public:
CFIOpndEmitVisitor(maplebe::Emitter & asmEmitter)310     explicit CFIOpndEmitVisitor(maplebe::Emitter &asmEmitter) : emitter(asmEmitter) {}
311     virtual ~CFIOpndEmitVisitor() = default;
312 
313 protected:
314     maplebe::Emitter &emitter;
315 
316 private:
317     void Visit(RegOperand *v) final;
318     void Visit(ImmOperand *v) final;
319     void Visit(SymbolOperand *v) final;
320     void Visit(StrOperand *v) final;
321     void Visit(LabelOperand *v) final;
322 };
323 } /* namespace cfi */
324 
325 #endif /* MAPLEBE_INCLUDE_CG_CFI_H */
326