Changes from Nick Lewycky with a simplified PPCTargetAsmInfo.
[oota-llvm.git] / include / llvm / Target / TargetLowering.h
index 01f63c8a4bc5529a8d1e2ff0b113554beeb59c42..f3f4eda3b6a73446b9d1bc569634b2b7ad8eb661 100644 (file)
@@ -25,7 +25,6 @@
 #include "llvm/Type.h"
 #include "llvm/CodeGen/SelectionDAGNodes.h"
 #include <map>
-#include <list>
 
 namespace llvm {
   class Value;
@@ -86,6 +85,10 @@ public:
   MVT::ValueType getShiftAmountTy() const { return ShiftAmountTy; }
   OutOfRangeShiftAmount getShiftAmountFlavor() const {return ShiftAmtHandling; }
 
+  /// usesGlobalOffsetTable - Return true if this target uses a GOT for PIC
+  /// codegen.
+  bool usesGlobalOffsetTable() const { return UsesGlobalOffsetTable; }
+  
   /// isSetCCExpensive - Return true if the setcc operation is expensive for
   /// this target.
   bool isSetCCExpensive() const { return SetCCIsExpensive; }
@@ -165,15 +168,36 @@ public:
 
   /// getTypeToTransformTo - For types supported by the target, this is an
   /// identity function.  For types that must be promoted to larger types, this
-  /// returns the larger type to promote to.  For types that are larger than the
-  /// largest integer register, this contains one step in the expansion to get
-  /// to the smaller register.
+  /// returns the larger type to promote to.  For integer types that are larger
+  /// than the largest integer register, this contains one step in the expansion
+  /// to get to the smaller register. For illegal floating point types, this
+  /// returns the integer type to transform to.
   MVT::ValueType getTypeToTransformTo(MVT::ValueType VT) const {
     return TransformToType[VT];
   }
   
+  /// getTypeToExpandTo - For types supported by the target, this is an
+  /// identity function.  For types that must be expanded (i.e. integer types
+  /// that are larger than the largest integer register or illegal floating
+  /// point types), this returns the largest legal type it will be expanded to.
+  MVT::ValueType getTypeToExpandTo(MVT::ValueType VT) const {
+    while (true) {
+      switch (getTypeAction(VT)) {
+      case Legal:
+        return VT;
+      case Expand:
+        VT = TransformToType[VT];
+        break;
+      default:
+        assert(false && "Type is not legal nor is it to be expanded!");
+        return VT;
+      }
+    }
+    return VT;
+  }
+
   /// getPackedTypeBreakdown - Packed types are broken down into some number of
-  /// legal first class types.  For example, <8 x float> maps to 2 MVT::v2f32
+  /// legal first class types.  For example, <8 x float> maps to 2 MVT::v4f32
   /// with Altivec or SSE1, or 8 promoted MVT::f64 values with the X86 FP stack.
   /// Similarly, <2 x long> turns into 4 MVT::i32 values with both PPC and X86.
   ///
@@ -226,6 +250,67 @@ public:
            getOperationAction(Op, VT) == Custom;
   }
   
