Reorder some fields in SDNode. This avoids padding,
[oota-llvm.git] / include / llvm / CodeGen / SelectionDAGNodes.h
index a1c1ec9f159249144cad46688749e8ef07d11ce7..1c3a50de1478a131482f5d1f6e2d89f436762197 100644 (file)
@@ -22,7 +22,7 @@
 #include "llvm/Value.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/iterator"
+#include "llvm/ADT/iterator.h"
 #include "llvm/ADT/APFloat.h"
 #include "llvm/ADT/APInt.h"
 #include "llvm/CodeGen/ValueTypes.h"
@@ -48,7 +48,7 @@ template<typename NodeTy> class ilist_iterator;
 /// SelectionDAG::getVTList(...).
 ///
 struct SDVTList {
-  const MVT::ValueType *VTs;
+  const MVT *VTs;
   unsigned short NumVTs;
 };
 
@@ -332,6 +332,14 @@ namespace ISD {
     // (op #2) as a CondCodeSDNode.
     SETCC,
 
+    // Vector SetCC operator - This evaluates to a vector of integer elements
+    // with the high bit in each element set to true if the comparison is true
+    // and false if the comparison is false.  All other bits in each element 
+    // are undefined.  The operands to this are the left and right operands
+    // to compare (ops #0, and #1) and the condition code to compare them with
+    // (op #2) as a CondCodeSDNode.
+    VSETCC,
+
     // SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded
     // integer shift operations, just like ADD/SUB_PARTS.  The operation
     // ordering is:
@@ -594,6 +602,25 @@ namespace ISD {
     // the return is always the original value in *ptr
     ATOMIC_SWAP,
 
+    // Val, OUTCHAIN = ATOMIC_LSS(INCHAIN, ptr, amt)
+    // this corresponds to the atomic.lss intrinsic.
+    // *ptr - amt is stored to *ptr atomically.
+    // the return is always the original value in *ptr
+    ATOMIC_LSS,
+    
+    // Val, OUTCHAIN = ATOMIC_L[OpName]S(INCHAIN, ptr, amt)
+    // this corresponds to the atomic.[OpName] intrinsic.
+    // op(*ptr, amt) is stored to *ptr atomically.
+    // the return is always the original value in *ptr
+    ATOMIC_LOAD_AND,
+    ATOMIC_LOAD_OR,
+    ATOMIC_LOAD_XOR,
+    ATOMIC_LOAD_NAND,
+    ATOMIC_LOAD_MIN,
+    ATOMIC_LOAD_MAX,
+    ATOMIC_LOAD_UMIN,
+    ATOMIC_LOAD_UMAX,
+    
     // BUILTIN_OP_END - This must be the last enum value in this list.
     BUILTIN_OP_END
   };
@@ -808,12 +835,12 @@ public:
 
   /// getValueType - Return the ValueType of the referenced return value.
   ///
-  inline MVT::ValueType getValueType() const;
+  inline MVT getValueType() const;
 
-  /// getValueSizeInBits - Returns MVT::getSizeInBits(getValueType()).
+  /// getValueSizeInBits - Returns the size of the value in bits.
   ///
   unsigned getValueSizeInBits() const {
-    return MVT::getSizeInBits(getValueType());
+    return getValueType().getSizeInBits();
   }
 
   // Forwarding methods - These forward to the corresponding methods in SDNode.
@@ -968,20 +995,16 @@ class SDOperandPtr {
   const SDOperand *ptr; // The pointer to the SDOperand object
   int object_size;      // The size of the object containg the SDOperand
 public:
+  SDOperandPtr() : ptr(0), object_size(0) {}
+
   SDOperandPtr(SDUse * use_ptr) { 
     ptr = &use_ptr->getSDOperand(); 
-    object_size = sizeof(SDUse); 
+    object_size = (int)sizeof(SDUse); 
   }
 
   SDOperandPtr(const SDOperand * op_ptr) { 
     ptr = op_ptr; 
-    object_size = sizeof(SDOperand); 
-  }
-
-  operator const SDOperand *() const {
-    assert(object_size == sizeof(SDOperand) && 
-           "Only SDOperand can be converted");
-    return ptr;
+    object_size = (int)sizeof(SDOperand); 
   }
 
   const SDOperand operator *() { return *ptr; }
@@ -1023,22 +1046,22 @@ private:
   
   /// ValueList - The types of the values this node defines.  SDNode's may
   /// define multiple values simultaneously.
-  const MVT::ValueType *ValueList;
+  const MVT *ValueList;
 
   /// NumOperands/NumValues - The number of entries in the Operand/Value list.
   unsigned short NumOperands, NumValues;
   
-  /// Prev/Next pointers - These pointers form the linked list of of the
-  /// AllNodes list in the current DAG.
-  SDNode *Prev, *Next;
-  friend struct ilist_traits<SDNode>;
-
   /// UsesSize - The size of the uses list.
   unsigned UsesSize;
 
   /// Uses - List of uses for this SDNode.
   SDUse *Uses;
 
+  /// Prev/Next pointers - These pointers form the linked list of of the
+  /// AllNodes list in the current DAG.
+  SDNode *Prev, *Next;
+  friend struct ilist_traits<SDNode>;
+
   /// addUse - add SDUse to the list of uses.
   void addUse(SDUse &U) { U.addToList(&Uses); }
 
@@ -1111,7 +1134,7 @@ public:
     /// getOperandNum - Retrive a number of a current operand.
     unsigned getOperandNum() const {
       assert(Op && "Cannot dereference end iterator!");
-      return (Op - Op->getUser()->OperandList);
+      return (unsigned)(Op - Op->getUser()->OperandList);
     }
 
     /// Retrieve a reference to the current operand.
@@ -1194,7 +1217,7 @@ public:
 
   /// getValueType - Return the type of a specified result.
   ///
-  MVT::ValueType getValueType(unsigned ResNo) const {
+  MVT getValueType(unsigned ResNo) const {
     assert(ResNo < NumValues && "Illegal result number!");
     return ValueList[ResNo];
   }
@@ -1202,10 +1225,10 @@ public:
   /// getValueSizeInBits - Returns MVT::getSizeInBits(getValueType(ResNo)).
   ///
   unsigned getValueSizeInBits(unsigned ResNo) const {
-    return MVT::getSizeInBits(getValueType(ResNo));
+    return getValueType(ResNo).getSizeInBits();
   }
 
-  typedef const MVT::ValueType* value_iterator;
+  typedef const MVT* value_iterator;
   value_iterator value_begin() const { return ValueList; }
   value_iterator value_end() const { return ValueList+NumValues; }
 
@@ -1227,8 +1250,8 @@ protected:
   
   /// getValueTypeList - Return a pointer to the specified value type.
   ///
-  static const MVT::ValueType *getValueTypeList(MVT::ValueType VT);
-  static SDVTList getSDVTList(MVT::ValueType VT) {
+  static const MVT *getValueTypeList(MVT VT);
+  static SDVTList getSDVTList(MVT VT) {
     SDVTList Ret = { getValueTypeList(VT), 1 };
     return Ret;
   }
@@ -1300,7 +1323,7 @@ protected:
   /// opcode, types, and operands to the specified value.  This should only be
   /// used by the SelectionDAG class.
   void MorphNodeTo(unsigned Opc, SDVTList L,
-                   const SDOperand *Ops, unsigned NumOps);
+                   SDOperandPtr Ops, unsigned NumOps);
   
   void addUser(unsigned i, SDNode *User) {
     assert(User->OperandList[i].getUser() && "Node without parent");
@@ -1322,7 +1345,7 @@ protected:
 inline unsigned SDOperand::getOpcode() const {
   return Val->getOpcode();
 }
-inline MVT::ValueType SDOperand::getValueType() const {
+inline MVT SDOperand::getValueType() const {
   return Val->getValueType(ResNo);
 }
 inline unsigned SDOperand::getNumOperands() const {
@@ -1399,7 +1422,13 @@ class HandleSDNode : public SDNode {
   virtual void ANCHOR();  // Out-of-line virtual method to give class a home.
   SDUse Op;
 public:
+  // FIXME: Remove the "noinline" attribute once <rdar://problem/5852746> is
+  // fixed.
+#ifdef __GNUC__
+  explicit __attribute__((__noinline__)) HandleSDNode(SDOperand X)
+#else
   explicit HandleSDNode(SDOperand X)
+#endif
     : SDNode(ISD::HANDLENODE, getSDVTList(MVT::Other)) {
     Op = X;
     InitOperands(&Op, 1);
@@ -1411,10 +1440,10 @@ public:
 class AtomicSDNode : public SDNode {
   virtual void ANCHOR();  // Out-of-line virtual method to give class a home.
   SDUse Ops[4];
-  MVT::ValueType OrigVT;
+  MVT OrigVT;
 public:
   AtomicSDNode(unsigned Opc, SDVTList VTL, SDOperand Chain, SDOperand Ptr, 
-               SDOperand Cmp, SDOperand Swp, MVT::ValueType VT)
+               SDOperand Cmp, SDOperand Swp, MVT VT)
     : SDNode(Opc, VTL) {
     Ops[0] = Chain;
     Ops[1] = Ptr;
@@ -1424,7 +1453,7 @@ public:
     OrigVT=VT;
   }
   AtomicSDNode(unsigned Opc, SDVTList VTL, SDOperand Chain, SDOperand Ptr, 
-               SDOperand Val, MVT::ValueType VT)
+               SDOperand Val, MVT VT)
     : SDNode(Opc, VTL) {
     Ops[0] = Chain;
     Ops[1] = Ptr;
@@ -1432,7 +1461,7 @@ public:
     InitOperands(Ops, 3);
     OrigVT=VT;
   }
-  MVT::ValueType getVT() const { return OrigVT; }
+  MVT getVT() const { return OrigVT; }
   bool isCompareAndSwap() const { return getOpcode() == ISD::ATOMIC_LCS; }
 };
 
@@ -1457,7 +1486,7 @@ class ConstantSDNode : public SDNode {
   virtual void ANCHOR();  // Out-of-line virtual method to give class a home.
 protected:
   friend class SelectionDAG;
-  ConstantSDNode(bool isTarget, const APInt &val, MVT::ValueType VT)
+  ConstantSDNode(bool isTarget, const APInt &val, MVT VT)
     : SDNode(isTarget ? ISD::TargetConstant : ISD::Constant, getSDVTList(VT)),
       Value(val) {
   }
@@ -1467,13 +1496,13 @@ public:
   uint64_t getValue() const { return Value.getZExtValue(); }
 
   int64_t getSignExtended() const {
-    unsigned Bits = MVT::getSizeInBits(getValueType(0));
+    unsigned Bits = getValueType(0).getSizeInBits();
     return ((int64_t)Value.getZExtValue() << (64-Bits)) >> (64-Bits);
   }
 
   bool isNullValue() const { return Value == 0; }
   bool isAllOnesValue() const {
-    return Value == MVT::getIntVTBitMask(getValueType(0));
+    return Value == getValueType(0).getIntegerVTBitMask();
   }
 
   static bool classof(const ConstantSDNode *) { return true; }
@@ -1488,7 +1517,7 @@ class ConstantFPSDNode : public SDNode {
   virtual void ANCHOR();  // Out-of-line virtual method to give class a home.
 protected:
   friend class SelectionDAG;
-  ConstantFPSDNode(bool isTarget, const APFloat& val, MVT::ValueType VT)
+  ConstantFPSDNode(bool isTarget, const APFloat& val, MVT VT)
     : SDNode(isTarget ? ISD::TargetConstantFP : ISD::ConstantFP,
              getSDVTList(VT)), Value(val) {
   }
@@ -1504,14 +1533,17 @@ public:
   /// We leave the version with the double argument here because it's just so
   /// convenient to write "2.0" and the like.  Without this function we'd 
   /// have to duplicate its logic everywhere it's called.
-  bool isExactlyValue(double V) const { 
+  bool isExactlyValue(double V) const {
+    // convert is not supported on this type
+    if (&Value.getSemantics() == &APFloat::PPCDoubleDouble)
+      return false;
     APFloat Tmp(V);
     Tmp.convert(Value.getSemantics(), APFloat::rmNearestTiesToEven);
     return isExactlyValue(Tmp);
   }
   bool isExactlyValue(const APFloat& V) const;
 
-  bool isValueValidForType(MVT::ValueType VT, const APFloat& Val);
+  bool isValueValidForType(MVT VT, const APFloat& Val);
 
   static bool classof(const ConstantFPSDNode *) { return true; }
   static bool classof(const SDNode *N) {
@@ -1526,8 +1558,7 @@ class GlobalAddressSDNode : public SDNode {
   virtual void ANCHOR();  // Out-of-line virtual method to give class a home.
 protected:
   friend class SelectionDAG;
-  GlobalAddressSDNode(bool isTarget, const GlobalValue *GA, MVT::ValueType VT,
-                      int o = 0);
+  GlobalAddressSDNode(bool isTarget, const GlobalValue *GA, MVT VT, int o = 0);
 public:
 
   GlobalValue *getGlobal() const { return TheGlobal; }
@@ -1547,7 +1578,7 @@ class FrameIndexSDNode : public SDNode {
   virtual void ANCHOR();  // Out-of-line virtual method to give class a home.
 protected:
   friend class SelectionDAG;
-  FrameIndexSDNode(int fi, MVT::ValueType VT, bool isTarg)
+  FrameIndexSDNode(int fi, MVT VT, bool isTarg)
     : SDNode(isTarg ? ISD::TargetFrameIndex : ISD::FrameIndex, getSDVTList(VT)),
       FI(fi) {
   }
@@ -1567,7 +1598,7 @@ class JumpTableSDNode : public SDNode {
   virtual void ANCHOR();  // Out-of-line virtual method to give class a home.
 protected:
   friend class SelectionDAG;
-  JumpTableSDNode(int jti, MVT::ValueType VT, bool isTarg)
+  JumpTableSDNode(int jti, MVT VT, bool isTarg)
     : SDNode(isTarg ? ISD::TargetJumpTable : ISD::JumpTable, getSDVTList(VT)),
       JTI(jti) {
   }
@@ -1592,22 +1623,20 @@ class ConstantPoolSDNode : public SDNode {
   virtual void ANCHOR();  // Out-of-line virtual method to give class a home.
 protected:
   friend class SelectionDAG;
-  ConstantPoolSDNode(bool isTarget, Constant *c, MVT::ValueType VT,
-                     int o=0)
+  ConstantPoolSDNode(bool isTarget, Constant *c, MVT VT, int o=0)
     : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool,
              getSDVTList(VT)), Offset(o), Alignment(0) {
     assert((int)Offset >= 0 && "Offset is too large");
     Val.ConstVal = c;
   }
-  ConstantPoolSDNode(bool isTarget, Constant *c, MVT::ValueType VT, int o,
-                     unsigned Align)
+  ConstantPoolSDNode(bool isTarget, Constant *c, MVT VT, int o, unsigned Align)
     : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, 
              getSDVTList(VT)), Offset(o), Alignment(Align) {
     assert((int)Offset >= 0 && "Offset is too large");
     Val.ConstVal = c;
   }
   ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v,
-                     MVT::ValueType VT, int o=0)
+                     MVT VT, int o=0)
     : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, 
              getSDVTList(VT)), Offset(o), Alignment(0) {
     assert((int)Offset >= 0 && "Offset is too large");
@@ -1615,7 +1644,7 @@ protected:
     Offset |= 1 << (sizeof(unsigned)*8-1);
   }
   ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v,
-                     MVT::ValueType VT, int o, unsigned Align)
+                     MVT VT, int o, unsigned Align)
     : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool,
              getSDVTList(VT)), Offset(o), Alignment(Align) {
     assert((int)Offset >= 0 && "Offset is too large");
@@ -1729,7 +1758,7 @@ class RegisterSDNode : public SDNode {
   virtual void ANCHOR();  // Out-of-line virtual method to give class a home.
 protected:
   friend class SelectionDAG;
-  RegisterSDNode(unsigned reg, MVT::ValueType VT)
+  RegisterSDNode(unsigned reg, MVT VT)
     : SDNode(ISD::Register, getSDVTList(VT)), Reg(reg) {
   }
 public:
@@ -1747,7 +1776,7 @@ class ExternalSymbolSDNode : public SDNode {
   virtual void ANCHOR();  // Out-of-line virtual method to give class a home.
 protected:
   friend class SelectionDAG;
-  ExternalSymbolSDNode(bool isTarget, const char *Sym, MVT::ValueType VT)
+  ExternalSymbolSDNode(bool isTarget, const char *Sym, MVT VT)
     : SDNode(isTarget ? ISD::TargetExternalSymbol : ISD::ExternalSymbol,
              getSDVTList(VT)), Symbol(Sym) {
   }
@@ -1883,19 +1912,19 @@ public:
   }
 };
 
-/// VTSDNode - This class is used to represent MVT::ValueType's, which are used
+/// VTSDNode - This class is used to represent MVT's, which are used
 /// to parameterize some operations.
 class VTSDNode : public SDNode {
-  MVT::ValueType ValueType;
+  MVT ValueType;
   virtual void ANCHOR();  // Out-of-line virtual method to give class a home.
 protected:
   friend class SelectionDAG;
-  explicit VTSDNode(MVT::ValueType VT)
+  explicit VTSDNode(MVT VT)
     : SDNode(ISD::VALUETYPE, getSDVTList(MVT::Other)), ValueType(VT) {
   }
 public:
 
-  MVT::ValueType getVT() const { return ValueType; }
+  MVT getVT() const { return ValueType; }
 
   static bool classof(const VTSDNode *) { return true; }
   static bool classof(const SDNode *N) {
@@ -1911,7 +1940,7 @@ private:
   ISD::MemIndexedMode AddrMode;
 
   // MemoryVT - VT of in-memory value.
-  MVT::ValueType MemoryVT;
+  MVT MemoryVT;
 
   //! SrcValue - Memory location for alias analysis.
   const Value *SrcValue;
@@ -1933,15 +1962,15 @@ protected:
    */
   SDUse Ops[4];
 public:
-  LSBaseSDNode(ISD::NodeType NodeTy, SDOperand *Operands, unsigned NumOperands,
-               SDVTList VTs, ISD::MemIndexedMode AM, MVT::ValueType VT, 
+  LSBaseSDNode(ISD::NodeType NodeTy, SDOperand *Operands, unsigned numOperands,
+               SDVTList VTs, ISD::MemIndexedMode AM, MVT VT,
                const Value *SV, int SVO, unsigned Align, bool Vol)
     : SDNode(NodeTy, VTs),
       AddrMode(AM), MemoryVT(VT),
       SrcValue(SV), SVOffset(SVO), Alignment(Align), IsVolatile(Vol) {
-    for (unsigned i = 0; i != NumOperands; ++i)
+    for (unsigned i = 0; i != numOperands; ++i)
       Ops[i] = Operands[i];
-    InitOperands(Ops, NumOperands);
+    InitOperands(Ops, numOperands);
     assert(Align != 0 && "Loads and stores should have non-zero aligment");
     assert((getOffset().getOpcode() == ISD::UNDEF || isIndexed()) &&
            "Only indexed loads and stores have a non-undef offset operand");
@@ -1958,7 +1987,7 @@ public:
   const Value *getSrcValue() const { return SrcValue; }
   int getSrcValueOffset() const { return SVOffset; }
   unsigned getAlignment() const { return Alignment; }
-  MVT::ValueType getMemoryVT() const { return MemoryVT; }
+  MVT getMemoryVT() const { return MemoryVT; }
   bool isVolatile() const { return IsVolatile; }
 
   ISD::MemIndexedMode getAddressingMode() const { return AddrMode; }
@@ -1973,7 +2002,7 @@ public:
   /// reference performed by this load or store.
   MachineMemOperand getMemOperand() const;
 
-  static bool classof(const LSBaseSDNode *N) { return true; }
+  static bool classof(const LSBaseSDNode *) { return true; }
   static bool classof(const SDNode *N) {
     return N->getOpcode() == ISD::LOAD ||
            N->getOpcode() == ISD::STORE;
@@ -1991,7 +2020,7 @@ class LoadSDNode : public LSBaseSDNode {
 protected:
   friend class SelectionDAG;
   LoadSDNode(SDOperand *ChainPtrOff, SDVTList VTs,
-             ISD::MemIndexedMode AM, ISD::LoadExtType ETy, MVT::ValueType LVT,
+             ISD::MemIndexedMode AM, ISD::LoadExtType ETy, MVT LVT,
              const Value *SV, int O=0, unsigned Align=0, bool Vol=false)
     : LSBaseSDNode(ISD::LOAD, ChainPtrOff, 3,
                    VTs, AM, LVT, SV, O, Align, Vol),
@@ -2018,7 +2047,7 @@ class StoreSDNode : public LSBaseSDNode {
 protected:
   friend class SelectionDAG;
   StoreSDNode(SDOperand *ChainValuePtrOff, SDVTList VTs,
-              ISD::MemIndexedMode AM, bool isTrunc, MVT::ValueType SVT,
+              ISD::MemIndexedMode AM, bool isTrunc, MVT SVT,
               const Value *SV, int O=0, unsigned Align=0, bool Vol=false)
     : LSBaseSDNode(ISD::STORE, ChainValuePtrOff, 4,
                    VTs, AM, SVT, SV, O, Align, Vol),
@@ -2103,71 +2132,82 @@ struct ilist_traits<SDNode> {
   //static SDNode *createNode(const SDNode &V) { return new SDNode(V); }
   
   
-  void addNodeToList(SDNode *NTy) {}
-  void removeNodeFromList(SDNode *NTy) {}
-  void transferNodesFromList(iplist<SDNode, ilist_traits> &L2,
-                             const ilist_iterator<SDNode> &X,
-                             const ilist_iterator<SDNode> &Y) {}
+  void addNodeToList(SDNode *) {}
+  void removeNodeFromList(SDNode *) {}
+  void transferNodesFromList(iplist<SDNode, ilist_traits> &,
+                             const ilist_iterator<SDNode> &,
+                             const ilist_iterator<SDNode> &) {}
 };
 
 namespace ISD {
   /// isNormalLoad - Returns true if the specified node is a non-extending
   /// and unindexed load.
   inline bool isNormalLoad(const SDNode *N) {
-    if (N->getOpcode() != ISD::LOAD)
-      return false;
-    const LoadSDNode *Ld = cast<LoadSDNode>(N);
-    return Ld->getExtensionType() == ISD::NON_EXTLOAD &&
+    const LoadSDNode *Ld = dyn_cast<LoadSDNode>(N);
+    return Ld && Ld->getExtensionType() == ISD::NON_EXTLOAD &&
       Ld->getAddressingMode() == ISD::UNINDEXED;
   }
 
   /// isNON_EXTLoad - Returns true if the specified node is a non-extending
   /// load.
   inline bool isNON_EXTLoad(const SDNode *N) {
-    return N->getOpcode() == ISD::LOAD &&
+    return isa<LoadSDNode>(N) &&
       cast<LoadSDNode>(N)->getExtensionType() == ISD::NON_EXTLOAD;
   }
 
   /// isEXTLoad - Returns true if the specified node is a EXTLOAD.
   ///
   inline bool isEXTLoad(const SDNode *N) {
-    return N->getOpcode() == ISD::LOAD &&
+    return isa<LoadSDNode>(N) &&
       cast<LoadSDNode>(N)->getExtensionType() == ISD::EXTLOAD;
   }
 
   /// isSEXTLoad - Returns true if the specified node is a SEXTLOAD.
   ///
   inline bool isSEXTLoad(const SDNode *N) {
-    return N->getOpcode() == ISD::LOAD &&
+    return isa<LoadSDNode>(N) &&
       cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD;
   }
 
   /// isZEXTLoad - Returns true if the specified node is a ZEXTLOAD.
   ///
   inline bool isZEXTLoad(const SDNode *N) {
-    return N->getOpcode() == ISD::LOAD &&
+    return isa<LoadSDNode>(N) &&
       cast<LoadSDNode>(N)->getExtensionType() == ISD::ZEXTLOAD;
   }
 
-  /// isUNINDEXEDLoad - Returns true if the specified node is a unindexed load.
+  /// isUNINDEXEDLoad - Returns true if the specified node is an unindexed load.
   ///
   inline bool isUNINDEXEDLoad(const SDNode *N) {
-    return N->getOpcode() == ISD::LOAD &&
+    return isa<LoadSDNode>(N) &&
       cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
   }
 
+  /// isNormalStore - Returns true if the specified node is a non-truncating
+  /// and unindexed store.
+  inline bool isNormalStore(const SDNode *N) {
+    const StoreSDNode *St = dyn_cast<StoreSDNode>(N);
+    return St && !St->isTruncatingStore() &&
+      St->getAddressingMode() == ISD::UNINDEXED;
+  }
+
   /// isNON_TRUNCStore - Returns true if the specified node is a non-truncating
   /// store.
   inline bool isNON_TRUNCStore(const SDNode *N) {
-    return N->getOpcode() == ISD::STORE &&
-      !cast<StoreSDNode>(N)->isTruncatingStore();
+    return isa<StoreSDNode>(N) && !cast<StoreSDNode>(N)->isTruncatingStore();
   }
 
   /// isTRUNCStore - Returns true if the specified node is a truncating
   /// store.
   inline bool isTRUNCStore(const SDNode *N) {
-    return N->getOpcode() == ISD::STORE &&
-      cast<StoreSDNode>(N)->isTruncatingStore();
+    return isa<StoreSDNode>(N) && cast<StoreSDNode>(N)->isTruncatingStore();
+  }
+
+  /// isUNINDEXEDStore - Returns true if the specified node is an
+  /// unindexed store.
+  inline bool isUNINDEXEDStore(const SDNode *N) {
+    return isa<StoreSDNode>(N) &&
+      cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
   }
 }