104eeddc0SDimitry Andric //===-- CSKYConstantPoolValue.h - CSKY constantpool value -----*- C++ -*---===// 204eeddc0SDimitry Andric // 304eeddc0SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 404eeddc0SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 504eeddc0SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 604eeddc0SDimitry Andric // 704eeddc0SDimitry Andric //===----------------------------------------------------------------------===// 804eeddc0SDimitry Andric // 904eeddc0SDimitry Andric // This file implements the CSKY specific constantpool value class. 1004eeddc0SDimitry Andric // 1104eeddc0SDimitry Andric //===----------------------------------------------------------------------===// 1204eeddc0SDimitry Andric 1304eeddc0SDimitry Andric #ifndef LLVM_TARGET_CSKY_CONSTANTPOOLVALUE_H 1404eeddc0SDimitry Andric #define LLVM_TARGET_CSKY_CONSTANTPOOLVALUE_H 1504eeddc0SDimitry Andric 1604eeddc0SDimitry Andric #include "llvm/ADT/StringRef.h" 1704eeddc0SDimitry Andric #include "llvm/CodeGen/MachineConstantPool.h" 1804eeddc0SDimitry Andric #include "llvm/Support/Casting.h" 1904eeddc0SDimitry Andric #include "llvm/Support/ErrorHandling.h" 2004eeddc0SDimitry Andric #include <cstddef> 2104eeddc0SDimitry Andric 2204eeddc0SDimitry Andric namespace llvm { 2304eeddc0SDimitry Andric 2404eeddc0SDimitry Andric class BlockAddress; 2504eeddc0SDimitry Andric class Constant; 2604eeddc0SDimitry Andric class GlobalValue; 2704eeddc0SDimitry Andric class LLVMContext; 2804eeddc0SDimitry Andric class MachineBasicBlock; 2904eeddc0SDimitry Andric 3004eeddc0SDimitry Andric namespace CSKYCP { 3104eeddc0SDimitry Andric enum CSKYCPKind { 3204eeddc0SDimitry Andric CPValue, 3304eeddc0SDimitry Andric CPExtSymbol, 3404eeddc0SDimitry Andric CPBlockAddress, 3504eeddc0SDimitry Andric CPMachineBasicBlock, 36*bdd1243dSDimitry Andric CPJT, 37*bdd1243dSDimitry Andric CPConstPool 3804eeddc0SDimitry Andric }; 3904eeddc0SDimitry Andric 4004eeddc0SDimitry Andric enum CSKYCPModifier { NO_MOD, ADDR, GOT, GOTOFF, PLT, TLSLE, TLSIE, TLSGD }; 4104eeddc0SDimitry Andric } // namespace CSKYCP 4204eeddc0SDimitry Andric 4304eeddc0SDimitry Andric /// CSKYConstantPoolValue - CSKY specific constantpool value. This is used to 4404eeddc0SDimitry Andric /// represent PC-relative displacement between the address of the load 4504eeddc0SDimitry Andric /// instruction and the constant being loaded, i.e. (&GV-(LPIC+8)). 4604eeddc0SDimitry Andric class CSKYConstantPoolValue : public MachineConstantPoolValue { 4704eeddc0SDimitry Andric protected: 4804eeddc0SDimitry Andric CSKYCP::CSKYCPKind Kind; // Kind of constant. 4904eeddc0SDimitry Andric unsigned PCAdjust; // Extra adjustment if constantpool is pc-relative. 5004eeddc0SDimitry Andric CSKYCP::CSKYCPModifier Modifier; // GV modifier 5104eeddc0SDimitry Andric bool AddCurrentAddress; 5204eeddc0SDimitry Andric 5304eeddc0SDimitry Andric unsigned LabelId = 0; 5404eeddc0SDimitry Andric 5504eeddc0SDimitry Andric CSKYConstantPoolValue(Type *Ty, CSKYCP::CSKYCPKind Kind, unsigned PCAdjust, 5604eeddc0SDimitry Andric CSKYCP::CSKYCPModifier Modifier, bool AddCurrentAddress, 5704eeddc0SDimitry Andric unsigned ID = 0); 5804eeddc0SDimitry Andric 5904eeddc0SDimitry Andric public: 6004eeddc0SDimitry Andric const char *getModifierText() const; getPCAdjustment()6104eeddc0SDimitry Andric unsigned getPCAdjustment() const { return PCAdjust; } mustAddCurrentAddress()6204eeddc0SDimitry Andric bool mustAddCurrentAddress() const { return AddCurrentAddress; } getModifier()6304eeddc0SDimitry Andric CSKYCP::CSKYCPModifier getModifier() const { return Modifier; } getLabelID()6404eeddc0SDimitry Andric unsigned getLabelID() const { return LabelId; } 6504eeddc0SDimitry Andric isGlobalValue()6604eeddc0SDimitry Andric bool isGlobalValue() const { return Kind == CSKYCP::CPValue; } isExtSymbol()6704eeddc0SDimitry Andric bool isExtSymbol() const { return Kind == CSKYCP::CPExtSymbol; } isBlockAddress()6804eeddc0SDimitry Andric bool isBlockAddress() const { return Kind == CSKYCP::CPBlockAddress; } isMachineBasicBlock()6904eeddc0SDimitry Andric bool isMachineBasicBlock() const { 7004eeddc0SDimitry Andric return Kind == CSKYCP::CPMachineBasicBlock; 7104eeddc0SDimitry Andric } isJT()7204eeddc0SDimitry Andric bool isJT() const { return Kind == CSKYCP::CPJT; } isConstPool()73*bdd1243dSDimitry Andric bool isConstPool() const { return Kind == CSKYCP::CPConstPool; } 7404eeddc0SDimitry Andric 7504eeddc0SDimitry Andric int getExistingMachineCPValue(MachineConstantPool *CP, 7604eeddc0SDimitry Andric Align Alignment) override; 7704eeddc0SDimitry Andric 7804eeddc0SDimitry Andric void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 7904eeddc0SDimitry Andric 8004eeddc0SDimitry Andric void print(raw_ostream &O) const override; 8104eeddc0SDimitry Andric equals(const CSKYConstantPoolValue * A)8204eeddc0SDimitry Andric bool equals(const CSKYConstantPoolValue *A) const { 8304eeddc0SDimitry Andric return this->LabelId == A->LabelId && this->PCAdjust == A->PCAdjust && 8404eeddc0SDimitry Andric this->Modifier == A->Modifier; 8504eeddc0SDimitry Andric } 8604eeddc0SDimitry Andric 8704eeddc0SDimitry Andric template <typename Derived> getExistingMachineCPValueImpl(MachineConstantPool * CP,Align Alignment)8804eeddc0SDimitry Andric int getExistingMachineCPValueImpl(MachineConstantPool *CP, Align Alignment) { 8904eeddc0SDimitry Andric const std::vector<MachineConstantPoolEntry> &Constants = CP->getConstants(); 9004eeddc0SDimitry Andric for (unsigned i = 0, e = Constants.size(); i != e; ++i) { 9104eeddc0SDimitry Andric if (Constants[i].isMachineConstantPoolEntry() && 9204eeddc0SDimitry Andric Constants[i].getAlign() >= Alignment) { 9304eeddc0SDimitry Andric auto *CPV = 9404eeddc0SDimitry Andric static_cast<CSKYConstantPoolValue *>(Constants[i].Val.MachineCPVal); 9504eeddc0SDimitry Andric if (Derived *APC = dyn_cast<Derived>(CPV)) 9604eeddc0SDimitry Andric if (cast<Derived>(this)->equals(APC)) 9704eeddc0SDimitry Andric return i; 9804eeddc0SDimitry Andric } 9904eeddc0SDimitry Andric } 10004eeddc0SDimitry Andric 10104eeddc0SDimitry Andric return -1; 10204eeddc0SDimitry Andric } 10304eeddc0SDimitry Andric }; 10404eeddc0SDimitry Andric 10504eeddc0SDimitry Andric /// CSKY-specific constant pool values for Constants, 10604eeddc0SDimitry Andric /// Functions, and BlockAddresses. 10704eeddc0SDimitry Andric class CSKYConstantPoolConstant : public CSKYConstantPoolValue { 10804eeddc0SDimitry Andric const Constant *CVal; // Constant being loaded. 10904eeddc0SDimitry Andric 110*bdd1243dSDimitry Andric CSKYConstantPoolConstant(const Constant *C, Type *Ty, CSKYCP::CSKYCPKind Kind, 11104eeddc0SDimitry Andric unsigned PCAdjust, CSKYCP::CSKYCPModifier Modifier, 11204eeddc0SDimitry Andric bool AddCurrentAddress, unsigned ID); 11304eeddc0SDimitry Andric 11404eeddc0SDimitry Andric public: 11504eeddc0SDimitry Andric static CSKYConstantPoolConstant * 11604eeddc0SDimitry Andric Create(const Constant *C, CSKYCP::CSKYCPKind Kind, unsigned PCAdjust, 11704eeddc0SDimitry Andric CSKYCP::CSKYCPModifier Modifier, bool AddCurrentAddress, 11804eeddc0SDimitry Andric unsigned ID = 0); 119*bdd1243dSDimitry Andric static CSKYConstantPoolConstant * 120*bdd1243dSDimitry Andric Create(const Constant *C, Type *Ty, CSKYCP::CSKYCPKind Kind, 121*bdd1243dSDimitry Andric unsigned PCAdjust, CSKYCP::CSKYCPModifier Modifier, 122*bdd1243dSDimitry Andric bool AddCurrentAddress, unsigned ID = 0); 12304eeddc0SDimitry Andric const GlobalValue *getGV() const; 12404eeddc0SDimitry Andric const BlockAddress *getBlockAddress() const; 125*bdd1243dSDimitry Andric const Constant *getConstantPool() const; 12604eeddc0SDimitry Andric 12704eeddc0SDimitry Andric int getExistingMachineCPValue(MachineConstantPool *CP, 12804eeddc0SDimitry Andric Align Alignment) override; 12904eeddc0SDimitry Andric void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 13004eeddc0SDimitry Andric void print(raw_ostream &O) const override; 13104eeddc0SDimitry Andric equals(const CSKYConstantPoolConstant * A)13204eeddc0SDimitry Andric bool equals(const CSKYConstantPoolConstant *A) const { 13304eeddc0SDimitry Andric return CVal == A->CVal && CSKYConstantPoolValue::equals(A); 13404eeddc0SDimitry Andric } 13504eeddc0SDimitry Andric classof(const CSKYConstantPoolValue * APV)13604eeddc0SDimitry Andric static bool classof(const CSKYConstantPoolValue *APV) { 137*bdd1243dSDimitry Andric return APV->isGlobalValue() || APV->isBlockAddress() || APV->isConstPool(); 13804eeddc0SDimitry Andric } 13904eeddc0SDimitry Andric }; 14004eeddc0SDimitry Andric 14104eeddc0SDimitry Andric /// CSKYConstantPoolSymbol - CSKY-specific constantpool values for external 14204eeddc0SDimitry Andric /// symbols. 14304eeddc0SDimitry Andric class CSKYConstantPoolSymbol : public CSKYConstantPoolValue { 14404eeddc0SDimitry Andric const std::string S; // ExtSymbol being loaded. 14504eeddc0SDimitry Andric 14604eeddc0SDimitry Andric CSKYConstantPoolSymbol(Type *Ty, const char *S, unsigned PCAdjust, 14704eeddc0SDimitry Andric CSKYCP::CSKYCPModifier Modifier, 14804eeddc0SDimitry Andric bool AddCurrentAddress); 14904eeddc0SDimitry Andric 15004eeddc0SDimitry Andric public: 15104eeddc0SDimitry Andric static CSKYConstantPoolSymbol *Create(Type *Ty, const char *S, 15204eeddc0SDimitry Andric unsigned PCAdjust, 15304eeddc0SDimitry Andric CSKYCP::CSKYCPModifier Modifier); 15404eeddc0SDimitry Andric getSymbol()15504eeddc0SDimitry Andric StringRef getSymbol() const { return S; } 15604eeddc0SDimitry Andric 15704eeddc0SDimitry Andric int getExistingMachineCPValue(MachineConstantPool *CP, 15804eeddc0SDimitry Andric Align Alignment) override; 15904eeddc0SDimitry Andric void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 16004eeddc0SDimitry Andric void print(raw_ostream &O) const override; 16104eeddc0SDimitry Andric equals(const CSKYConstantPoolSymbol * A)16204eeddc0SDimitry Andric bool equals(const CSKYConstantPoolSymbol *A) const { 16304eeddc0SDimitry Andric return S == A->S && CSKYConstantPoolValue::equals(A); 16404eeddc0SDimitry Andric } 16504eeddc0SDimitry Andric classof(const CSKYConstantPoolValue * ACPV)16604eeddc0SDimitry Andric static bool classof(const CSKYConstantPoolValue *ACPV) { 16704eeddc0SDimitry Andric return ACPV->isExtSymbol(); 16804eeddc0SDimitry Andric } 16904eeddc0SDimitry Andric }; 17004eeddc0SDimitry Andric 17104eeddc0SDimitry Andric /// CSKYConstantPoolMBB - CSKY-specific constantpool value of a machine basic 17204eeddc0SDimitry Andric /// block. 17304eeddc0SDimitry Andric class CSKYConstantPoolMBB : public CSKYConstantPoolValue { 17404eeddc0SDimitry Andric const MachineBasicBlock *MBB; // Machine basic block. 17504eeddc0SDimitry Andric 17604eeddc0SDimitry Andric CSKYConstantPoolMBB(Type *Ty, const MachineBasicBlock *Mbb, unsigned PCAdjust, 17704eeddc0SDimitry Andric CSKYCP::CSKYCPModifier Modifier, bool AddCurrentAddress); 17804eeddc0SDimitry Andric 17904eeddc0SDimitry Andric public: 18004eeddc0SDimitry Andric static CSKYConstantPoolMBB *Create(Type *Ty, const MachineBasicBlock *Mbb, 18104eeddc0SDimitry Andric unsigned PCAdjust); 18204eeddc0SDimitry Andric getMBB()18304eeddc0SDimitry Andric const MachineBasicBlock *getMBB() const { return MBB; } 18404eeddc0SDimitry Andric 18504eeddc0SDimitry Andric int getExistingMachineCPValue(MachineConstantPool *CP, 18604eeddc0SDimitry Andric Align Alignment) override; 18704eeddc0SDimitry Andric void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 18804eeddc0SDimitry Andric void print(raw_ostream &O) const override; 18904eeddc0SDimitry Andric equals(const CSKYConstantPoolMBB * A)19004eeddc0SDimitry Andric bool equals(const CSKYConstantPoolMBB *A) const { 19104eeddc0SDimitry Andric return MBB == A->MBB && CSKYConstantPoolValue::equals(A); 19204eeddc0SDimitry Andric } 19304eeddc0SDimitry Andric classof(const CSKYConstantPoolValue * ACPV)19404eeddc0SDimitry Andric static bool classof(const CSKYConstantPoolValue *ACPV) { 19504eeddc0SDimitry Andric return ACPV->isMachineBasicBlock(); 19604eeddc0SDimitry Andric } 19704eeddc0SDimitry Andric }; 19804eeddc0SDimitry Andric 19904eeddc0SDimitry Andric /// CSKY-specific constantpool value of a jump table. 20004eeddc0SDimitry Andric class CSKYConstantPoolJT : public CSKYConstantPoolValue { 20104eeddc0SDimitry Andric signed JTI; // Machine basic block. 20204eeddc0SDimitry Andric 20304eeddc0SDimitry Andric CSKYConstantPoolJT(Type *Ty, int JTIndex, unsigned PCAdj, 20404eeddc0SDimitry Andric CSKYCP::CSKYCPModifier Modifier, bool AddCurrentAddress); 20504eeddc0SDimitry Andric 20604eeddc0SDimitry Andric public: 20704eeddc0SDimitry Andric static CSKYConstantPoolJT *Create(Type *Ty, int JTI, unsigned PCAdj, 20804eeddc0SDimitry Andric CSKYCP::CSKYCPModifier Modifier); 20904eeddc0SDimitry Andric getJTI()21004eeddc0SDimitry Andric signed getJTI() { return JTI; } 21104eeddc0SDimitry Andric 21204eeddc0SDimitry Andric int getExistingMachineCPValue(MachineConstantPool *CP, 21304eeddc0SDimitry Andric Align Alignment) override; 21404eeddc0SDimitry Andric void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 21504eeddc0SDimitry Andric void print(raw_ostream &O) const override; 21604eeddc0SDimitry Andric equals(const CSKYConstantPoolJT * A)21704eeddc0SDimitry Andric bool equals(const CSKYConstantPoolJT *A) const { 21804eeddc0SDimitry Andric return JTI == A->JTI && CSKYConstantPoolValue::equals(A); 21904eeddc0SDimitry Andric } 22004eeddc0SDimitry Andric classof(const CSKYConstantPoolValue * ACPV)22104eeddc0SDimitry Andric static bool classof(const CSKYConstantPoolValue *ACPV) { 22204eeddc0SDimitry Andric return ACPV->isJT(); 22304eeddc0SDimitry Andric } 22404eeddc0SDimitry Andric }; 22504eeddc0SDimitry Andric 22604eeddc0SDimitry Andric } // namespace llvm 22704eeddc0SDimitry Andric 22804eeddc0SDimitry Andric #endif 229