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
22namespace llvm {
23
24class BlockAddress;
25class Constant;
26class GlobalValue;
27class LLVMContext;
28class MachineBasicBlock;
29
30namespace CSKYCP {
31enum CSKYCPKind {
32  CPValue,
33  CPExtSymbol,
34  CPBlockAddress,
35  CPMachineBasicBlock,
36  CPJT,
37  CPConstPool
38};
39
40enum 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)).
46class CSKYConstantPoolValue : public MachineConstantPoolValue {
47protected:
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
59public:
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.
107class 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
114public:
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.
143class 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
150public:
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.
173class 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
179public:
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.
200class 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
206public:
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