+/// LSBaseSDNode - Base class for LoadSDNode and StoreSDNode
+///
+class LSBaseSDNode : public SDNode {
+private:
+ // AddrMode - unindexed, pre-indexed, post-indexed.
+ ISD::MemIndexedMode AddrMode;
+
+ // MemoryVT - VT of in-memory value.
+ MVT MemoryVT;
+
+ //! SrcValue - Memory location for alias analysis.
+ const Value *SrcValue;
+
+ //! SVOffset - Memory location offset.
+ int SVOffset;
+
+ //! Alignment - Alignment of memory location in bytes.
+ unsigned Alignment;
+
+ //! IsVolatile - True if the store is volatile.
+ bool IsVolatile;
+protected:
+ //! Operand array for load and store
+ /*!
+ \note Moving this array to the base class captures more
+ common functionality shared between LoadSDNode and
+ StoreSDNode
+ */
+ SDUse Ops[4];
+public:
+ 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)
+ Ops[i] = Operands[i];
+ 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");
+ }
+
+ const SDOperand &getChain() const { return getOperand(0); }
+ const SDOperand &getBasePtr() const {
+ return getOperand(getOpcode() == ISD::LOAD ? 1 : 2);
+ }
+ const SDOperand &getOffset() const {
+ return getOperand(getOpcode() == ISD::LOAD ? 2 : 3);
+ }
+
+ const Value *getSrcValue() const { return SrcValue; }
+ int getSrcValueOffset() const { return SVOffset; }
+ unsigned getAlignment() const { return Alignment; }
+ MVT getMemoryVT() const { return MemoryVT; }
+ bool isVolatile() const { return IsVolatile; }
+
+ ISD::MemIndexedMode getAddressingMode() const { return AddrMode; }
+
+ /// isIndexed - Return true if this is a pre/post inc/dec load/store.
+ bool isIndexed() const { return AddrMode != ISD::UNINDEXED; }
+
+ /// isUnindexed - Return true if this is NOT a pre/post inc/dec load/store.
+ bool isUnindexed() const { return AddrMode == ISD::UNINDEXED; }
+
+ /// getMemOperand - Return a MachineMemOperand object describing the memory
+ /// reference performed by this load or store.
+ MachineMemOperand getMemOperand() const;
+
+ static bool classof(const LSBaseSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::LOAD ||
+ N->getOpcode() == ISD::STORE;
+ }
+};
+
+/// LoadSDNode - This class is used to represent ISD::LOAD nodes.
+///
+class LoadSDNode : public LSBaseSDNode {
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+
+ // ExtType - non-ext, anyext, sext, zext.
+ ISD::LoadExtType ExtType;
+
+protected:
+ friend class SelectionDAG;
+ LoadSDNode(SDOperand *ChainPtrOff, SDVTList VTs,
+ 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),
+ ExtType(ETy) {}
+public:
+
+ ISD::LoadExtType getExtensionType() const { return ExtType; }
+ const SDOperand &getBasePtr() const { return getOperand(1); }
+ const SDOperand &getOffset() const { return getOperand(2); }
+
+ static bool classof(const LoadSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::LOAD;
+ }
+};
+
+/// StoreSDNode - This class is used to represent ISD::STORE nodes.
+///
+class StoreSDNode : public LSBaseSDNode {
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+
+ // IsTruncStore - True if the op does a truncation before store.
+ bool IsTruncStore;
+protected:
+ friend class SelectionDAG;
+ StoreSDNode(SDOperand *ChainValuePtrOff, SDVTList VTs,
+ 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),
+ IsTruncStore(isTrunc) {}
+public:
+
+ bool isTruncatingStore() const { return IsTruncStore; }
+ const SDOperand &getValue() const { return getOperand(1); }
+ const SDOperand &getBasePtr() const { return getOperand(2); }
+ const SDOperand &getOffset() const { return getOperand(3); }
+
+ static bool classof(const StoreSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::STORE;
+ }
+};
+