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 Constant; 24 class BlockAddress; 25 class GlobalValue; 26 class LLVMContext; 27 28 namespace ARMCP { 29 enum ARMCPKind { 30 CPValue, 31 CPExtSymbol, 32 CPBlockAddress, 33 CPLSDA 34 }; 35 36 enum ARMCPModifier { 37 no_modifier, 38 TLSGD, 39 GOT, 40 GOTOFF, 41 GOTTPOFF, 42 TPOFF 43 }; 44 } 45 46 /// ARMConstantPoolValue - ARM specific constantpool value. This is used to 47 /// represent PC-relative displacement between the address of the load 48 /// instruction and the constant being loaded, i.e. (&GV-(LPIC+8)). 49 class ARMConstantPoolValue : public MachineConstantPoolValue { 50 const Constant *CVal; // Constant being loaded. 51 const char *S; // ExtSymbol being loaded. 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 public: 60 ARMConstantPoolValue(const Constant *cval, unsigned id, 61 ARMCP::ARMCPKind Kind = ARMCP::CPValue, 62 unsigned char PCAdj = 0, 63 ARMCP::ARMCPModifier Modifier = ARMCP::no_modifier, 64 bool AddCurrentAddress = false); 65 ARMConstantPoolValue(LLVMContext &C, const char *s, unsigned id, 66 unsigned char PCAdj = 0, 67 ARMCP::ARMCPModifier Modifier = ARMCP::no_modifier, 68 bool AddCurrentAddress = false); 69 ARMConstantPoolValue(const GlobalValue *GV, ARMCP::ARMCPModifier Modifier); 70 ARMConstantPoolValue(); 71 ~ARMConstantPoolValue(); 72 73 const GlobalValue *getGV() const; 74 const char *getSymbol() const { return S; } 75 const BlockAddress *getBlockAddress() const; 76 ARMCP::ARMCPModifier getModifier() const { return Modifier; } 77 const char *getModifierText() const { 78 switch (Modifier) { 79 default: llvm_unreachable("Unknown modifier!"); 80 // FIXME: Are these case sensitive? It'd be nice to lower-case all the 81 // strings if that's legal. 82 case ARMCP::no_modifier: return "none"; 83 case ARMCP::TLSGD: return "tlsgd"; 84 case ARMCP::GOT: return "GOT"; 85 case ARMCP::GOTOFF: return "GOTOFF"; 86 case ARMCP::GOTTPOFF: return "gottpoff"; 87 case ARMCP::TPOFF: return "tpoff"; 88 } 89 } 90 bool hasModifier() const { return Modifier != ARMCP::no_modifier; } 91 bool mustAddCurrentAddress() const { return AddCurrentAddress; } 92 unsigned getLabelId() const { return LabelId; } 93 unsigned char getPCAdjustment() const { return PCAdjust; } 94 bool isGlobalValue() const { return Kind == ARMCP::CPValue; } 95 bool isExtSymbol() const { return Kind == ARMCP::CPExtSymbol; } 96 bool isBlockAddress() { return Kind == ARMCP::CPBlockAddress; } 97 bool isLSDA() { return Kind == ARMCP::CPLSDA; } 98 99 virtual unsigned getRelocationInfo() const { return 2; } 100 101 virtual int getExistingMachineCPValue(MachineConstantPool *CP, 102 unsigned Alignment); 103 104 virtual void AddSelectionDAGCSEId(FoldingSetNodeID &ID); 105 106 /// hasSameValue - Return true if this ARM constpool value 107 /// can share the same constantpool entry as another ARM constpool value. 108 bool hasSameValue(ARMConstantPoolValue *ACPV); 109 110 void print(raw_ostream *O) const { if (O) print(*O); } 111 void print(raw_ostream &O) const; 112 void dump() const; 113 }; 114 115 inline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) { 116 V.print(O); 117 return O; 118 } 119 120 } // End llvm namespace 121 122 #endif 123