• 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(MemPool & memPool,maplebe::MOperator op,maplebe::Operand & opnd0)64     CfiInsn(MemPool &memPool, maplebe::MOperator op, maplebe::Operand &opnd0) : Insn(memPool, op, opnd0) {}
65 
CfiInsn(MemPool & memPool,maplebe::MOperator op,maplebe::Operand & opnd0,maplebe::Operand & opnd1)66     CfiInsn(MemPool &memPool, maplebe::MOperator op, maplebe::Operand &opnd0, maplebe::Operand &opnd1)
67         : Insn(memPool, op, opnd0, opnd1)
68     {
69     }
70 
CfiInsn(MemPool & memPool,maplebe::MOperator op,maplebe::Operand & opnd0,maplebe::Operand & opnd1,maplebe::Operand & opnd2)71     CfiInsn(MemPool &memPool, maplebe::MOperator op, maplebe::Operand &opnd0, maplebe::Operand &opnd1,
72             maplebe::Operand &opnd2)
73         : Insn(memPool, op, opnd0, opnd1, opnd2)
74     {
75     }
76 
77     ~CfiInsn() = default;
78 
IsMachineInstruction()79     bool IsMachineInstruction() const override
80     {
81         return false;
82     }
83 
84     void Dump() const override;
85 
86 #if DEBUG
87     void Check() const override;
88 #endif
89 
IsCfiInsn()90     bool IsCfiInsn() const override
91     {
92         return true;
93     }
94 
IsTargetInsn()95     bool IsTargetInsn() const override
96     {
97         return false;
98     }
99 
IsRegDefined(maplebe::regno_t regNO)100     bool IsRegDefined(maplebe::regno_t regNO) const override
101     {
102         CHECK_FATAL(false, "cfi do not def regs");
103         return false;
104     }
105 
GetDefRegs()106     std::set<uint32> GetDefRegs() const override
107     {
108         CHECK_FATAL(false, "cfi do not def regs");
109         return std::set<uint32>();
110     }
111 
GetBothDefUseOpnd()112     uint32 GetBothDefUseOpnd() const override
113     {
114         return maplebe::kInsnMaxOpnd;
115     }
116 
117 private:
118     CfiInsn &operator=(const CfiInsn &);
119 };
120 
121 class RegOperand : public maplebe::OperandVisitable<RegOperand> {
122 public:
RegOperand(uint32 no,uint32 size)123     RegOperand(uint32 no, uint32 size) : OperandVisitable(kOpdRegister, size), regNO(no) {}
124 
125     ~RegOperand() = default;
126     using OperandVisitable<RegOperand>::OperandVisitable;
127 
GetRegisterNO()128     uint32 GetRegisterNO() const
129     {
130         return regNO;
131     }
Clone(MemPool & memPool)132     Operand *Clone(MemPool &memPool) const override
133     {
134         Operand *opnd = memPool.Clone<RegOperand>(*this);
135         return opnd;
136     }
137 
138     void Dump() const override;
139 
Less(const Operand & right)140     bool Less(const Operand &right) const override
141     {
142         (void)right;
143         return false;
144     }
145 
146 private:
147     uint32 regNO;
148 };
149 
150 class ImmOperand : public maplebe::OperandVisitable<ImmOperand> {
151 public:
ImmOperand(int64 val,uint32 size)152     ImmOperand(int64 val, uint32 size) : OperandVisitable(kOpdImmediate, size), val(val) {}
153 
154     ~ImmOperand() = default;
155     using OperandVisitable<ImmOperand>::OperandVisitable;
156 
Clone(MemPool & memPool)157     Operand *Clone(MemPool &memPool) const override
158     {
159         Operand *opnd = memPool.Clone<ImmOperand>(*this);
160         return opnd;
161     }
GetValue()162     int64 GetValue() const
163     {
164         return val;
165     }
166 
167     void Dump() const override;
168 
Less(const Operand & right)169     bool Less(const Operand &right) const override
170     {
171         (void)right;
172         return false;
173     }
174 
175 private:
176     int64 val;
177 };
178 
179 class SymbolOperand : public maplebe::OperandVisitable<SymbolOperand> {
180 public:
SymbolOperand(maple::MIRSymbol & mirSymbol,uint8 size)181     SymbolOperand(maple::MIRSymbol &mirSymbol, uint8 size) : OperandVisitable(kOpdStImmediate, size), symbol(&mirSymbol)
182     {
183     }
184     ~SymbolOperand() = default;
185     using OperandVisitable<SymbolOperand>::OperandVisitable;
186 
Clone(MemPool & memPool)187     Operand *Clone(MemPool &memPool) const override
188     {
189         Operand *opnd = memPool.Clone<SymbolOperand>(*this);
190         return opnd;
191     }
192 
Less(const Operand & right)193     bool Less(const Operand &right) const override
194     {
195         (void)right;
196         return false;
197     }
198 
Dump()199     void Dump() const override
200     {
201         LogInfo::MapleLogger() << "symbol is  : " << symbol->GetName();
202     }
203 
204 private:
205     maple::MIRSymbol *symbol;
206 };
207 
208 class StrOperand : public maplebe::OperandVisitable<StrOperand> {
209 public:
StrOperand(const std::string & str,MemPool & memPool)210     StrOperand(const std::string &str, MemPool &memPool) : OperandVisitable(kOpdString, 0), str(str, &memPool) {}
211 
212     ~StrOperand() = default;
213     using OperandVisitable<StrOperand>::OperandVisitable;
214 
Clone(MemPool & memPool)215     Operand *Clone(MemPool &memPool) const override
216     {
217         Operand *opnd = memPool.Clone<StrOperand>(*this);
218         return opnd;
219     }
220 
Less(const Operand & right)221     bool Less(const Operand &right) const override
222     {
223         (void)right;
224         return false;
225     }
226 
GetStr()227     const MapleString &GetStr() const
228     {
229         return str;
230     }
231 
232     void Dump() const override;
233 
234 private:
235     const MapleString str;
236 };
237 
238 class LabelOperand : public maplebe::OperandVisitable<LabelOperand> {
239 public:
LabelOperand(const std::string & parent,LabelIdx labIdx,MemPool & memPool)240     LabelOperand(const std::string &parent, LabelIdx labIdx, MemPool &memPool)
241         : OperandVisitable(kOpdBBAddress, 0), parentFunc(parent, &memPool), labelIndex(labIdx)
242     {
243     }
244 
245     ~LabelOperand() = default;
246     using OperandVisitable<LabelOperand>::OperandVisitable;
247 
Clone(MemPool & memPool)248     Operand *Clone(MemPool &memPool) const override
249     {
250         Operand *opnd = memPool.Clone<LabelOperand>(*this);
251         return opnd;
252     }
253 
Less(const Operand & right)254     bool Less(const Operand &right) const override
255     {
256         (void)right;
257         return false;
258     }
259 
260     void Dump() const override;
261 
GetParentFunc()262     const MapleString &GetParentFunc() const
263     {
264         return parentFunc;
265     }
GetIabelIdx()266     LabelIdx GetIabelIdx() const
267     {
268         return labelIndex;
269     };
270 
271 private:
272     const MapleString parentFunc;
273     LabelIdx labelIndex;
274 };
275 
276 class CFIOpndEmitVisitor
277     : public maplebe::OperandVisitorBase,
278       public maplebe::OperandVisitors<RegOperand, ImmOperand, SymbolOperand, StrOperand, LabelOperand> {
279 public:
CFIOpndEmitVisitor(maplebe::Emitter & asmEmitter)280     explicit CFIOpndEmitVisitor(maplebe::Emitter &asmEmitter) : emitter(asmEmitter) {}
281     virtual ~CFIOpndEmitVisitor() = default;
282 
283 protected:
284     maplebe::Emitter &emitter;
285 
286 private:
287     void Visit(RegOperand *v) final;
288     void Visit(ImmOperand *v) final;
289     void Visit(SymbolOperand *v) final;
290     void Visit(StrOperand *v) final;
291     void Visit(LabelOperand *v) final;
292 };
293 } /* namespace cfi */
294 
295 #endif /* MAPLEBE_INCLUDE_CG_CFI_H */
296