1 | //===-- CSKYConstantPoolValue.h - CSKY constantpool value -----*- C++ -*---===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file implements the CSKY specific constantpool value class. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #ifndef LLVM_TARGET_CSKY_CONSTANTPOOLVALUE_H |
14 | #define LLVM_TARGET_CSKY_CONSTANTPOOLVALUE_H |
15 | |
16 | #include "llvm/ADT/StringRef.h" |
17 | #include "llvm/CodeGen/MachineConstantPool.h" |
18 | #include "llvm/Support/Casting.h" |
19 | #include "llvm/Support/ErrorHandling.h" |
20 | #include <cstddef> |
21 | |
22 | namespace llvm { |
23 | |
24 | class BlockAddress; |
25 | class Constant; |
26 | class GlobalValue; |
27 | class LLVMContext; |
28 | class MachineBasicBlock; |
29 | |
30 | namespace CSKYCP { |
31 | enum CSKYCPKind { |
32 | CPValue, |
33 | CPExtSymbol, |
34 | CPBlockAddress, |
35 | CPMachineBasicBlock, |
36 | CPJT, |
37 | CPConstPool |
38 | }; |
39 | |
40 | enum CSKYCPModifier { NO_MOD, ADDR, GOT, GOTOFF, PLT, TLSLE, TLSIE, TLSGD }; |
41 | } // namespace CSKYCP |
42 | |
43 | /// CSKYConstantPoolValue - CSKY specific constantpool value. This is used to |
44 | /// represent PC-relative displacement between the address of the load |
45 | /// instruction and the constant being loaded, i.e. (&GV-(LPIC+8)). |
46 | class CSKYConstantPoolValue : public MachineConstantPoolValue { |
47 | protected: |
48 | CSKYCP::CSKYCPKind Kind; // Kind of constant. |
49 | unsigned PCAdjust; // Extra adjustment if constantpool is pc-relative. |
50 | CSKYCP::CSKYCPModifier Modifier; // GV modifier |
51 | bool AddCurrentAddress; |
52 | |
53 | unsigned LabelId = 0; |
54 | |
55 | CSKYConstantPoolValue(Type *Ty, CSKYCP::CSKYCPKind Kind, unsigned PCAdjust, |
56 | CSKYCP::CSKYCPModifier Modifier, bool AddCurrentAddress, |
57 | unsigned ID = 0); |
58 | |
59 | public: |
60 | const char *getModifierText() const; |
61 | unsigned getPCAdjustment() const { return PCAdjust; } |
62 | bool mustAddCurrentAddress() const { return AddCurrentAddress; } |
63 | CSKYCP::CSKYCPModifier getModifier() const { return Modifier; } |
64 | unsigned getLabelID() const { return LabelId; } |
65 | |
66 | bool isGlobalValue() const { return Kind == CSKYCP::CPValue; } |
67 | bool isExtSymbol() const { return Kind == CSKYCP::CPExtSymbol; } |
68 | bool isBlockAddress() const { return Kind == CSKYCP::CPBlockAddress; } |
69 | bool isMachineBasicBlock() const { |
70 | return Kind == CSKYCP::CPMachineBasicBlock; |
71 | } |
72 | bool isJT() const { return Kind == CSKYCP::CPJT; } |
73 | bool isConstPool() const { return Kind == CSKYCP::CPConstPool; } |
74 | |
75 | int getExistingMachineCPValue(MachineConstantPool *CP, |
76 | Align Alignment) override; |
77 | |
78 | void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; |
79 | |
80 | void print(raw_ostream &O) const override; |
81 | |
82 | bool equals(const CSKYConstantPoolValue *A) const { |
83 | return this->LabelId == A->LabelId && this->PCAdjust == A->PCAdjust && |
84 | this->Modifier == A->Modifier; |
85 | } |
86 | |
87 | template <typename Derived> |
88 | int getExistingMachineCPValueImpl(MachineConstantPool *CP, Align Alignment) { |
89 | const std::vector<MachineConstantPoolEntry> &Constants = CP->getConstants(); |
90 | for (unsigned i = 0, e = Constants.size(); i != e; ++i) { |
91 | if (Constants[i].isMachineConstantPoolEntry() && |
92 | Constants[i].getAlign() >= Alignment) { |
93 | auto *CPV = |
94 | static_cast<CSKYConstantPoolValue *>(Constants[i].Val.MachineCPVal); |
95 | if (Derived *APC = dyn_cast<Derived>(CPV)) |
96 | if (cast<Derived>(this)->equals(APC)) |
97 | return i; |
98 | } |
99 | } |
100 | |
101 | return -1; |
102 | } |
103 | }; |
104 | |
105 | /// CSKY-specific constant pool values for Constants, |
106 | /// Functions, and BlockAddresses. |
107 | class CSKYConstantPoolConstant : public CSKYConstantPoolValue { |
108 | const Constant *CVal; // Constant being loaded. |
109 | |
110 | CSKYConstantPoolConstant(const Constant *C, Type *Ty, CSKYCP::CSKYCPKind Kind, |
111 | unsigned PCAdjust, CSKYCP::CSKYCPModifier Modifier, |
112 | bool AddCurrentAddress, unsigned ID); |
113 | |
114 | public: |
115 | static CSKYConstantPoolConstant * |
116 | Create(const Constant *C, CSKYCP::CSKYCPKind Kind, unsigned PCAdjust, |
117 | CSKYCP::CSKYCPModifier Modifier, bool AddCurrentAddress, |
118 | unsigned ID = 0); |
119 | static CSKYConstantPoolConstant * |
120 | Create(const Constant *C, Type *Ty, CSKYCP::CSKYCPKind Kind, |
121 | unsigned PCAdjust, CSKYCP::CSKYCPModifier Modifier, |
122 | bool AddCurrentAddress, unsigned ID = 0); |
123 | const GlobalValue *getGV() const; |
124 | const BlockAddress *getBlockAddress() const; |
125 | const Constant *getConstantPool() const; |
126 | |
127 | int getExistingMachineCPValue(MachineConstantPool *CP, |
128 | Align Alignment) override; |
129 | void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; |
130 | void print(raw_ostream &O) const override; |
131 | |
132 | bool equals(const CSKYConstantPoolConstant *A) const { |
133 | return CVal == A->CVal && CSKYConstantPoolValue::equals(A); |
134 | } |
135 | |
136 | static bool classof(const CSKYConstantPoolValue *APV) { |
137 | return APV->isGlobalValue() || APV->isBlockAddress() || APV->isConstPool(); |
138 | } |
139 | }; |
140 | |
141 | /// CSKYConstantPoolSymbol - CSKY-specific constantpool values for external |
142 | /// symbols. |
143 | class CSKYConstantPoolSymbol : public CSKYConstantPoolValue { |
144 | const std::string S; // ExtSymbol being loaded. |
145 | |
146 | CSKYConstantPoolSymbol(Type *Ty, const char *S, unsigned PCAdjust, |
147 | CSKYCP::CSKYCPModifier Modifier, |
148 | bool AddCurrentAddress); |
149 | |
150 | public: |
151 | static CSKYConstantPoolSymbol *Create(Type *Ty, const char *S, |
152 | unsigned PCAdjust, |
153 | CSKYCP::CSKYCPModifier Modifier); |
154 | |
155 | StringRef getSymbol() const { return S; } |
156 | |
157 | int getExistingMachineCPValue(MachineConstantPool *CP, |
158 | Align Alignment) override; |
159 | void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; |
160 | void print(raw_ostream &O) const override; |
161 | |
162 | bool equals(const CSKYConstantPoolSymbol *A) const { |
163 | return S == A->S && CSKYConstantPoolValue::equals(A); |
164 | } |
165 | |
166 | static bool classof(const CSKYConstantPoolValue *ACPV) { |
167 | return ACPV->isExtSymbol(); |
168 | } |
169 | }; |
170 | |
171 | /// CSKYConstantPoolMBB - CSKY-specific constantpool value of a machine basic |
172 | /// block. |
173 | class CSKYConstantPoolMBB : public CSKYConstantPoolValue { |
174 | const MachineBasicBlock *MBB; // Machine basic block. |
175 | |
176 | CSKYConstantPoolMBB(Type *Ty, const MachineBasicBlock *Mbb, unsigned PCAdjust, |
177 | CSKYCP::CSKYCPModifier Modifier, bool AddCurrentAddress); |
178 | |
179 | public: |
180 | static CSKYConstantPoolMBB *Create(Type *Ty, const MachineBasicBlock *Mbb, |
181 | unsigned PCAdjust); |
182 | |
183 | const MachineBasicBlock *getMBB() const { return MBB; } |
184 | |
185 | int getExistingMachineCPValue(MachineConstantPool *CP, |
186 | Align Alignment) override; |
187 | void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; |
188 | void print(raw_ostream &O) const override; |
189 | |
190 | bool equals(const CSKYConstantPoolMBB *A) const { |
191 | return MBB == A->MBB && CSKYConstantPoolValue::equals(A); |
192 | } |
193 | |
194 | static bool classof(const CSKYConstantPoolValue *ACPV) { |
195 | return ACPV->isMachineBasicBlock(); |
196 | } |
197 | }; |
198 | |
199 | /// CSKY-specific constantpool value of a jump table. |
200 | class CSKYConstantPoolJT : public CSKYConstantPoolValue { |
201 | signed JTI; // Machine basic block. |
202 | |
203 | CSKYConstantPoolJT(Type *Ty, int JTIndex, unsigned PCAdj, |
204 | CSKYCP::CSKYCPModifier Modifier, bool AddCurrentAddress); |
205 | |
206 | public: |
207 | static CSKYConstantPoolJT *Create(Type *Ty, int JTI, unsigned PCAdj, |
208 | CSKYCP::CSKYCPModifier Modifier); |
209 | |
210 | signed getJTI() { return JTI; } |
211 | |
212 | int getExistingMachineCPValue(MachineConstantPool *CP, |
213 | Align Alignment) override; |
214 | void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; |
215 | void print(raw_ostream &O) const override; |
216 | |
217 | bool equals(const CSKYConstantPoolJT *A) const { |
218 | return JTI == A->JTI && CSKYConstantPoolValue::equals(A); |
219 | } |
220 | |
221 | static bool classof(const CSKYConstantPoolValue *ACPV) { |
222 | return ACPV->isJT(); |
223 | } |
224 | }; |
225 | |
226 | } // namespace llvm |
227 | |
228 | #endif |
229 | |