+  /// getLoadXAction - Return how this load with extension should be treated:
+  /// either it is legal, needs to be promoted to a larger size, needs to be
+  /// expanded to some other code sequence, or the target has a custom expander
+  /// for it.
+  LegalizeAction getLoadXAction(unsigned LType, MVT::ValueType VT) const {
+    return (LegalizeAction)((LoadXActions[LType] >> (2*VT)) & 3);
+  }
+  
+  /// isLoadXLegal - Return true if the specified load with extension is legal
+  /// on this target.
+  bool isLoadXLegal(unsigned LType, MVT::ValueType VT) const {
+    return getLoadXAction(LType, VT) == Legal ||
+           getLoadXAction(LType, VT) == Custom;
+  }
+  
+  /// getStoreXAction - Return how this store with truncation should be treated:
+  /// either it is legal, needs to be promoted to a larger size, needs to be
+  /// expanded to some other code sequence, or the target has a custom expander
+  /// for it.
+  LegalizeAction getStoreXAction(MVT::ValueType VT) const {
+    return (LegalizeAction)((StoreXActions >> (2*VT)) & 3);
+  }
+  
+  /// isStoreXLegal - Return true if the specified store with truncation is
+  /// legal on this target.
+  bool isStoreXLegal(MVT::ValueType VT) const {
+    return getStoreXAction(VT) == Legal || getStoreXAction(VT) == Custom;
+  }
+
+  /// getIndexedLoadAction - Return how the indexed load should be treated:
+  /// either it is legal, needs to be promoted to a larger size, needs to be
+  /// expanded to some other code sequence, or the target has a custom expander
+  /// for it.
+  LegalizeAction
+  getIndexedLoadAction(unsigned IdxMode, MVT::ValueType VT) const {
+    return (LegalizeAction)((IndexedModeActions[0][IdxMode] >> (2*VT)) & 3);
+  }
+
+  /// isIndexedLoadLegal - Return true if the specified indexed load is legal
+  /// on this target.
+  bool isIndexedLoadLegal(unsigned IdxMode, MVT::ValueType VT) const {
+    return getIndexedLoadAction(IdxMode, VT) == Legal ||
+           getIndexedLoadAction(IdxMode, VT) == Custom;
+  }
+  
+  /// getIndexedStoreAction - Return how the indexed store should be treated:
+  /// either it is legal, needs to be promoted to a larger size, needs to be
+  /// expanded to some other code sequence, or the target has a custom expander
+  /// for it.
+  LegalizeAction
+  getIndexedStoreAction(unsigned IdxMode, MVT::ValueType VT) const {
+    return (LegalizeAction)((IndexedModeActions[1][IdxMode] >> (2*VT)) & 3);
+  }  
+  
+  /// isIndexedStoreLegal - Return true if the specified indexed load is legal
+  /// on this target.
+  bool isIndexedStoreLegal(unsigned IdxMode, MVT::ValueType VT) const {
+    return getIndexedStoreAction(IdxMode, VT) == Legal ||
+           getIndexedStoreAction(IdxMode, VT) == Custom;
+  }
+  
   /// getTypeToPromoteTo - If the action for this operation is to promote, this
   /// method returns the ValueType to promote to.
   MVT::ValueType getTypeToPromoteTo(unsigned Op, MVT::ValueType VT) const {
@@ -274,9 +359,9 @@ public:
   }
 
   /// getNumElements - Return the number of registers that this ValueType will
-  /// eventually require.  This is always one for all non-integer types, is
-  /// one for any types promoted to live in larger registers, but may be more
-  /// than one for types (like i64) that are split into pieces.
+  /// eventually require.  This is one for any types promoted to live in larger
+  /// registers, but may be more than one for types (like i64) that are split
+  /// into pieces.
   unsigned getNumElements(MVT::ValueType VT) const {
     return NumElementsForVT[VT];
   }
@@ -315,12 +400,18 @@ public:
     return allowUnalignedMemoryAccesses;
   }
   
-  /// usesUnderscoreSetJmpLongJmp - Determine if we should use _setjmp or setjmp
+  /// usesUnderscoreSetJmp - Determine if we should use _setjmp or setjmp
   /// to implement llvm.setjmp.
-  bool usesUnderscoreSetJmpLongJmp() const {
-    return UseUnderscoreSetJmpLongJmp;
+  bool usesUnderscoreSetJmp() const {
+    return UseUnderscoreSetJmp;
   }
-  
+
+  /// usesUnderscoreLongJmp - Determine if we should use _longjmp or longjmp
+  /// to implement llvm.longjmp.
+  bool usesUnderscoreLongJmp() const {
+    return UseUnderscoreLongJmp;
+  }
+
   /// getStackPointerRegisterToSaveRestore - If a physical register, this
   /// specifies the register that llvm.savestack/llvm.restorestack should save
   /// and restore.
@@ -328,6 +419,38 @@ public:
     return StackPointerRegisterToSaveRestore;
   }
 
