1235633Sdim//===-- ARMConstantPoolValue.h - ARM constantpool value ---------*- C++ -*-===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file implements the ARM specific constantpool value class. 11193323Sed// 12193323Sed//===----------------------------------------------------------------------===// 13193323Sed 14193323Sed#ifndef LLVM_TARGET_ARM_CONSTANTPOOLVALUE_H 15193323Sed#define LLVM_TARGET_ARM_CONSTANTPOOLVALUE_H 16193323Sed 17193323Sed#include "llvm/CodeGen/MachineConstantPool.h" 18263509Sdim#include "llvm/Support/Casting.h" 19218893Sdim#include "llvm/Support/ErrorHandling.h" 20210299Sed#include <cstddef> 21193323Sed 22193323Sednamespace llvm { 23193323Sed 24226890Sdimclass BlockAddress; 25198892Srdivackyclass Constant; 26193323Sedclass GlobalValue; 27198090Srdivackyclass LLVMContext; 28226890Sdimclass MachineBasicBlock; 29193323Sed 30193323Sednamespace ARMCP { 31193323Sed enum ARMCPKind { 32193323Sed CPValue, 33198892Srdivacky CPExtSymbol, 34198892Srdivacky CPBlockAddress, 35226890Sdim CPLSDA, 36226890Sdim CPMachineBasicBlock 37193323Sed }; 38218893Sdim 39218893Sdim enum ARMCPModifier { 40218893Sdim no_modifier, 41218893Sdim TLSGD, 42218893Sdim GOT, 43218893Sdim GOTOFF, 44218893Sdim GOTTPOFF, 45218893Sdim TPOFF 46218893Sdim }; 47193323Sed} 48193323Sed 49193323Sed/// ARMConstantPoolValue - ARM specific constantpool value. This is used to 50198892Srdivacky/// represent PC-relative displacement between the address of the load 51198892Srdivacky/// instruction and the constant being loaded, i.e. (&GV-(LPIC+8)). 52193323Sedclass ARMConstantPoolValue : public MachineConstantPoolValue { 53193323Sed unsigned LabelId; // Label id of the load. 54198892Srdivacky ARMCP::ARMCPKind Kind; // Kind of constant. 55198892Srdivacky unsigned char PCAdjust; // Extra adjustment if constantpool is pc-relative. 56193323Sed // 8 for ARM, 4 for Thumb. 57218893Sdim ARMCP::ARMCPModifier Modifier; // GV modifier i.e. (&GV(modifier)-(LPIC+8)) 58193323Sed bool AddCurrentAddress; 59193323Sed 60226890Sdimprotected: 61226890Sdim ARMConstantPoolValue(Type *Ty, unsigned id, ARMCP::ARMCPKind Kind, 62226890Sdim unsigned char PCAdj, ARMCP::ARMCPModifier Modifier, 63226890Sdim bool AddCurrentAddress); 64226890Sdim 65226890Sdim ARMConstantPoolValue(LLVMContext &C, unsigned id, ARMCP::ARMCPKind Kind, 66226890Sdim unsigned char PCAdj, ARMCP::ARMCPModifier Modifier, 67226890Sdim bool AddCurrentAddress); 68263509Sdim 69263509Sdim template <typename Derived> 70263509Sdim int getExistingMachineCPValueImpl(MachineConstantPool *CP, 71263509Sdim unsigned Alignment) { 72263509Sdim unsigned AlignMask = Alignment - 1; 73263509Sdim const std::vector<MachineConstantPoolEntry> &Constants = CP->getConstants(); 74263509Sdim for (unsigned i = 0, e = Constants.size(); i != e; ++i) { 75263509Sdim if (Constants[i].isMachineConstantPoolEntry() && 76263509Sdim (Constants[i].getAlignment() & AlignMask) == 0) { 77263509Sdim ARMConstantPoolValue *CPV = 78263509Sdim (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal; 79263509Sdim if (Derived *APC = dyn_cast<Derived>(CPV)) 80263509Sdim if (cast<Derived>(this)->equals(APC)) 81263509Sdim return i; 82263509Sdim } 83263509Sdim } 84263509Sdim 85263509Sdim return -1; 86263509Sdim } 87263509Sdim 88193323Sedpublic: 89226890Sdim virtual ~ARMConstantPoolValue(); 90193323Sed 91218893Sdim ARMCP::ARMCPModifier getModifier() const { return Modifier; } 92226890Sdim const char *getModifierText() const; 93218893Sdim bool hasModifier() const { return Modifier != ARMCP::no_modifier; } 94226890Sdim 95193323Sed bool mustAddCurrentAddress() const { return AddCurrentAddress; } 96226890Sdim 97193323Sed unsigned getLabelId() const { return LabelId; } 98193323Sed unsigned char getPCAdjustment() const { return PCAdjust; } 99226890Sdim 100198892Srdivacky bool isGlobalValue() const { return Kind == ARMCP::CPValue; } 101198892Srdivacky bool isExtSymbol() const { return Kind == ARMCP::CPExtSymbol; } 102226890Sdim bool isBlockAddress() const { return Kind == ARMCP::CPBlockAddress; } 103226890Sdim bool isLSDA() const { return Kind == ARMCP::CPLSDA; } 104226890Sdim bool isMachineBasicBlock() const{ return Kind == ARMCP::CPMachineBasicBlock; } 105193323Sed 106218893Sdim virtual unsigned getRelocationInfo() const { return 2; } 107198090Srdivacky 108193323Sed virtual int getExistingMachineCPValue(MachineConstantPool *CP, 109193323Sed unsigned Alignment); 110193323Sed 111226890Sdim virtual void addSelectionDAGCSEId(FoldingSetNodeID &ID); 112193323Sed 113226890Sdim /// hasSameValue - Return true if this ARM constpool value can share the same 114226890Sdim /// constantpool entry as another ARM constpool value. 115226890Sdim virtual bool hasSameValue(ARMConstantPoolValue *ACPV); 116199481Srdivacky 117226890Sdim bool equals(const ARMConstantPoolValue *A) const { 118226890Sdim return this->LabelId == A->LabelId && 119226890Sdim this->PCAdjust == A->PCAdjust && 120226890Sdim this->Modifier == A->Modifier; 121226890Sdim } 122226890Sdim 123226890Sdim virtual void print(raw_ostream &O) const; 124193323Sed void print(raw_ostream *O) const { if (O) print(*O); } 125193323Sed void dump() const; 126193323Sed}; 127193323Sed 128193323Sedinline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) { 129193323Sed V.print(O); 130193323Sed return O; 131193323Sed} 132193323Sed 133226890Sdim/// ARMConstantPoolConstant - ARM-specific constant pool values for Constants, 134226890Sdim/// Functions, and BlockAddresses. 135226890Sdimclass ARMConstantPoolConstant : public ARMConstantPoolValue { 136226890Sdim const Constant *CVal; // Constant being loaded. 137226890Sdim 138226890Sdim ARMConstantPoolConstant(const Constant *C, 139226890Sdim unsigned ID, 140226890Sdim ARMCP::ARMCPKind Kind, 141226890Sdim unsigned char PCAdj, 142226890Sdim ARMCP::ARMCPModifier Modifier, 143226890Sdim bool AddCurrentAddress); 144226890Sdim ARMConstantPoolConstant(Type *Ty, const Constant *C, 145226890Sdim unsigned ID, 146226890Sdim ARMCP::ARMCPKind Kind, 147226890Sdim unsigned char PCAdj, 148226890Sdim ARMCP::ARMCPModifier Modifier, 149226890Sdim bool AddCurrentAddress); 150226890Sdim 151226890Sdimpublic: 152226890Sdim static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID); 153226890Sdim static ARMConstantPoolConstant *Create(const GlobalValue *GV, 154226890Sdim ARMCP::ARMCPModifier Modifier); 155226890Sdim static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID, 156226890Sdim ARMCP::ARMCPKind Kind, 157226890Sdim unsigned char PCAdj); 158226890Sdim static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID, 159226890Sdim ARMCP::ARMCPKind Kind, 160226890Sdim unsigned char PCAdj, 161226890Sdim ARMCP::ARMCPModifier Modifier, 162226890Sdim bool AddCurrentAddress); 163226890Sdim 164226890Sdim const GlobalValue *getGV() const; 165226890Sdim const BlockAddress *getBlockAddress() const; 166226890Sdim 167226890Sdim virtual int getExistingMachineCPValue(MachineConstantPool *CP, 168226890Sdim unsigned Alignment); 169226890Sdim 170226890Sdim /// hasSameValue - Return true if this ARM constpool value can share the same 171226890Sdim /// constantpool entry as another ARM constpool value. 172226890Sdim virtual bool hasSameValue(ARMConstantPoolValue *ACPV); 173226890Sdim 174226890Sdim virtual void addSelectionDAGCSEId(FoldingSetNodeID &ID); 175226890Sdim 176226890Sdim virtual void print(raw_ostream &O) const; 177226890Sdim static bool classof(const ARMConstantPoolValue *APV) { 178226890Sdim return APV->isGlobalValue() || APV->isBlockAddress() || APV->isLSDA(); 179226890Sdim } 180263509Sdim 181263509Sdim bool equals(const ARMConstantPoolConstant *A) const { 182263509Sdim return CVal == A->CVal && ARMConstantPoolValue::equals(A); 183263509Sdim } 184226890Sdim}; 185226890Sdim 186226890Sdim/// ARMConstantPoolSymbol - ARM-specific constantpool values for external 187226890Sdim/// symbols. 188226890Sdimclass ARMConstantPoolSymbol : public ARMConstantPoolValue { 189252723Sdim const std::string S; // ExtSymbol being loaded. 190226890Sdim 191226890Sdim ARMConstantPoolSymbol(LLVMContext &C, const char *s, unsigned id, 192226890Sdim unsigned char PCAdj, ARMCP::ARMCPModifier Modifier, 193226890Sdim bool AddCurrentAddress); 194226890Sdim 195226890Sdimpublic: 196226890Sdim static ARMConstantPoolSymbol *Create(LLVMContext &C, const char *s, 197226890Sdim unsigned ID, unsigned char PCAdj); 198226890Sdim 199252723Sdim const char *getSymbol() const { return S.c_str(); } 200226890Sdim 201226890Sdim virtual int getExistingMachineCPValue(MachineConstantPool *CP, 202226890Sdim unsigned Alignment); 203226890Sdim 204226890Sdim virtual void addSelectionDAGCSEId(FoldingSetNodeID &ID); 205226890Sdim 206226890Sdim /// hasSameValue - Return true if this ARM constpool value can share the same 207226890Sdim /// constantpool entry as another ARM constpool value. 208226890Sdim virtual bool hasSameValue(ARMConstantPoolValue *ACPV); 209226890Sdim 210226890Sdim virtual void print(raw_ostream &O) const; 211226890Sdim 212226890Sdim static bool classof(const ARMConstantPoolValue *ACPV) { 213226890Sdim return ACPV->isExtSymbol(); 214226890Sdim } 215263509Sdim 216263509Sdim bool equals(const ARMConstantPoolSymbol *A) const { 217263509Sdim return S == A->S && ARMConstantPoolValue::equals(A); 218263509Sdim } 219226890Sdim}; 220226890Sdim 221226890Sdim/// ARMConstantPoolMBB - ARM-specific constantpool value of a machine basic 222226890Sdim/// block. 223226890Sdimclass ARMConstantPoolMBB : public ARMConstantPoolValue { 224226890Sdim const MachineBasicBlock *MBB; // Machine basic block. 225226890Sdim 226226890Sdim ARMConstantPoolMBB(LLVMContext &C, const MachineBasicBlock *mbb, unsigned id, 227226890Sdim unsigned char PCAdj, ARMCP::ARMCPModifier Modifier, 228226890Sdim bool AddCurrentAddress); 229226890Sdim 230226890Sdimpublic: 231226890Sdim static ARMConstantPoolMBB *Create(LLVMContext &C, 232226890Sdim const MachineBasicBlock *mbb, 233226890Sdim unsigned ID, unsigned char PCAdj); 234226890Sdim 235226890Sdim const MachineBasicBlock *getMBB() const { return MBB; } 236226890Sdim 237226890Sdim virtual int getExistingMachineCPValue(MachineConstantPool *CP, 238226890Sdim unsigned Alignment); 239226890Sdim 240226890Sdim virtual void addSelectionDAGCSEId(FoldingSetNodeID &ID); 241226890Sdim 242226890Sdim /// hasSameValue - Return true if this ARM constpool value can share the same 243226890Sdim /// constantpool entry as another ARM constpool value. 244226890Sdim virtual bool hasSameValue(ARMConstantPoolValue *ACPV); 245226890Sdim 246226890Sdim virtual void print(raw_ostream &O) const; 247226890Sdim 248226890Sdim static bool classof(const ARMConstantPoolValue *ACPV) { 249226890Sdim return ACPV->isMachineBasicBlock(); 250226890Sdim } 251263509Sdim 252263509Sdim bool equals(const ARMConstantPoolMBB *A) const { 253263509Sdim return MBB == A->MBB && ARMConstantPoolValue::equals(A); 254263509Sdim } 255226890Sdim}; 256226890Sdim 257193323Sed} // End llvm namespace 258193323Sed 259193323Sed#endif 260