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