1 //===-- ARMConstantPoolValue.h - ARM constantpool value ---------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the ARM specific constantpool value class.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H
15 #define LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H
17 #include "llvm/CodeGen/MachineConstantPool.h"
18 #include "llvm/Support/Casting.h"
19 #include "llvm/Support/ErrorHandling.h"
28 class MachineBasicBlock;
41 TLSGD, /// Thread Local Storage (General Dynamic Mode)
42 GOT_PREL, /// Global Offset Table, PC Relative
43 GOTTPOFF, /// Global Offset Table, Thread Pointer Offset
44 TPOFF, /// Thread Pointer Offset
45 SECREL, /// Section Relative (Windows TLS)
49 /// ARMConstantPoolValue - ARM specific constantpool value. This is used to
50 /// represent PC-relative displacement between the address of the load
51 /// instruction and the constant being loaded, i.e. (&GV-(LPIC+8)).
52 class ARMConstantPoolValue : public MachineConstantPoolValue {
53 unsigned LabelId; // Label id of the load.
54 ARMCP::ARMCPKind Kind; // Kind of constant.
55 unsigned char PCAdjust; // Extra adjustment if constantpool is pc-relative.
56 // 8 for ARM, 4 for Thumb.
57 ARMCP::ARMCPModifier Modifier; // GV modifier i.e. (&GV(modifier)-(LPIC+8))
58 bool AddCurrentAddress;
61 ARMConstantPoolValue(Type *Ty, unsigned id, ARMCP::ARMCPKind Kind,
62 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
63 bool AddCurrentAddress);
65 ARMConstantPoolValue(LLVMContext &C, unsigned id, ARMCP::ARMCPKind Kind,
66 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
67 bool AddCurrentAddress);
69 template <typename Derived>
70 int getExistingMachineCPValueImpl(MachineConstantPool *CP,
72 unsigned AlignMask = Alignment - 1;
73 const std::vector<MachineConstantPoolEntry> &Constants = CP->getConstants();
74 for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
75 if (Constants[i].isMachineConstantPoolEntry() &&
76 (Constants[i].getAlignment() & AlignMask) == 0) {
77 ARMConstantPoolValue *CPV =
78 (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal;
79 if (Derived *APC = dyn_cast<Derived>(CPV))
80 if (cast<Derived>(this)->equals(APC))
89 ~ARMConstantPoolValue() override;
91 ARMCP::ARMCPModifier getModifier() const { return Modifier; }
92 const char *getModifierText() const;
93 bool hasModifier() const { return Modifier != ARMCP::no_modifier; }
95 bool mustAddCurrentAddress() const { return AddCurrentAddress; }
97 unsigned getLabelId() const { return LabelId; }
98 unsigned char getPCAdjustment() const { return PCAdjust; }
100 bool isGlobalValue() const { return Kind == ARMCP::CPValue; }
101 bool isExtSymbol() const { return Kind == ARMCP::CPExtSymbol; }
102 bool isBlockAddress() const { return Kind == ARMCP::CPBlockAddress; }
103 bool isLSDA() const { return Kind == ARMCP::CPLSDA; }
104 bool isMachineBasicBlock() const{ return Kind == ARMCP::CPMachineBasicBlock; }
106 int getExistingMachineCPValue(MachineConstantPool *CP,
107 unsigned Alignment) override;
109 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
111 /// hasSameValue - Return true if this ARM constpool value can share the same
112 /// constantpool entry as another ARM constpool value.
113 virtual bool hasSameValue(ARMConstantPoolValue *ACPV);
115 bool equals(const ARMConstantPoolValue *A) const {
116 return this->LabelId == A->LabelId &&
117 this->PCAdjust == A->PCAdjust &&
118 this->Modifier == A->Modifier;
121 void print(raw_ostream &O) const override;
122 void print(raw_ostream *O) const { if (O) print(*O); }
126 inline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) {
131 /// ARMConstantPoolConstant - ARM-specific constant pool values for Constants,
132 /// Functions, and BlockAddresses.
133 class ARMConstantPoolConstant : public ARMConstantPoolValue {
134 const Constant *CVal; // Constant being loaded.
136 ARMConstantPoolConstant(const Constant *C,
138 ARMCP::ARMCPKind Kind,
140 ARMCP::ARMCPModifier Modifier,
141 bool AddCurrentAddress);
142 ARMConstantPoolConstant(Type *Ty, const Constant *C,
144 ARMCP::ARMCPKind Kind,
146 ARMCP::ARMCPModifier Modifier,
147 bool AddCurrentAddress);
150 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID);
151 static ARMConstantPoolConstant *Create(const GlobalValue *GV,
152 ARMCP::ARMCPModifier Modifier);
153 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,
154 ARMCP::ARMCPKind Kind,
155 unsigned char PCAdj);
156 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,
157 ARMCP::ARMCPKind Kind,
159 ARMCP::ARMCPModifier Modifier,
160 bool AddCurrentAddress);
162 const GlobalValue *getGV() const;
163 const BlockAddress *getBlockAddress() const;
165 int getExistingMachineCPValue(MachineConstantPool *CP,
166 unsigned Alignment) override;
168 /// hasSameValue - Return true if this ARM constpool value can share the same
169 /// constantpool entry as another ARM constpool value.
170 bool hasSameValue(ARMConstantPoolValue *ACPV) override;
172 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
174 void print(raw_ostream &O) const override;
175 static bool classof(const ARMConstantPoolValue *APV) {
176 return APV->isGlobalValue() || APV->isBlockAddress() || APV->isLSDA();
179 bool equals(const ARMConstantPoolConstant *A) const {
180 return CVal == A->CVal && ARMConstantPoolValue::equals(A);
184 /// ARMConstantPoolSymbol - ARM-specific constantpool values for external
186 class ARMConstantPoolSymbol : public ARMConstantPoolValue {
187 const std::string S; // ExtSymbol being loaded.
189 ARMConstantPoolSymbol(LLVMContext &C, const char *s, unsigned id,
190 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
191 bool AddCurrentAddress);
194 static ARMConstantPoolSymbol *Create(LLVMContext &C, const char *s,
195 unsigned ID, unsigned char PCAdj);
197 const char *getSymbol() const { return S.c_str(); }
199 int getExistingMachineCPValue(MachineConstantPool *CP,
200 unsigned Alignment) override;
202 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
204 /// hasSameValue - Return true if this ARM constpool value can share the same
205 /// constantpool entry as another ARM constpool value.
206 bool hasSameValue(ARMConstantPoolValue *ACPV) override;
208 void print(raw_ostream &O) const override;
210 static bool classof(const ARMConstantPoolValue *ACPV) {
211 return ACPV->isExtSymbol();
214 bool equals(const ARMConstantPoolSymbol *A) const {
215 return S == A->S && ARMConstantPoolValue::equals(A);
219 /// ARMConstantPoolMBB - ARM-specific constantpool value of a machine basic
221 class ARMConstantPoolMBB : public ARMConstantPoolValue {
222 const MachineBasicBlock *MBB; // Machine basic block.
224 ARMConstantPoolMBB(LLVMContext &C, const MachineBasicBlock *mbb, unsigned id,
225 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
226 bool AddCurrentAddress);
229 static ARMConstantPoolMBB *Create(LLVMContext &C,
230 const MachineBasicBlock *mbb,
231 unsigned ID, unsigned char PCAdj);
233 const MachineBasicBlock *getMBB() const { return MBB; }
235 int getExistingMachineCPValue(MachineConstantPool *CP,
236 unsigned Alignment) override;
238 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
240 /// hasSameValue - Return true if this ARM constpool value can share the same
241 /// constantpool entry as another ARM constpool value.
242 bool hasSameValue(ARMConstantPoolValue *ACPV) override;
244 void print(raw_ostream &O) const override;
246 static bool classof(const ARMConstantPoolValue *ACPV) {
247 return ACPV->isMachineBasicBlock();
250 bool equals(const ARMConstantPoolMBB *A) const {
251 return MBB == A->MBB && ARMConstantPoolValue::equals(A);
255 } // End llvm namespace