1 //===-- CSKYConstantPoolValue.h - CSKY constantpool value -----*- C++ -*---===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements the CSKY specific constantpool value class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_TARGET_CSKY_CONSTANTPOOLVALUE_H 14 #define LLVM_TARGET_CSKY_CONSTANTPOOLVALUE_H 15 16 #include "llvm/ADT/StringRef.h" 17 #include "llvm/CodeGen/MachineConstantPool.h" 18 #include "llvm/Support/Casting.h" 19 #include "llvm/Support/ErrorHandling.h" 20 #include <cstddef> 21 22 namespace llvm { 23 24 class BlockAddress; 25 class Constant; 26 class GlobalValue; 27 class LLVMContext; 28 class MachineBasicBlock; 29 30 namespace CSKYCP { 31 enum CSKYCPKind { 32 CPValue, 33 CPExtSymbol, 34 CPBlockAddress, 35 CPMachineBasicBlock, 36 CPJT 37 }; 38 39 enum CSKYCPModifier { NO_MOD, ADDR, GOT, GOTOFF, PLT, TLSLE, TLSIE, TLSGD }; 40 } // namespace CSKYCP 41 42 /// CSKYConstantPoolValue - CSKY specific constantpool value. This is used to 43 /// represent PC-relative displacement between the address of the load 44 /// instruction and the constant being loaded, i.e. (&GV-(LPIC+8)). 45 class CSKYConstantPoolValue : public MachineConstantPoolValue { 46 protected: 47 CSKYCP::CSKYCPKind Kind; // Kind of constant. 48 unsigned PCAdjust; // Extra adjustment if constantpool is pc-relative. 49 CSKYCP::CSKYCPModifier Modifier; // GV modifier 50 bool AddCurrentAddress; 51 52 unsigned LabelId = 0; 53 54 CSKYConstantPoolValue(Type *Ty, CSKYCP::CSKYCPKind Kind, unsigned PCAdjust, 55 CSKYCP::CSKYCPModifier Modifier, bool AddCurrentAddress, 56 unsigned ID = 0); 57 58 public: 59 const char *getModifierText() const; 60 unsigned getPCAdjustment() const { return PCAdjust; } 61 bool mustAddCurrentAddress() const { return AddCurrentAddress; } 62 CSKYCP::CSKYCPModifier getModifier() const { return Modifier; } 63 unsigned getLabelID() const { return LabelId; } 64 65 bool isGlobalValue() const { return Kind == CSKYCP::CPValue; } 66 bool isExtSymbol() const { return Kind == CSKYCP::CPExtSymbol; } 67 bool isBlockAddress() const { return Kind == CSKYCP::CPBlockAddress; } 68 bool isMachineBasicBlock() const { 69 return Kind == CSKYCP::CPMachineBasicBlock; 70 } 71 bool isJT() const { return Kind == CSKYCP::CPJT; } 72 73 int getExistingMachineCPValue(MachineConstantPool *CP, 74 Align Alignment) override; 75 76 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 77 78 void print(raw_ostream &O) const override; 79 80 bool equals(const CSKYConstantPoolValue *A) const { 81 return this->LabelId == A->LabelId && this->PCAdjust == A->PCAdjust && 82 this->Modifier == A->Modifier; 83 } 84 85 template <typename Derived> 86 int getExistingMachineCPValueImpl(MachineConstantPool *CP, Align Alignment) { 87 const std::vector<MachineConstantPoolEntry> &Constants = CP->getConstants(); 88 for (unsigned i = 0, e = Constants.size(); i != e; ++i) { 89 if (Constants[i].isMachineConstantPoolEntry() && 90 Constants[i].getAlign() >= Alignment) { 91 auto *CPV = 92 static_cast<CSKYConstantPoolValue *>(Constants[i].Val.MachineCPVal); 93 if (Derived *APC = dyn_cast<Derived>(CPV)) 94 if (cast<Derived>(this)->equals(APC)) 95 return i; 96 } 97 } 98 99 return -1; 100 } 101 }; 102 103 /// CSKY-specific constant pool values for Constants, 104 /// Functions, and BlockAddresses. 105 class CSKYConstantPoolConstant : public CSKYConstantPoolValue { 106 const Constant *CVal; // Constant being loaded. 107 108 CSKYConstantPoolConstant(const Constant *C, CSKYCP::CSKYCPKind Kind, 109 unsigned PCAdjust, CSKYCP::CSKYCPModifier Modifier, 110 bool AddCurrentAddress, unsigned ID); 111 112 public: 113 static CSKYConstantPoolConstant * 114 Create(const Constant *C, CSKYCP::CSKYCPKind Kind, unsigned PCAdjust, 115 CSKYCP::CSKYCPModifier Modifier, bool AddCurrentAddress, 116 unsigned ID = 0); 117 const GlobalValue *getGV() const; 118 const BlockAddress *getBlockAddress() const; 119 120 int getExistingMachineCPValue(MachineConstantPool *CP, 121 Align Alignment) override; 122 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 123 void print(raw_ostream &O) const override; 124 125 bool equals(const CSKYConstantPoolConstant *A) const { 126 return CVal == A->CVal && CSKYConstantPoolValue::equals(A); 127 } 128 129 static bool classof(const CSKYConstantPoolValue *APV) { 130 return APV->isGlobalValue() || APV->isBlockAddress(); 131 } 132 }; 133 134 /// CSKYConstantPoolSymbol - CSKY-specific constantpool values for external 135 /// symbols. 136 class CSKYConstantPoolSymbol : public CSKYConstantPoolValue { 137 const std::string S; // ExtSymbol being loaded. 138 139 CSKYConstantPoolSymbol(Type *Ty, const char *S, unsigned PCAdjust, 140 CSKYCP::CSKYCPModifier Modifier, 141 bool AddCurrentAddress); 142 143 public: 144 static CSKYConstantPoolSymbol *Create(Type *Ty, const char *S, 145 unsigned PCAdjust, 146 CSKYCP::CSKYCPModifier Modifier); 147 148 StringRef getSymbol() const { return S; } 149 150 int getExistingMachineCPValue(MachineConstantPool *CP, 151 Align Alignment) override; 152 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 153 void print(raw_ostream &O) const override; 154 155 bool equals(const CSKYConstantPoolSymbol *A) const { 156 return S == A->S && CSKYConstantPoolValue::equals(A); 157 } 158 159 static bool classof(const CSKYConstantPoolValue *ACPV) { 160 return ACPV->isExtSymbol(); 161 } 162 }; 163 164 /// CSKYConstantPoolMBB - CSKY-specific constantpool value of a machine basic 165 /// block. 166 class CSKYConstantPoolMBB : public CSKYConstantPoolValue { 167 const MachineBasicBlock *MBB; // Machine basic block. 168 169 CSKYConstantPoolMBB(Type *Ty, const MachineBasicBlock *Mbb, unsigned PCAdjust, 170 CSKYCP::CSKYCPModifier Modifier, bool AddCurrentAddress); 171 172 public: 173 static CSKYConstantPoolMBB *Create(Type *Ty, const MachineBasicBlock *Mbb, 174 unsigned PCAdjust); 175 176 const MachineBasicBlock *getMBB() const { return MBB; } 177 178 int getExistingMachineCPValue(MachineConstantPool *CP, 179 Align Alignment) override; 180 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 181 void print(raw_ostream &O) const override; 182 183 bool equals(const CSKYConstantPoolMBB *A) const { 184 return MBB == A->MBB && CSKYConstantPoolValue::equals(A); 185 } 186 187 static bool classof(const CSKYConstantPoolValue *ACPV) { 188 return ACPV->isMachineBasicBlock(); 189 } 190 }; 191 192 /// CSKY-specific constantpool value of a jump table. 193 class CSKYConstantPoolJT : public CSKYConstantPoolValue { 194 signed JTI; // Machine basic block. 195 196 CSKYConstantPoolJT(Type *Ty, int JTIndex, unsigned PCAdj, 197 CSKYCP::CSKYCPModifier Modifier, bool AddCurrentAddress); 198 199 public: 200 static CSKYConstantPoolJT *Create(Type *Ty, int JTI, unsigned PCAdj, 201 CSKYCP::CSKYCPModifier Modifier); 202 203 signed getJTI() { return JTI; } 204 205 int getExistingMachineCPValue(MachineConstantPool *CP, 206 Align Alignment) override; 207 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 208 void print(raw_ostream &O) const override; 209 210 bool equals(const CSKYConstantPoolJT *A) const { 211 return JTI == A->JTI && CSKYConstantPoolValue::equals(A); 212 } 213 214 static bool classof(const CSKYConstantPoolValue *ACPV) { 215 return ACPV->isJT(); 216 } 217 }; 218 219 } // namespace llvm 220 221 #endif 222