blob: 6b18a4e528786b5ef97b88d075d868392f09f476 [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
Benjamin Kramera7c40ef2014-08-13 16:26:38 +000014#ifndef LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H
15#define LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H
Evan Cheng10043e22007-01-19 07:51:42 +000016
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,
Peter Collingbourne97aae402015-10-26 18:23:16 +000042 GOT_PREL,
Jim Grosbacha942ad42010-11-09 21:36:17 +000043 GOTTPOFF,
44 TPOFF
45 };
Alexander Kornienkof00654e2015-06-23 09:49:53 +000046}
Jim Grosbach20eac922009-09-01 01:57:56 +000047
Evan Cheng10043e22007-01-19 07:51:42 +000048/// ARMConstantPoolValue - ARM specific constantpool value. This is used to
Bob Wilson4c00a522009-11-02 17:10:37 +000049/// represent PC-relative displacement between the address of the load
Bob Wilson433ab092009-11-02 16:59:06 +000050/// instruction and the constant being loaded, i.e. (&GV-(LPIC+8)).
Evan Cheng10043e22007-01-19 07:51:42 +000051class ARMConstantPoolValue : public MachineConstantPoolValue {
Evan Cheng10043e22007-01-19 07:51:42 +000052 unsigned LabelId; // Label id of the load.
Bob Wilson433ab092009-11-02 16:59:06 +000053 ARMCP::ARMCPKind Kind; // Kind of constant.
Bob Wilson4c00a522009-11-02 17:10:37 +000054 unsigned char PCAdjust; // Extra adjustment if constantpool is pc-relative.
Evan Cheng10043e22007-01-19 07:51:42 +000055 // 8 for ARM, 4 for Thumb.
Jim Grosbacha942ad42010-11-09 21:36:17 +000056 ARMCP::ARMCPModifier Modifier; // GV modifier i.e. (&GV(modifier)-(LPIC+8))
Lauro Ramos Venancioc39c12a2007-04-27 13:54:47 +000057 bool AddCurrentAddress;
Evan Cheng10043e22007-01-19 07:51:42 +000058
Bill Wendling396c2112011-10-01 06:40:33 +000059protected:
60 ARMConstantPoolValue(Type *Ty, unsigned id, ARMCP::ARMCPKind Kind,
61 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
62 bool AddCurrentAddress);
63
Bill Wendlingd7fa0162011-10-01 08:36:59 +000064 ARMConstantPoolValue(LLVMContext &C, unsigned id, ARMCP::ARMCPKind Kind,
65 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
66 bool AddCurrentAddress);
Benjamin Kramer2ef689c2013-09-16 10:17:31 +000067
68 template <typename Derived>
69 int getExistingMachineCPValueImpl(MachineConstantPool *CP,
70 unsigned Alignment) {
71 unsigned AlignMask = Alignment - 1;
72 const std::vector<MachineConstantPoolEntry> &Constants = CP->getConstants();
73 for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
74 if (Constants[i].isMachineConstantPoolEntry() &&
75 (Constants[i].getAlignment() & AlignMask) == 0) {
76 ARMConstantPoolValue *CPV =
77 (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal;
78 if (Derived *APC = dyn_cast<Derived>(CPV))
79 if (cast<Derived>(this)->equals(APC))
80 return i;
81 }
82 }
83
84 return -1;
85 }
86
Evan Cheng10043e22007-01-19 07:51:42 +000087public:
Alexander Kornienkof817c1c2015-04-11 02:11:45 +000088 ~ARMConstantPoolValue() override;
Lauro Ramos Venancioee2d1642007-04-22 00:04:12 +000089
Jim Grosbacha942ad42010-11-09 21:36:17 +000090 ARMCP::ARMCPModifier getModifier() const { return Modifier; }
Bill Wendlinge8e4dbf2011-09-30 18:42:06 +000091 const char *getModifierText() const;
Jim Grosbacha942ad42010-11-09 21:36:17 +000092 bool hasModifier() const { return Modifier != ARMCP::no_modifier; }
Bill Wendlinge8e4dbf2011-09-30 18:42:06 +000093
Lauro Ramos Venancioc39c12a2007-04-27 13:54:47 +000094 bool mustAddCurrentAddress() const { return AddCurrentAddress; }
Bill Wendlinge8e4dbf2011-09-30 18:42:06 +000095
Evan Cheng10043e22007-01-19 07:51:42 +000096 unsigned getLabelId() const { return LabelId; }
Evan Cheng10043e22007-01-19 07:51:42 +000097 unsigned char getPCAdjustment() const { return PCAdjust; }
Bill Wendlinge8e4dbf2011-09-30 18:42:06 +000098
Bob Wilson433ab092009-11-02 16:59:06 +000099 bool isGlobalValue() const { return Kind == ARMCP::CPValue; }
100 bool isExtSymbol() const { return Kind == ARMCP::CPExtSymbol; }
Bill Wendling396c2112011-10-01 06:40:33 +0000101 bool isBlockAddress() const { return Kind == ARMCP::CPBlockAddress; }
Bill Wendlinge8e4dbf2011-09-30 18:42:06 +0000102 bool isLSDA() const { return Kind == ARMCP::CPLSDA; }
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000103 bool isMachineBasicBlock() const{ return Kind == ARMCP::CPMachineBasicBlock; }
Evan Cheng10043e22007-01-19 07:51:42 +0000104
Craig Topper6bc27bf2014-03-10 02:09:33 +0000105 int getExistingMachineCPValue(MachineConstantPool *CP,
106 unsigned Alignment) override;
Evan Cheng10043e22007-01-19 07:51:42 +0000107
Craig Topper6bc27bf2014-03-10 02:09:33 +0000108 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
Evan Cheng10043e22007-01-19 07:51:42 +0000109
Bill Wendling396c2112011-10-01 06:40:33 +0000110 /// hasSameValue - Return true if this ARM constpool value can share the same
111 /// constantpool entry as another ARM constpool value.
112 virtual bool hasSameValue(ARMConstantPoolValue *ACPV);
Evan Cheng7ff83192009-11-07 03:52:02 +0000113
Bill Wendlingf977ff52011-10-01 12:44:28 +0000114 bool equals(const ARMConstantPoolValue *A) const {
115 return this->LabelId == A->LabelId &&
116 this->PCAdjust == A->PCAdjust &&
117 this->Modifier == A->Modifier;
118 }
119
Craig Topper6bc27bf2014-03-10 02:09:33 +0000120 void print(raw_ostream &O) const override;
Evan Chengde9dbc52008-10-29 23:55:17 +0000121 void print(raw_ostream *O) const { if (O) print(*O); }
Evan Chengde9dbc52008-10-29 23:55:17 +0000122 void dump() const;
Evan Cheng10043e22007-01-19 07:51:42 +0000123};
Evan Chengde9dbc52008-10-29 23:55:17 +0000124
Evan Chengde9dbc52008-10-29 23:55:17 +0000125inline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) {
126 V.print(O);
127 return O;
128}
129
Bill Wendling396c2112011-10-01 06:40:33 +0000130/// ARMConstantPoolConstant - ARM-specific constant pool values for Constants,
131/// Functions, and BlockAddresses.
132class ARMConstantPoolConstant : public ARMConstantPoolValue {
133 const Constant *CVal; // Constant being loaded.
134
135 ARMConstantPoolConstant(const Constant *C,
136 unsigned ID,
137 ARMCP::ARMCPKind Kind,
138 unsigned char PCAdj,
139 ARMCP::ARMCPModifier Modifier,
140 bool AddCurrentAddress);
Bill Wendlingf117a352011-10-01 07:52:37 +0000141 ARMConstantPoolConstant(Type *Ty, const Constant *C,
142 unsigned ID,
143 ARMCP::ARMCPKind Kind,
144 unsigned char PCAdj,
145 ARMCP::ARMCPModifier Modifier,
146 bool AddCurrentAddress);
147
Bill Wendling396c2112011-10-01 06:40:33 +0000148public:
149 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID);
Bill Wendlingf117a352011-10-01 07:52:37 +0000150 static ARMConstantPoolConstant *Create(const GlobalValue *GV,
151 ARMCP::ARMCPModifier Modifier);
Bill Wendling67225562011-10-01 06:44:24 +0000152 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,
153 ARMCP::ARMCPKind Kind,
154 unsigned char PCAdj);
Bill Wendlingf117a352011-10-01 07:52:37 +0000155 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,
156 ARMCP::ARMCPKind Kind,
157 unsigned char PCAdj,
158 ARMCP::ARMCPModifier Modifier,
159 bool AddCurrentAddress);
Bill Wendling396c2112011-10-01 06:40:33 +0000160
161 const GlobalValue *getGV() const;
Bill Wendlingf117a352011-10-01 07:52:37 +0000162 const BlockAddress *getBlockAddress() const;
163
Craig Topper6bc27bf2014-03-10 02:09:33 +0000164 int getExistingMachineCPValue(MachineConstantPool *CP,
165 unsigned Alignment) override;
Bill Wendling396c2112011-10-01 06:40:33 +0000166
167 /// hasSameValue - Return true if this ARM constpool value can share the same
168 /// constantpool entry as another ARM constpool value.
Craig Topper6bc27bf2014-03-10 02:09:33 +0000169 bool hasSameValue(ARMConstantPoolValue *ACPV) override;
Bill Wendling396c2112011-10-01 06:40:33 +0000170
Craig Topper6bc27bf2014-03-10 02:09:33 +0000171 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
Bill Wendling396c2112011-10-01 06:40:33 +0000172
Craig Topper6bc27bf2014-03-10 02:09:33 +0000173 void print(raw_ostream &O) const override;
Bill Wendling396c2112011-10-01 06:40:33 +0000174 static bool classof(const ARMConstantPoolValue *APV) {
175 return APV->isGlobalValue() || APV->isBlockAddress() || APV->isLSDA();
176 }
Benjamin Kramer2ef689c2013-09-16 10:17:31 +0000177
178 bool equals(const ARMConstantPoolConstant *A) const {
179 return CVal == A->CVal && ARMConstantPoolValue::equals(A);
180 }
Bill Wendling396c2112011-10-01 06:40:33 +0000181};
182
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000183/// ARMConstantPoolSymbol - ARM-specific constantpool values for external
184/// symbols.
185class ARMConstantPoolSymbol : public ARMConstantPoolValue {
Benjamin Kramer9d461102012-12-24 19:23:30 +0000186 const std::string S; // ExtSymbol being loaded.
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000187
188 ARMConstantPoolSymbol(LLVMContext &C, const char *s, unsigned id,
189 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
190 bool AddCurrentAddress);
191
192public:
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000193 static ARMConstantPoolSymbol *Create(LLVMContext &C, const char *s,
Bill Wendlingc214cb02011-10-01 08:58:29 +0000194 unsigned ID, unsigned char PCAdj);
195
Benjamin Kramer9d461102012-12-24 19:23:30 +0000196 const char *getSymbol() const { return S.c_str(); }
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000197
Craig Topper6bc27bf2014-03-10 02:09:33 +0000198 int getExistingMachineCPValue(MachineConstantPool *CP,
199 unsigned Alignment) override;
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000200
Craig Topper6bc27bf2014-03-10 02:09:33 +0000201 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000202
203 /// hasSameValue - Return true if this ARM constpool value can share the same
204 /// constantpool entry as another ARM constpool value.
Craig Topper6bc27bf2014-03-10 02:09:33 +0000205 bool hasSameValue(ARMConstantPoolValue *ACPV) override;
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000206
Craig Topper6bc27bf2014-03-10 02:09:33 +0000207 void print(raw_ostream &O) const override;
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000208
209 static bool classof(const ARMConstantPoolValue *ACPV) {
210 return ACPV->isExtSymbol();
211 }
Benjamin Kramer2ef689c2013-09-16 10:17:31 +0000212
213 bool equals(const ARMConstantPoolSymbol *A) const {
214 return S == A->S && ARMConstantPoolValue::equals(A);
215 }
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000216};
217
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000218/// ARMConstantPoolMBB - ARM-specific constantpool value of a machine basic
219/// block.
220class ARMConstantPoolMBB : public ARMConstantPoolValue {
Bill Wendling4a4772f2011-10-01 09:30:42 +0000221 const MachineBasicBlock *MBB; // Machine basic block.
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000222
Bill Wendling4a4772f2011-10-01 09:30:42 +0000223 ARMConstantPoolMBB(LLVMContext &C, const MachineBasicBlock *mbb, unsigned id,
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000224 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
225 bool AddCurrentAddress);
226
227public:
Bill Wendling4a4772f2011-10-01 09:30:42 +0000228 static ARMConstantPoolMBB *Create(LLVMContext &C,
229 const MachineBasicBlock *mbb,
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000230 unsigned ID, unsigned char PCAdj);
231
232 const MachineBasicBlock *getMBB() const { return MBB; }
233
Craig Topper6bc27bf2014-03-10 02:09:33 +0000234 int getExistingMachineCPValue(MachineConstantPool *CP,
235 unsigned Alignment) override;
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000236
Craig Topper6bc27bf2014-03-10 02:09:33 +0000237 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000238
239 /// hasSameValue - Return true if this ARM constpool value can share the same
240 /// constantpool entry as another ARM constpool value.
Craig Topper6bc27bf2014-03-10 02:09:33 +0000241 bool hasSameValue(ARMConstantPoolValue *ACPV) override;
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000242
Craig Topper6bc27bf2014-03-10 02:09:33 +0000243 void print(raw_ostream &O) const override;
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000244
245 static bool classof(const ARMConstantPoolValue *ACPV) {
246 return ACPV->isMachineBasicBlock();
247 }
Benjamin Kramer2ef689c2013-09-16 10:17:31 +0000248
249 bool equals(const ARMConstantPoolMBB *A) const {
250 return MBB == A->MBB && ARMConstantPoolValue::equals(A);
251 }
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000252};
253
Alexander Kornienkof00654e2015-06-23 09:49:53 +0000254} // End llvm namespace
Evan Cheng10043e22007-01-19 07:51:42 +0000255
256#endif