+  /// getJumpBufSize - returns the target's jmp_buf size in bytes (if never
+  /// set, the default is 200)
+  unsigned getJumpBufSize() const {
+    return JumpBufSize;
+  }
+
+  /// getJumpBufAlignment - returns the target's jmp_buf alignment in bytes
+  /// (if never set, the default is 0)
+  unsigned getJumpBufAlignment() const {
+    return JumpBufAlignment;
+  }
+
+  /// getPreIndexedAddressParts - returns true by value, base pointer and
+  /// offset pointer and addressing mode by reference if the node's address
+  /// can be legally represented as pre-indexed load / store address.
+  virtual bool getPreIndexedAddressParts(SDNode *N, SDOperand &Base,
+                                         SDOperand &Offset,
+                                         ISD::MemIndexedMode &AM,
+                                         SelectionDAG &DAG) {
+    return false;
+  }
+  
+  /// getPostIndexedAddressParts - returns true by value, base pointer and
+  /// offset pointer and addressing mode by reference if this node can be
+  /// combined with a load / store to form a post-indexed load / store.
+  virtual bool getPostIndexedAddressParts(SDNode *N, SDNode *Op,
+                                          SDOperand &Base, SDOperand &Offset,
+                                          ISD::MemIndexedMode &AM,
+                                          SelectionDAG &DAG) {
+    return false;
+  }
+  
   //===--------------------------------------------------------------------===//
   // TargetLowering Optimization Methods
   //
@@ -441,6 +564,9 @@ public:
   //
 
 protected:
+  /// setUsesGlobalOffsetTable - Specify that this target does or doesn't use a
+  /// GOT for PC-relative code.
+  void setUsesGlobalOffsetTable(bool V) { UsesGlobalOffsetTable = V; }
 
   /// setShiftAmountType - Describe the type that should be used for shift
   /// amounts.  This type defaults to the pointer type.
@@ -465,13 +591,20 @@ protected:
     ShiftAmtHandling = OORSA;
   }
 
-  /// setUseUnderscoreSetJmpLongJmp - Indicate whether this target prefers to
-  /// use _setjmp and _longjmp to or implement llvm.setjmp/llvm.longjmp or
-  /// the non _ versions.  Defaults to false.
-  void setUseUnderscoreSetJmpLongJmp(bool Val) {
-    UseUnderscoreSetJmpLongJmp = Val;
+  /// setUseUnderscoreSetJmp - Indicate whether this target prefers to
+  /// use _setjmp to implement llvm.setjmp or the non _ version.
+  /// Defaults to false.
+  void setUseUnderscoreSetJmp(bool Val) {
+    UseUnderscoreSetJmp = Val;
   }
-  
+
+  /// setUseUnderscoreLongJmp - Indicate whether this target prefers to
+  /// use _longjmp to implement llvm.longjmp or the non _ version.
+  /// Defaults to false.
+  void setUseUnderscoreLongJmp(bool Val) {
+    UseUnderscoreLongJmp = Val;
+  }
+
   /// setStackPointerRegisterToSaveRestore - If set to a physical register, this
   /// specifies the register that llvm.savestack/llvm.restorestack should save
   /// and restore.
@@ -512,10 +645,54 @@ protected:
                           LegalizeAction Action) {
     assert(VT < 32 && Op < sizeof(OpActions)/sizeof(OpActions[0]) &&
            "Table isn't big enough!");
-    OpActions[Op] &= ~(3ULL << VT*2);
+    OpActions[Op] &= ~(uint64_t(3UL) << VT*2);
     OpActions[Op] |= (uint64_t)Action << VT*2;
   }
   
