diff options
Diffstat (limited to 'lib/Target')
| -rw-r--r-- | lib/Target/SystemZ/SystemZInstrInfo.td | 15 | ||||
| -rw-r--r-- | lib/Target/SystemZ/SystemZOperators.td | 21 |
2 files changed, 27 insertions, 9 deletions
diff --git a/lib/Target/SystemZ/SystemZInstrInfo.td b/lib/Target/SystemZ/SystemZInstrInfo.td index 062266b..c9ec6bc 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/lib/Target/SystemZ/SystemZInstrInfo.td @@ -382,13 +382,14 @@ let neverHasSideEffects = 1 in { def LRVGR : UnaryRRE<"lrvgr", 0xB90F, bswap, GR64, GR64>; } -// Byte-swapping loads. -def LRV : UnaryRXY<"lrv", 0xE31E, loadu<bswap>, GR32>; -def LRVG : UnaryRXY<"lrvg", 0xE30F, loadu<bswap>, GR64>; - -// Byte-swapping stores. -def STRV : StoreRXY<"strv", 0xE33E, storeu<bswap>, GR32>; -def STRVG : StoreRXY<"strvg", 0xE32F, storeu<bswap>, GR64>; +// Byte-swapping loads. Unlike normal loads, these instructions are +// allowed to access storage more than once. +def LRV : UnaryRXY<"lrv", 0xE31E, loadu<bswap, nonvolatile_load>, GR32>; +def LRVG : UnaryRXY<"lrvg", 0xE30F, loadu<bswap, nonvolatile_load>, GR64>; + +// Likewise byte-swapping stores. +def STRV : StoreRXY<"strv", 0xE33E, storeu<bswap, nonvolatile_store>, GR32>; +def STRVG : StoreRXY<"strvg", 0xE32F, storeu<bswap, nonvolatile_store>, GR64>; //===----------------------------------------------------------------------===// // Load address instructions diff --git a/lib/Target/SystemZ/SystemZOperators.td b/lib/Target/SystemZ/SystemZOperators.td index 8c4df56..ab01b25 100644 --- a/lib/Target/SystemZ/SystemZOperators.td +++ b/lib/Target/SystemZ/SystemZOperators.td @@ -142,6 +142,23 @@ def aligned_store : AlignedStore<store>; def aligned_truncstorei16 : AlignedStore<truncstorei16>; def aligned_truncstorei32 : AlignedStore<truncstorei32>; +// Non-volatile loads. Used for instructions that might access the storage +// location multiple times. +class NonvolatileLoad<SDPatternOperator load> + : PatFrag<(ops node:$addr), (load node:$addr), [{ + LoadSDNode *Load = cast<LoadSDNode>(N); + return !Load->isVolatile(); +}]>; +def nonvolatile_load : NonvolatileLoad<load>; + +// Non-volatile stores. +class NonvolatileStore<SDPatternOperator store> + : PatFrag<(ops node:$src, node:$addr), (store node:$src, node:$addr), [{ + StoreSDNode *Store = cast<StoreSDNode>(N); + return !Store->isVolatile(); +}]>; +def nonvolatile_store : NonvolatileStore<store>; + // Insertions. def inserti8 : PatFrag<(ops node:$src1, node:$src2), (or (and node:$src1, -256), node:$src2)>; @@ -186,11 +203,11 @@ def fnabs : PatFrag<(ops node:$ptr), (fneg (fabs node:$ptr))>; // Create a unary operator that loads from memory and then performs // the given operation on it. -class loadu<SDPatternOperator operator> +class loadu<SDPatternOperator operator, SDPatternOperator load = load> : PatFrag<(ops node:$addr), (operator (load node:$addr))>; // Create a store operator that performs the given unary operation // on the value before storing it. -class storeu<SDPatternOperator operator> +class storeu<SDPatternOperator operator, SDPatternOperator store = store> : PatFrag<(ops node:$value, node:$addr), (store (operator node:$value), node:$addr)>; |
