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