blob: c7a84155bd486f4f4f7174e2d7a96172e160d8f8 [file] [log] [blame]
Jia Liub22310f2012-02-18 12:03:15 +00001//===-- ARMConstantPoolValue.h - ARM constantpool value ---------*- C++ -*-===//
Evan Cheng10043e22007-01-19 07:51:42 +00002//
3// The LLVM Compiler Infrastructure
4//
Chris Lattnerf3ebc3f2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Evan Cheng10043e22007-01-19 07:51:42 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the ARM specific constantpool value class.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_TARGET_ARM_CONSTANTPOOLVALUE_H
15#define LLVM_TARGET_ARM_CONSTANTPOOLVALUE_H
16
17#include "llvm/CodeGen/MachineConstantPool.h"
Benjamin Kramer2ef689c2013-09-16 10:17:31 +000018#include "llvm/Support/Casting.h"
Jim Grosbacha942ad42010-11-09 21:36:17 +000019#include "llvm/Support/ErrorHandling.h"
Daniel Dunbar09041342010-06-15 14:50:42 +000020#include <cstddef>
Evan Cheng10043e22007-01-19 07:51:42 +000021
22namespace llvm {
23
Bob Wilson433ab092009-11-02 16:59:06 +000024class BlockAddress;
Bill Wendlinga1127b22011-09-29 23:48:44 +000025class Constant;
Dan Gohman0597e5b2008-07-11 20:38:31 +000026class GlobalValue;
Owen Anderson55f1c092009-08-13 21:58:54 +000027class LLVMContext;
Bill Wendlinga1127b22011-09-29 23:48:44 +000028class MachineBasicBlock;
Dan Gohman0597e5b2008-07-11 20:38:31 +000029
Jim Grosbach20eac922009-09-01 01:57:56 +000030namespace ARMCP {
31 enum ARMCPKind {
32 CPValue,
Bob Wilson433ab092009-11-02 16:59:06 +000033 CPExtSymbol,
34 CPBlockAddress,
Bill Wendlinga1127b22011-09-29 23:48:44 +000035 CPLSDA,
36 CPMachineBasicBlock
Jim Grosbach20eac922009-09-01 01:57:56 +000037 };
Jim Grosbacha942ad42010-11-09 21:36:17 +000038
39 enum ARMCPModifier {
40 no_modifier,
41 TLSGD,
42 GOT,
43 GOTOFF,
44 GOTTPOFF,
45 TPOFF
46 };
Jim Grosbach20eac922009-09-01 01:57:56 +000047}
48
Evan Cheng10043e22007-01-19 07:51:42 +000049/// ARMConstantPoolValue - ARM specific constantpool value. This is used to
Bob Wilson4c00a522009-11-02 17:10:37 +000050/// represent PC-relative displacement between the address of the load
Bob Wilson433ab092009-11-02 16:59:06 +000051/// instruction and the constant being loaded, i.e. (&GV-(LPIC+8)).
Evan Cheng10043e22007-01-19 07:51:42 +000052class ARMConstantPoolValue : public MachineConstantPoolValue {
Evan Cheng10043e22007-01-19 07:51:42 +000053 unsigned LabelId; // Label id of the load.
Bob Wilson433ab092009-11-02 16:59:06 +000054 ARMCP::ARMCPKind Kind; // Kind of constant.
Bob Wilson4c00a522009-11-02 17:10:37 +000055 unsigned char PCAdjust; // Extra adjustment if constantpool is pc-relative.
Evan Cheng10043e22007-01-19 07:51:42 +000056 // 8 for ARM, 4 for Thumb.
Jim Grosbacha942ad42010-11-09 21:36:17 +000057 ARMCP::ARMCPModifier Modifier; // GV modifier i.e. (&GV(modifier)-(LPIC+8))
Lauro Ramos Venancioc39c12a2007-04-27 13:54:47 +000058 bool AddCurrentAddress;
Evan Cheng10043e22007-01-19 07:51:42 +000059
Bill Wendling396c2112011-10-01 06:40:33 +000060protected:
61 ARMConstantPoolValue(Type *Ty, unsigned id, ARMCP::ARMCPKind Kind,
62 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
63 bool AddCurrentAddress);
64
Bill Wendlingd7fa0162011-10-01 08:36:59 +000065 ARMConstantPoolValue(LLVMContext &C, unsigned id, ARMCP::ARMCPKind Kind,
66 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
67 bool AddCurrentAddress);
Benjamin Kramer2ef689c2013-09-16 10:17:31 +000068
69 template <typename Derived>
70 int getExistingMachineCPValueImpl(MachineConstantPool *CP,
71 unsigned Alignment) {
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))
81 return i;
82 }
83 }
84
85 return -1;
86 }
87
Evan Cheng10043e22007-01-19 07:51:42 +000088public:
Bill Wendlingd7fa0162011-10-01 08:36:59 +000089 virtual ~ARMConstantPoolValue();
Lauro Ramos Venancioee2d1642007-04-22 00:04:12 +000090
Jim Grosbacha942ad42010-11-09 21:36:17 +000091 ARMCP::ARMCPModifier getModifier() const { return Modifier; }
Bill Wendlinge8e4dbf2011-09-30 18:42:06 +000092 const char *getModifierText() const;
Jim Grosbacha942ad42010-11-09 21:36:17 +000093 bool hasModifier() const { return Modifier != ARMCP::no_modifier; }
Bill Wendlinge8e4dbf2011-09-30 18:42:06 +000094
Lauro Ramos Venancioc39c12a2007-04-27 13:54:47 +000095 bool mustAddCurrentAddress() const { return AddCurrentAddress; }
Bill Wendlinge8e4dbf2011-09-30 18:42:06 +000096
Evan Cheng10043e22007-01-19 07:51:42 +000097 unsigned getLabelId() const { return LabelId; }
Evan Cheng10043e22007-01-19 07:51:42 +000098 unsigned char getPCAdjustment() const { return PCAdjust; }
Bill Wendlinge8e4dbf2011-09-30 18:42:06 +000099
Bob Wilson433ab092009-11-02 16:59:06 +0000100 bool isGlobalValue() const { return Kind == ARMCP::CPValue; }
101 bool isExtSymbol() const { return Kind == ARMCP::CPExtSymbol; }
Bill Wendling396c2112011-10-01 06:40:33 +0000102 bool isBlockAddress() const { return Kind == ARMCP::CPBlockAddress; }
Bill Wendlinge8e4dbf2011-09-30 18:42:06 +0000103 bool isLSDA() const { return Kind == ARMCP::CPLSDA; }
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000104 bool isMachineBasicBlock() const{ return Kind == ARMCP::CPMachineBasicBlock; }
Evan Cheng10043e22007-01-19 07:51:42 +0000105
Craig Topper6bc27bf2014-03-10 02:09:33 +0000106 unsigned getRelocationInfo() const override { return 2; }
Chris Lattnercfb01e22009-07-21 23:34:23 +0000107
Craig Topper6bc27bf2014-03-10 02:09:33 +0000108 int getExistingMachineCPValue(MachineConstantPool *CP,
109 unsigned Alignment) override;
Evan Cheng10043e22007-01-19 07:51:42 +0000110
Craig Topper6bc27bf2014-03-10 02:09:33 +0000111 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
Evan Cheng10043e22007-01-19 07:51:42 +0000112
Bill Wendling396c2112011-10-01 06:40:33 +0000113 /// 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);
Evan Cheng7ff83192009-11-07 03:52:02 +0000116
Bill Wendlingf977ff52011-10-01 12:44:28 +0000117 bool equals(const ARMConstantPoolValue *A) const {
118 return this->LabelId == A->LabelId &&
119 this->PCAdjust == A->PCAdjust &&
120 this->Modifier == A->Modifier;
121 }
122
Craig Topper6bc27bf2014-03-10 02:09:33 +0000123 void print(raw_ostream &O) const override;
Evan Chengde9dbc52008-10-29 23:55:17 +0000124 void print(raw_ostream *O) const { if (O) print(*O); }
Evan Chengde9dbc52008-10-29 23:55:17 +0000125 void dump() const;
Evan Cheng10043e22007-01-19 07:51:42 +0000126};
Evan Chengde9dbc52008-10-29 23:55:17 +0000127
Evan Chengde9dbc52008-10-29 23:55:17 +0000128inline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) {
129 V.print(O);
130 return O;
131}
132
Bill Wendling396c2112011-10-01 06:40:33 +0000133/// ARMConstantPoolConstant - ARM-specific constant pool values for Constants,
134/// Functions, and BlockAddresses.
135class ARMConstantPoolConstant : public ARMConstantPoolValue {
136 const Constant *CVal; // Constant being loaded.
137
138 ARMConstantPoolConstant(const Constant *C,
139 unsigned ID,
140 ARMCP::ARMCPKind Kind,
141 unsigned char PCAdj,
142 ARMCP::ARMCPModifier Modifier,
143 bool AddCurrentAddress);
Bill Wendlingf117a352011-10-01 07:52:37 +0000144 ARMConstantPoolConstant(Type *Ty, const Constant *C,
145 unsigned ID,
146 ARMCP::ARMCPKind Kind,
147 unsigned char PCAdj,
148 ARMCP::ARMCPModifier Modifier,
149 bool AddCurrentAddress);
150
Bill Wendling396c2112011-10-01 06:40:33 +0000151public:
152 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID);
Bill Wendlingf117a352011-10-01 07:52:37 +0000153 static ARMConstantPoolConstant *Create(const GlobalValue *GV,
154 ARMCP::ARMCPModifier Modifier);
Bill Wendling67225562011-10-01 06:44:24 +0000155 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,
156 ARMCP::ARMCPKind Kind,
157 unsigned char PCAdj);
Bill Wendlingf117a352011-10-01 07:52:37 +0000158 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,
159 ARMCP::ARMCPKind Kind,
160 unsigned char PCAdj,
161 ARMCP::ARMCPModifier Modifier,
162 bool AddCurrentAddress);
Bill Wendling396c2112011-10-01 06:40:33 +0000163
164 const GlobalValue *getGV() const;
Bill Wendlingf117a352011-10-01 07:52:37 +0000165 const BlockAddress *getBlockAddress() const;
166
Craig Topper6bc27bf2014-03-10 02:09:33 +0000167 int getExistingMachineCPValue(MachineConstantPool *CP,
168 unsigned Alignment) override;
Bill Wendling396c2112011-10-01 06:40:33 +0000169
170 /// hasSameValue - Return true if this ARM constpool value can share the same
171 /// constantpool entry as another ARM constpool value.
Craig Topper6bc27bf2014-03-10 02:09:33 +0000172 bool hasSameValue(ARMConstantPoolValue *ACPV) override;
Bill Wendling396c2112011-10-01 06:40:33 +0000173
Craig Topper6bc27bf2014-03-10 02:09:33 +0000174 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
Bill Wendling396c2112011-10-01 06:40:33 +0000175
Craig Topper6bc27bf2014-03-10 02:09:33 +0000176 void print(raw_ostream &O) const override;
Bill Wendling396c2112011-10-01 06:40:33 +0000177 static bool classof(const ARMConstantPoolValue *APV) {
178 return APV->isGlobalValue() || APV->isBlockAddress() || APV->isLSDA();
179 }
Benjamin Kramer2ef689c2013-09-16 10:17:31 +0000180
181 bool equals(const ARMConstantPoolConstant *A) const {
182 return CVal == A->CVal && ARMConstantPoolValue::equals(A);
183 }
Bill Wendling396c2112011-10-01 06:40:33 +0000184};
185
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000186/// ARMConstantPoolSymbol - ARM-specific constantpool values for external
187/// symbols.
188class ARMConstantPoolSymbol : public ARMConstantPoolValue {
Benjamin Kramer9d461102012-12-24 19:23:30 +0000189 const std::string S; // ExtSymbol being loaded.
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000190
191 ARMConstantPoolSymbol(LLVMContext &C, const char *s, unsigned id,
192 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
193 bool AddCurrentAddress);
194
195public:
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000196 static ARMConstantPoolSymbol *Create(LLVMContext &C, const char *s,
Bill Wendlingc214cb02011-10-01 08:58:29 +0000197 unsigned ID, unsigned char PCAdj);
198
Benjamin Kramer9d461102012-12-24 19:23:30 +0000199 const char *getSymbol() const { return S.c_str(); }
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000200
Craig Topper6bc27bf2014-03-10 02:09:33 +0000201 int getExistingMachineCPValue(MachineConstantPool *CP,
202 unsigned Alignment) override;
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000203
Craig Topper6bc27bf2014-03-10 02:09:33 +0000204 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000205
206 /// hasSameValue - Return true if this ARM constpool value can share the same
207 /// constantpool entry as another ARM constpool value.
Craig Topper6bc27bf2014-03-10 02:09:33 +0000208 bool hasSameValue(ARMConstantPoolValue *ACPV) override;
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000209
Craig Topper6bc27bf2014-03-10 02:09:33 +0000210 void print(raw_ostream &O) const override;
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000211
212 static bool classof(const ARMConstantPoolValue *ACPV) {
213 return ACPV->isExtSymbol();
214 }
Benjamin Kramer2ef689c2013-09-16 10:17:31 +0000215
216 bool equals(const ARMConstantPoolSymbol *A) const {
217 return S == A->S && ARMConstantPoolValue::equals(A);
218 }
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000219};
220
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000221/// ARMConstantPoolMBB - ARM-specific constantpool value of a machine basic
222/// block.
223class ARMConstantPoolMBB : public ARMConstantPoolValue {
Bill Wendling4a4772f2011-10-01 09:30:42 +0000224 const MachineBasicBlock *MBB; // Machine basic block.
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000225
Bill Wendling4a4772f2011-10-01 09:30:42 +0000226 ARMConstantPoolMBB(LLVMContext &C, const MachineBasicBlock *mbb, unsigned id,
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000227 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
228 bool AddCurrentAddress);
229
230public:
Bill Wendling4a4772f2011-10-01 09:30:42 +0000231 static ARMConstantPoolMBB *Create(LLVMContext &C,
232 const MachineBasicBlock *mbb,
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000233 unsigned ID, unsigned char PCAdj);
234
235 const MachineBasicBlock *getMBB() const { return MBB; }
236
Craig Topper6bc27bf2014-03-10 02:09:33 +0000237 int getExistingMachineCPValue(MachineConstantPool *CP,
238 unsigned Alignment) override;
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000239
Craig Topper6bc27bf2014-03-10 02:09:33 +0000240 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000241
242 /// hasSameValue - Return true if this ARM constpool value can share the same
243 /// constantpool entry as another ARM constpool value.
Craig Topper6bc27bf2014-03-10 02:09:33 +0000244 bool hasSameValue(ARMConstantPoolValue *ACPV) override;
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000245
Craig Topper6bc27bf2014-03-10 02:09:33 +0000246 void print(raw_ostream &O) const override;
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000247
248 static bool classof(const ARMConstantPoolValue *ACPV) {
249 return ACPV->isMachineBasicBlock();
250 }
Benjamin Kramer2ef689c2013-09-16 10:17:31 +0000251
252 bool equals(const ARMConstantPoolMBB *A) const {
253 return MBB == A->MBB && ARMConstantPoolValue::equals(A);
254 }
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000255};
256
Evan Chengde9dbc52008-10-29 23:55:17 +0000257} // End llvm namespace
Evan Cheng10043e22007-01-19 07:51:42 +0000258
259#endif