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