diff options
Diffstat (limited to 'include/llvm/CodeGen/SelectionDAGNodes.h')
-rw-r--r-- | include/llvm/CodeGen/SelectionDAGNodes.h | 165 |
1 files changed, 144 insertions, 21 deletions
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 8a480a4bd9..0b2bcd7be3 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -380,21 +380,6 @@ namespace ISD { // the elements, a token chain, a pointer operand, and a SRCVALUE node. VLOAD, - // Load a value from memory and extend them to a larger value (e.g. load a - // byte into a word register). All three of these have four operands, a - // token chain, a pointer to load from, a SRCVALUE for alias analysis, a - // VALUETYPE node indicating the type to load, and an enum indicating what - // sub-type of LOADX it is: - // - // SEXTLOAD loads the integer operand and sign extends it to a larger - // integer result type. - // ZEXTLOAD loads the integer operand and zero extends it to a larger - // integer result type. - // EXTLOAD is used for three things: floating point extending loads, - // integer extending loads [the top bits are undefined], and vector - // extending loads [load into low elt]. - LOADX, - // TRUNCSTORE - This operators truncates (for integer) or rounds (for FP) a // value and stores it to memory in one operation. This can be used for // either integer or floating point operands. The first four operands of @@ -534,10 +519,52 @@ namespace ISD { bool isBuildVectorAllZeros(const SDNode *N); //===--------------------------------------------------------------------===// + /// MemOpAddrMode enum - This enum defines the three load / store addressing + /// modes. + /// + /// UNINDEXED "Normal" load / store. The effective address is already + /// computed and is available in the base pointer. The offset + /// operand is always undefined. An unindexed load produces one + /// value (result of the load); an unindexed store does not + /// produces a value. + /// + /// PRE_INDEXED Similar to the unindexed mode where the effective address is + /// the result of computation of the base pointer. However, it + /// considers the computation as being folded into the load / + /// store operation (i.e. the load / store does the address + /// computation as well as performing the memory transaction). + /// The base operand is always undefined. A pre-indexed load + /// produces two values (result of the load and the result of + /// the address computation); a pre-indexed store produces one + /// value (result of the address computation). + /// + /// POST_INDEXED The effective address is the value of the base pointer. The + /// value of the offset operand is then added to the base after + /// memory transaction. A post-indexed load produces two values + /// (the result of the load and the result of the base + offset + /// computation); a post-indexed store produces one value (the + /// the result of the base + offset computation). + /// + enum MemOpAddrMode { + UNINDEXED = 0, + PRE_INDEXED, + POST_INDEXED + }; + + //===--------------------------------------------------------------------===// /// LoadExtType enum - This enum defines the three variants of LOADEXT /// (load with extension). /// + /// SEXTLOAD loads the integer operand and sign extends it to a larger + /// integer result type. + /// ZEXTLOAD loads the integer operand and zero extends it to a larger + /// integer result type. + /// EXTLOAD is used for three things: floating point extending loads, + /// integer extending loads [the top bits are undefined], and vector + /// extending loads [load into low elt]. + /// enum LoadExtType { + NON_EXTLOAD = 0, EXTLOAD, SEXTLOAD, ZEXTLOAD, @@ -1345,6 +1372,95 @@ public: } }; +/// LoadSDNode - This class is used to represent ISD::LOAD nodes. +/// +class LoadSDNode : public SDNode { + ISD::MemOpAddrMode AddrMode; // unindexed, pre-indexed, post-indexed. + ISD::LoadExtType ExtType; // non-ext, anyext, sext, zext. + MVT::ValueType LoadVT; // VT of loaded value before extension. + const Value *SrcValue; + int SVOffset; + unsigned Alignment; + bool IsVolatile; +protected: + friend class SelectionDAG; + LoadSDNode(SDOperand Chain, SDOperand Ptr, SDOperand Off, + ISD::MemOpAddrMode AM, ISD::LoadExtType ETy, MVT::ValueType LVT, + const Value *SV, int O=0, unsigned Align=1, bool Vol=false) + : SDNode(ISD::LOAD, Chain, Ptr, Off), + AddrMode(AM), ExtType(ETy), LoadVT(LVT), SrcValue(SV), SVOffset(O), + Alignment(Align), IsVolatile(Vol) { + assert((Off.getOpcode() == ISD::UNDEF || AddrMode == ISD::POST_INDEXED) && + "Only post-indexed load has a non-undef offset operand"); + } + LoadSDNode(SDOperand Chain, SDOperand Ptr, SDOperand Off, + ISD::LoadExtType ETy, MVT::ValueType LVT, + const Value *SV, int O=0, unsigned Align=1, bool Vol=false) + : SDNode(ISD::LOAD, Chain, Ptr, Off), + AddrMode(ISD::UNINDEXED), ExtType(ETy), LoadVT(LVT), SrcValue(SV), + SVOffset(O), Alignment(Align), IsVolatile(Vol) { + assert((Off.getOpcode() == ISD::UNDEF || AddrMode == ISD::POST_INDEXED) && + "Only post-indexed load has a non-undef offset operand"); + } +public: + + const SDOperand &getChain() const { return getOperand(0); } + const SDOperand &getBasePtr() const { return getOperand(1); } + const SDOperand &getOffset() const { return getOperand(2); } + ISD::MemOpAddrMode getAddressingMode() const { return AddrMode; } + ISD::LoadExtType getExtensionType() const { return ExtType; } + MVT::ValueType getLoadVT() const { return LoadVT; } + 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 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 SDNode { + ISD::MemOpAddrMode AddrMode; // unindexed, pre-indexed, post-indexed. + bool IsTruncStore; // is value truncated before store? + MVT::ValueType StoredVT; // VT of value that's actually stored. + const Value *SrcValue; + int SVOffset; + unsigned Alignment; + bool IsVolatile; +protected: + friend class SelectionDAG; + StoreSDNode(SDOperand Chain, SDOperand Ptr, SDOperand Off, + ISD::MemOpAddrMode AM, bool isTrunc, MVT::ValueType SVT, + const Value *SV, int O=0, unsigned Align=0, bool Vol=false) + : SDNode(ISD::STORE, Chain, Ptr, Off), + AddrMode(AM), IsTruncStore(isTrunc), StoredVT(SVT), SrcValue(SV), + SVOffset(O), Alignment(Align), IsVolatile(Vol) { + assert((Off.getOpcode() == ISD::UNDEF || AddrMode == ISD::POST_INDEXED) && + "Only post-indexed store has a non-undef offset operand"); + } +public: + + const SDOperand &getChain() const { return getOperand(0); } + const SDOperand &getBasePtr() const { return getOperand(1); } + const SDOperand &getOffset() const { return getOperand(2); } + ISD::MemOpAddrMode getAddressingMode() const { return AddrMode; } + bool isTruncatingStore() const { return IsTruncStore; } + MVT::ValueType getStoredVT() const { return StoredVT; } + 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 LoadSDNode *) { return true; } + static bool classof(const SDNode *N) { + return N->getOpcode() == ISD::STORE; + } +}; + class SDNodeIterator : public forward_iterator<SDNode, ptrdiff_t> { SDNode *Node; @@ -1420,25 +1536,32 @@ struct ilist_traits<SDNode> { }; namespace ISD { + /// 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 && + 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::LOADX && - N->getConstantOperandVal(4) == ISD::EXTLOAD; + return N->getOpcode() == ISD::LOAD && + 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::LOADX && - N->getConstantOperandVal(4) == ISD::SEXTLOAD; + return N->getOpcode() == ISD::LOAD && + 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::LOADX && - N->getConstantOperandVal(4) == ISD::ZEXTLOAD; + return N->getOpcode() == ISD::LOAD && + cast<LoadSDNode>(N)->getExtensionType() == ISD::ZEXTLOAD; } } |