+/// LSBaseSDNode - Base class for LoadSDNode and StoreSDNode
+///
+class LSBaseSDNode : public SDNode {
+private:
+ //! 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
+ */
+ SDOperand Ops[4];
+public:
+ LSBaseSDNode(ISD::NodeType NodeTy, SDVTList VTs, const Value *SV, int SVO,
+ unsigned Align, bool Vol)
+ : SDNode(NodeTy, VTs),
+ SrcValue(SV), SVOffset(SVO), Alignment(Align), IsVolatile(Vol)
+ { }
+
+ 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 SDOperand getValue() const {
+ assert(getOpcode() == ISD::STORE);
+ return getOperand(1);
+ }
+
+ const Value *getSrcValue() const { return SrcValue; }
+ int getSrcValueOffset() const { return SVOffset; }
+ unsigned getAlignment() const { return Alignment; }
+ bool isVolatile() const { return IsVolatile; }
+
+ static bool classof(const LSBaseSDNode *N) { return true; }
+ static bool classof(const SDNode *N) { return true; }
+};
+
+/// 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.
+
+ // AddrMode - unindexed, pre-indexed, post-indexed.
+ ISD::MemIndexedMode AddrMode;
+
+ // ExtType - non-ext, anyext, sext, zext.
+ ISD::LoadExtType ExtType;
+
+ // LoadedVT - VT of loaded value before extension.
+ MVT::ValueType LoadedVT;
+protected:
+ friend class SelectionDAG;
+ LoadSDNode(SDOperand *ChainPtrOff, SDVTList VTs,
+ ISD::MemIndexedMode AM, ISD::LoadExtType ETy, MVT::ValueType LVT,
+ const Value *SV, int O=0, unsigned Align=0, bool Vol=false)
+ : LSBaseSDNode(ISD::LOAD, VTs, SV, O, Align, Vol),
+ AddrMode(AM), ExtType(ETy), LoadedVT(LVT) {
+ Ops[0] = ChainPtrOff[0]; // Chain
+ Ops[1] = ChainPtrOff[1]; // Ptr
+ Ops[2] = ChainPtrOff[2]; // Off
+ InitOperands(Ops, 3);
+ assert(Align != 0 && "Loads should have non-zero aligment");
+ assert((getOffset().getOpcode() == ISD::UNDEF ||
+ AddrMode != ISD::UNINDEXED) &&
+ "Only indexed load has a non-undef offset operand");
+ }
+public:
+
+ ISD::MemIndexedMode getAddressingMode() const { return AddrMode; }
+ ISD::LoadExtType getExtensionType() const { return ExtType; }
+ MVT::ValueType getLoadedVT() const { return LoadedVT; }
+
+ /// isIndexed - Return true if this is a pre/post inc/dec load.
+ bool isIndexed() const { return AddrMode != ISD::UNINDEXED; }
+
+ /// isUnindexed - Return true if this is NOT a pre/post inc/dec load.
+ bool isUnindexed() const { return AddrMode == ISD::UNINDEXED; }
+
+ 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.
+
+ // AddrMode - unindexed, pre-indexed, post-indexed.
+ ISD::MemIndexedMode AddrMode;
+
+ // IsTruncStore - True if the op does a truncation before store.
+ bool IsTruncStore;
+
+ // StoredVT - VT of the value after truncation.
+ MVT::ValueType StoredVT;
+protected:
+ friend class SelectionDAG;
+ StoreSDNode(SDOperand *ChainValuePtrOff, SDVTList VTs,
+ ISD::MemIndexedMode AM, bool isTrunc, MVT::ValueType SVT,
+ const Value *SV, int O=0, unsigned Align=0, bool Vol=false)
+ : LSBaseSDNode(ISD::STORE, VTs, SV, O, Align, Vol),
+ AddrMode(AM), IsTruncStore(isTrunc), StoredVT(SVT) {
+ Ops[0] = ChainValuePtrOff[0]; // Chain
+ Ops[1] = ChainValuePtrOff[1]; // Value
+ Ops[2] = ChainValuePtrOff[2]; // Ptr
+ Ops[3] = ChainValuePtrOff[3]; // Off
+ InitOperands(Ops, 4);
+ assert(Align != 0 && "Stores should have non-zero aligment");
+ assert((getOffset().getOpcode() == ISD::UNDEF || isIndexed()) &&
+ "Only indexed store has a non-undef offset operand");
+ }
+public:
+
+ bool isTruncatingStore() const { return IsTruncStore; }
+ MVT::ValueType getStoredVT() const { return StoredVT; }
+ ISD::MemIndexedMode getAddressingMode() const { return AddrMode; }
+
+ /// isIndexed - Return true if this is a pre/post inc/dec store.
+ bool isIndexed() const { return AddrMode != ISD::UNINDEXED; }
+
+ /// isUnindexed - Return true if this is NOT a pre/post inc/dec store.
+ bool isUnindexed() const { return AddrMode == ISD::UNINDEXED; }
+
+ static bool classof(const StoreSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::STORE;
+ }
+};
+