+  /// setLoadXAction - Indicate that the specified load with extension does not
+  /// work with the with specified type and indicate what to do about it.
+  void setLoadXAction(unsigned ExtType, MVT::ValueType VT,
+                      LegalizeAction Action) {
+    assert(VT < 32 && ExtType < sizeof(LoadXActions)/sizeof(LoadXActions[0]) &&
+           "Table isn't big enough!");
+    LoadXActions[ExtType] &= ~(uint64_t(3UL) << VT*2);
+    LoadXActions[ExtType] |= (uint64_t)Action << VT*2;
+  }
+  
+  /// setStoreXAction - Indicate that the specified store with truncation does
+  /// not work with the with specified type and indicate what to do about it.
+  void setStoreXAction(MVT::ValueType VT, LegalizeAction Action) {
+    assert(VT < 32 && "Table isn't big enough!");
+    StoreXActions &= ~(uint64_t(3UL) << VT*2);
+    StoreXActions |= (uint64_t)Action << VT*2;
+  }
+
+  /// setIndexedLoadAction - Indicate that the specified indexed load does or
+  /// does not work with the with specified type and indicate what to do abort
+  /// it. NOTE: All indexed mode loads are initialized to Expand in
+  /// TargetLowering.cpp
+  void setIndexedLoadAction(unsigned IdxMode, MVT::ValueType VT,
+                            LegalizeAction Action) {
+    assert(VT < 32 && IdxMode <
+           sizeof(IndexedModeActions[0]) / sizeof(IndexedModeActions[0][0]) &&
+           "Table isn't big enough!");
+    IndexedModeActions[0][IdxMode] &= ~(uint64_t(3UL) << VT*2);
+    IndexedModeActions[0][IdxMode] |= (uint64_t)Action << VT*2;
+  }
+  
+  /// setIndexedStoreAction - Indicate that the specified indexed store does or
+  /// does not work with the with specified type and indicate what to do about
+  /// it. NOTE: All indexed mode stores are initialized to Expand in
+  /// TargetLowering.cpp
+  void setIndexedStoreAction(unsigned IdxMode, MVT::ValueType VT,
+                             LegalizeAction Action) {
+    assert(VT < 32 && IdxMode <
+           sizeof(IndexedModeActions[1]) / sizeof(IndexedModeActions[1][0]) &&
+           "Table isn't big enough!");
+    IndexedModeActions[1][IdxMode] &= ~(uint64_t(3UL) << VT*2);
+    IndexedModeActions[1][IdxMode] |= (uint64_t)Action << VT*2;
+  }
+  
   /// AddPromotedToType - If Opc/OrigVT is specified as being promoted, the
   /// promotion code defaults to trying a larger integer/fp until it can find
   /// one that works.  If that default is insufficient, this method can be used
@@ -538,6 +715,18 @@ protected:
     TargetDAGCombineArray[NT >> 3] |= 1 << (NT&7);
   }
   
+  /// setJumpBufSize - Set the target's required jmp_buf buffer size (in
+  /// bytes); default is 200
+  void setJumpBufSize(unsigned Size) {
+    JumpBufSize = Size;
+  }
+
+  /// setJumpBufAlignment - Set the target's required jmp_buf buffer
+  /// alignment (in bytes); default is 0
+  void setJumpBufAlignment(unsigned Align) {
+    JumpBufAlignment = Align;
+  }
+  
 public:
 
   //===--------------------------------------------------------------------===//
@@ -610,16 +799,25 @@ public:
 
   /// getRegForInlineAsmConstraint - Given a physical register constraint (e.g.
   /// {edx}), return the register number and the register class for the
-  /// register.  This should only be used for C_Register constraints.  On error,
-  /// this returns a register number of 0.
+  /// register.
+  ///
+  /// Given a register class constraint, like 'r', if this corresponds directly
+  /// to an LLVM register class, return a register of 0 and the register class
+  /// pointer.
+  ///
+  /// This should only be used for C_Register constraints.  On error,
+  /// this returns a register number of 0 and a null register class pointer..
   virtual std::pair<unsigned, const TargetRegisterClass*> 
     getRegForInlineAsmConstraint(const std::string &Constraint,
                                  MVT::ValueType VT) const;
   
   
