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
107inline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) {
108  V.print(O);
109  return O;
110}
111
112/// ARMConstantPoolConstant - ARM-specific constant pool values for Constants,
113/// Functions, and BlockAddresses.
114class ARMConstantPoolConstant : public ARMConstantPoolValue {
115  const Constant *CVal;         // Constant being loaded.
116
117  ARMConstantPoolConstant(const Constant *C,
118                          unsigned ID,
119                          ARMCP::ARMCPKind Kind,
120                          unsigned char PCAdj,
121                          ARMCP::ARMCPModifier Modifier,
122                          bool AddCurrentAddress);
123  ARMConstantPoolConstant(Type *Ty, const Constant *C,
124                          unsigned ID,
125                          ARMCP::ARMCPKind Kind,
126                          unsigned char PCAdj,
127                          ARMCP::ARMCPModifier Modifier,
128                          bool AddCurrentAddress);
129
130public:
131  static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID);
132  static ARMConstantPoolConstant *Create(const GlobalValue *GV,
133                                         ARMCP::ARMCPModifier Modifier);
134  static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,
135                                         ARMCP::ARMCPKind Kind,
136                                         unsigned char PCAdj);
137  static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,
138                                         ARMCP::ARMCPKind Kind,
139                                         unsigned char PCAdj,
140                                         ARMCP::ARMCPModifier Modifier,
141                                         bool AddCurrentAddress);
142
143  const GlobalValue *getGV() const;
144  const BlockAddress *getBlockAddress() const;
145
146  virtual int getExistingMachineCPValue(MachineConstantPool *CP,
147                                        unsigned Alignment);
148
149  /// hasSameValue - Return true if this ARM constpool value can share the same
150  /// constantpool entry as another ARM constpool value.
151  virtual bool hasSameValue(ARMConstantPoolValue *ACPV);
152
153  virtual void addSelectionDAGCSEId(FoldingSetNodeID &ID);
154
155  virtual void print(raw_ostream &O) const;
156  static bool classof(const ARMConstantPoolValue *APV) {
157    return APV->isGlobalValue() || APV->isBlockAddress() || APV->isLSDA();
158  }
159};
160
161/// ARMConstantPoolSymbol - ARM-specific constantpool values for external
162/// symbols.
163class ARMConstantPoolSymbol : public ARMConstantPoolValue {
164  const std::string S;          // ExtSymbol being loaded.
165
166  ARMConstantPoolSymbol(LLVMContext &C, const char *s, unsigned id,
167                        unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
168                        bool AddCurrentAddress);
169
170public:
171  static ARMConstantPoolSymbol *Create(LLVMContext &C, const char *s,
172                                       unsigned ID, unsigned char PCAdj);
173
174  const char *getSymbol() const { return S.c_str(); }
175
176  virtual int getExistingMachineCPValue(MachineConstantPool *CP,
177                                        unsigned Alignment);
178
179  virtual void addSelectionDAGCSEId(FoldingSetNodeID &ID);
180
181  /// hasSameValue - Return true if this ARM constpool value can share the same
182  /// constantpool entry as another ARM constpool value.
183  virtual bool hasSameValue(ARMConstantPoolValue *ACPV);
184
185  virtual void print(raw_ostream &O) const;
186
187  static bool classof(const ARMConstantPoolValue *ACPV) {
188    return ACPV->isExtSymbol();
189  }
190};
191
192/// ARMConstantPoolMBB - ARM-specific constantpool value of a machine basic
193/// block.
194class ARMConstantPoolMBB : public ARMConstantPoolValue {
195  const MachineBasicBlock *MBB; // Machine basic block.
196
197  ARMConstantPoolMBB(LLVMContext &C, const MachineBasicBlock *mbb, unsigned id,
198                     unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
199                     bool AddCurrentAddress);
200
201public:
202  static ARMConstantPoolMBB *Create(LLVMContext &C,
203                                    const MachineBasicBlock *mbb,
204                                    unsigned ID, unsigned char PCAdj);
205
206  const MachineBasicBlock *getMBB() const { return MBB; }
207
208  virtual int getExistingMachineCPValue(MachineConstantPool *CP,
209                                        unsigned Alignment);
210
211  virtual void addSelectionDAGCSEId(FoldingSetNodeID &ID);
212
213  /// hasSameValue - Return true if this ARM constpool value can share the same
214  /// constantpool entry as another ARM constpool value.
215  virtual bool hasSameValue(ARMConstantPoolValue *ACPV);
216
217  virtual void print(raw_ostream &O) const;
218
219  static bool classof(const ARMConstantPoolValue *ACPV) {
220    return ACPV->isMachineBasicBlock();
221  }
222};
223
224} // End llvm namespace
225
226#endif
227