xref: /freebsd/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYConstantPoolValue.h (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
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