-  /// isOperandValidForConstraint - Return true if the specified SDOperand is
-  /// valid for the specified target constraint letter.
-  virtual bool isOperandValidForConstraint(SDOperand Op, char ConstraintLetter);
+  /// isOperandValidForConstraint - Return the specified operand (possibly
+  /// modified) if the specified SDOperand is valid for the specified target
+  /// constraint letter, otherwise return null.
+  virtual SDOperand 
+    isOperandValidForConstraint(SDOperand Op, char ConstraintLetter,
+                                SelectionDAG &DAG);
   
   //===--------------------------------------------------------------------===//
   // Scheduler hooks
@@ -654,9 +852,9 @@ public:
   // Div utility functions
   //
   SDOperand BuildSDIV(SDNode *N, SelectionDAG &DAG, 
-                     std::list<SDNode*>* Created) const;
+                     std::vector<SDNode*>* Created) const;
   SDOperand BuildUDIV(SDNode *N, SelectionDAG &DAG, 
-                     std::list<SDNode*>* Created) const;
+                     std::vector<SDNode*>* Created) const;
 
 
 protected:
@@ -681,6 +879,10 @@ private:
   ///
   MVT::ValueType PointerTy;
 
+  /// UsesGlobalOffsetTable - True if this target uses a GOT for PIC codegen.
+  ///
+  bool UsesGlobalOffsetTable;
+  
   /// ShiftAmountTy - The type to use for shift amounts, usually i8 or whatever
   /// PointerTy is.
   MVT::ValueType ShiftAmountTy;
@@ -715,9 +917,20 @@ private:
   /// total cycles or lowest register usage.
   SchedPreference SchedPreferenceInfo;
   
-  /// UseUnderscoreSetJmpLongJmp - This target prefers to use _setjmp and
-  /// _longjmp to implement llvm.setjmp/llvm.longjmp.  Defaults to false.
-  bool UseUnderscoreSetJmpLongJmp;
+  /// UseUnderscoreSetJmp - This target prefers to use _setjmp to implement
+  /// llvm.setjmp.  Defaults to false.
+  bool UseUnderscoreSetJmp;
+
+  /// UseUnderscoreLongJmp - This target prefers to use _longjmp to implement
+  /// llvm.longjmp.  Defaults to false.
+  bool UseUnderscoreLongJmp;
+
+  /// JumpBufSize - The size, in bytes, of the target's jmp_buf buffers
+  unsigned JumpBufSize;
+  
+  /// JumpBufAlignment - The alignment, in bytes, of the target's jmp_buf
+  /// buffers
+  unsigned JumpBufAlignment;
   
   /// StackPointerRegisterToSaveRestore - If set to a physical register, this
   /// specifies the register that llvm.savestack/llvm.restorestack should save
@@ -743,6 +956,21 @@ private:
   /// non-legal value types are not described here.
   uint64_t OpActions[156];
   
+  /// LoadXActions - For each load of load extension type and each value type,
+  /// keep a LegalizeAction that indicates how instruction selection should deal
+  /// with the load.
+  uint64_t LoadXActions[ISD::LAST_LOADX_TYPE];
+  
+  /// StoreXActions - For each store with truncation of each value type, keep a
+  /// LegalizeAction that indicates how instruction selection should deal with
+  /// the store.
+  uint64_t StoreXActions;
+
+  /// IndexedModeActions - For each indexed mode and each value type, keep a
+  /// pair of LegalizeAction that indicates how instruction selection should
+  /// deal with the load / store.
+  uint64_t IndexedModeActions[2][ISD::LAST_INDEXED_MODE];
+  
   ValueTypeActionImpl ValueTypeActions;
 
   std::vector<double> LegalFPImmediates;