BSwapOp = DAG.getNode(ISD::ANY_EXTEND, SDLoc(N), MVT::i32, BSwapOp);
SDValue Ops[] = {
- N->getOperand(0), BSwapOp, N->getOperand(2),
- DAG.getValueType(Op1.getValueType())
+ N->getOperand(0), BSwapOp, N->getOperand(2)
};
return
// Create the byte-swapping load.
SDValue Ops[] = {
LD->getChain(), // Chain
- LD->getBasePtr(), // Ptr
- DAG.getValueType(N->getValueType(0)) // VT
+ LD->getBasePtr() // Ptr
};
+ EVT LoadVT = N->getValueType(0);
+ if (LoadVT == MVT::i16)
+ LoadVT = MVT::i32;
SDValue BSLoad =
DAG.getMemIntrinsicNode(SystemZISD::LRV, SDLoc(N),
- DAG.getVTList(N->getValueType(0) == MVT::i64 ?
- MVT::i64 : MVT::i32, MVT::Other),
+ DAG.getVTList(LoadVT, MVT::Other),
Ops, LD->getMemoryVT(), LD->getMemOperand());
// If this is an i16 load, insert the truncate.
// Val, CC, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap)
ATOMIC_CMP_SWAP_128,
- // Byte swapping load.
- //
- // Operand 0: the address to load from
- // Operand 1: the type of load (i16, i32, i64)
- LRV,
-
- // Byte swapping store.
- //
- // Operand 0: the value to store
- // Operand 1: the address to store to
- // Operand 2: the type of store (i16, i32, i64)
- STRV,
+ // Byte swapping load/store. Same operands as regular load/store.
+ LRV, STRV,
// Prefetch from the second operand using the 4-bit control code in
// the first operand. The code is 1 for a load prefetch and 2 for
def LRVR : UnaryRRE<"lrvr", 0xB91F, bswap, GR32, GR32>;
def LRVGR : UnaryRRE<"lrvgr", 0xB90F, bswap, GR64, GR64>;
-// Byte-swapping loads. Unlike normal loads, these instructions are
-// allowed to access storage more than once.
-def LRVH : UnaryRXY<"lrvh", 0xE31F, z_lrvh, GR32, 2>;
-def LRV : UnaryRXY<"lrv", 0xE31E, z_lrv, GR32, 4>;
-def LRVG : UnaryRXY<"lrvg", 0xE30F, z_lrvg, GR64, 8>;
-
-// Likewise byte-swapping stores.
-def STRVH : StoreRXY<"strvh", 0xE33F, z_strvh, GR32, 2>;
-def STRV : StoreRXY<"strv", 0xE33E, z_strv, GR32, 4>;
-def STRVG : StoreRXY<"strvg", 0xE32F, z_strvg, GR64, 8>;
+// Byte-swapping loads.
+def LRVH : UnaryRXY<"lrvh", 0xE31F, z_loadbswap16, GR32, 2>;
+def LRV : UnaryRXY<"lrv", 0xE31E, z_loadbswap32, GR32, 4>;
+def LRVG : UnaryRXY<"lrvg", 0xE30F, z_loadbswap64, GR64, 8>;
+
+// Byte-swapping stores.
+def STRVH : StoreRXY<"strvh", 0xE33F, z_storebswap16, GR32, 2>;
+def STRV : StoreRXY<"strv", 0xE33E, z_storebswap32, GR32, 4>;
+def STRVG : StoreRXY<"strvg", 0xE32F, z_storebswap64, GR64, 8>;
// Byte-swapping memory-to-memory moves.
let mayLoad = 1, mayStore = 1 in
def SDT_ZPrefetch : SDTypeProfile<0, 2,
[SDTCisVT<0, i32>,
SDTCisPtrTy<1>]>;
-def SDT_ZLoadBSwap : SDTypeProfile<1, 2,
- [SDTCisInt<0>,
- SDTCisPtrTy<1>,
- SDTCisVT<2, OtherVT>]>;
-def SDT_ZStoreBSwap : SDTypeProfile<0, 3,
- [SDTCisInt<0>,
- SDTCisPtrTy<1>,
- SDTCisVT<2, OtherVT>]>;
def SDT_ZTBegin : SDTypeProfile<1, 2,
[SDTCisVT<0, i32>,
SDTCisPtrTy<1>,
def z_membarrier : SDNode<"SystemZISD::MEMBARRIER", SDTNone,
[SDNPHasChain, SDNPSideEffect]>;
-def z_loadbswap : SDNode<"SystemZISD::LRV", SDT_ZLoadBSwap,
+def z_loadbswap : SDNode<"SystemZISD::LRV", SDTLoad,
[SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
-def z_storebswap : SDNode<"SystemZISD::STRV", SDT_ZStoreBSwap,
+def z_storebswap : SDNode<"SystemZISD::STRV", SDTStore,
[SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
def z_tdc : SDNode<"SystemZISD::TDC", SDT_ZTest>;
// Pattern fragments
//===----------------------------------------------------------------------===//
-def z_lrvh : PatFrag<(ops node:$addr), (z_loadbswap node:$addr, i16)>;
-def z_lrv : PatFrag<(ops node:$addr), (z_loadbswap node:$addr, i32)>;
-def z_lrvg : PatFrag<(ops node:$addr), (z_loadbswap node:$addr, i64)>;
+def z_loadbswap16 : PatFrag<(ops node:$addr), (z_loadbswap node:$addr), [{
+ return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i16;
+}]>;
+def z_loadbswap32 : PatFrag<(ops node:$addr), (z_loadbswap node:$addr), [{
+ return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i32;
+}]>;
+def z_loadbswap64 : PatFrag<(ops node:$addr), (z_loadbswap node:$addr), [{
+ return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i64;
+}]>;
-def z_strvh : PatFrag<(ops node:$src, node:$addr),
- (z_storebswap node:$src, node:$addr, i16)>;
-def z_strv : PatFrag<(ops node:$src, node:$addr),
- (z_storebswap node:$src, node:$addr, i32)>;
-def z_strvg : PatFrag<(ops node:$src, node:$addr),
- (z_storebswap node:$src, node:$addr, i64)>;
+def z_storebswap16 : PatFrag<(ops node:$src, node:$addr),
+ (z_storebswap node:$src, node:$addr), [{
+ return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i16;
+}]>;
+def z_storebswap32 : PatFrag<(ops node:$src, node:$addr),
+ (z_storebswap node:$src, node:$addr), [{
+ return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i32;
+}]>;
+def z_storebswap64 : PatFrag<(ops node:$src, node:$addr),
+ (z_storebswap node:$src, node:$addr), [{
+ return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i64;
+}]>;
// Fragments including CC as an implicit source.
def z_br_ccmask