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 21 namespace llvm { 22 23 class BlockAddress; 24 class Constant; 25 class GlobalValue; 26 class LLVMContext; 27 class MachineBasicBlock; 28 29 namespace 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)). 51 class 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 59 protected: 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); 67 public: 68 virtual ~ARMConstantPoolValue(); 69 getModifier()70 ARMCP::ARMCPModifier getModifier() const { return Modifier; } 71 const char *getModifierText() const; hasModifier()72 bool hasModifier() const { return Modifier != ARMCP::no_modifier; } 73 mustAddCurrentAddress()74 bool mustAddCurrentAddress() const { return AddCurrentAddress; } 75 getLabelId()76 unsigned getLabelId() const { return LabelId; } getPCAdjustment()77 unsigned char getPCAdjustment() const { return PCAdjust; } 78 isGlobalValue()79 bool isGlobalValue() const { return Kind == ARMCP::CPValue; } isExtSymbol()80 bool isExtSymbol() const { return Kind == ARMCP::CPExtSymbol; } isBlockAddress()81 bool isBlockAddress() const { return Kind == ARMCP::CPBlockAddress; } isLSDA()82 bool isLSDA() const { return Kind == ARMCP::CPLSDA; } isMachineBasicBlock()83 bool isMachineBasicBlock() const{ return Kind == ARMCP::CPMachineBasicBlock; } 84 getRelocationInfo()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 equals(const ARMConstantPoolValue * A)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; print(raw_ostream * O)103 void print(raw_ostream *O) const { if (O) print(*O); } 104 void dump() const; 105 }; 106 107 inline 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. 114 class 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 130 public: 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; classof(const ARMConstantPoolValue * APV)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. 163 class 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 170 public: 171 static ARMConstantPoolSymbol *Create(LLVMContext &C, const char *s, 172 unsigned ID, unsigned char PCAdj); 173 getSymbol()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 classof(const ARMConstantPoolValue * ACPV)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. 194 class 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 201 public: 202 static ARMConstantPoolMBB *Create(LLVMContext &C, 203 const MachineBasicBlock *mbb, 204 unsigned ID, unsigned char PCAdj); 205 getMBB()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 classof(const ARMConstantPoolValue * ACPV)219 static bool classof(const ARMConstantPoolValue *ACPV) { 220 return ACPV->isMachineBasicBlock(); 221 } 222 }; 223 224 } // End llvm namespace 225 226 #endif 227