1*9880d681SAndroid Build Coastguard Worker //===-- ARMConstantPoolValue.h - ARM constantpool value ---------*- C++ -*-===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker // 10*9880d681SAndroid Build Coastguard Worker // This file implements the ARM specific constantpool value class. 11*9880d681SAndroid Build Coastguard Worker // 12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H 15*9880d681SAndroid Build Coastguard Worker #define LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H 16*9880d681SAndroid Build Coastguard Worker 17*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineConstantPool.h" 18*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Casting.h" 19*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h" 20*9880d681SAndroid Build Coastguard Worker #include <cstddef> 21*9880d681SAndroid Build Coastguard Worker 22*9880d681SAndroid Build Coastguard Worker namespace llvm { 23*9880d681SAndroid Build Coastguard Worker 24*9880d681SAndroid Build Coastguard Worker class BlockAddress; 25*9880d681SAndroid Build Coastguard Worker class Constant; 26*9880d681SAndroid Build Coastguard Worker class GlobalValue; 27*9880d681SAndroid Build Coastguard Worker class LLVMContext; 28*9880d681SAndroid Build Coastguard Worker class MachineBasicBlock; 29*9880d681SAndroid Build Coastguard Worker 30*9880d681SAndroid Build Coastguard Worker namespace ARMCP { 31*9880d681SAndroid Build Coastguard Worker enum ARMCPKind { 32*9880d681SAndroid Build Coastguard Worker CPValue, 33*9880d681SAndroid Build Coastguard Worker CPExtSymbol, 34*9880d681SAndroid Build Coastguard Worker CPBlockAddress, 35*9880d681SAndroid Build Coastguard Worker CPLSDA, 36*9880d681SAndroid Build Coastguard Worker CPMachineBasicBlock 37*9880d681SAndroid Build Coastguard Worker }; 38*9880d681SAndroid Build Coastguard Worker 39*9880d681SAndroid Build Coastguard Worker enum ARMCPModifier { 40*9880d681SAndroid Build Coastguard Worker no_modifier, /// None 41*9880d681SAndroid Build Coastguard Worker TLSGD, /// Thread Local Storage (General Dynamic Mode) 42*9880d681SAndroid Build Coastguard Worker GOT_PREL, /// Global Offset Table, PC Relative 43*9880d681SAndroid Build Coastguard Worker GOTTPOFF, /// Global Offset Table, Thread Pointer Offset 44*9880d681SAndroid Build Coastguard Worker TPOFF, /// Thread Pointer Offset 45*9880d681SAndroid Build Coastguard Worker SECREL, /// Section Relative (Windows TLS) 46*9880d681SAndroid Build Coastguard Worker }; 47*9880d681SAndroid Build Coastguard Worker } 48*9880d681SAndroid Build Coastguard Worker 49*9880d681SAndroid Build Coastguard Worker /// ARMConstantPoolValue - ARM specific constantpool value. This is used to 50*9880d681SAndroid Build Coastguard Worker /// represent PC-relative displacement between the address of the load 51*9880d681SAndroid Build Coastguard Worker /// instruction and the constant being loaded, i.e. (&GV-(LPIC+8)). 52*9880d681SAndroid Build Coastguard Worker class ARMConstantPoolValue : public MachineConstantPoolValue { 53*9880d681SAndroid Build Coastguard Worker unsigned LabelId; // Label id of the load. 54*9880d681SAndroid Build Coastguard Worker ARMCP::ARMCPKind Kind; // Kind of constant. 55*9880d681SAndroid Build Coastguard Worker unsigned char PCAdjust; // Extra adjustment if constantpool is pc-relative. 56*9880d681SAndroid Build Coastguard Worker // 8 for ARM, 4 for Thumb. 57*9880d681SAndroid Build Coastguard Worker ARMCP::ARMCPModifier Modifier; // GV modifier i.e. (&GV(modifier)-(LPIC+8)) 58*9880d681SAndroid Build Coastguard Worker bool AddCurrentAddress; 59*9880d681SAndroid Build Coastguard Worker 60*9880d681SAndroid Build Coastguard Worker protected: 61*9880d681SAndroid Build Coastguard Worker ARMConstantPoolValue(Type *Ty, unsigned id, ARMCP::ARMCPKind Kind, 62*9880d681SAndroid Build Coastguard Worker unsigned char PCAdj, ARMCP::ARMCPModifier Modifier, 63*9880d681SAndroid Build Coastguard Worker bool AddCurrentAddress); 64*9880d681SAndroid Build Coastguard Worker 65*9880d681SAndroid Build Coastguard Worker ARMConstantPoolValue(LLVMContext &C, unsigned id, ARMCP::ARMCPKind Kind, 66*9880d681SAndroid Build Coastguard Worker unsigned char PCAdj, ARMCP::ARMCPModifier Modifier, 67*9880d681SAndroid Build Coastguard Worker bool AddCurrentAddress); 68*9880d681SAndroid Build Coastguard Worker 69*9880d681SAndroid Build Coastguard Worker template <typename Derived> getExistingMachineCPValueImpl(MachineConstantPool * CP,unsigned Alignment)70*9880d681SAndroid Build Coastguard Worker int getExistingMachineCPValueImpl(MachineConstantPool *CP, 71*9880d681SAndroid Build Coastguard Worker unsigned Alignment) { 72*9880d681SAndroid Build Coastguard Worker unsigned AlignMask = Alignment - 1; 73*9880d681SAndroid Build Coastguard Worker const std::vector<MachineConstantPoolEntry> &Constants = CP->getConstants(); 74*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = Constants.size(); i != e; ++i) { 75*9880d681SAndroid Build Coastguard Worker if (Constants[i].isMachineConstantPoolEntry() && 76*9880d681SAndroid Build Coastguard Worker (Constants[i].getAlignment() & AlignMask) == 0) { 77*9880d681SAndroid Build Coastguard Worker ARMConstantPoolValue *CPV = 78*9880d681SAndroid Build Coastguard Worker (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal; 79*9880d681SAndroid Build Coastguard Worker if (Derived *APC = dyn_cast<Derived>(CPV)) 80*9880d681SAndroid Build Coastguard Worker if (cast<Derived>(this)->equals(APC)) 81*9880d681SAndroid Build Coastguard Worker return i; 82*9880d681SAndroid Build Coastguard Worker } 83*9880d681SAndroid Build Coastguard Worker } 84*9880d681SAndroid Build Coastguard Worker 85*9880d681SAndroid Build Coastguard Worker return -1; 86*9880d681SAndroid Build Coastguard Worker } 87*9880d681SAndroid Build Coastguard Worker 88*9880d681SAndroid Build Coastguard Worker public: 89*9880d681SAndroid Build Coastguard Worker ~ARMConstantPoolValue() override; 90*9880d681SAndroid Build Coastguard Worker getModifier()91*9880d681SAndroid Build Coastguard Worker ARMCP::ARMCPModifier getModifier() const { return Modifier; } 92*9880d681SAndroid Build Coastguard Worker const char *getModifierText() const; hasModifier()93*9880d681SAndroid Build Coastguard Worker bool hasModifier() const { return Modifier != ARMCP::no_modifier; } 94*9880d681SAndroid Build Coastguard Worker mustAddCurrentAddress()95*9880d681SAndroid Build Coastguard Worker bool mustAddCurrentAddress() const { return AddCurrentAddress; } 96*9880d681SAndroid Build Coastguard Worker getLabelId()97*9880d681SAndroid Build Coastguard Worker unsigned getLabelId() const { return LabelId; } getPCAdjustment()98*9880d681SAndroid Build Coastguard Worker unsigned char getPCAdjustment() const { return PCAdjust; } 99*9880d681SAndroid Build Coastguard Worker isGlobalValue()100*9880d681SAndroid Build Coastguard Worker bool isGlobalValue() const { return Kind == ARMCP::CPValue; } isExtSymbol()101*9880d681SAndroid Build Coastguard Worker bool isExtSymbol() const { return Kind == ARMCP::CPExtSymbol; } isBlockAddress()102*9880d681SAndroid Build Coastguard Worker bool isBlockAddress() const { return Kind == ARMCP::CPBlockAddress; } isLSDA()103*9880d681SAndroid Build Coastguard Worker bool isLSDA() const { return Kind == ARMCP::CPLSDA; } isMachineBasicBlock()104*9880d681SAndroid Build Coastguard Worker bool isMachineBasicBlock() const{ return Kind == ARMCP::CPMachineBasicBlock; } 105*9880d681SAndroid Build Coastguard Worker 106*9880d681SAndroid Build Coastguard Worker int getExistingMachineCPValue(MachineConstantPool *CP, 107*9880d681SAndroid Build Coastguard Worker unsigned Alignment) override; 108*9880d681SAndroid Build Coastguard Worker 109*9880d681SAndroid Build Coastguard Worker void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 110*9880d681SAndroid Build Coastguard Worker 111*9880d681SAndroid Build Coastguard Worker /// hasSameValue - Return true if this ARM constpool value can share the same 112*9880d681SAndroid Build Coastguard Worker /// constantpool entry as another ARM constpool value. 113*9880d681SAndroid Build Coastguard Worker virtual bool hasSameValue(ARMConstantPoolValue *ACPV); 114*9880d681SAndroid Build Coastguard Worker equals(const ARMConstantPoolValue * A)115*9880d681SAndroid Build Coastguard Worker bool equals(const ARMConstantPoolValue *A) const { 116*9880d681SAndroid Build Coastguard Worker return this->LabelId == A->LabelId && 117*9880d681SAndroid Build Coastguard Worker this->PCAdjust == A->PCAdjust && 118*9880d681SAndroid Build Coastguard Worker this->Modifier == A->Modifier; 119*9880d681SAndroid Build Coastguard Worker } 120*9880d681SAndroid Build Coastguard Worker 121*9880d681SAndroid Build Coastguard Worker void print(raw_ostream &O) const override; print(raw_ostream * O)122*9880d681SAndroid Build Coastguard Worker void print(raw_ostream *O) const { if (O) print(*O); } 123*9880d681SAndroid Build Coastguard Worker void dump() const; 124*9880d681SAndroid Build Coastguard Worker }; 125*9880d681SAndroid Build Coastguard Worker 126*9880d681SAndroid Build Coastguard Worker inline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) { 127*9880d681SAndroid Build Coastguard Worker V.print(O); 128*9880d681SAndroid Build Coastguard Worker return O; 129*9880d681SAndroid Build Coastguard Worker } 130*9880d681SAndroid Build Coastguard Worker 131*9880d681SAndroid Build Coastguard Worker /// ARMConstantPoolConstant - ARM-specific constant pool values for Constants, 132*9880d681SAndroid Build Coastguard Worker /// Functions, and BlockAddresses. 133*9880d681SAndroid Build Coastguard Worker class ARMConstantPoolConstant : public ARMConstantPoolValue { 134*9880d681SAndroid Build Coastguard Worker const Constant *CVal; // Constant being loaded. 135*9880d681SAndroid Build Coastguard Worker 136*9880d681SAndroid Build Coastguard Worker ARMConstantPoolConstant(const Constant *C, 137*9880d681SAndroid Build Coastguard Worker unsigned ID, 138*9880d681SAndroid Build Coastguard Worker ARMCP::ARMCPKind Kind, 139*9880d681SAndroid Build Coastguard Worker unsigned char PCAdj, 140*9880d681SAndroid Build Coastguard Worker ARMCP::ARMCPModifier Modifier, 141*9880d681SAndroid Build Coastguard Worker bool AddCurrentAddress); 142*9880d681SAndroid Build Coastguard Worker ARMConstantPoolConstant(Type *Ty, const Constant *C, 143*9880d681SAndroid Build Coastguard Worker unsigned ID, 144*9880d681SAndroid Build Coastguard Worker ARMCP::ARMCPKind Kind, 145*9880d681SAndroid Build Coastguard Worker unsigned char PCAdj, 146*9880d681SAndroid Build Coastguard Worker ARMCP::ARMCPModifier Modifier, 147*9880d681SAndroid Build Coastguard Worker bool AddCurrentAddress); 148*9880d681SAndroid Build Coastguard Worker 149*9880d681SAndroid Build Coastguard Worker public: 150*9880d681SAndroid Build Coastguard Worker static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID); 151*9880d681SAndroid Build Coastguard Worker static ARMConstantPoolConstant *Create(const GlobalValue *GV, 152*9880d681SAndroid Build Coastguard Worker ARMCP::ARMCPModifier Modifier); 153*9880d681SAndroid Build Coastguard Worker static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID, 154*9880d681SAndroid Build Coastguard Worker ARMCP::ARMCPKind Kind, 155*9880d681SAndroid Build Coastguard Worker unsigned char PCAdj); 156*9880d681SAndroid Build Coastguard Worker static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID, 157*9880d681SAndroid Build Coastguard Worker ARMCP::ARMCPKind Kind, 158*9880d681SAndroid Build Coastguard Worker unsigned char PCAdj, 159*9880d681SAndroid Build Coastguard Worker ARMCP::ARMCPModifier Modifier, 160*9880d681SAndroid Build Coastguard Worker bool AddCurrentAddress); 161*9880d681SAndroid Build Coastguard Worker 162*9880d681SAndroid Build Coastguard Worker const GlobalValue *getGV() const; 163*9880d681SAndroid Build Coastguard Worker const BlockAddress *getBlockAddress() const; 164*9880d681SAndroid Build Coastguard Worker 165*9880d681SAndroid Build Coastguard Worker int getExistingMachineCPValue(MachineConstantPool *CP, 166*9880d681SAndroid Build Coastguard Worker unsigned Alignment) override; 167*9880d681SAndroid Build Coastguard Worker 168*9880d681SAndroid Build Coastguard Worker /// hasSameValue - Return true if this ARM constpool value can share the same 169*9880d681SAndroid Build Coastguard Worker /// constantpool entry as another ARM constpool value. 170*9880d681SAndroid Build Coastguard Worker bool hasSameValue(ARMConstantPoolValue *ACPV) override; 171*9880d681SAndroid Build Coastguard Worker 172*9880d681SAndroid Build Coastguard Worker void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 173*9880d681SAndroid Build Coastguard Worker 174*9880d681SAndroid Build Coastguard Worker void print(raw_ostream &O) const override; classof(const ARMConstantPoolValue * APV)175*9880d681SAndroid Build Coastguard Worker static bool classof(const ARMConstantPoolValue *APV) { 176*9880d681SAndroid Build Coastguard Worker return APV->isGlobalValue() || APV->isBlockAddress() || APV->isLSDA(); 177*9880d681SAndroid Build Coastguard Worker } 178*9880d681SAndroid Build Coastguard Worker equals(const ARMConstantPoolConstant * A)179*9880d681SAndroid Build Coastguard Worker bool equals(const ARMConstantPoolConstant *A) const { 180*9880d681SAndroid Build Coastguard Worker return CVal == A->CVal && ARMConstantPoolValue::equals(A); 181*9880d681SAndroid Build Coastguard Worker } 182*9880d681SAndroid Build Coastguard Worker }; 183*9880d681SAndroid Build Coastguard Worker 184*9880d681SAndroid Build Coastguard Worker /// ARMConstantPoolSymbol - ARM-specific constantpool values for external 185*9880d681SAndroid Build Coastguard Worker /// symbols. 186*9880d681SAndroid Build Coastguard Worker class ARMConstantPoolSymbol : public ARMConstantPoolValue { 187*9880d681SAndroid Build Coastguard Worker const std::string S; // ExtSymbol being loaded. 188*9880d681SAndroid Build Coastguard Worker 189*9880d681SAndroid Build Coastguard Worker ARMConstantPoolSymbol(LLVMContext &C, const char *s, unsigned id, 190*9880d681SAndroid Build Coastguard Worker unsigned char PCAdj, ARMCP::ARMCPModifier Modifier, 191*9880d681SAndroid Build Coastguard Worker bool AddCurrentAddress); 192*9880d681SAndroid Build Coastguard Worker 193*9880d681SAndroid Build Coastguard Worker public: 194*9880d681SAndroid Build Coastguard Worker static ARMConstantPoolSymbol *Create(LLVMContext &C, const char *s, 195*9880d681SAndroid Build Coastguard Worker unsigned ID, unsigned char PCAdj); 196*9880d681SAndroid Build Coastguard Worker getSymbol()197*9880d681SAndroid Build Coastguard Worker const char *getSymbol() const { return S.c_str(); } 198*9880d681SAndroid Build Coastguard Worker 199*9880d681SAndroid Build Coastguard Worker int getExistingMachineCPValue(MachineConstantPool *CP, 200*9880d681SAndroid Build Coastguard Worker unsigned Alignment) override; 201*9880d681SAndroid Build Coastguard Worker 202*9880d681SAndroid Build Coastguard Worker void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 203*9880d681SAndroid Build Coastguard Worker 204*9880d681SAndroid Build Coastguard Worker /// hasSameValue - Return true if this ARM constpool value can share the same 205*9880d681SAndroid Build Coastguard Worker /// constantpool entry as another ARM constpool value. 206*9880d681SAndroid Build Coastguard Worker bool hasSameValue(ARMConstantPoolValue *ACPV) override; 207*9880d681SAndroid Build Coastguard Worker 208*9880d681SAndroid Build Coastguard Worker void print(raw_ostream &O) const override; 209*9880d681SAndroid Build Coastguard Worker classof(const ARMConstantPoolValue * ACPV)210*9880d681SAndroid Build Coastguard Worker static bool classof(const ARMConstantPoolValue *ACPV) { 211*9880d681SAndroid Build Coastguard Worker return ACPV->isExtSymbol(); 212*9880d681SAndroid Build Coastguard Worker } 213*9880d681SAndroid Build Coastguard Worker equals(const ARMConstantPoolSymbol * A)214*9880d681SAndroid Build Coastguard Worker bool equals(const ARMConstantPoolSymbol *A) const { 215*9880d681SAndroid Build Coastguard Worker return S == A->S && ARMConstantPoolValue::equals(A); 216*9880d681SAndroid Build Coastguard Worker } 217*9880d681SAndroid Build Coastguard Worker }; 218*9880d681SAndroid Build Coastguard Worker 219*9880d681SAndroid Build Coastguard Worker /// ARMConstantPoolMBB - ARM-specific constantpool value of a machine basic 220*9880d681SAndroid Build Coastguard Worker /// block. 221*9880d681SAndroid Build Coastguard Worker class ARMConstantPoolMBB : public ARMConstantPoolValue { 222*9880d681SAndroid Build Coastguard Worker const MachineBasicBlock *MBB; // Machine basic block. 223*9880d681SAndroid Build Coastguard Worker 224*9880d681SAndroid Build Coastguard Worker ARMConstantPoolMBB(LLVMContext &C, const MachineBasicBlock *mbb, unsigned id, 225*9880d681SAndroid Build Coastguard Worker unsigned char PCAdj, ARMCP::ARMCPModifier Modifier, 226*9880d681SAndroid Build Coastguard Worker bool AddCurrentAddress); 227*9880d681SAndroid Build Coastguard Worker 228*9880d681SAndroid Build Coastguard Worker public: 229*9880d681SAndroid Build Coastguard Worker static ARMConstantPoolMBB *Create(LLVMContext &C, 230*9880d681SAndroid Build Coastguard Worker const MachineBasicBlock *mbb, 231*9880d681SAndroid Build Coastguard Worker unsigned ID, unsigned char PCAdj); 232*9880d681SAndroid Build Coastguard Worker getMBB()233*9880d681SAndroid Build Coastguard Worker const MachineBasicBlock *getMBB() const { return MBB; } 234*9880d681SAndroid Build Coastguard Worker 235*9880d681SAndroid Build Coastguard Worker int getExistingMachineCPValue(MachineConstantPool *CP, 236*9880d681SAndroid Build Coastguard Worker unsigned Alignment) override; 237*9880d681SAndroid Build Coastguard Worker 238*9880d681SAndroid Build Coastguard Worker void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 239*9880d681SAndroid Build Coastguard Worker 240*9880d681SAndroid Build Coastguard Worker /// hasSameValue - Return true if this ARM constpool value can share the same 241*9880d681SAndroid Build Coastguard Worker /// constantpool entry as another ARM constpool value. 242*9880d681SAndroid Build Coastguard Worker bool hasSameValue(ARMConstantPoolValue *ACPV) override; 243*9880d681SAndroid Build Coastguard Worker 244*9880d681SAndroid Build Coastguard Worker void print(raw_ostream &O) const override; 245*9880d681SAndroid Build Coastguard Worker classof(const ARMConstantPoolValue * ACPV)246*9880d681SAndroid Build Coastguard Worker static bool classof(const ARMConstantPoolValue *ACPV) { 247*9880d681SAndroid Build Coastguard Worker return ACPV->isMachineBasicBlock(); 248*9880d681SAndroid Build Coastguard Worker } 249*9880d681SAndroid Build Coastguard Worker equals(const ARMConstantPoolMBB * A)250*9880d681SAndroid Build Coastguard Worker bool equals(const ARMConstantPoolMBB *A) const { 251*9880d681SAndroid Build Coastguard Worker return MBB == A->MBB && ARMConstantPoolValue::equals(A); 252*9880d681SAndroid Build Coastguard Worker } 253*9880d681SAndroid Build Coastguard Worker }; 254*9880d681SAndroid Build Coastguard Worker 255*9880d681SAndroid Build Coastguard Worker } // End llvm namespace 256*9880d681SAndroid Build Coastguard Worker 257*9880d681SAndroid Build Coastguard Worker #endif 258