mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-01 00:11:00 +00:00
Merging ISD::LOAD and ISD::LOADX. Added LoadSDNode to represent load nodes.
Chain and address ptr remains as operands. SrcValue, extending mode, extending VT (or rather loaded VT before extension) are now instance variables of LoadSDNode. Introduce load / store addressing modes to represent pre- and post-indexed load and store. Also added an additional operand offset that is only used in post-indexed mode (i.e. base ptr += offset after load/store). Added alignment info (not yet used) and isVolatile fields. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30843 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9f5d48bcb1
commit
24446e253a
@ -300,12 +300,12 @@ public:
|
|||||||
/// determined by their operands, and they produce a value AND a token chain.
|
/// determined by their operands, and they produce a value AND a token chain.
|
||||||
///
|
///
|
||||||
SDOperand getLoad(MVT::ValueType VT, SDOperand Chain, SDOperand Ptr,
|
SDOperand getLoad(MVT::ValueType VT, SDOperand Chain, SDOperand Ptr,
|
||||||
SDOperand SV);
|
const Value *SV, int SVOffset, bool isVolatile=false);
|
||||||
|
SDOperand getExtLoad(ISD::LoadExtType ExtType, MVT::ValueType VT,
|
||||||
|
SDOperand Chain, SDOperand Ptr, const Value *SV,
|
||||||
|
int SVOffset, MVT::ValueType EVT, bool isVolatile=false);
|
||||||
SDOperand getVecLoad(unsigned Count, MVT::ValueType VT, SDOperand Chain,
|
SDOperand getVecLoad(unsigned Count, MVT::ValueType VT, SDOperand Chain,
|
||||||
SDOperand Ptr, SDOperand SV);
|
SDOperand Ptr, SDOperand SV);
|
||||||
SDOperand getExtLoad(ISD::LoadExtType LType, MVT::ValueType VT,
|
|
||||||
SDOperand Chain, SDOperand Ptr, SDOperand SV,
|
|
||||||
MVT::ValueType EVT);
|
|
||||||
|
|
||||||
/// getStore - Helper function to build ISD::STORE nodes.
|
/// getStore - Helper function to build ISD::STORE nodes.
|
||||||
///
|
///
|
||||||
|
@ -380,21 +380,6 @@ namespace ISD {
|
|||||||
// the elements, a token chain, a pointer operand, and a SRCVALUE node.
|
// the elements, a token chain, a pointer operand, and a SRCVALUE node.
|
||||||
VLOAD,
|
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
|
// 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
|
// 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
|
// either integer or floating point operands. The first four operands of
|
||||||
@ -533,11 +518,53 @@ namespace ISD {
|
|||||||
/// BUILD_VECTOR where all of the elements are 0 or undef.
|
/// BUILD_VECTOR where all of the elements are 0 or undef.
|
||||||
bool isBuildVectorAllZeros(const SDNode *N);
|
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
|
/// LoadExtType enum - This enum defines the three variants of LOADEXT
|
||||||
/// (load with extension).
|
/// (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 {
|
enum LoadExtType {
|
||||||
|
NON_EXTLOAD = 0,
|
||||||
EXTLOAD,
|
EXTLOAD,
|
||||||
SEXTLOAD,
|
SEXTLOAD,
|
||||||
ZEXTLOAD,
|
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> {
|
class SDNodeIterator : public forward_iterator<SDNode, ptrdiff_t> {
|
||||||
SDNode *Node;
|
SDNode *Node;
|
||||||
@ -1420,25 +1536,32 @@ struct ilist_traits<SDNode> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
namespace ISD {
|
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.
|
/// isEXTLoad - Returns true if the specified node is a EXTLOAD.
|
||||||
///
|
///
|
||||||
inline bool isEXTLoad(const SDNode *N) {
|
inline bool isEXTLoad(const SDNode *N) {
|
||||||
return N->getOpcode() == ISD::LOADX &&
|
return N->getOpcode() == ISD::LOAD &&
|
||||||
N->getConstantOperandVal(4) == ISD::EXTLOAD;
|
cast<LoadSDNode>(N)->getExtensionType() == ISD::EXTLOAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// isSEXTLoad - Returns true if the specified node is a SEXTLOAD.
|
/// isSEXTLoad - Returns true if the specified node is a SEXTLOAD.
|
||||||
///
|
///
|
||||||
inline bool isSEXTLoad(const SDNode *N) {
|
inline bool isSEXTLoad(const SDNode *N) {
|
||||||
return N->getOpcode() == ISD::LOADX &&
|
return N->getOpcode() == ISD::LOAD &&
|
||||||
N->getConstantOperandVal(4) == ISD::SEXTLOAD;
|
cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// isZEXTLoad - Returns true if the specified node is a ZEXTLOAD.
|
/// isZEXTLoad - Returns true if the specified node is a ZEXTLOAD.
|
||||||
///
|
///
|
||||||
inline bool isZEXTLoad(const SDNode *N) {
|
inline bool isZEXTLoad(const SDNode *N) {
|
||||||
return N->getOpcode() == ISD::LOADX &&
|
return N->getOpcode() == ISD::LOAD &&
|
||||||
N->getConstantOperandVal(4) == ISD::ZEXTLOAD;
|
cast<LoadSDNode>(N)->getExtensionType() == ISD::ZEXTLOAD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,14 +219,12 @@ public:
|
|||||||
/// expanded to some other code sequence, or the target has a custom expander
|
/// expanded to some other code sequence, or the target has a custom expander
|
||||||
/// for it.
|
/// for it.
|
||||||
LegalizeAction getOperationAction(unsigned Op, MVT::ValueType VT) const {
|
LegalizeAction getOperationAction(unsigned Op, MVT::ValueType VT) const {
|
||||||
assert(Op != ISD::LOADX && "Should use getLoadXAction instead");
|
|
||||||
return (LegalizeAction)((OpActions[Op] >> (2*VT)) & 3);
|
return (LegalizeAction)((OpActions[Op] >> (2*VT)) & 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// isOperationLegal - Return true if the specified operation is legal on this
|
/// isOperationLegal - Return true if the specified operation is legal on this
|
||||||
/// target.
|
/// target.
|
||||||
bool isOperationLegal(unsigned Op, MVT::ValueType VT) const {
|
bool isOperationLegal(unsigned Op, MVT::ValueType VT) const {
|
||||||
assert(Op != ISD::LOADX && "Should use isLoadXLegal instead");
|
|
||||||
return getOperationAction(Op, VT) == Legal ||
|
return getOperationAction(Op, VT) == Legal ||
|
||||||
getOperationAction(Op, VT) == Custom;
|
getOperationAction(Op, VT) == Custom;
|
||||||
}
|
}
|
||||||
@ -545,7 +543,6 @@ protected:
|
|||||||
/// with the specified type and indicate what to do about it.
|
/// with the specified type and indicate what to do about it.
|
||||||
void setOperationAction(unsigned Op, MVT::ValueType VT,
|
void setOperationAction(unsigned Op, MVT::ValueType VT,
|
||||||
LegalizeAction Action) {
|
LegalizeAction Action) {
|
||||||
assert(Op != ISD::LOADX && "Should use setLoadXAction instead");
|
|
||||||
assert(VT < 32 && Op < sizeof(OpActions)/sizeof(OpActions[0]) &&
|
assert(VT < 32 && Op < sizeof(OpActions)/sizeof(OpActions[0]) &&
|
||||||
"Table isn't big enough!");
|
"Table isn't big enough!");
|
||||||
OpActions[Op] &= ~(uint64_t(3UL) << VT*2);
|
OpActions[Op] &= ~(uint64_t(3UL) << VT*2);
|
||||||
@ -554,11 +551,12 @@ protected:
|
|||||||
|
|
||||||
/// setLoadXAction - Indicate that the specified load with extension does not
|
/// setLoadXAction - Indicate that the specified load with extension does not
|
||||||
/// work with the with specified type and indicate what to do about it.
|
/// work with the with specified type and indicate what to do about it.
|
||||||
void setLoadXAction(unsigned LType, MVT::ValueType VT, LegalizeAction Action){
|
void setLoadXAction(unsigned ExtType, MVT::ValueType VT,
|
||||||
assert(VT < 32 && LType < sizeof(LoadXActions)/sizeof(LoadXActions[0]) &&
|
LegalizeAction Action) {
|
||||||
|
assert(VT < 32 && ExtType < sizeof(LoadXActions)/sizeof(LoadXActions[0]) &&
|
||||||
"Table isn't big enough!");
|
"Table isn't big enough!");
|
||||||
LoadXActions[LType] &= ~(uint64_t(3UL) << VT*2);
|
LoadXActions[ExtType] &= ~(uint64_t(3UL) << VT*2);
|
||||||
LoadXActions[LType] |= (uint64_t)Action << VT*2;
|
LoadXActions[ExtType] |= (uint64_t)Action << VT*2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// AddPromotedToType - If Opc/OrigVT is specified as being promoted, the
|
/// AddPromotedToType - If Opc/OrigVT is specified as being promoted, the
|
||||||
|
Loading…
Reference in New Issue
Block a user