1*0fca6ea1SDimitry Andric //===- XtensaConstantPoolValue.h - Xtensa constantpool value ----*- C++ -*-===// 2*0fca6ea1SDimitry Andric // 3*0fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0fca6ea1SDimitry Andric // 7*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 8*0fca6ea1SDimitry Andric // 9*0fca6ea1SDimitry Andric // This file implements the Xtensa specific constantpool value class. 10*0fca6ea1SDimitry Andric // 11*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 12*0fca6ea1SDimitry Andric 13*0fca6ea1SDimitry Andric #ifndef LLVM_LIB_TARGET_XTENSA_XTENSACONSTANTPOOLVALUE_H 14*0fca6ea1SDimitry Andric #define LLVM_LIB_TARGET_XTENSA_XTENSACONSTANTPOOLVALUE_H 15*0fca6ea1SDimitry Andric 16*0fca6ea1SDimitry Andric #include "llvm/CodeGen/MachineConstantPool.h" 17*0fca6ea1SDimitry Andric #include "llvm/Support/Casting.h" 18*0fca6ea1SDimitry Andric #include "llvm/Support/ErrorHandling.h" 19*0fca6ea1SDimitry Andric #include <cstddef> 20*0fca6ea1SDimitry Andric #include <string> 21*0fca6ea1SDimitry Andric #include <vector> 22*0fca6ea1SDimitry Andric 23*0fca6ea1SDimitry Andric namespace llvm { 24*0fca6ea1SDimitry Andric 25*0fca6ea1SDimitry Andric class BlockAddress; 26*0fca6ea1SDimitry Andric class Constant; 27*0fca6ea1SDimitry Andric class GlobalValue; 28*0fca6ea1SDimitry Andric class LLVMContext; 29*0fca6ea1SDimitry Andric class MachineBasicBlock; 30*0fca6ea1SDimitry Andric 31*0fca6ea1SDimitry Andric namespace XtensaCP { 32*0fca6ea1SDimitry Andric enum XtensaCPKind { 33*0fca6ea1SDimitry Andric CPExtSymbol, 34*0fca6ea1SDimitry Andric CPBlockAddress, 35*0fca6ea1SDimitry Andric CPMachineBasicBlock, 36*0fca6ea1SDimitry Andric CPJumpTable 37*0fca6ea1SDimitry Andric }; 38*0fca6ea1SDimitry Andric 39*0fca6ea1SDimitry Andric enum XtensaCPModifier { 40*0fca6ea1SDimitry Andric no_modifier, // None 41*0fca6ea1SDimitry Andric TPOFF // Thread Pointer Offset 42*0fca6ea1SDimitry Andric }; 43*0fca6ea1SDimitry Andric } // namespace XtensaCP 44*0fca6ea1SDimitry Andric 45*0fca6ea1SDimitry Andric /// XtensaConstantPoolValue - Xtensa specific constantpool value. This is used 46*0fca6ea1SDimitry Andric /// to represent PC-relative displacement between the address of the load 47*0fca6ea1SDimitry Andric /// instruction and the constant being loaded. 48*0fca6ea1SDimitry Andric class XtensaConstantPoolValue : public MachineConstantPoolValue { 49*0fca6ea1SDimitry Andric unsigned LabelId; // Label id of the load. 50*0fca6ea1SDimitry Andric XtensaCP::XtensaCPKind Kind; // Kind of constant. 51*0fca6ea1SDimitry Andric XtensaCP::XtensaCPModifier Modifier; // Symbol name modifier 52*0fca6ea1SDimitry Andric //(for example Global Variable name) 53*0fca6ea1SDimitry Andric 54*0fca6ea1SDimitry Andric protected: 55*0fca6ea1SDimitry Andric XtensaConstantPoolValue( 56*0fca6ea1SDimitry Andric Type *Ty, unsigned ID, XtensaCP::XtensaCPKind Kind, 57*0fca6ea1SDimitry Andric XtensaCP::XtensaCPModifier Modifier = XtensaCP::no_modifier); 58*0fca6ea1SDimitry Andric 59*0fca6ea1SDimitry Andric XtensaConstantPoolValue( 60*0fca6ea1SDimitry Andric LLVMContext &C, unsigned id, XtensaCP::XtensaCPKind Kind, 61*0fca6ea1SDimitry Andric XtensaCP::XtensaCPModifier Modifier = XtensaCP::no_modifier); 62*0fca6ea1SDimitry Andric 63*0fca6ea1SDimitry Andric template <typename Derived> 64*0fca6ea1SDimitry Andric int getExistingMachineCPValueImpl(MachineConstantPool *CP, Align Alignment) { 65*0fca6ea1SDimitry Andric const std::vector<MachineConstantPoolEntry> &Constants = CP->getConstants(); 66*0fca6ea1SDimitry Andric for (unsigned i = 0, e = Constants.size(); i != e; ++i) { 67*0fca6ea1SDimitry Andric if (Constants[i].isMachineConstantPoolEntry() && 68*0fca6ea1SDimitry Andric (Constants[i].getAlign() >= Alignment)) { 69*0fca6ea1SDimitry Andric auto *CPV = static_cast<XtensaConstantPoolValue *>( 70*0fca6ea1SDimitry Andric Constants[i].Val.MachineCPVal); 71*0fca6ea1SDimitry Andric if (Derived *APC = dyn_cast<Derived>(CPV)) 72*0fca6ea1SDimitry Andric if (cast<Derived>(this)->equals(APC)) 73*0fca6ea1SDimitry Andric return i; 74*0fca6ea1SDimitry Andric } 75*0fca6ea1SDimitry Andric } 76*0fca6ea1SDimitry Andric 77*0fca6ea1SDimitry Andric return -1; 78*0fca6ea1SDimitry Andric } 79*0fca6ea1SDimitry Andric 80*0fca6ea1SDimitry Andric public: 81*0fca6ea1SDimitry Andric ~XtensaConstantPoolValue() override; 82*0fca6ea1SDimitry Andric 83*0fca6ea1SDimitry Andric XtensaCP::XtensaCPModifier getModifier() const { return Modifier; } 84*0fca6ea1SDimitry Andric bool hasModifier() const { return Modifier != XtensaCP::no_modifier; } 85*0fca6ea1SDimitry Andric StringRef getModifierText() const; 86*0fca6ea1SDimitry Andric 87*0fca6ea1SDimitry Andric unsigned getLabelId() const { return LabelId; } 88*0fca6ea1SDimitry Andric void setLabelId(unsigned ID) { LabelId = ID; } 89*0fca6ea1SDimitry Andric 90*0fca6ea1SDimitry Andric bool isExtSymbol() const { return Kind == XtensaCP::CPExtSymbol; } 91*0fca6ea1SDimitry Andric bool isBlockAddress() const { return Kind == XtensaCP::CPBlockAddress; } 92*0fca6ea1SDimitry Andric bool isMachineBasicBlock() const { 93*0fca6ea1SDimitry Andric return Kind == XtensaCP::CPMachineBasicBlock; 94*0fca6ea1SDimitry Andric } 95*0fca6ea1SDimitry Andric bool isJumpTable() const { return Kind == XtensaCP::CPJumpTable; } 96*0fca6ea1SDimitry Andric 97*0fca6ea1SDimitry Andric int getExistingMachineCPValue(MachineConstantPool *CP, 98*0fca6ea1SDimitry Andric Align Alignment) override; 99*0fca6ea1SDimitry Andric 100*0fca6ea1SDimitry Andric void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 101*0fca6ea1SDimitry Andric 102*0fca6ea1SDimitry Andric /// hasSameValue - Return true if this Xtensa constpool value can share the 103*0fca6ea1SDimitry Andric /// same constantpool entry as another Xtensa constpool value. 104*0fca6ea1SDimitry Andric virtual bool hasSameValue(XtensaConstantPoolValue *ACPV); 105*0fca6ea1SDimitry Andric 106*0fca6ea1SDimitry Andric bool equals(const XtensaConstantPoolValue *A) const { 107*0fca6ea1SDimitry Andric return this->LabelId == A->LabelId && this->Modifier == A->Modifier; 108*0fca6ea1SDimitry Andric } 109*0fca6ea1SDimitry Andric 110*0fca6ea1SDimitry Andric void print(raw_ostream &O) const override; 111*0fca6ea1SDimitry Andric 112*0fca6ea1SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 113*0fca6ea1SDimitry Andric void dump() const; 114*0fca6ea1SDimitry Andric #endif 115*0fca6ea1SDimitry Andric }; 116*0fca6ea1SDimitry Andric 117*0fca6ea1SDimitry Andric inline raw_ostream &operator<<(raw_ostream &O, 118*0fca6ea1SDimitry Andric const XtensaConstantPoolValue &V) { 119*0fca6ea1SDimitry Andric V.print(O); 120*0fca6ea1SDimitry Andric return O; 121*0fca6ea1SDimitry Andric } 122*0fca6ea1SDimitry Andric 123*0fca6ea1SDimitry Andric /// XtensaConstantPoolConstant - Xtensa-specific constant pool values for 124*0fca6ea1SDimitry Andric /// Constants (for example BlockAddresses). 125*0fca6ea1SDimitry Andric class XtensaConstantPoolConstant : public XtensaConstantPoolValue { 126*0fca6ea1SDimitry Andric const Constant *CVal; // Constant being loaded. 127*0fca6ea1SDimitry Andric 128*0fca6ea1SDimitry Andric XtensaConstantPoolConstant(const Constant *C, unsigned ID, 129*0fca6ea1SDimitry Andric XtensaCP::XtensaCPKind Kind); 130*0fca6ea1SDimitry Andric 131*0fca6ea1SDimitry Andric public: 132*0fca6ea1SDimitry Andric static XtensaConstantPoolConstant *Create(const Constant *C, unsigned ID, 133*0fca6ea1SDimitry Andric XtensaCP::XtensaCPKind Kind); 134*0fca6ea1SDimitry Andric 135*0fca6ea1SDimitry Andric const BlockAddress *getBlockAddress() const; 136*0fca6ea1SDimitry Andric 137*0fca6ea1SDimitry Andric int getExistingMachineCPValue(MachineConstantPool *CP, 138*0fca6ea1SDimitry Andric Align Alignment) override; 139*0fca6ea1SDimitry Andric 140*0fca6ea1SDimitry Andric /// hasSameValue - Return true if this Xtensa constpool value can share the 141*0fca6ea1SDimitry Andric /// same constantpool entry as another Xtensa constpool value. 142*0fca6ea1SDimitry Andric bool hasSameValue(XtensaConstantPoolValue *ACPV) override; 143*0fca6ea1SDimitry Andric 144*0fca6ea1SDimitry Andric void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 145*0fca6ea1SDimitry Andric 146*0fca6ea1SDimitry Andric void print(raw_ostream &O) const override; 147*0fca6ea1SDimitry Andric static bool classof(const XtensaConstantPoolValue *APV) { 148*0fca6ea1SDimitry Andric return APV->isBlockAddress(); 149*0fca6ea1SDimitry Andric } 150*0fca6ea1SDimitry Andric 151*0fca6ea1SDimitry Andric bool equals(const XtensaConstantPoolConstant *A) const { 152*0fca6ea1SDimitry Andric return CVal == A->CVal && XtensaConstantPoolValue::equals(A); 153*0fca6ea1SDimitry Andric } 154*0fca6ea1SDimitry Andric }; 155*0fca6ea1SDimitry Andric 156*0fca6ea1SDimitry Andric /// XtensaConstantPoolSymbol - Xtensa-specific constantpool values for external 157*0fca6ea1SDimitry Andric /// symbols. 158*0fca6ea1SDimitry Andric class XtensaConstantPoolSymbol : public XtensaConstantPoolValue { 159*0fca6ea1SDimitry Andric const std::string S; // ExtSymbol being loaded. 160*0fca6ea1SDimitry Andric bool PrivateLinkage; 161*0fca6ea1SDimitry Andric 162*0fca6ea1SDimitry Andric XtensaConstantPoolSymbol( 163*0fca6ea1SDimitry Andric LLVMContext &C, const char *S, unsigned Id, bool PrivLinkage, 164*0fca6ea1SDimitry Andric XtensaCP::XtensaCPModifier Modifier = XtensaCP::no_modifier); 165*0fca6ea1SDimitry Andric 166*0fca6ea1SDimitry Andric public: 167*0fca6ea1SDimitry Andric static XtensaConstantPoolSymbol * 168*0fca6ea1SDimitry Andric Create(LLVMContext &C, const char *S, unsigned ID, bool PrivLinkage, 169*0fca6ea1SDimitry Andric XtensaCP::XtensaCPModifier Modifier = XtensaCP::no_modifier); 170*0fca6ea1SDimitry Andric 171*0fca6ea1SDimitry Andric const char *getSymbol() const { return S.c_str(); } 172*0fca6ea1SDimitry Andric 173*0fca6ea1SDimitry Andric int getExistingMachineCPValue(MachineConstantPool *CP, 174*0fca6ea1SDimitry Andric Align Alignment) override; 175*0fca6ea1SDimitry Andric 176*0fca6ea1SDimitry Andric void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 177*0fca6ea1SDimitry Andric 178*0fca6ea1SDimitry Andric /// hasSameValue - Return true if this Xtensa constpool value can share the 179*0fca6ea1SDimitry Andric /// same constantpool entry as another Xtensa constpool value. 180*0fca6ea1SDimitry Andric bool hasSameValue(XtensaConstantPoolValue *ACPV) override; 181*0fca6ea1SDimitry Andric 182*0fca6ea1SDimitry Andric bool isPrivateLinkage() { return PrivateLinkage; } 183*0fca6ea1SDimitry Andric 184*0fca6ea1SDimitry Andric void print(raw_ostream &O) const override; 185*0fca6ea1SDimitry Andric 186*0fca6ea1SDimitry Andric static bool classof(const XtensaConstantPoolValue *ACPV) { 187*0fca6ea1SDimitry Andric return ACPV->isExtSymbol(); 188*0fca6ea1SDimitry Andric } 189*0fca6ea1SDimitry Andric 190*0fca6ea1SDimitry Andric bool equals(const XtensaConstantPoolSymbol *A) const { 191*0fca6ea1SDimitry Andric return S == A->S && XtensaConstantPoolValue::equals(A); 192*0fca6ea1SDimitry Andric } 193*0fca6ea1SDimitry Andric }; 194*0fca6ea1SDimitry Andric 195*0fca6ea1SDimitry Andric /// XtensaConstantPoolMBB - Xtensa-specific constantpool value of a machine 196*0fca6ea1SDimitry Andric /// basic block. 197*0fca6ea1SDimitry Andric class XtensaConstantPoolMBB : public XtensaConstantPoolValue { 198*0fca6ea1SDimitry Andric const MachineBasicBlock *MBB; // Machine basic block. 199*0fca6ea1SDimitry Andric 200*0fca6ea1SDimitry Andric XtensaConstantPoolMBB(LLVMContext &C, const MachineBasicBlock *M, 201*0fca6ea1SDimitry Andric unsigned ID); 202*0fca6ea1SDimitry Andric 203*0fca6ea1SDimitry Andric public: 204*0fca6ea1SDimitry Andric static XtensaConstantPoolMBB *Create(LLVMContext &C, 205*0fca6ea1SDimitry Andric const MachineBasicBlock *M, unsigned ID); 206*0fca6ea1SDimitry Andric 207*0fca6ea1SDimitry Andric const MachineBasicBlock *getMBB() const { return MBB; } 208*0fca6ea1SDimitry Andric 209*0fca6ea1SDimitry Andric int getExistingMachineCPValue(MachineConstantPool *CP, 210*0fca6ea1SDimitry Andric Align Alignment) override; 211*0fca6ea1SDimitry Andric 212*0fca6ea1SDimitry Andric void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 213*0fca6ea1SDimitry Andric 214*0fca6ea1SDimitry Andric /// hasSameValue - Return true if this Xtensa constpool value can share the 215*0fca6ea1SDimitry Andric /// same constantpool entry as another Xtensa constpool value. 216*0fca6ea1SDimitry Andric bool hasSameValue(XtensaConstantPoolValue *ACPV) override; 217*0fca6ea1SDimitry Andric 218*0fca6ea1SDimitry Andric void print(raw_ostream &O) const override; 219*0fca6ea1SDimitry Andric 220*0fca6ea1SDimitry Andric static bool classof(const XtensaConstantPoolValue *ACPV) { 221*0fca6ea1SDimitry Andric return ACPV->isMachineBasicBlock(); 222*0fca6ea1SDimitry Andric } 223*0fca6ea1SDimitry Andric 224*0fca6ea1SDimitry Andric bool equals(const XtensaConstantPoolMBB *A) const { 225*0fca6ea1SDimitry Andric return MBB == A->MBB && XtensaConstantPoolValue::equals(A); 226*0fca6ea1SDimitry Andric } 227*0fca6ea1SDimitry Andric }; 228*0fca6ea1SDimitry Andric 229*0fca6ea1SDimitry Andric /// XtensaConstantPoolJumpTable - Xtensa-specific constantpool values for Jump 230*0fca6ea1SDimitry Andric /// Table symbols. 231*0fca6ea1SDimitry Andric class XtensaConstantPoolJumpTable : public XtensaConstantPoolValue { 232*0fca6ea1SDimitry Andric unsigned Idx; // Jump Table Index. 233*0fca6ea1SDimitry Andric 234*0fca6ea1SDimitry Andric XtensaConstantPoolJumpTable(LLVMContext &C, unsigned Idx); 235*0fca6ea1SDimitry Andric 236*0fca6ea1SDimitry Andric public: 237*0fca6ea1SDimitry Andric static XtensaConstantPoolJumpTable *Create(LLVMContext &C, unsigned Idx); 238*0fca6ea1SDimitry Andric 239*0fca6ea1SDimitry Andric unsigned getIndex() const { return Idx; } 240*0fca6ea1SDimitry Andric 241*0fca6ea1SDimitry Andric int getExistingMachineCPValue(MachineConstantPool *CP, 242*0fca6ea1SDimitry Andric Align Alignment) override; 243*0fca6ea1SDimitry Andric 244*0fca6ea1SDimitry Andric void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 245*0fca6ea1SDimitry Andric 246*0fca6ea1SDimitry Andric /// hasSameValue - Return true if this Xtensa constpool value can share the 247*0fca6ea1SDimitry Andric /// same constantpool entry as another Xtensa constpool value. 248*0fca6ea1SDimitry Andric bool hasSameValue(XtensaConstantPoolValue *ACPV) override; 249*0fca6ea1SDimitry Andric 250*0fca6ea1SDimitry Andric void print(raw_ostream &O) const override; 251*0fca6ea1SDimitry Andric 252*0fca6ea1SDimitry Andric static bool classof(const XtensaConstantPoolValue *ACPV) { 253*0fca6ea1SDimitry Andric return ACPV->isJumpTable(); 254*0fca6ea1SDimitry Andric } 255*0fca6ea1SDimitry Andric 256*0fca6ea1SDimitry Andric bool equals(const XtensaConstantPoolJumpTable *A) const { 257*0fca6ea1SDimitry Andric return Idx == A->Idx && XtensaConstantPoolValue::equals(A); 258*0fca6ea1SDimitry Andric } 259*0fca6ea1SDimitry Andric }; 260*0fca6ea1SDimitry Andric 261*0fca6ea1SDimitry Andric } // namespace llvm 262*0fca6ea1SDimitry Andric 263*0fca6ea1SDimitry Andric #endif /* LLVM_LIB_TARGET_XTENSA_XTENSACONSTANTPOOLVALUE_H */ 264