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