[AMDGPU] Check for immediate SrcC in mfma in AsmParser
[llvm-core.git] / lib / Target / ARM / ARMConstantPoolValue.h
blob660b7fc88d82ec450f394ef65a9359cdfcf52dcc
1 //===- ARMConstantPoolValue.h - ARM 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 ARM specific constantpool value class.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H
14 #define LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H
16 #include "llvm/ADT/SmallPtrSet.h"
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/ADT/iterator_range.h"
19 #include "llvm/CodeGen/MachineConstantPool.h"
20 #include "llvm/Support/Casting.h"
21 #include <string>
22 #include <vector>
24 namespace llvm {
26 class BlockAddress;
27 class Constant;
28 class GlobalValue;
29 class GlobalVariable;
30 class LLVMContext;
31 class MachineBasicBlock;
32 class raw_ostream;
33 class Type;
35 namespace ARMCP {
37 enum ARMCPKind {
38 CPValue,
39 CPExtSymbol,
40 CPBlockAddress,
41 CPLSDA,
42 CPMachineBasicBlock,
43 CPPromotedGlobal
46 enum ARMCPModifier {
47 no_modifier, /// None
48 TLSGD, /// Thread Local Storage (General Dynamic Mode)
49 GOT_PREL, /// Global Offset Table, PC Relative
50 GOTTPOFF, /// Global Offset Table, Thread Pointer Offset
51 TPOFF, /// Thread Pointer Offset
52 SECREL, /// Section Relative (Windows TLS)
53 SBREL, /// Static Base Relative (RWPI)
56 } // end namespace ARMCP
58 /// ARMConstantPoolValue - ARM specific constantpool value. This is used to
59 /// represent PC-relative displacement between the address of the load
60 /// instruction and the constant being loaded, i.e. (&GV-(LPIC+8)).
61 class ARMConstantPoolValue : public MachineConstantPoolValue {
62 unsigned LabelId; // Label id of the load.
63 ARMCP::ARMCPKind Kind; // Kind of constant.
64 unsigned char PCAdjust; // Extra adjustment if constantpool is pc-relative.
65 // 8 for ARM, 4 for Thumb.
66 ARMCP::ARMCPModifier Modifier; // GV modifier i.e. (&GV(modifier)-(LPIC+8))
67 bool AddCurrentAddress;
69 protected:
70 ARMConstantPoolValue(Type *Ty, unsigned id, ARMCP::ARMCPKind Kind,
71 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
72 bool AddCurrentAddress);
74 ARMConstantPoolValue(LLVMContext &C, unsigned id, ARMCP::ARMCPKind Kind,
75 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
76 bool AddCurrentAddress);
78 template <typename Derived>
79 int getExistingMachineCPValueImpl(MachineConstantPool *CP,
80 unsigned Alignment) {
81 unsigned AlignMask = Alignment - 1;
82 const std::vector<MachineConstantPoolEntry> &Constants = CP->getConstants();
83 for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
84 if (Constants[i].isMachineConstantPoolEntry() &&
85 (Constants[i].getAlignment() & AlignMask) == 0) {
86 auto *CPV =
87 static_cast<ARMConstantPoolValue*>(Constants[i].Val.MachineCPVal);
88 if (Derived *APC = dyn_cast<Derived>(CPV))
89 if (cast<Derived>(this)->equals(APC))
90 return i;
94 return -1;
97 public:
98 ~ARMConstantPoolValue() override;
100 ARMCP::ARMCPModifier getModifier() const { return Modifier; }
101 StringRef getModifierText() const;
102 bool hasModifier() const { return Modifier != ARMCP::no_modifier; }
104 bool mustAddCurrentAddress() const { return AddCurrentAddress; }
106 unsigned getLabelId() const { return LabelId; }
107 unsigned char getPCAdjustment() const { return PCAdjust; }
109 bool isGlobalValue() const { return Kind == ARMCP::CPValue; }
110 bool isExtSymbol() const { return Kind == ARMCP::CPExtSymbol; }
111 bool isBlockAddress() const { return Kind == ARMCP::CPBlockAddress; }
112 bool isLSDA() const { return Kind == ARMCP::CPLSDA; }
113 bool isMachineBasicBlock() const{ return Kind == ARMCP::CPMachineBasicBlock; }
114 bool isPromotedGlobal() const{ return Kind == ARMCP::CPPromotedGlobal; }
116 int getExistingMachineCPValue(MachineConstantPool *CP,
117 unsigned Alignment) override;
119 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
121 /// hasSameValue - Return true if this ARM constpool value can share the same
122 /// constantpool entry as another ARM constpool value.
123 virtual bool hasSameValue(ARMConstantPoolValue *ACPV);
125 bool equals(const ARMConstantPoolValue *A) const {
126 return this->LabelId == A->LabelId &&
127 this->PCAdjust == A->PCAdjust &&
128 this->Modifier == A->Modifier;
131 void print(raw_ostream &O) const override;
132 void print(raw_ostream *O) const { if (O) print(*O); }
133 void dump() const;
136 inline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) {
137 V.print(O);
138 return O;
141 /// ARMConstantPoolConstant - ARM-specific constant pool values for Constants,
142 /// Functions, and BlockAddresses.
143 class ARMConstantPoolConstant : public ARMConstantPoolValue {
144 const Constant *CVal; // Constant being loaded.
145 SmallPtrSet<const GlobalVariable*, 1> GVars;
147 ARMConstantPoolConstant(const Constant *C,
148 unsigned ID,
149 ARMCP::ARMCPKind Kind,
150 unsigned char PCAdj,
151 ARMCP::ARMCPModifier Modifier,
152 bool AddCurrentAddress);
153 ARMConstantPoolConstant(Type *Ty, const Constant *C,
154 unsigned ID,
155 ARMCP::ARMCPKind Kind,
156 unsigned char PCAdj,
157 ARMCP::ARMCPModifier Modifier,
158 bool AddCurrentAddress);
159 ARMConstantPoolConstant(const GlobalVariable *GV, const Constant *Init);
161 public:
162 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID);
163 static ARMConstantPoolConstant *Create(const GlobalValue *GV,
164 ARMCP::ARMCPModifier Modifier);
165 static ARMConstantPoolConstant *Create(const GlobalVariable *GV,
166 const Constant *Initializer);
167 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,
168 ARMCP::ARMCPKind Kind,
169 unsigned char PCAdj);
170 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,
171 ARMCP::ARMCPKind Kind,
172 unsigned char PCAdj,
173 ARMCP::ARMCPModifier Modifier,
174 bool AddCurrentAddress);
176 const GlobalValue *getGV() const;
177 const BlockAddress *getBlockAddress() const;
179 using promoted_iterator = SmallPtrSet<const GlobalVariable *, 1>::iterator;
181 iterator_range<promoted_iterator> promotedGlobals() {
182 return iterator_range<promoted_iterator>(GVars.begin(), GVars.end());
185 const Constant *getPromotedGlobalInit() const {
186 return CVal;
189 int getExistingMachineCPValue(MachineConstantPool *CP,
190 unsigned Alignment) override;
192 /// hasSameValue - Return true if this ARM constpool value can share the same
193 /// constantpool entry as another ARM constpool value.
194 bool hasSameValue(ARMConstantPoolValue *ACPV) override;
196 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
198 void print(raw_ostream &O) const override;
200 static bool classof(const ARMConstantPoolValue *APV) {
201 return APV->isGlobalValue() || APV->isBlockAddress() || APV->isLSDA() ||
202 APV->isPromotedGlobal();
205 bool equals(const ARMConstantPoolConstant *A) const {
206 return CVal == A->CVal && ARMConstantPoolValue::equals(A);
210 /// ARMConstantPoolSymbol - ARM-specific constantpool values for external
211 /// symbols.
212 class ARMConstantPoolSymbol : public ARMConstantPoolValue {
213 const std::string S; // ExtSymbol being loaded.
215 ARMConstantPoolSymbol(LLVMContext &C, StringRef s, unsigned id,
216 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
217 bool AddCurrentAddress);
219 public:
220 static ARMConstantPoolSymbol *Create(LLVMContext &C, StringRef s, unsigned ID,
221 unsigned char PCAdj);
223 StringRef getSymbol() const { return S; }
225 int getExistingMachineCPValue(MachineConstantPool *CP,
226 unsigned Alignment) override;
228 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
230 /// hasSameValue - Return true if this ARM constpool value can share the same
231 /// constantpool entry as another ARM constpool value.
232 bool hasSameValue(ARMConstantPoolValue *ACPV) override;
234 void print(raw_ostream &O) const override;
236 static bool classof(const ARMConstantPoolValue *ACPV) {
237 return ACPV->isExtSymbol();
240 bool equals(const ARMConstantPoolSymbol *A) const {
241 return S == A->S && ARMConstantPoolValue::equals(A);
245 /// ARMConstantPoolMBB - ARM-specific constantpool value of a machine basic
246 /// block.
247 class ARMConstantPoolMBB : public ARMConstantPoolValue {
248 const MachineBasicBlock *MBB; // Machine basic block.
250 ARMConstantPoolMBB(LLVMContext &C, const MachineBasicBlock *mbb, unsigned id,
251 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
252 bool AddCurrentAddress);
254 public:
255 static ARMConstantPoolMBB *Create(LLVMContext &C,
256 const MachineBasicBlock *mbb,
257 unsigned ID, unsigned char PCAdj);
259 const MachineBasicBlock *getMBB() const { return MBB; }
261 int getExistingMachineCPValue(MachineConstantPool *CP,
262 unsigned Alignment) override;
264 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
266 /// hasSameValue - Return true if this ARM constpool value can share the same
267 /// constantpool entry as another ARM constpool value.
268 bool hasSameValue(ARMConstantPoolValue *ACPV) override;
270 void print(raw_ostream &O) const override;
272 static bool classof(const ARMConstantPoolValue *ACPV) {
273 return ACPV->isMachineBasicBlock();
276 bool equals(const ARMConstantPoolMBB *A) const {
277 return MBB == A->MBB && ARMConstantPoolValue::equals(A);
281 } // end namespace llvm
283 #endif // LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H