Home | History | Annotate | Download | only in ARM
      1 //===-- ARMConstantPoolValue.h - ARM constantpool value ---------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file implements the ARM specific constantpool value class.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_TARGET_ARM_CONSTANTPOOLVALUE_H
     15 #define LLVM_TARGET_ARM_CONSTANTPOOLVALUE_H
     16 
     17 #include "llvm/CodeGen/MachineConstantPool.h"
     18 #include "llvm/Support/ErrorHandling.h"
     19 #include <cstddef>
     20 
     21 namespace llvm {
     22 
     23 class BlockAddress;
     24 class Constant;
     25 class GlobalValue;
     26 class LLVMContext;
     27 class MachineBasicBlock;
     28 
     29 namespace ARMCP {
     30   enum ARMCPKind {
     31     CPValue,
     32     CPExtSymbol,
     33     CPBlockAddress,
     34     CPLSDA,
     35     CPMachineBasicBlock
     36   };
     37 
     38   enum ARMCPModifier {
     39     no_modifier,
     40     TLSGD,
     41     GOT,
     42     GOTOFF,
     43     GOTTPOFF,
     44     TPOFF
     45   };
     46 }
     47 
     48 /// ARMConstantPoolValue - ARM specific constantpool value. This is used to
     49 /// represent PC-relative displacement between the address of the load
     50 /// instruction and the constant being loaded, i.e. (&GV-(LPIC+8)).
     51 class ARMConstantPoolValue : public MachineConstantPoolValue {
     52   unsigned LabelId;        // Label id of the load.
     53   ARMCP::ARMCPKind Kind;   // Kind of constant.
     54   unsigned char PCAdjust;  // Extra adjustment if constantpool is pc-relative.
     55                            // 8 for ARM, 4 for Thumb.
     56   ARMCP::ARMCPModifier Modifier;   // GV modifier i.e. (&GV(modifier)-(LPIC+8))
     57   bool AddCurrentAddress;
     58 
     59 protected:
     60   ARMConstantPoolValue(Type *Ty, unsigned id, ARMCP::ARMCPKind Kind,
     61                        unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
     62                        bool AddCurrentAddress);
     63 
     64   ARMConstantPoolValue(LLVMContext &C, unsigned id, ARMCP::ARMCPKind Kind,
     65                        unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
     66                        bool AddCurrentAddress);
     67 public:
     68   virtual ~ARMConstantPoolValue();
     69 
     70   ARMCP::ARMCPModifier getModifier() const { return Modifier; }
     71   const char *getModifierText() const;
     72   bool hasModifier() const { return Modifier != ARMCP::no_modifier; }
     73 
     74   bool mustAddCurrentAddress() const { return AddCurrentAddress; }
     75 
     76   unsigned getLabelId() const { return LabelId; }
     77   unsigned char getPCAdjustment() const { return PCAdjust; }
     78 
     79   bool isGlobalValue() const { return Kind == ARMCP::CPValue; }
     80   bool isExtSymbol() const { return Kind == ARMCP::CPExtSymbol; }
     81   bool isBlockAddress() const { return Kind == ARMCP::CPBlockAddress; }
     82   bool isLSDA() const { return Kind == ARMCP::CPLSDA; }
     83   bool isMachineBasicBlock() const{ return Kind == ARMCP::CPMachineBasicBlock; }
     84 
     85   virtual unsigned getRelocationInfo() const { return 2; }
     86 
     87   virtual int getExistingMachineCPValue(MachineConstantPool *CP,
     88                                         unsigned Alignment);
     89 
     90   virtual void addSelectionDAGCSEId(FoldingSetNodeID &ID);
     91 
     92   /// hasSameValue - Return true if this ARM constpool value can share the same
     93   /// constantpool entry as another ARM constpool value.
     94   virtual bool hasSameValue(ARMConstantPoolValue *ACPV);
     95 
     96   bool equals(const ARMConstantPoolValue *A) const {
     97     return this->LabelId == A->LabelId &&
     98       this->PCAdjust == A->PCAdjust &&
     99       this->Modifier == A->Modifier;
    100   }
    101 
    102   virtual void print(raw_ostream &O) const;
    103   void print(raw_ostream *O) const { if (O) print(*O); }
    104   void dump() const;
    105 };
    106 
    107 inline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) {
    108   V.print(O);
    109   return O;
    110 }
    111 
    112 /// ARMConstantPoolConstant - ARM-specific constant pool values for Constants,
    113 /// Functions, and BlockAddresses.
    114 class ARMConstantPoolConstant : public ARMConstantPoolValue {
    115   const Constant *CVal;         // Constant being loaded.
    116 
    117   ARMConstantPoolConstant(const Constant *C,
    118                           unsigned ID,
    119                           ARMCP::ARMCPKind Kind,
    120                           unsigned char PCAdj,
    121                           ARMCP::ARMCPModifier Modifier,
    122                           bool AddCurrentAddress);
    123   ARMConstantPoolConstant(Type *Ty, const Constant *C,
    124                           unsigned ID,
    125                           ARMCP::ARMCPKind Kind,
    126                           unsigned char PCAdj,
    127                           ARMCP::ARMCPModifier Modifier,
    128                           bool AddCurrentAddress);
    129 
    130 public:
    131   static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID);
    132   static ARMConstantPoolConstant *Create(const GlobalValue *GV,
    133                                          ARMCP::ARMCPModifier Modifier);
    134   static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,
    135                                          ARMCP::ARMCPKind Kind,
    136                                          unsigned char PCAdj);
    137   static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,
    138                                          ARMCP::ARMCPKind Kind,
    139                                          unsigned char PCAdj,
    140                                          ARMCP::ARMCPModifier Modifier,
    141                                          bool AddCurrentAddress);
    142 
    143   const GlobalValue *getGV() const;
    144   const BlockAddress *getBlockAddress() const;
    145 
    146   virtual int getExistingMachineCPValue(MachineConstantPool *CP,
    147                                         unsigned Alignment);
    148 
    149   /// hasSameValue - Return true if this ARM constpool value can share the same
    150   /// constantpool entry as another ARM constpool value.
    151   virtual bool hasSameValue(ARMConstantPoolValue *ACPV);
    152 
    153   virtual void addSelectionDAGCSEId(FoldingSetNodeID &ID);
    154 
    155   virtual void print(raw_ostream &O) const;
    156   static bool classof(const ARMConstantPoolValue *APV) {
    157     return APV->isGlobalValue() || APV->isBlockAddress() || APV->isLSDA();
    158   }
    159 };
    160 
    161 /// ARMConstantPoolSymbol - ARM-specific constantpool values for external
    162 /// symbols.
    163 class ARMConstantPoolSymbol : public ARMConstantPoolValue {
    164   const std::string S;          // ExtSymbol being loaded.
    165 
    166   ARMConstantPoolSymbol(LLVMContext &C, const char *s, unsigned id,
    167                         unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
    168                         bool AddCurrentAddress);
    169 
    170 public:
    171   static ARMConstantPoolSymbol *Create(LLVMContext &C, const char *s,
    172                                        unsigned ID, unsigned char PCAdj);
    173 
    174   const char *getSymbol() const { return S.c_str(); }
    175 
    176   virtual int getExistingMachineCPValue(MachineConstantPool *CP,
    177                                         unsigned Alignment);
    178 
    179   virtual void addSelectionDAGCSEId(FoldingSetNodeID &ID);
    180 
    181   /// hasSameValue - Return true if this ARM constpool value can share the same
    182   /// constantpool entry as another ARM constpool value.
    183   virtual bool hasSameValue(ARMConstantPoolValue *ACPV);
    184 
    185   virtual void print(raw_ostream &O) const;
    186 
    187   static bool classof(const ARMConstantPoolValue *ACPV) {
    188     return ACPV->isExtSymbol();
    189   }
    190 };
    191 
    192 /// ARMConstantPoolMBB - ARM-specific constantpool value of a machine basic
    193 /// block.
    194 class ARMConstantPoolMBB : public ARMConstantPoolValue {
    195   const MachineBasicBlock *MBB; // Machine basic block.
    196 
    197   ARMConstantPoolMBB(LLVMContext &C, const MachineBasicBlock *mbb, unsigned id,
    198                      unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
    199                      bool AddCurrentAddress);
    200 
    201 public:
    202   static ARMConstantPoolMBB *Create(LLVMContext &C,
    203                                     const MachineBasicBlock *mbb,
    204                                     unsigned ID, unsigned char PCAdj);
    205 
    206   const MachineBasicBlock *getMBB() const { return MBB; }
    207 
    208   virtual int getExistingMachineCPValue(MachineConstantPool *CP,
    209                                         unsigned Alignment);
    210 
    211   virtual void addSelectionDAGCSEId(FoldingSetNodeID &ID);
    212 
    213   /// hasSameValue - Return true if this ARM constpool value can share the same
    214   /// constantpool entry as another ARM constpool value.
    215   virtual bool hasSameValue(ARMConstantPoolValue *ACPV);
    216 
    217   virtual void print(raw_ostream &O) const;
    218 
    219   static bool classof(const ARMConstantPoolValue *ACPV) {
    220     return ACPV->isMachineBasicBlock();
    221   }
    222 };
    223 
    224 } // End llvm namespace
    225 
    226 #endif
    227