| //===-- CSKYConstantPoolValue.h - CSKY constantpool value -----*- C++ -*---===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file implements the CSKY specific constantpool value class. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_TARGET_CSKY_CONSTANTPOOLVALUE_H |
| #define LLVM_TARGET_CSKY_CONSTANTPOOLVALUE_H |
| |
| #include "llvm/ADT/StringRef.h" |
| #include "llvm/CodeGen/MachineConstantPool.h" |
| #include "llvm/Support/Casting.h" |
| #include "llvm/Support/ErrorHandling.h" |
| #include <cstddef> |
| |
| namespace llvm { |
| |
| class BlockAddress; |
| class Constant; |
| class GlobalValue; |
| class LLVMContext; |
| class MachineBasicBlock; |
| |
| namespace CSKYCP { |
| enum CSKYCPKind { |
| CPValue, |
| CPExtSymbol, |
| CPBlockAddress, |
| CPMachineBasicBlock, |
| CPJT, |
| CPConstPool |
| }; |
| |
| enum CSKYCPModifier { NO_MOD, ADDR, GOT, GOTOFF, PLT, TLSLE, TLSIE, TLSGD }; |
| } // namespace CSKYCP |
| |
| /// CSKYConstantPoolValue - CSKY specific constantpool value. This is used to |
| /// represent PC-relative displacement between the address of the load |
| /// instruction and the constant being loaded, i.e. (&GV-(LPIC+8)). |
| class CSKYConstantPoolValue : public MachineConstantPoolValue { |
| protected: |
| CSKYCP::CSKYCPKind Kind; // Kind of constant. |
| unsigned PCAdjust; // Extra adjustment if constantpool is pc-relative. |
| CSKYCP::CSKYCPModifier Modifier; // GV modifier |
| bool AddCurrentAddress; |
| |
| unsigned LabelId = 0; |
| |
| CSKYConstantPoolValue(Type *Ty, CSKYCP::CSKYCPKind Kind, unsigned PCAdjust, |
| CSKYCP::CSKYCPModifier Modifier, bool AddCurrentAddress, |
| unsigned ID = 0); |
| |
| public: |
| const char *getModifierText() const; |
| unsigned getPCAdjustment() const { return PCAdjust; } |
| bool mustAddCurrentAddress() const { return AddCurrentAddress; } |
| CSKYCP::CSKYCPModifier getModifier() const { return Modifier; } |
| unsigned getLabelID() const { return LabelId; } |
| |
| bool isGlobalValue() const { return Kind == CSKYCP::CPValue; } |
| bool isExtSymbol() const { return Kind == CSKYCP::CPExtSymbol; } |
| bool isBlockAddress() const { return Kind == CSKYCP::CPBlockAddress; } |
| bool isMachineBasicBlock() const { |
| return Kind == CSKYCP::CPMachineBasicBlock; |
| } |
| bool isJT() const { return Kind == CSKYCP::CPJT; } |
| bool isConstPool() const { return Kind == CSKYCP::CPConstPool; } |
| |
| int getExistingMachineCPValue(MachineConstantPool *CP, |
| Align Alignment) override; |
| |
| void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; |
| |
| void print(raw_ostream &O) const override; |
| |
| bool equals(const CSKYConstantPoolValue *A) const { |
| return this->LabelId == A->LabelId && this->PCAdjust == A->PCAdjust && |
| this->Modifier == A->Modifier; |
| } |
| |
| template <typename Derived> |
| int getExistingMachineCPValueImpl(MachineConstantPool *CP, Align Alignment) { |
| const std::vector<MachineConstantPoolEntry> &Constants = CP->getConstants(); |
| for (unsigned i = 0, e = Constants.size(); i != e; ++i) { |
| if (Constants[i].isMachineConstantPoolEntry() && |
| Constants[i].getAlign() >= Alignment) { |
| auto *CPV = |
| static_cast<CSKYConstantPoolValue *>(Constants[i].Val.MachineCPVal); |
| if (Derived *APC = dyn_cast<Derived>(CPV)) |
| if (cast<Derived>(this)->equals(APC)) |
| return i; |
| } |
| } |
| |
| return -1; |
| } |
| }; |
| |
| /// CSKY-specific constant pool values for Constants, |
| /// Functions, and BlockAddresses. |
| class CSKYConstantPoolConstant : public CSKYConstantPoolValue { |
| const Constant *CVal; // Constant being loaded. |
| |
| CSKYConstantPoolConstant(const Constant *C, Type *Ty, CSKYCP::CSKYCPKind Kind, |
| unsigned PCAdjust, CSKYCP::CSKYCPModifier Modifier, |
| bool AddCurrentAddress, unsigned ID); |
| |
| public: |
| static CSKYConstantPoolConstant * |
| Create(const Constant *C, CSKYCP::CSKYCPKind Kind, unsigned PCAdjust, |
| CSKYCP::CSKYCPModifier Modifier, bool AddCurrentAddress, |
| unsigned ID = 0); |
| static CSKYConstantPoolConstant * |
| Create(const Constant *C, Type *Ty, CSKYCP::CSKYCPKind Kind, |
| unsigned PCAdjust, CSKYCP::CSKYCPModifier Modifier, |
| bool AddCurrentAddress, unsigned ID = 0); |
| const GlobalValue *getGV() const; |
| const BlockAddress *getBlockAddress() const; |
| const Constant *getConstantPool() const; |
| |
| int getExistingMachineCPValue(MachineConstantPool *CP, |
| Align Alignment) override; |
| void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; |
| void print(raw_ostream &O) const override; |
| |
| bool equals(const CSKYConstantPoolConstant *A) const { |
| return CVal == A->CVal && CSKYConstantPoolValue::equals(A); |
| } |
| |
| static bool classof(const CSKYConstantPoolValue *APV) { |
| return APV->isGlobalValue() || APV->isBlockAddress() || APV->isConstPool(); |
| } |
| }; |
| |
| /// CSKYConstantPoolSymbol - CSKY-specific constantpool values for external |
| /// symbols. |
| class CSKYConstantPoolSymbol : public CSKYConstantPoolValue { |
| const std::string S; // ExtSymbol being loaded. |
| |
| CSKYConstantPoolSymbol(Type *Ty, const char *S, unsigned PCAdjust, |
| CSKYCP::CSKYCPModifier Modifier, |
| bool AddCurrentAddress); |
| |
| public: |
| static CSKYConstantPoolSymbol *Create(Type *Ty, const char *S, |
| unsigned PCAdjust, |
| CSKYCP::CSKYCPModifier Modifier); |
| |
| StringRef getSymbol() const { return S; } |
| |
| int getExistingMachineCPValue(MachineConstantPool *CP, |
| Align Alignment) override; |
| void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; |
| void print(raw_ostream &O) const override; |
| |
| bool equals(const CSKYConstantPoolSymbol *A) const { |
| return S == A->S && CSKYConstantPoolValue::equals(A); |
| } |
| |
| static bool classof(const CSKYConstantPoolValue *ACPV) { |
| return ACPV->isExtSymbol(); |
| } |
| }; |
| |
| /// CSKYConstantPoolMBB - CSKY-specific constantpool value of a machine basic |
| /// block. |
| class CSKYConstantPoolMBB : public CSKYConstantPoolValue { |
| const MachineBasicBlock *MBB; // Machine basic block. |
| |
| CSKYConstantPoolMBB(Type *Ty, const MachineBasicBlock *Mbb, unsigned PCAdjust, |
| CSKYCP::CSKYCPModifier Modifier, bool AddCurrentAddress); |
| |
| public: |
| static CSKYConstantPoolMBB *Create(Type *Ty, const MachineBasicBlock *Mbb, |
| unsigned PCAdjust); |
| |
| const MachineBasicBlock *getMBB() const { return MBB; } |
| |
| int getExistingMachineCPValue(MachineConstantPool *CP, |
| Align Alignment) override; |
| void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; |
| void print(raw_ostream &O) const override; |
| |
| bool equals(const CSKYConstantPoolMBB *A) const { |
| return MBB == A->MBB && CSKYConstantPoolValue::equals(A); |
| } |
| |
| static bool classof(const CSKYConstantPoolValue *ACPV) { |
| return ACPV->isMachineBasicBlock(); |
| } |
| }; |
| |
| /// CSKY-specific constantpool value of a jump table. |
| class CSKYConstantPoolJT : public CSKYConstantPoolValue { |
| signed JTI; // Machine basic block. |
| |
| CSKYConstantPoolJT(Type *Ty, int JTIndex, unsigned PCAdj, |
| CSKYCP::CSKYCPModifier Modifier, bool AddCurrentAddress); |
| |
| public: |
| static CSKYConstantPoolJT *Create(Type *Ty, int JTI, unsigned PCAdj, |
| CSKYCP::CSKYCPModifier Modifier); |
| |
| signed getJTI() { return JTI; } |
| |
| int getExistingMachineCPValue(MachineConstantPool *CP, |
| Align Alignment) override; |
| void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; |
| void print(raw_ostream &O) const override; |
| |
| bool equals(const CSKYConstantPoolJT *A) const { |
| return JTI == A->JTI && CSKYConstantPoolValue::equals(A); |
| } |
| |
| static bool classof(const CSKYConstantPoolValue *ACPV) { |
| return ACPV->isJT(); |
| } |
| }; |
| |
| } // namespace llvm |
| |
| #endif |