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