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;
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 virtual ~ARMConstantPoolValue();
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 unsigned getRelocationInfo() const override { return 2; }
108 int getExistingMachineCPValue(MachineConstantPool *CP,
109 unsigned Alignment) override;
111 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
113 /// hasSameValue - Return true if this ARM constpool value can share the same
114 /// constantpool entry as another ARM constpool value.
115 virtual bool hasSameValue(ARMConstantPoolValue *ACPV);
117 bool equals(const ARMConstantPoolValue *A) const {
118 return this->LabelId == A->LabelId &&
119 this->PCAdjust == A->PCAdjust &&
120 this->Modifier == A->Modifier;
123 void print(raw_ostream &O) const override;
124 void print(raw_ostream *O) const { if (O) print(*O); }
128 inline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) {
133 /// ARMConstantPoolConstant - ARM-specific constant pool values for Constants,
134 /// Functions, and BlockAddresses.
135 class ARMConstantPoolConstant : public ARMConstantPoolValue {
136 const Constant *CVal; // Constant being loaded.
138 ARMConstantPoolConstant(const Constant *C,
140 ARMCP::ARMCPKind Kind,
142 ARMCP::ARMCPModifier Modifier,
143 bool AddCurrentAddress);
144 ARMConstantPoolConstant(Type *Ty, const Constant *C,
146 ARMCP::ARMCPKind Kind,
148 ARMCP::ARMCPModifier Modifier,
149 bool AddCurrentAddress);
152 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID);
153 static ARMConstantPoolConstant *Create(const GlobalValue *GV,
154 ARMCP::ARMCPModifier Modifier);
155 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,
156 ARMCP::ARMCPKind Kind,
157 unsigned char PCAdj);
158 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,
159 ARMCP::ARMCPKind Kind,
161 ARMCP::ARMCPModifier Modifier,
162 bool AddCurrentAddress);
164 const GlobalValue *getGV() const;
165 const BlockAddress *getBlockAddress() const;
167 int getExistingMachineCPValue(MachineConstantPool *CP,
168 unsigned Alignment) override;
170 /// hasSameValue - Return true if this ARM constpool value can share the same
171 /// constantpool entry as another ARM constpool value.
172 bool hasSameValue(ARMConstantPoolValue *ACPV) override;
174 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
176 void print(raw_ostream &O) const override;
177 static bool classof(const ARMConstantPoolValue *APV) {
178 return APV->isGlobalValue() || APV->isBlockAddress() || APV->isLSDA();
181 bool equals(const ARMConstantPoolConstant *A) const {
182 return CVal == A->CVal && ARMConstantPoolValue::equals(A);
186 /// ARMConstantPoolSymbol - ARM-specific constantpool values for external
188 class ARMConstantPoolSymbol : public ARMConstantPoolValue {
189 const std::string S; // ExtSymbol being loaded.
191 ARMConstantPoolSymbol(LLVMContext &C, const char *s, unsigned id,
192 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
193 bool AddCurrentAddress);
196 static ARMConstantPoolSymbol *Create(LLVMContext &C, const char *s,
197 unsigned ID, unsigned char PCAdj);
199 const char *getSymbol() const { return S.c_str(); }
201 int getExistingMachineCPValue(MachineConstantPool *CP,
202 unsigned Alignment) override;
204 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
206 /// hasSameValue - Return true if this ARM constpool value can share the same
207 /// constantpool entry as another ARM constpool value.
208 bool hasSameValue(ARMConstantPoolValue *ACPV) override;
210 void print(raw_ostream &O) const override;
212 static bool classof(const ARMConstantPoolValue *ACPV) {
213 return ACPV->isExtSymbol();
216 bool equals(const ARMConstantPoolSymbol *A) const {
217 return S == A->S && ARMConstantPoolValue::equals(A);
221 /// ARMConstantPoolMBB - ARM-specific constantpool value of a machine basic
223 class ARMConstantPoolMBB : public ARMConstantPoolValue {
224 const MachineBasicBlock *MBB; // Machine basic block.
226 ARMConstantPoolMBB(LLVMContext &C, const MachineBasicBlock *mbb, unsigned id,
227 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
228 bool AddCurrentAddress);
231 static ARMConstantPoolMBB *Create(LLVMContext &C,
232 const MachineBasicBlock *mbb,
233 unsigned ID, unsigned char PCAdj);
235 const MachineBasicBlock *getMBB() const { return MBB; }
237 int getExistingMachineCPValue(MachineConstantPool *CP,
238 unsigned Alignment) override;
240 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
242 /// hasSameValue - Return true if this ARM constpool value can share the same
243 /// constantpool entry as another ARM constpool value.
244 bool hasSameValue(ARMConstantPoolValue *ACPV) override;
246 void print(raw_ostream &O) const override;
248 static bool classof(const ARMConstantPoolValue *ACPV) {
249 return ACPV->isMachineBasicBlock();
252 bool equals(const ARMConstantPoolMBB *A) const {
253 return MBB == A->MBB && ARMConstantPoolValue::equals(A);
257 } // End llvm namespace