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