1//===-- ARMConstantPoolValue.h - ARM constantpool value ---------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
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"
18#include "llvm/Support/ErrorHandling.h"
19#include <cstddef>
20
21namespace llvm {
22
23class BlockAddress;
24class Constant;
25class GlobalValue;
26class LLVMContext;
27class MachineBasicBlock;
28
29namespace ARMCP {
30  enum ARMCPKind {
31    CPValue,
32    CPExtSymbol,
33    CPBlockAddress,
34    CPLSDA,
35    CPMachineBasicBlock
36  };
37
38  enum ARMCPModifier {
39    no_modifier,
40    TLSGD,
41    GOT,
42    GOTOFF,
43    GOTTPOFF,
44    TPOFF
45  };
46}
47
48/// ARMConstantPoolValue - ARM specific constantpool value. This is used to
49/// represent PC-relative displacement between the address of the load
50/// instruction and the constant being loaded, i.e. (&GV-(LPIC+8)).
51class ARMConstantPoolValue : public MachineConstantPoolValue {
52  unsigned LabelId;        // Label id of the load.
53  ARMCP::ARMCPKind Kind;   // Kind of constant.
54  unsigned char PCAdjust;  // Extra adjustment if constantpool is pc-relative.
55                           // 8 for ARM, 4 for Thumb.
56  ARMCP::ARMCPModifier Modifier;   // GV modifier i.e. (&GV(modifier)-(LPIC+8))
57  bool AddCurrentAddress;
58
59protected:
60  ARMConstantPoolValue(Type *Ty, unsigned id, ARMCP::ARMCPKind Kind,
61                       unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
62                       bool AddCurrentAddress);
63
64  ARMConstantPoolValue(LLVMContext &C, unsigned id, ARMCP::ARMCPKind Kind,
65                       unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
66                       bool AddCurrentAddress);
67public:
68  virtual ~ARMConstantPoolValue();
69
70  ARMCP::ARMCPModifier getModifier() const { return Modifier; }
71  const char *getModifierText() const;
72  bool hasModifier() const { return Modifier != ARMCP::no_modifier; }
73
74  bool mustAddCurrentAddress() const { return AddCurrentAddress; }
75
76  unsigned getLabelId() const { return LabelId; }
77  unsigned char getPCAdjustment() const { return PCAdjust; }
78
79  bool isGlobalValue() const { return Kind == ARMCP::CPValue; }
80  bool isExtSymbol() const { return Kind == ARMCP::CPExtSymbol; }
81  bool isBlockAddress() const { return Kind == ARMCP::CPBlockAddress; }
82  bool isLSDA() const { return Kind == ARMCP::CPLSDA; }
83  bool isMachineBasicBlock() const{ return Kind == ARMCP::CPMachineBasicBlock; }
84
85  virtual unsigned getRelocationInfo() const { return 2; }
86
87  virtual int getExistingMachineCPValue(MachineConstantPool *CP,
88                                        unsigned Alignment);
89
90  virtual void addSelectionDAGCSEId(FoldingSetNodeID &ID);
91
92  /// hasSameValue - Return true if this ARM constpool value can share the same
93  /// constantpool entry as another ARM constpool value.
94  virtual bool hasSameValue(ARMConstantPoolValue *ACPV);
95
96  bool equals(const ARMConstantPoolValue *A) const {
97    return this->LabelId == A->LabelId &&
98      this->PCAdjust == A->PCAdjust &&
99      this->Modifier == A->Modifier;
100  }
101
102  virtual void print(raw_ostream &O) const;
103  void print(raw_ostream *O) const { if (O) print(*O); }
104  void dump() const;
105
106  static bool classof(const ARMConstantPoolValue *) { return true; }
107};
108
109inline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) {
110  V.print(O);
111  return O;
112}
113
114/// ARMConstantPoolConstant - ARM-specific constant pool values for Constants,
115/// Functions, and BlockAddresses.
116class ARMConstantPoolConstant : public ARMConstantPoolValue {
117  const Constant *CVal;         // Constant being loaded.
118
119  ARMConstantPoolConstant(const Constant *C,
120                          unsigned ID,
121                          ARMCP::ARMCPKind Kind,
122                          unsigned char PCAdj,
123                          ARMCP::ARMCPModifier Modifier,
124                          bool AddCurrentAddress);
125  ARMConstantPoolConstant(Type *Ty, const Constant *C,
126                          unsigned ID,
127                          ARMCP::ARMCPKind Kind,
128                          unsigned char PCAdj,
129                          ARMCP::ARMCPModifier Modifier,
130                          bool AddCurrentAddress);
131
132public:
133  static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID);
134  static ARMConstantPoolConstant *Create(const GlobalValue *GV,
135                                         ARMCP::ARMCPModifier Modifier);
136  static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,
137                                         ARMCP::ARMCPKind Kind,
138                                         unsigned char PCAdj);
139  static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,
140                                         ARMCP::ARMCPKind Kind,
141                                         unsigned char PCAdj,
142                                         ARMCP::ARMCPModifier Modifier,
143                                         bool AddCurrentAddress);
144
145  const GlobalValue *getGV() const;
146  const BlockAddress *getBlockAddress() const;
147
148  virtual int getExistingMachineCPValue(MachineConstantPool *CP,
149                                        unsigned Alignment);
150
151  /// hasSameValue - Return true if this ARM constpool value can share the same
152  /// constantpool entry as another ARM constpool value.
153  virtual bool hasSameValue(ARMConstantPoolValue *ACPV);
154
155  virtual void addSelectionDAGCSEId(FoldingSetNodeID &ID);
156
157  virtual void print(raw_ostream &O) const;
158  static bool classof(const ARMConstantPoolValue *APV) {
159    return APV->isGlobalValue() || APV->isBlockAddress() || APV->isLSDA();
160  }
161  static bool classof(const ARMConstantPoolConstant *) { return true; }
162};
163
164/// ARMConstantPoolSymbol - ARM-specific constantpool values for external
165/// symbols.
166class ARMConstantPoolSymbol : public ARMConstantPoolValue {
167  const char *S;                // ExtSymbol being loaded.
168
169  ARMConstantPoolSymbol(LLVMContext &C, const char *s, unsigned id,
170                        unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
171                        bool AddCurrentAddress);
172
173public:
174  ~ARMConstantPoolSymbol();
175
176  static ARMConstantPoolSymbol *Create(LLVMContext &C, const char *s,
177                                       unsigned ID, unsigned char PCAdj);
178
179  const char *getSymbol() const { return S; }
180
181  virtual int getExistingMachineCPValue(MachineConstantPool *CP,
182                                        unsigned Alignment);
183
184  virtual void addSelectionDAGCSEId(FoldingSetNodeID &ID);
185
186  /// hasSameValue - Return true if this ARM constpool value can share the same
187  /// constantpool entry as another ARM constpool value.
188  virtual bool hasSameValue(ARMConstantPoolValue *ACPV);
189
190  virtual void print(raw_ostream &O) const;
191
192  static bool classof(const ARMConstantPoolValue *ACPV) {
193    return ACPV->isExtSymbol();
194  }
195  static bool classof(const ARMConstantPoolSymbol *) { return true; }
196};
197
198/// ARMConstantPoolMBB - ARM-specific constantpool value of a machine basic
199/// block.
200class ARMConstantPoolMBB : public ARMConstantPoolValue {
201  const MachineBasicBlock *MBB; // Machine basic block.
202
203  ARMConstantPoolMBB(LLVMContext &C, const MachineBasicBlock *mbb, unsigned id,
204                     unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
205                     bool AddCurrentAddress);
206
207public:
208  static ARMConstantPoolMBB *Create(LLVMContext &C,
209                                    const MachineBasicBlock *mbb,
210                                    unsigned ID, unsigned char PCAdj);
211
212  const MachineBasicBlock *getMBB() const { return MBB; }
213
214  virtual int getExistingMachineCPValue(MachineConstantPool *CP,
215                                        unsigned Alignment);
216
217  virtual void addSelectionDAGCSEId(FoldingSetNodeID &ID);
218
219  /// hasSameValue - Return true if this ARM constpool value can share the same
220  /// constantpool entry as another ARM constpool value.
221  virtual bool hasSameValue(ARMConstantPoolValue *ACPV);
222
223  virtual void print(raw_ostream &O) const;
224
225  static bool classof(const ARMConstantPoolValue *ACPV) {
226    return ACPV->isMachineBasicBlock();
227  }
228  static bool classof(const ARMConstantPoolMBB *) { return true; }
229};
230
231} // End llvm namespace
232
233#endif
234