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_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H 15#define LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H 16 17#include "llvm/CodeGen/MachineConstantPool.h" 18#include "llvm/Support/Casting.h" 19#include "llvm/Support/ErrorHandling.h" 20#include <cstddef> 21 22namespace llvm { 23 24class BlockAddress; 25class Constant; 26class GlobalValue; 27class LLVMContext; 28class MachineBasicBlock; 29 30namespace ARMCP { 31 enum ARMCPKind { 32 CPValue, 33 CPExtSymbol, 34 CPBlockAddress, 35 CPLSDA, 36 CPMachineBasicBlock 37 }; 38 39 enum ARMCPModifier { 40 no_modifier, 41 TLSGD, 42 GOT, 43 GOTOFF, 44 GOTTPOFF, 45 TPOFF 46 }; 47} 48 49/// ARMConstantPoolValue - ARM specific constantpool value. This is used to 50/// represent PC-relative displacement between the address of the load 51/// instruction and the constant being loaded, i.e. (&GV-(LPIC+8)). 52class ARMConstantPoolValue : public MachineConstantPoolValue { 53 unsigned LabelId; // Label id of the load. 54 ARMCP::ARMCPKind Kind; // Kind of constant. 55 unsigned char PCAdjust; // Extra adjustment if constantpool is pc-relative. 56 // 8 for ARM, 4 for Thumb. 57 ARMCP::ARMCPModifier Modifier; // GV modifier i.e. (&GV(modifier)-(LPIC+8)) 58 bool AddCurrentAddress; 59 60protected: 61 ARMConstantPoolValue(Type *Ty, unsigned id, ARMCP::ARMCPKind Kind, 62 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier, 63 bool AddCurrentAddress); 64 65 ARMConstantPoolValue(LLVMContext &C, unsigned id, ARMCP::ARMCPKind Kind, 66 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier, 67 bool AddCurrentAddress); 68 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 88public: 89 ~ARMConstantPoolValue() override; 90 91 ARMCP::ARMCPModifier getModifier() const { return Modifier; } 92 const char *getModifierText() const; 93 bool hasModifier() const { return Modifier != ARMCP::no_modifier; } 94 95 bool mustAddCurrentAddress() const { return AddCurrentAddress; } 96 97 unsigned getLabelId() const { return LabelId; } 98 unsigned char getPCAdjustment() const { return PCAdjust; } 99 100 bool isGlobalValue() const { return Kind == ARMCP::CPValue; } 101 bool isExtSymbol() const { return Kind == ARMCP::CPExtSymbol; } 102 bool isBlockAddress() const { return Kind == ARMCP::CPBlockAddress; } 103 bool isLSDA() const { return Kind == ARMCP::CPLSDA; } 104 bool isMachineBasicBlock() const{ return Kind == ARMCP::CPMachineBasicBlock; } 105 106 unsigned getRelocationInfo() const override { return 2; } 107 108 int getExistingMachineCPValue(MachineConstantPool *CP, 109 unsigned Alignment) override; 110 111 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 112 113 /// 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); 116 117 bool equals(const ARMConstantPoolValue *A) const { 118 return this->LabelId == A->LabelId && 119 this->PCAdjust == A->PCAdjust && 120 this->Modifier == A->Modifier; 121 } 122 123 void print(raw_ostream &O) const override; 124 void print(raw_ostream *O) const { if (O) print(*O); } 125 void dump() const; 126}; 127 128inline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) { 129 V.print(O); 130 return O; 131} 132 133/// 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); 144 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 151public: 152 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID); 153 static ARMConstantPoolConstant *Create(const GlobalValue *GV, 154 ARMCP::ARMCPModifier Modifier); 155 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID, 156 ARMCP::ARMCPKind Kind, 157 unsigned char PCAdj); 158 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID, 159 ARMCP::ARMCPKind Kind, 160 unsigned char PCAdj, 161 ARMCP::ARMCPModifier Modifier, 162 bool AddCurrentAddress); 163 164 const GlobalValue *getGV() const; 165 const BlockAddress *getBlockAddress() const; 166 167 int getExistingMachineCPValue(MachineConstantPool *CP, 168 unsigned Alignment) override; 169 170 /// hasSameValue - Return true if this ARM constpool value can share the same 171 /// constantpool entry as another ARM constpool value. 172 bool hasSameValue(ARMConstantPoolValue *ACPV) override; 173 174 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 175 176 void print(raw_ostream &O) const override; 177 static bool classof(const ARMConstantPoolValue *APV) { 178 return APV->isGlobalValue() || APV->isBlockAddress() || APV->isLSDA(); 179 } 180 181 bool equals(const ARMConstantPoolConstant *A) const { 182 return CVal == A->CVal && ARMConstantPoolValue::equals(A); 183 } 184}; 185 186/// ARMConstantPoolSymbol - ARM-specific constantpool values for external 187/// symbols. 188class ARMConstantPoolSymbol : public ARMConstantPoolValue { 189 const std::string S; // ExtSymbol being loaded. 190 191 ARMConstantPoolSymbol(LLVMContext &C, const char *s, unsigned id, 192 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier, 193 bool AddCurrentAddress); 194 195public: 196 static ARMConstantPoolSymbol *Create(LLVMContext &C, const char *s, 197 unsigned ID, unsigned char PCAdj); 198 199 const char *getSymbol() const { return S.c_str(); } 200 201 int getExistingMachineCPValue(MachineConstantPool *CP, 202 unsigned Alignment) override; 203 204 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 205 206 /// hasSameValue - Return true if this ARM constpool value can share the same 207 /// constantpool entry as another ARM constpool value. 208 bool hasSameValue(ARMConstantPoolValue *ACPV) override; 209 210 void print(raw_ostream &O) const override; 211 212 static bool classof(const ARMConstantPoolValue *ACPV) { 213 return ACPV->isExtSymbol(); 214 } 215 216 bool equals(const ARMConstantPoolSymbol *A) const { 217 return S == A->S && ARMConstantPoolValue::equals(A); 218 } 219}; 220 221/// ARMConstantPoolMBB - ARM-specific constantpool value of a machine basic 222/// block. 223class ARMConstantPoolMBB : public ARMConstantPoolValue { 224 const MachineBasicBlock *MBB; // Machine basic block. 225 226 ARMConstantPoolMBB(LLVMContext &C, const MachineBasicBlock *mbb, unsigned id, 227 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier, 228 bool AddCurrentAddress); 229 230public: 231 static ARMConstantPoolMBB *Create(LLVMContext &C, 232 const MachineBasicBlock *mbb, 233 unsigned ID, unsigned char PCAdj); 234 235 const MachineBasicBlock *getMBB() const { return MBB; } 236 237 int getExistingMachineCPValue(MachineConstantPool *CP, 238 unsigned Alignment) override; 239 240 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 241 242 /// hasSameValue - Return true if this ARM constpool value can share the same 243 /// constantpool entry as another ARM constpool value. 244 bool hasSameValue(ARMConstantPoolValue *ACPV) override; 245 246 void print(raw_ostream &O) const override; 247 248 static bool classof(const ARMConstantPoolValue *ACPV) { 249 return ACPV->isMachineBasicBlock(); 250 } 251 252 bool equals(const ARMConstantPoolMBB *A) const { 253 return MBB == A->MBB && ARMConstantPoolValue::equals(A); 254 } 255}; 256 257} // End llvm namespace 258 259#endif 260