]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: simplify shift lowering on s390x
authorMichael Munday <mike.munday@ibm.com>
Mon, 30 Apr 2018 12:27:50 +0000 (13:27 +0100)
committerMichael Munday <mike.munday@ibm.com>
Tue, 8 May 2018 16:19:56 +0000 (16:19 +0000)
Use conditional moves instead of subtractions with borrow to handle
saturation cases. This allows us to delete the SUBE/SUBEW ops and
associated rules from the SSA backend. Using conditional moves also
means we can detect when shift values are masked so I've added some
new rules to constant fold the relevant comparisons and masking ops.

Also use the new shiftIsBounded() function to avoid generating code
to handle saturation cases where possible.

Updates #25167 for s390x.

Change-Id: Ief9991c91267c9151ce4c5ec07642abb4dcc1c0d
Reviewed-on: https://go-review.googlesource.com/110070
Run-TryBot: Michael Munday <mike.munday@ibm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/cmd/compile/internal/s390x/ssa.go
src/cmd/compile/internal/ssa/gen/S390X.rules
src/cmd/compile/internal/ssa/gen/S390XOps.go
src/cmd/compile/internal/ssa/opGen.go
src/cmd/compile/internal/ssa/rewriteS390X.go
test/codegen/shift.go [new file with mode: 0644]

index 6b8d8ab4b3d19081074995087153236c9c5b9429..fe206f74e865b32cac9c81370c220feeb20db78b 100644 (file)
@@ -305,13 +305,6 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                }
                p.To.Type = obj.TYPE_REG
                p.To.Reg = r
-       case ssa.OpS390XSUBEcarrymask, ssa.OpS390XSUBEWcarrymask:
-               r := v.Reg()
-               p := s.Prog(v.Op.Asm())
-               p.From.Type = obj.TYPE_REG
-               p.From.Reg = r
-               p.To.Type = obj.TYPE_REG
-               p.To.Reg = r
        case ssa.OpS390XMOVDaddridx:
                r := v.Args[0].Reg()
                i := v.Args[1].Reg()
index ba0891c18728eeb867511c0a5ab7b782f1f2cbb0..61ac734224c15198d5a8a22d7b211d386b082d2f 100644 (file)
 (Round(32|64)F x) -> (LoweredRound(32|64)F x)
 
 // Lowering shifts
+
+// Lower bounded shifts first. No need to check shift value.
+(Lsh64x(64|32|16|8)  x y) && shiftIsBounded(v) -> (SLD x y)
+(Lsh32x(64|32|16|8)  x y) && shiftIsBounded(v) -> (SLW x y)
+(Lsh16x(64|32|16|8)  x y) && shiftIsBounded(v) -> (SLW x y)
+(Lsh8x(64|32|16|8)   x y) && shiftIsBounded(v) -> (SLW x y)
+(Rsh64Ux(64|32|16|8) x y) && shiftIsBounded(v) -> (SRD x y)
+(Rsh32Ux(64|32|16|8) x y) && shiftIsBounded(v) -> (SRW x y)
+(Rsh16Ux(64|32|16|8) x y) && shiftIsBounded(v) -> (SRW (MOVHZreg x) y)
+(Rsh8Ux(64|32|16|8)  x y) && shiftIsBounded(v) -> (SRW (MOVBZreg x) y)
+(Rsh64x(64|32|16|8)  x y) && shiftIsBounded(v) -> (SRAD x y)
+(Rsh32x(64|32|16|8)  x y) && shiftIsBounded(v) -> (SRAW x y)
+(Rsh16x(64|32|16|8)  x y) && shiftIsBounded(v) -> (SRAW (MOVHreg x) y)
+(Rsh8x(64|32|16|8)   x y) && shiftIsBounded(v) -> (SRAW (MOVBreg x) y)
+
 // Unsigned shifts need to return 0 if shift amount is >= width of shifted value.
-//   result = (arg << shift) & (shift >= argbits ? 0 : 0xffffffffffffffff)
-(Lsh64x64 <t> x y) -> (AND (SLD <t> x y) (SUBEcarrymask <t> (CMPUconst y [63])))
-(Lsh64x32 <t> x y) -> (AND (SLD <t> x y) (SUBEcarrymask <t> (CMPWUconst y [63])))
-(Lsh64x16 <t> x y) -> (AND (SLD <t> x y) (SUBEcarrymask <t> (CMPWUconst (MOVHZreg y) [63])))
-(Lsh64x8  <t> x y) -> (AND (SLD <t> x y) (SUBEcarrymask <t> (CMPWUconst (MOVBZreg y) [63])))
-
-(Lsh32x64 <t> x y) -> (ANDW (SLW <t> x y) (SUBEWcarrymask <t> (CMPUconst y [31])))
-(Lsh32x32 <t> x y) -> (ANDW (SLW <t> x y) (SUBEWcarrymask <t> (CMPWUconst y [31])))
-(Lsh32x16 <t> x y) -> (ANDW (SLW <t> x y) (SUBEWcarrymask <t> (CMPWUconst (MOVHZreg y) [31])))
-(Lsh32x8  <t> x y) -> (ANDW (SLW <t> x y) (SUBEWcarrymask <t> (CMPWUconst (MOVBZreg y) [31])))
-
-(Lsh16x64 <t> x y) -> (ANDW (SLW <t> x y) (SUBEWcarrymask <t> (CMPUconst y [31])))
-(Lsh16x32 <t> x y) -> (ANDW (SLW <t> x y) (SUBEWcarrymask <t> (CMPWUconst y [31])))
-(Lsh16x16 <t> x y) -> (ANDW (SLW <t> x y) (SUBEWcarrymask <t> (CMPWUconst (MOVHZreg y) [31])))
-(Lsh16x8  <t> x y) -> (ANDW (SLW <t> x y) (SUBEWcarrymask <t> (CMPWUconst (MOVBZreg y) [31])))
-
-(Lsh8x64 <t> x y)  -> (ANDW (SLW <t> x y) (SUBEWcarrymask <t> (CMPUconst y [31])))
-(Lsh8x32 <t> x y)  -> (ANDW (SLW <t> x y) (SUBEWcarrymask <t> (CMPWUconst y [31])))
-(Lsh8x16 <t> x y)  -> (ANDW (SLW <t> x y) (SUBEWcarrymask <t> (CMPWUconst (MOVHZreg y) [31])))
-(Lsh8x8  <t> x y)  -> (ANDW (SLW <t> x y) (SUBEWcarrymask <t> (CMPWUconst (MOVBZreg y) [31])))
-
-(Rsh64Ux64 <t> x y) -> (AND (SRD <t> x y) (SUBEcarrymask <t> (CMPUconst y [63])))
-(Rsh64Ux32 <t> x y) -> (AND (SRD <t> x y) (SUBEcarrymask <t> (CMPWUconst y [63])))
-(Rsh64Ux16 <t> x y) -> (AND (SRD <t> x y) (SUBEcarrymask <t> (CMPWUconst (MOVHZreg y) [63])))
-(Rsh64Ux8  <t> x y) -> (AND (SRD <t> x y) (SUBEcarrymask <t> (CMPWUconst (MOVBZreg y) [63])))
-
-(Rsh32Ux64 <t> x y) -> (ANDW (SRW <t> x y) (SUBEWcarrymask <t> (CMPUconst y [31])))
-(Rsh32Ux32 <t> x y) -> (ANDW (SRW <t> x y) (SUBEWcarrymask <t> (CMPWUconst y [31])))
-(Rsh32Ux16 <t> x y) -> (ANDW (SRW <t> x y) (SUBEWcarrymask <t> (CMPWUconst (MOVHZreg y) [31])))
-(Rsh32Ux8  <t> x y) -> (ANDW (SRW <t> x y) (SUBEWcarrymask <t> (CMPWUconst (MOVBZreg y) [31])))
-
-(Rsh16Ux64 <t> x y) -> (ANDW (SRW <t> (MOVHZreg x) y) (SUBEWcarrymask <t> (CMPUconst y [15])))
-(Rsh16Ux32 <t> x y) -> (ANDW (SRW <t> (MOVHZreg x) y) (SUBEWcarrymask <t> (CMPWUconst y [15])))
-(Rsh16Ux16 <t> x y) -> (ANDW (SRW <t> (MOVHZreg x) y) (SUBEWcarrymask <t> (CMPWUconst (MOVHZreg y) [15])))
-(Rsh16Ux8  <t> x y) -> (ANDW (SRW <t> (MOVHZreg x) y) (SUBEWcarrymask <t> (CMPWUconst (MOVBZreg y) [15])))
-
-(Rsh8Ux64 <t> x y)  -> (ANDW (SRW <t> (MOVBZreg x) y) (SUBEWcarrymask <t> (CMPUconst y [7])))
-(Rsh8Ux32 <t> x y)  -> (ANDW (SRW <t> (MOVBZreg x) y) (SUBEWcarrymask <t> (CMPWUconst y [7])))
-(Rsh8Ux16 <t> x y)  -> (ANDW (SRW <t> (MOVBZreg x) y) (SUBEWcarrymask <t> (CMPWUconst (MOVHZreg y) [7])))
-(Rsh8Ux8  <t> x y)  -> (ANDW (SRW <t> (MOVBZreg x) y) (SUBEWcarrymask <t> (CMPWUconst (MOVBZreg y) [7])))
+//   result = shift >= 64 ? 0 : arg << shift
+(Lsh(64|32|16|8)x64 <t> x y) -> (MOVDGE <t> (SL(D|W|W|W) <t> x y) (MOVDconst [0]) (CMPUconst y [64]))
+(Lsh(64|32|16|8)x32 <t> x y) -> (MOVDGE <t> (SL(D|W|W|W) <t> x y) (MOVDconst [0]) (CMPWUconst y [64]))
+(Lsh(64|32|16|8)x16 <t> x y) -> (MOVDGE <t> (SL(D|W|W|W) <t> x y) (MOVDconst [0]) (CMPWUconst (MOVHZreg y) [64]))
+(Lsh(64|32|16|8)x8  <t> x y) -> (MOVDGE <t> (SL(D|W|W|W) <t> x y) (MOVDconst [0]) (CMPWUconst (MOVBZreg y) [64]))
+
+(Rsh(64|32)Ux64 <t> x y) -> (MOVDGE <t> (SR(D|W) <t> x y) (MOVDconst [0]) (CMPUconst y [64]))
+(Rsh(64|32)Ux32 <t> x y) -> (MOVDGE <t> (SR(D|W) <t> x y) (MOVDconst [0]) (CMPWUconst y [64]))
+(Rsh(64|32)Ux16 <t> x y) -> (MOVDGE <t> (SR(D|W) <t> x y) (MOVDconst [0]) (CMPWUconst (MOVHZreg y) [64]))
+(Rsh(64|32)Ux8  <t> x y) -> (MOVDGE <t> (SR(D|W) <t> x y) (MOVDconst [0]) (CMPWUconst (MOVBZreg y) [64]))
+
+(Rsh(16|8)Ux64 <t> x y) -> (MOVDGE <t> (SRW <t> (MOV(H|B)Zreg x) y) (MOVDconst [0]) (CMPUconst y [64]))
+(Rsh(16|8)Ux32 <t> x y) -> (MOVDGE <t> (SRW <t> (MOV(H|B)Zreg x) y) (MOVDconst [0]) (CMPWUconst y [64]))
+(Rsh(16|8)Ux16 <t> x y) -> (MOVDGE <t> (SRW <t> (MOV(H|B)Zreg x) y) (MOVDconst [0]) (CMPWUconst (MOVHZreg y) [64]))
+(Rsh(16|8)Ux8  <t> x y) -> (MOVDGE <t> (SRW <t> (MOV(H|B)Zreg x) y) (MOVDconst [0]) (CMPWUconst (MOVBZreg y) [64]))
 
 // Signed right shift needs to return 0/-1 if shift amount is >= width of shifted value.
-// We implement this by setting the shift value to -1 (all ones) if the shift value is >= width.
-(Rsh64x64 <t> x y) -> (SRAD <t> x (OR <y.Type> y (NOT <y.Type> (SUBEcarrymask <y.Type> (CMPUconst y [63])))))
-(Rsh64x32 <t> x y) -> (SRAD <t> x (ORW <y.Type> y (NOTW <y.Type> (SUBEWcarrymask <y.Type> (CMPWUconst y [63])))))
-(Rsh64x16 <t> x y) -> (SRAD <t> x (ORW <y.Type> y (NOTW <y.Type> (SUBEWcarrymask <y.Type> (CMPWUconst (MOVHZreg y) [63])))))
-(Rsh64x8  <t> x y) -> (SRAD <t> x (ORW <y.Type> y (NOTW <y.Type> (SUBEWcarrymask <y.Type> (CMPWUconst (MOVBZreg y) [63])))))
-
-(Rsh32x64 <t> x y) -> (SRAW <t> x (OR <y.Type> y (NOT <y.Type> (SUBEcarrymask <y.Type> (CMPUconst y [31])))))
-(Rsh32x32 <t> x y) -> (SRAW <t> x (ORW <y.Type> y (NOTW <y.Type> (SUBEWcarrymask <y.Type> (CMPWUconst y [31])))))
-(Rsh32x16 <t> x y) -> (SRAW <t> x (ORW <y.Type> y (NOTW <y.Type> (SUBEWcarrymask <y.Type> (CMPWUconst (MOVHZreg y) [31])))))
-(Rsh32x8  <t> x y) -> (SRAW <t> x (ORW <y.Type> y (NOTW <y.Type> (SUBEWcarrymask <y.Type> (CMPWUconst (MOVBZreg y) [31])))))
-
-(Rsh16x64 <t> x y) -> (SRAW <t> (MOVHreg x) (OR <y.Type> y (NOT <y.Type> (SUBEcarrymask <y.Type> (CMPUconst y [15])))))
-(Rsh16x32 <t> x y) -> (SRAW <t> (MOVHreg x) (ORW <y.Type> y (NOTW <y.Type> (SUBEWcarrymask <y.Type> (CMPWUconst y [15])))))
-(Rsh16x16 <t> x y) -> (SRAW <t> (MOVHreg x) (ORW <y.Type> y (NOTW <y.Type> (SUBEWcarrymask <y.Type> (CMPWUconst (MOVHZreg y) [15])))))
-(Rsh16x8  <t> x y) -> (SRAW <t> (MOVHreg x) (ORW <y.Type> y (NOTW <y.Type> (SUBEWcarrymask <y.Type> (CMPWUconst (MOVBZreg y) [15])))))
-
-(Rsh8x64 <t> x y)  -> (SRAW <t> (MOVBreg x) (OR <y.Type> y (NOT <y.Type> (SUBEcarrymask <y.Type> (CMPUconst y [7])))))
-(Rsh8x32 <t> x y)  -> (SRAW <t> (MOVBreg x) (ORW <y.Type> y (NOTW <y.Type> (SUBEWcarrymask <y.Type> (CMPWUconst y [7])))))
-(Rsh8x16 <t> x y)  -> (SRAW <t> (MOVBreg x) (ORW <y.Type> y (NOTW <y.Type> (SUBEWcarrymask <y.Type> (CMPWUconst (MOVHZreg y) [7])))))
-(Rsh8x8  <t> x y)  -> (SRAW <t> (MOVBreg x) (ORW <y.Type> y (NOTW <y.Type> (SUBEWcarrymask <y.Type> (CMPWUconst (MOVBZreg y) [7])))))
+// We implement this by setting the shift value to 63 (all ones) if the shift value is more than 63.
+//   result = arg >> (shift >= 64 ? 63 : shift)
+(Rsh(64|32)x64 x y) -> (SRA(D|W) x (MOVDGE <y.Type> y (MOVDconst <y.Type> [63]) (CMPUconst  y [64])))
+(Rsh(64|32)x32 x y) -> (SRA(D|W) x (MOVDGE <y.Type> y (MOVDconst <y.Type> [63]) (CMPWUconst y [64])))
+(Rsh(64|32)x16 x y) -> (SRA(D|W) x (MOVDGE <y.Type> y (MOVDconst <y.Type> [63]) (CMPWUconst (MOVHZreg y) [64])))
+(Rsh(64|32)x8  x y) -> (SRA(D|W) x (MOVDGE <y.Type> y (MOVDconst <y.Type> [63]) (CMPWUconst (MOVBZreg y) [64])))
+
+(Rsh(16|8)x64 x y) -> (SRAW (MOV(H|B)reg x) (MOVDGE <y.Type> y (MOVDconst <y.Type> [63]) (CMPUconst  y [64])))
+(Rsh(16|8)x32 x y) -> (SRAW (MOV(H|B)reg x) (MOVDGE <y.Type> y (MOVDconst <y.Type> [63]) (CMPWUconst y [64])))
+(Rsh(16|8)x16 x y) -> (SRAW (MOV(H|B)reg x) (MOVDGE <y.Type> y (MOVDconst <y.Type> [63]) (CMPWUconst (MOVHZreg y) [64])))
+(Rsh(16|8)x8  x y) -> (SRAW (MOV(H|B)reg x) (MOVDGE <y.Type> y (MOVDconst <y.Type> [63]) (CMPWUconst (MOVBZreg y) [64])))
 
 // Lowering comparisons
 (Less64      x y) -> (MOVDLT (MOVDconst [0]) (MOVDconst [1]) (CMP x y))
 // TODO(mundaym): modify the assembler to accept 64-bit values
 // and use isU32Bit(^c).
 (AND x (MOVDconst [c])) && is32Bit(c) && c < 0 -> (ANDconst [c] x)
+(AND x (MOVDconst [c])) && is32Bit(c) && c >= 0 -> (MOVWZreg (ANDWconst <typ.UInt32> [int64(int32(c))] x))
 (ANDW x (MOVDconst [c])) -> (ANDWconst [int64(int32(c))] x)
 
 (ANDWconst [c] (ANDWconst [d] x)) -> (ANDWconst [c & d] x)
 (XOR x (MOVDconst [c])) && isU32Bit(c) -> (XORconst [c] x)
 (XORW x (MOVDconst [c])) -> (XORWconst [int64(int32(c))] x)
 
-(SLD x (MOVDconst [c])) -> (SLDconst [c&63] x)
-(SLW x (MOVDconst [c])) -> (SLWconst [c&63] x)
-(SRD x (MOVDconst [c])) -> (SRDconst [c&63] x)
-(SRW x (MOVDconst [c])) -> (SRWconst [c&63] x)
-(SRAD x (MOVDconst [c])) -> (SRADconst [c&63] x)
-(SRAW x (MOVDconst [c])) -> (SRAWconst [c&63] x)
-
-(SRAW x (ANDWconst [63] y)) -> (SRAW x y)
-(SRAD x (ANDconst [63] y)) -> (SRAD x y)
-(SLW x (ANDWconst [63] y)) -> (SLW x y)
-(SLD x (ANDconst [63] y)) -> (SLD x y)
-(SRW x (ANDWconst [63] y)) -> (SRW x y)
-(SRD x (ANDconst [63] y)) -> (SRD x y)
+// Constant shifts.
+(S(LD|RD|RAD|LW|RW|RAW) x (MOVDconst [c]))
+       -> (S(LD|RD|RAD|LW|RW|RAW)const x [c&63])
+
+// Shifts only use the rightmost 6 bits of the shift value.
+(S(LD|RD|RAD|LW|RW|RAW) x (AND (MOVDconst [c]) y))
+       -> (S(LD|RD|RAD|LW|RW|RAW) x (ANDWconst <typ.UInt32> [c&63] y))
+(S(LD|RD|RAD|LW|RW|RAW) x (ANDWconst [c] y)) && c&63 == 63
+       -> (S(LD|RD|RAD|LW|RW|RAW) x y)
+(SLD  x (MOV(D|W|H|B|WZ|HZ|BZ)reg y)) -> (SLD  x y)
+(SRD  x (MOV(D|W|H|B|WZ|HZ|BZ)reg y)) -> (SRD  x y)
+(SRAD x (MOV(D|W|H|B|WZ|HZ|BZ)reg y)) -> (SRAD x y)
+(SLW  x (MOV(D|W|H|B|WZ|HZ|BZ)reg y)) -> (SLW  x y)
+(SRW  x (MOV(D|W|H|B|WZ|HZ|BZ)reg y)) -> (SRW  x y)
+(SRAW x (MOV(D|W|H|B|WZ|HZ|BZ)reg y)) -> (SRAW x y)
 
 // Rotate generation
 (ADD (SLDconst x [c]) (SRDconst x [d])) && d == 64-c -> (RLLGconst [c] x)
 (CMPWUconst (MOVDconst [x]) [y]) && uint32(x)<uint32(y) -> (FlagLT)
 (CMPWUconst (MOVDconst [x]) [y]) && uint32(x)>uint32(y) -> (FlagGT)
 
-// Other known comparisons.
-(CMPconst (MOVBZreg _) [c]) && 0xFF < c -> (FlagLT)
-(CMPconst (MOVHZreg _) [c]) && 0xFFFF < c -> (FlagLT)
-(CMPconst (MOVWZreg _) [c]) && 0xFFFFFFFF < c -> (FlagLT)
-(CMPWconst (SRWconst _ [c]) [n]) && 0 <= n && 0 < c && c <= 32 && (1<<uint64(32-c)) <= uint64(n) -> (FlagLT)
-(CMPconst (SRDconst _ [c]) [n]) && 0 <= n && 0 < c && c <= 64 && (1<<uint64(64-c)) <= uint64(n) -> (FlagLT)
-(CMPconst (ANDconst _ [m]) [n]) && 0 <= m && m < n -> (FlagLT)
-(CMPWconst (ANDWconst _ [m]) [n]) && 0 <= int32(m) && int32(m) < int32(n) -> (FlagLT)
-
-// Absorb flag constants into SBB ops.
-(SUBEcarrymask (FlagEQ)) -> (MOVDconst [-1])
-(SUBEcarrymask (FlagLT)) -> (MOVDconst [-1])
-(SUBEcarrymask (FlagGT)) -> (MOVDconst [0])
-(SUBEWcarrymask (FlagEQ)) -> (MOVDconst [-1])
-(SUBEWcarrymask (FlagLT)) -> (MOVDconst [-1])
-(SUBEWcarrymask (FlagGT)) -> (MOVDconst [0])
+(CMP(W|WU)const (MOVBZreg _) [c]) &&   0xff < c -> (FlagLT)
+(CMP(W|WU)const (MOVHZreg _) [c]) && 0xffff < c -> (FlagLT)
+
+(CMPconst  (SRDconst _ [c]) [n]) && c > 0 && n < 0 -> (FlagGT)
+(CMPWconst (SRWconst _ [c]) [n]) && c > 0 && n < 0 -> (FlagGT)
+
+(CMPUconst  (SRDconst _ [c]) [n]) && c > 0 && c < 64 && (1<<uint(64-c)) <= uint64(n) -> (FlagLT)
+(CMPWUconst (SRWconst _ [c]) [n]) && c > 0 && c < 32 && (1<<uint(32-c)) <= uint32(n) -> (FlagLT)
+
+(CMPWconst  (ANDWconst _ [m]) [n]) && int32(m) >= 0 &&  int32(m) <  int32(n) -> (FlagLT)
+(CMPWUconst (ANDWconst _ [m]) [n]) && uint32(m) < uint32(n) -> (FlagLT)
+
+// Convert 64-bit comparisons to 32-bit comparisons and signed comparisons
+// to unsigned comparisons.
+// Helps simplify constant comparison detection.
+(CM(P|PU)const (MOV(W|WZ)reg x) [c]) -> (CMP(W|WU)const x [c])
+(CM(P|P|PU|PU)const x:(MOV(H|HZ|H|HZ)reg _) [c]) -> (CMP(W|W|WU|WU)const x [c])
+(CM(P|P|PU|PU)const x:(MOV(B|BZ|B|BZ)reg _) [c]) -> (CMP(W|W|WU|WU)const x [c])
+(CMPconst  (MOV(WZ|W)reg x:(ANDWconst [m] _)) [c]) && int32(m) >= 0 && c >= 0 -> (CMPWUconst x [c])
+(CMPUconst (MOV(WZ|W)reg x:(ANDWconst [m] _)) [c]) && int32(m) >= 0           -> (CMPWUconst x [c])
+(CMPconst  x:(SRDconst _ [c]) [n]) && c > 0 && n >= 0 -> (CMPUconst  x [n])
+(CMPWconst x:(SRWconst _ [c]) [n]) && c > 0 && n >= 0 -> (CMPWUconst x [n])
+
+// Absorb sign and zero extensions into 32-bit comparisons.
+(CMP(W|W|WU|WU)      x (MOV(W|WZ|W|WZ)reg y))   -> (CMP(W|W|WU|WU) x y)
+(CMP(W|W|WU|WU)      (MOV(W|WZ|W|WZ)reg x) y)   -> (CMP(W|W|WU|WU) x y)
+(CMP(W|W|WU|WU)const (MOV(W|WZ|W|WZ)reg x) [c]) -> (CMP(W|W|WU|WU)const x [c])
 
 // Absorb flag constants into branches.
 (EQ (FlagEQ) yes no) -> (First nil yes no)
 (XOR x x) -> (MOVDconst [0])
 (XORW x x) -> (MOVDconst [0])
 (NEG (ADDconst [c] (NEG x))) && c != -(1<<31) -> (ADDconst [-c] x)
+(MOVBZreg (ANDWconst [m] x)) -> (MOVWZreg (ANDWconst <typ.UInt32> [int64( uint8(m))] x))
+(MOVHZreg (ANDWconst [m] x)) -> (MOVWZreg (ANDWconst <typ.UInt32> [int64(uint16(m))] x))
+(MOVBreg  (ANDWconst [m] x)) &&  int8(m) >= 0 -> (MOVWZreg (ANDWconst <typ.UInt32> [int64( uint8(m))] x))
+(MOVHreg  (ANDWconst [m] x)) && int16(m) >= 0 -> (MOVWZreg (ANDWconst <typ.UInt32> [int64(uint16(m))] x))
 
 // fused multiply-add
 (FADD (FMUL y z) x) -> (FMADD x y z)
index 7a751a644c548f6985b4eb40c72d36f9d610ce9f..ae01375473396f5efa3f46a7d1c65b6da442f4e4 100644 (file)
@@ -152,7 +152,6 @@ func init() {
 
                gp2flags  = regInfo{inputs: []regMask{gpsp, gpsp}}
                gp1flags  = regInfo{inputs: []regMask{gpsp}}
-               flagsgp   = regInfo{outputs: gponly}
                gp2flags1 = regInfo{inputs: []regMask{gp, gp}, outputs: gponly}
 
                gpload       = regInfo{inputs: []regMask{ptrspsb, 0}, outputs: gponly}
@@ -334,10 +333,6 @@ func init() {
 
                {name: "FSQRT", argLength: 1, reg: fp11, asm: "FSQRT"}, // sqrt(arg0)
 
-               {name: "SUBEcarrymask", argLength: 1, reg: flagsgp, asm: "SUBE"},  // (int64)(-1) if carry is set, 0 if carry is clear.
-               {name: "SUBEWcarrymask", argLength: 1, reg: flagsgp, asm: "SUBE"}, // (int32)(-1) if carry is set, 0 if carry is clear.
-               // Note: 32-bits subtraction is not implemented in S390X. Temporarily use SUBE (64-bits).
-
                {name: "MOVDEQ", argLength: 3, reg: gp2flags1, resultInArg0: true, asm: "MOVDEQ"}, // extract == condition from arg0
                {name: "MOVDNE", argLength: 3, reg: gp2flags1, resultInArg0: true, asm: "MOVDNE"}, // extract != condition from arg0
                {name: "MOVDLT", argLength: 3, reg: gp2flags1, resultInArg0: true, asm: "MOVDLT"}, // extract signed < condition from arg0
index 4ddbec61e71ef2c4ef816bb1f8ced141687ada06..47a16ab819201af31dece6d2a5e2ef318c000632 100644 (file)
@@ -1760,8 +1760,6 @@ const (
        OpS390XNOT
        OpS390XNOTW
        OpS390XFSQRT
-       OpS390XSUBEcarrymask
-       OpS390XSUBEWcarrymask
        OpS390XMOVDEQ
        OpS390XMOVDNE
        OpS390XMOVDLT
@@ -23409,26 +23407,6 @@ var opcodeTable = [...]opInfo{
                        },
                },
        },
-       {
-               name:   "SUBEcarrymask",
-               argLen: 1,
-               asm:    s390x.ASUBE,
-               reg: regInfo{
-                       outputs: []outputInfo{
-                               {0, 23551}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14
-                       },
-               },
-       },
-       {
-               name:   "SUBEWcarrymask",
-               argLen: 1,
-               asm:    s390x.ASUBE,
-               reg: regInfo{
-                       outputs: []outputInfo{
-                               {0, 23551}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14
-                       },
-               },
-       },
        {
                name:         "MOVDEQ",
                argLen:       3,
index 959ed2b4444cb27be5cfa693e22feeca51695912..d5d392b94a590c04d2ba472d988a673a5683aa54 100644 (file)
@@ -482,7 +482,7 @@ func rewriteValueS390X(v *Value) bool {
        case OpS390XCMPU:
                return rewriteValueS390X_OpS390XCMPU_0(v)
        case OpS390XCMPUconst:
-               return rewriteValueS390X_OpS390XCMPUconst_0(v)
+               return rewriteValueS390X_OpS390XCMPUconst_0(v) || rewriteValueS390X_OpS390XCMPUconst_10(v)
        case OpS390XCMPW:
                return rewriteValueS390X_OpS390XCMPW_0(v)
        case OpS390XCMPWU:
@@ -492,7 +492,7 @@ func rewriteValueS390X(v *Value) bool {
        case OpS390XCMPWconst:
                return rewriteValueS390X_OpS390XCMPWconst_0(v)
        case OpS390XCMPconst:
-               return rewriteValueS390X_OpS390XCMPconst_0(v)
+               return rewriteValueS390X_OpS390XCMPconst_0(v) || rewriteValueS390X_OpS390XCMPconst_10(v)
        case OpS390XCPSDR:
                return rewriteValueS390X_OpS390XCPSDR_0(v)
        case OpS390XFADD:
@@ -656,33 +656,29 @@ func rewriteValueS390X(v *Value) bool {
        case OpS390XORload:
                return rewriteValueS390X_OpS390XORload_0(v)
        case OpS390XSLD:
-               return rewriteValueS390X_OpS390XSLD_0(v)
+               return rewriteValueS390X_OpS390XSLD_0(v) || rewriteValueS390X_OpS390XSLD_10(v)
        case OpS390XSLW:
-               return rewriteValueS390X_OpS390XSLW_0(v)
+               return rewriteValueS390X_OpS390XSLW_0(v) || rewriteValueS390X_OpS390XSLW_10(v)
        case OpS390XSRAD:
-               return rewriteValueS390X_OpS390XSRAD_0(v)
+               return rewriteValueS390X_OpS390XSRAD_0(v) || rewriteValueS390X_OpS390XSRAD_10(v)
        case OpS390XSRADconst:
                return rewriteValueS390X_OpS390XSRADconst_0(v)
        case OpS390XSRAW:
-               return rewriteValueS390X_OpS390XSRAW_0(v)
+               return rewriteValueS390X_OpS390XSRAW_0(v) || rewriteValueS390X_OpS390XSRAW_10(v)
        case OpS390XSRAWconst:
                return rewriteValueS390X_OpS390XSRAWconst_0(v)
        case OpS390XSRD:
-               return rewriteValueS390X_OpS390XSRD_0(v)
+               return rewriteValueS390X_OpS390XSRD_0(v) || rewriteValueS390X_OpS390XSRD_10(v)
        case OpS390XSRDconst:
                return rewriteValueS390X_OpS390XSRDconst_0(v)
        case OpS390XSRW:
-               return rewriteValueS390X_OpS390XSRW_0(v)
+               return rewriteValueS390X_OpS390XSRW_0(v) || rewriteValueS390X_OpS390XSRW_10(v)
        case OpS390XSTM2:
                return rewriteValueS390X_OpS390XSTM2_0(v)
        case OpS390XSTMG2:
                return rewriteValueS390X_OpS390XSTMG2_0(v)
        case OpS390XSUB:
                return rewriteValueS390X_OpS390XSUB_0(v)
-       case OpS390XSUBEWcarrymask:
-               return rewriteValueS390X_OpS390XSUBEWcarrymask_0(v)
-       case OpS390XSUBEcarrymask:
-               return rewriteValueS390X_OpS390XSUBEcarrymask_0(v)
        case OpS390XSUBW:
                return rewriteValueS390X_OpS390XSUBW_0(v)
        case OpS390XSUBWconst:
@@ -3486,77 +3482,132 @@ func rewriteValueS390X_OpLsh16x16_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
+       // match: (Lsh16x16 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SLW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSLW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
        // match: (Lsh16x16 <t> x y)
        // cond:
-       // result: (ANDW (SLW <t> x y) (SUBEWcarrymask <t> (CMPWUconst (MOVHZreg y) [31])))
+       // result: (MOVDGE <t> (SLW <t> x y) (MOVDconst [0]) (CMPWUconst (MOVHZreg y) [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XANDW)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSLW, t)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, t)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v1.AuxInt = 0
+               v.AddArg(v1)
                v2 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v2.AuxInt = 31
+               v2.AuxInt = 64
                v3 := b.NewValue0(v.Pos, OpS390XMOVHZreg, typ.UInt64)
                v3.AddArg(y)
                v2.AddArg(v3)
-               v1.AddArg(v2)
-               v.AddArg(v1)
+               v.AddArg(v2)
                return true
        }
 }
 func rewriteValueS390X_OpLsh16x32_0(v *Value) bool {
        b := v.Block
        _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Lsh16x32 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SLW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSLW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
        // match: (Lsh16x32 <t> x y)
        // cond:
-       // result: (ANDW (SLW <t> x y) (SUBEWcarrymask <t> (CMPWUconst y [31])))
+       // result: (MOVDGE <t> (SLW <t> x y) (MOVDconst [0]) (CMPWUconst y [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XANDW)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSLW, t)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, t)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v1.AuxInt = 0
+               v.AddArg(v1)
                v2 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v2.AuxInt = 31
+               v2.AuxInt = 64
                v2.AddArg(y)
-               v1.AddArg(v2)
-               v.AddArg(v1)
+               v.AddArg(v2)
                return true
        }
 }
 func rewriteValueS390X_OpLsh16x64_0(v *Value) bool {
        b := v.Block
        _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Lsh16x64 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SLW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSLW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
        // match: (Lsh16x64 <t> x y)
        // cond:
-       // result: (ANDW (SLW <t> x y) (SUBEWcarrymask <t> (CMPUconst y [31])))
+       // result: (MOVDGE <t> (SLW <t> x y) (MOVDconst [0]) (CMPUconst y [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XANDW)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSLW, t)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, t)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v1.AuxInt = 0
+               v.AddArg(v1)
                v2 := b.NewValue0(v.Pos, OpS390XCMPUconst, types.TypeFlags)
-               v2.AuxInt = 31
+               v2.AuxInt = 64
                v2.AddArg(y)
-               v1.AddArg(v2)
-               v.AddArg(v1)
+               v.AddArg(v2)
                return true
        }
 }
@@ -3565,27 +3616,44 @@ func rewriteValueS390X_OpLsh16x8_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
+       // match: (Lsh16x8 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SLW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSLW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
        // match: (Lsh16x8 <t> x y)
        // cond:
-       // result: (ANDW (SLW <t> x y) (SUBEWcarrymask <t> (CMPWUconst (MOVBZreg y) [31])))
+       // result: (MOVDGE <t> (SLW <t> x y) (MOVDconst [0]) (CMPWUconst (MOVBZreg y) [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XANDW)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSLW, t)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, t)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v1.AuxInt = 0
+               v.AddArg(v1)
                v2 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v2.AuxInt = 31
+               v2.AuxInt = 64
                v3 := b.NewValue0(v.Pos, OpS390XMOVBZreg, typ.UInt64)
                v3.AddArg(y)
                v2.AddArg(v3)
-               v1.AddArg(v2)
-               v.AddArg(v1)
+               v.AddArg(v2)
                return true
        }
 }
@@ -3594,77 +3662,132 @@ func rewriteValueS390X_OpLsh32x16_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
+       // match: (Lsh32x16 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SLW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSLW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
        // match: (Lsh32x16 <t> x y)
        // cond:
-       // result: (ANDW (SLW <t> x y) (SUBEWcarrymask <t> (CMPWUconst (MOVHZreg y) [31])))
+       // result: (MOVDGE <t> (SLW <t> x y) (MOVDconst [0]) (CMPWUconst (MOVHZreg y) [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XANDW)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSLW, t)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, t)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v1.AuxInt = 0
+               v.AddArg(v1)
                v2 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v2.AuxInt = 31
+               v2.AuxInt = 64
                v3 := b.NewValue0(v.Pos, OpS390XMOVHZreg, typ.UInt64)
                v3.AddArg(y)
                v2.AddArg(v3)
-               v1.AddArg(v2)
-               v.AddArg(v1)
+               v.AddArg(v2)
                return true
        }
 }
 func rewriteValueS390X_OpLsh32x32_0(v *Value) bool {
        b := v.Block
        _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Lsh32x32 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SLW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSLW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
        // match: (Lsh32x32 <t> x y)
        // cond:
-       // result: (ANDW (SLW <t> x y) (SUBEWcarrymask <t> (CMPWUconst y [31])))
+       // result: (MOVDGE <t> (SLW <t> x y) (MOVDconst [0]) (CMPWUconst y [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XANDW)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSLW, t)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, t)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v1.AuxInt = 0
+               v.AddArg(v1)
                v2 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v2.AuxInt = 31
+               v2.AuxInt = 64
                v2.AddArg(y)
-               v1.AddArg(v2)
-               v.AddArg(v1)
+               v.AddArg(v2)
                return true
        }
 }
 func rewriteValueS390X_OpLsh32x64_0(v *Value) bool {
        b := v.Block
        _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Lsh32x64 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SLW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSLW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
        // match: (Lsh32x64 <t> x y)
        // cond:
-       // result: (ANDW (SLW <t> x y) (SUBEWcarrymask <t> (CMPUconst y [31])))
+       // result: (MOVDGE <t> (SLW <t> x y) (MOVDconst [0]) (CMPUconst y [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XANDW)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSLW, t)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, t)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v1.AuxInt = 0
+               v.AddArg(v1)
                v2 := b.NewValue0(v.Pos, OpS390XCMPUconst, types.TypeFlags)
-               v2.AuxInt = 31
+               v2.AuxInt = 64
                v2.AddArg(y)
-               v1.AddArg(v2)
-               v.AddArg(v1)
+               v.AddArg(v2)
                return true
        }
 }
@@ -3673,27 +3796,44 @@ func rewriteValueS390X_OpLsh32x8_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
+       // match: (Lsh32x8 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SLW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSLW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
        // match: (Lsh32x8 <t> x y)
        // cond:
-       // result: (ANDW (SLW <t> x y) (SUBEWcarrymask <t> (CMPWUconst (MOVBZreg y) [31])))
+       // result: (MOVDGE <t> (SLW <t> x y) (MOVDconst [0]) (CMPWUconst (MOVBZreg y) [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XANDW)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSLW, t)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, t)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v1.AuxInt = 0
+               v.AddArg(v1)
                v2 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v2.AuxInt = 31
+               v2.AuxInt = 64
                v3 := b.NewValue0(v.Pos, OpS390XMOVBZreg, typ.UInt64)
                v3.AddArg(y)
                v2.AddArg(v3)
-               v1.AddArg(v2)
-               v.AddArg(v1)
+               v.AddArg(v2)
                return true
        }
 }
@@ -3702,77 +3842,132 @@ func rewriteValueS390X_OpLsh64x16_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
+       // match: (Lsh64x16 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SLD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSLD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
        // match: (Lsh64x16 <t> x y)
        // cond:
-       // result: (AND (SLD <t> x y) (SUBEcarrymask <t> (CMPWUconst (MOVHZreg y) [63])))
+       // result: (MOVDGE <t> (SLD <t> x y) (MOVDconst [0]) (CMPWUconst (MOVHZreg y) [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XAND)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSLD, t)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XSUBEcarrymask, t)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v1.AuxInt = 0
+               v.AddArg(v1)
                v2 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v2.AuxInt = 63
+               v2.AuxInt = 64
                v3 := b.NewValue0(v.Pos, OpS390XMOVHZreg, typ.UInt64)
                v3.AddArg(y)
                v2.AddArg(v3)
-               v1.AddArg(v2)
-               v.AddArg(v1)
+               v.AddArg(v2)
                return true
        }
 }
 func rewriteValueS390X_OpLsh64x32_0(v *Value) bool {
        b := v.Block
        _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Lsh64x32 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SLD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSLD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
        // match: (Lsh64x32 <t> x y)
        // cond:
-       // result: (AND (SLD <t> x y) (SUBEcarrymask <t> (CMPWUconst y [63])))
+       // result: (MOVDGE <t> (SLD <t> x y) (MOVDconst [0]) (CMPWUconst y [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XAND)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSLD, t)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XSUBEcarrymask, t)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v1.AuxInt = 0
+               v.AddArg(v1)
                v2 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v2.AuxInt = 63
+               v2.AuxInt = 64
                v2.AddArg(y)
-               v1.AddArg(v2)
-               v.AddArg(v1)
+               v.AddArg(v2)
                return true
        }
 }
 func rewriteValueS390X_OpLsh64x64_0(v *Value) bool {
        b := v.Block
        _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Lsh64x64 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SLD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSLD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
        // match: (Lsh64x64 <t> x y)
        // cond:
-       // result: (AND (SLD <t> x y) (SUBEcarrymask <t> (CMPUconst y [63])))
+       // result: (MOVDGE <t> (SLD <t> x y) (MOVDconst [0]) (CMPUconst y [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XAND)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSLD, t)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XSUBEcarrymask, t)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v1.AuxInt = 0
+               v.AddArg(v1)
                v2 := b.NewValue0(v.Pos, OpS390XCMPUconst, types.TypeFlags)
-               v2.AuxInt = 63
+               v2.AuxInt = 64
                v2.AddArg(y)
-               v1.AddArg(v2)
-               v.AddArg(v1)
+               v.AddArg(v2)
                return true
        }
 }
@@ -3781,27 +3976,44 @@ func rewriteValueS390X_OpLsh64x8_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
+       // match: (Lsh64x8 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SLD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSLD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
        // match: (Lsh64x8 <t> x y)
        // cond:
-       // result: (AND (SLD <t> x y) (SUBEcarrymask <t> (CMPWUconst (MOVBZreg y) [63])))
+       // result: (MOVDGE <t> (SLD <t> x y) (MOVDconst [0]) (CMPWUconst (MOVBZreg y) [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XAND)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSLD, t)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XSUBEcarrymask, t)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v1.AuxInt = 0
+               v.AddArg(v1)
                v2 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v2.AuxInt = 63
+               v2.AuxInt = 64
                v3 := b.NewValue0(v.Pos, OpS390XMOVBZreg, typ.UInt64)
                v3.AddArg(y)
                v2.AddArg(v3)
-               v1.AddArg(v2)
-               v.AddArg(v1)
+               v.AddArg(v2)
                return true
        }
 }
@@ -3810,77 +4022,132 @@ func rewriteValueS390X_OpLsh8x16_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
+       // match: (Lsh8x16 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SLW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSLW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
        // match: (Lsh8x16 <t> x y)
        // cond:
-       // result: (ANDW (SLW <t> x y) (SUBEWcarrymask <t> (CMPWUconst (MOVHZreg y) [31])))
+       // result: (MOVDGE <t> (SLW <t> x y) (MOVDconst [0]) (CMPWUconst (MOVHZreg y) [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XANDW)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSLW, t)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, t)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v1.AuxInt = 0
+               v.AddArg(v1)
                v2 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v2.AuxInt = 31
+               v2.AuxInt = 64
                v3 := b.NewValue0(v.Pos, OpS390XMOVHZreg, typ.UInt64)
                v3.AddArg(y)
                v2.AddArg(v3)
-               v1.AddArg(v2)
-               v.AddArg(v1)
+               v.AddArg(v2)
                return true
        }
 }
 func rewriteValueS390X_OpLsh8x32_0(v *Value) bool {
        b := v.Block
        _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Lsh8x32 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SLW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSLW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
        // match: (Lsh8x32 <t> x y)
        // cond:
-       // result: (ANDW (SLW <t> x y) (SUBEWcarrymask <t> (CMPWUconst y [31])))
+       // result: (MOVDGE <t> (SLW <t> x y) (MOVDconst [0]) (CMPWUconst y [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XANDW)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSLW, t)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, t)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v1.AuxInt = 0
+               v.AddArg(v1)
                v2 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v2.AuxInt = 31
+               v2.AuxInt = 64
                v2.AddArg(y)
-               v1.AddArg(v2)
-               v.AddArg(v1)
+               v.AddArg(v2)
                return true
        }
 }
 func rewriteValueS390X_OpLsh8x64_0(v *Value) bool {
        b := v.Block
        _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Lsh8x64 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SLW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSLW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
        // match: (Lsh8x64 <t> x y)
        // cond:
-       // result: (ANDW (SLW <t> x y) (SUBEWcarrymask <t> (CMPUconst y [31])))
+       // result: (MOVDGE <t> (SLW <t> x y) (MOVDconst [0]) (CMPUconst y [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XANDW)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSLW, t)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, t)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v1.AuxInt = 0
+               v.AddArg(v1)
                v2 := b.NewValue0(v.Pos, OpS390XCMPUconst, types.TypeFlags)
-               v2.AuxInt = 31
+               v2.AuxInt = 64
                v2.AddArg(y)
-               v1.AddArg(v2)
-               v.AddArg(v1)
+               v.AddArg(v2)
                return true
        }
 }
@@ -3889,27 +4156,44 @@ func rewriteValueS390X_OpLsh8x8_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
+       // match: (Lsh8x8 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SLW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSLW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
        // match: (Lsh8x8 <t> x y)
        // cond:
-       // result: (ANDW (SLW <t> x y) (SUBEWcarrymask <t> (CMPWUconst (MOVBZreg y) [31])))
+       // result: (MOVDGE <t> (SLW <t> x y) (MOVDconst [0]) (CMPWUconst (MOVBZreg y) [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XANDW)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSLW, t)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, t)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v1.AuxInt = 0
+               v.AddArg(v1)
                v2 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v2.AuxInt = 31
+               v2.AuxInt = 64
                v3 := b.NewValue0(v.Pos, OpS390XMOVBZreg, typ.UInt64)
                v3.AddArg(y)
                v2.AddArg(v3)
-               v1.AddArg(v2)
-               v.AddArg(v1)
+               v.AddArg(v2)
                return true
        }
 }
@@ -5062,29 +5346,48 @@ func rewriteValueS390X_OpRsh16Ux16_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
+       // match: (Rsh16Ux16 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRW (MOVHZreg x) y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRW)
+               v0 := b.NewValue0(v.Pos, OpS390XMOVHZreg, typ.UInt64)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               v.AddArg(y)
+               return true
+       }
        // match: (Rsh16Ux16 <t> x y)
        // cond:
-       // result: (ANDW (SRW <t> (MOVHZreg x) y) (SUBEWcarrymask <t> (CMPWUconst (MOVHZreg y) [15])))
+       // result: (MOVDGE <t> (SRW <t> (MOVHZreg x) y) (MOVDconst [0]) (CMPWUconst (MOVHZreg y) [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XANDW)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSRW, t)
                v1 := b.NewValue0(v.Pos, OpS390XMOVHZreg, typ.UInt64)
                v1.AddArg(x)
                v0.AddArg(v1)
                v0.AddArg(y)
                v.AddArg(v0)
-               v2 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, t)
+               v2 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v2.AuxInt = 0
+               v.AddArg(v2)
                v3 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v3.AuxInt = 15
+               v3.AuxInt = 64
                v4 := b.NewValue0(v.Pos, OpS390XMOVHZreg, typ.UInt64)
                v4.AddArg(y)
                v3.AddArg(v4)
-               v2.AddArg(v3)
-               v.AddArg(v2)
+               v.AddArg(v3)
                return true
        }
 }
@@ -5093,27 +5396,46 @@ func rewriteValueS390X_OpRsh16Ux32_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
+       // match: (Rsh16Ux32 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRW (MOVHZreg x) y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRW)
+               v0 := b.NewValue0(v.Pos, OpS390XMOVHZreg, typ.UInt64)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               v.AddArg(y)
+               return true
+       }
        // match: (Rsh16Ux32 <t> x y)
        // cond:
-       // result: (ANDW (SRW <t> (MOVHZreg x) y) (SUBEWcarrymask <t> (CMPWUconst y [15])))
+       // result: (MOVDGE <t> (SRW <t> (MOVHZreg x) y) (MOVDconst [0]) (CMPWUconst y [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XANDW)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSRW, t)
                v1 := b.NewValue0(v.Pos, OpS390XMOVHZreg, typ.UInt64)
                v1.AddArg(x)
                v0.AddArg(v1)
                v0.AddArg(y)
                v.AddArg(v0)
-               v2 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, t)
+               v2 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v2.AuxInt = 0
+               v.AddArg(v2)
                v3 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v3.AuxInt = 15
+               v3.AuxInt = 64
                v3.AddArg(y)
-               v2.AddArg(v3)
-               v.AddArg(v2)
+               v.AddArg(v3)
                return true
        }
 }
@@ -5122,27 +5444,46 @@ func rewriteValueS390X_OpRsh16Ux64_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
+       // match: (Rsh16Ux64 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRW (MOVHZreg x) y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRW)
+               v0 := b.NewValue0(v.Pos, OpS390XMOVHZreg, typ.UInt64)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               v.AddArg(y)
+               return true
+       }
        // match: (Rsh16Ux64 <t> x y)
        // cond:
-       // result: (ANDW (SRW <t> (MOVHZreg x) y) (SUBEWcarrymask <t> (CMPUconst y [15])))
+       // result: (MOVDGE <t> (SRW <t> (MOVHZreg x) y) (MOVDconst [0]) (CMPUconst y [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XANDW)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSRW, t)
                v1 := b.NewValue0(v.Pos, OpS390XMOVHZreg, typ.UInt64)
                v1.AddArg(x)
                v0.AddArg(v1)
                v0.AddArg(y)
                v.AddArg(v0)
-               v2 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, t)
+               v2 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v2.AuxInt = 0
+               v.AddArg(v2)
                v3 := b.NewValue0(v.Pos, OpS390XCMPUconst, types.TypeFlags)
-               v3.AuxInt = 15
+               v3.AuxInt = 64
                v3.AddArg(y)
-               v2.AddArg(v3)
-               v.AddArg(v2)
+               v.AddArg(v3)
                return true
        }
 }
@@ -5151,29 +5492,48 @@ func rewriteValueS390X_OpRsh16Ux8_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
+       // match: (Rsh16Ux8 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRW (MOVHZreg x) y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRW)
+               v0 := b.NewValue0(v.Pos, OpS390XMOVHZreg, typ.UInt64)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               v.AddArg(y)
+               return true
+       }
        // match: (Rsh16Ux8 <t> x y)
        // cond:
-       // result: (ANDW (SRW <t> (MOVHZreg x) y) (SUBEWcarrymask <t> (CMPWUconst (MOVBZreg y) [15])))
+       // result: (MOVDGE <t> (SRW <t> (MOVHZreg x) y) (MOVDconst [0]) (CMPWUconst (MOVBZreg y) [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XANDW)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSRW, t)
                v1 := b.NewValue0(v.Pos, OpS390XMOVHZreg, typ.UInt64)
                v1.AddArg(x)
                v0.AddArg(v1)
                v0.AddArg(y)
                v.AddArg(v0)
-               v2 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, t)
+               v2 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v2.AuxInt = 0
+               v.AddArg(v2)
                v3 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v3.AuxInt = 15
+               v3.AuxInt = 64
                v4 := b.NewValue0(v.Pos, OpS390XMOVBZreg, typ.UInt64)
                v4.AddArg(y)
                v3.AddArg(v4)
-               v2.AddArg(v3)
-               v.AddArg(v2)
+               v.AddArg(v3)
                return true
        }
 }
@@ -5182,31 +5542,45 @@ func rewriteValueS390X_OpRsh16x16_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Rsh16x16 <t> x y)
+       // match: (Rsh16x16 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRAW (MOVHreg x) y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRAW)
+               v0 := b.NewValue0(v.Pos, OpS390XMOVHreg, typ.Int64)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               v.AddArg(y)
+               return true
+       }
+       // match: (Rsh16x16 x y)
        // cond:
-       // result: (SRAW <t> (MOVHreg x) (ORW <y.Type> y (NOTW <y.Type> (SUBEWcarrymask <y.Type> (CMPWUconst (MOVHZreg y) [15])))))
+       // result: (SRAW (MOVHreg x) (MOVDGE <y.Type> y (MOVDconst <y.Type> [63]) (CMPWUconst (MOVHZreg y) [64])))
        for {
-               t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
                v.reset(OpS390XSRAW)
-               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XMOVHreg, typ.Int64)
                v0.AddArg(x)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XORW, y.Type)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDGE, y.Type)
                v1.AddArg(y)
-               v2 := b.NewValue0(v.Pos, OpS390XNOTW, y.Type)
-               v3 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, y.Type)
-               v4 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v4.AuxInt = 15
-               v5 := b.NewValue0(v.Pos, OpS390XMOVHZreg, typ.UInt64)
-               v5.AddArg(y)
-               v4.AddArg(v5)
-               v3.AddArg(v4)
-               v2.AddArg(v3)
+               v2 := b.NewValue0(v.Pos, OpS390XMOVDconst, y.Type)
+               v2.AuxInt = 63
                v1.AddArg(v2)
+               v3 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
+               v3.AuxInt = 64
+               v4 := b.NewValue0(v.Pos, OpS390XMOVHZreg, typ.UInt64)
+               v4.AddArg(y)
+               v3.AddArg(v4)
+               v1.AddArg(v3)
                v.AddArg(v1)
                return true
        }
@@ -5216,29 +5590,43 @@ func rewriteValueS390X_OpRsh16x32_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Rsh16x32 <t> x y)
+       // match: (Rsh16x32 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRAW (MOVHreg x) y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRAW)
+               v0 := b.NewValue0(v.Pos, OpS390XMOVHreg, typ.Int64)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               v.AddArg(y)
+               return true
+       }
+       // match: (Rsh16x32 x y)
        // cond:
-       // result: (SRAW <t> (MOVHreg x) (ORW <y.Type> y (NOTW <y.Type> (SUBEWcarrymask <y.Type> (CMPWUconst y [15])))))
+       // result: (SRAW (MOVHreg x) (MOVDGE <y.Type> y (MOVDconst <y.Type> [63]) (CMPWUconst y [64])))
        for {
-               t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
                v.reset(OpS390XSRAW)
-               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XMOVHreg, typ.Int64)
                v0.AddArg(x)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XORW, y.Type)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDGE, y.Type)
                v1.AddArg(y)
-               v2 := b.NewValue0(v.Pos, OpS390XNOTW, y.Type)
-               v3 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, y.Type)
-               v4 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v4.AuxInt = 15
-               v4.AddArg(y)
-               v3.AddArg(v4)
-               v2.AddArg(v3)
+               v2 := b.NewValue0(v.Pos, OpS390XMOVDconst, y.Type)
+               v2.AuxInt = 63
                v1.AddArg(v2)
+               v3 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
+               v3.AuxInt = 64
+               v3.AddArg(y)
+               v1.AddArg(v3)
                v.AddArg(v1)
                return true
        }
@@ -5248,29 +5636,43 @@ func rewriteValueS390X_OpRsh16x64_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Rsh16x64 <t> x y)
+       // match: (Rsh16x64 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRAW (MOVHreg x) y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRAW)
+               v0 := b.NewValue0(v.Pos, OpS390XMOVHreg, typ.Int64)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               v.AddArg(y)
+               return true
+       }
+       // match: (Rsh16x64 x y)
        // cond:
-       // result: (SRAW <t> (MOVHreg x) (OR <y.Type> y (NOT <y.Type> (SUBEcarrymask <y.Type> (CMPUconst y [15])))))
+       // result: (SRAW (MOVHreg x) (MOVDGE <y.Type> y (MOVDconst <y.Type> [63]) (CMPUconst y [64])))
        for {
-               t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
                v.reset(OpS390XSRAW)
-               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XMOVHreg, typ.Int64)
                v0.AddArg(x)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XOR, y.Type)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDGE, y.Type)
                v1.AddArg(y)
-               v2 := b.NewValue0(v.Pos, OpS390XNOT, y.Type)
-               v3 := b.NewValue0(v.Pos, OpS390XSUBEcarrymask, y.Type)
-               v4 := b.NewValue0(v.Pos, OpS390XCMPUconst, types.TypeFlags)
-               v4.AuxInt = 15
-               v4.AddArg(y)
-               v3.AddArg(v4)
-               v2.AddArg(v3)
+               v2 := b.NewValue0(v.Pos, OpS390XMOVDconst, y.Type)
+               v2.AuxInt = 63
                v1.AddArg(v2)
+               v3 := b.NewValue0(v.Pos, OpS390XCMPUconst, types.TypeFlags)
+               v3.AuxInt = 64
+               v3.AddArg(y)
+               v1.AddArg(v3)
                v.AddArg(v1)
                return true
        }
@@ -5280,31 +5682,45 @@ func rewriteValueS390X_OpRsh16x8_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Rsh16x8 <t> x y)
+       // match: (Rsh16x8 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRAW (MOVHreg x) y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRAW)
+               v0 := b.NewValue0(v.Pos, OpS390XMOVHreg, typ.Int64)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               v.AddArg(y)
+               return true
+       }
+       // match: (Rsh16x8 x y)
        // cond:
-       // result: (SRAW <t> (MOVHreg x) (ORW <y.Type> y (NOTW <y.Type> (SUBEWcarrymask <y.Type> (CMPWUconst (MOVBZreg y) [15])))))
+       // result: (SRAW (MOVHreg x) (MOVDGE <y.Type> y (MOVDconst <y.Type> [63]) (CMPWUconst (MOVBZreg y) [64])))
        for {
-               t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
                v.reset(OpS390XSRAW)
-               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XMOVHreg, typ.Int64)
                v0.AddArg(x)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XORW, y.Type)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDGE, y.Type)
                v1.AddArg(y)
-               v2 := b.NewValue0(v.Pos, OpS390XNOTW, y.Type)
-               v3 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, y.Type)
-               v4 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v4.AuxInt = 15
-               v5 := b.NewValue0(v.Pos, OpS390XMOVBZreg, typ.UInt64)
-               v5.AddArg(y)
-               v4.AddArg(v5)
-               v3.AddArg(v4)
-               v2.AddArg(v3)
+               v2 := b.NewValue0(v.Pos, OpS390XMOVDconst, y.Type)
+               v2.AuxInt = 63
                v1.AddArg(v2)
+               v3 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
+               v3.AuxInt = 64
+               v4 := b.NewValue0(v.Pos, OpS390XMOVBZreg, typ.UInt64)
+               v4.AddArg(y)
+               v3.AddArg(v4)
+               v1.AddArg(v3)
                v.AddArg(v1)
                return true
        }
@@ -5314,77 +5730,132 @@ func rewriteValueS390X_OpRsh32Ux16_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
+       // match: (Rsh32Ux16 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
        // match: (Rsh32Ux16 <t> x y)
        // cond:
-       // result: (ANDW (SRW <t> x y) (SUBEWcarrymask <t> (CMPWUconst (MOVHZreg y) [31])))
+       // result: (MOVDGE <t> (SRW <t> x y) (MOVDconst [0]) (CMPWUconst (MOVHZreg y) [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XANDW)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSRW, t)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, t)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v1.AuxInt = 0
+               v.AddArg(v1)
                v2 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v2.AuxInt = 31
+               v2.AuxInt = 64
                v3 := b.NewValue0(v.Pos, OpS390XMOVHZreg, typ.UInt64)
                v3.AddArg(y)
                v2.AddArg(v3)
-               v1.AddArg(v2)
-               v.AddArg(v1)
+               v.AddArg(v2)
                return true
        }
 }
 func rewriteValueS390X_OpRsh32Ux32_0(v *Value) bool {
        b := v.Block
        _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Rsh32Ux32 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
        // match: (Rsh32Ux32 <t> x y)
        // cond:
-       // result: (ANDW (SRW <t> x y) (SUBEWcarrymask <t> (CMPWUconst y [31])))
+       // result: (MOVDGE <t> (SRW <t> x y) (MOVDconst [0]) (CMPWUconst y [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XANDW)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSRW, t)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, t)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v1.AuxInt = 0
+               v.AddArg(v1)
                v2 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v2.AuxInt = 31
+               v2.AuxInt = 64
                v2.AddArg(y)
-               v1.AddArg(v2)
-               v.AddArg(v1)
+               v.AddArg(v2)
                return true
        }
 }
 func rewriteValueS390X_OpRsh32Ux64_0(v *Value) bool {
        b := v.Block
        _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Rsh32Ux64 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
        // match: (Rsh32Ux64 <t> x y)
        // cond:
-       // result: (ANDW (SRW <t> x y) (SUBEWcarrymask <t> (CMPUconst y [31])))
+       // result: (MOVDGE <t> (SRW <t> x y) (MOVDconst [0]) (CMPUconst y [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XANDW)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSRW, t)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, t)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v1.AuxInt = 0
+               v.AddArg(v1)
                v2 := b.NewValue0(v.Pos, OpS390XCMPUconst, types.TypeFlags)
-               v2.AuxInt = 31
+               v2.AuxInt = 64
                v2.AddArg(y)
-               v1.AddArg(v2)
-               v.AddArg(v1)
+               v.AddArg(v2)
                return true
        }
 }
@@ -5393,27 +5864,44 @@ func rewriteValueS390X_OpRsh32Ux8_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
+       // match: (Rsh32Ux8 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
        // match: (Rsh32Ux8 <t> x y)
        // cond:
-       // result: (ANDW (SRW <t> x y) (SUBEWcarrymask <t> (CMPWUconst (MOVBZreg y) [31])))
+       // result: (MOVDGE <t> (SRW <t> x y) (MOVDconst [0]) (CMPWUconst (MOVBZreg y) [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XANDW)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSRW, t)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, t)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v1.AuxInt = 0
+               v.AddArg(v1)
                v2 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v2.AuxInt = 31
+               v2.AuxInt = 64
                v3 := b.NewValue0(v.Pos, OpS390XMOVBZreg, typ.UInt64)
                v3.AddArg(y)
                v2.AddArg(v3)
-               v1.AddArg(v2)
-               v.AddArg(v1)
+               v.AddArg(v2)
                return true
        }
 }
@@ -5422,29 +5910,41 @@ func rewriteValueS390X_OpRsh32x16_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Rsh32x16 <t> x y)
+       // match: (Rsh32x16 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRAW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRAW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (Rsh32x16 x y)
        // cond:
-       // result: (SRAW <t> x (ORW <y.Type> y (NOTW <y.Type> (SUBEWcarrymask <y.Type> (CMPWUconst (MOVHZreg y) [31])))))
+       // result: (SRAW x (MOVDGE <y.Type> y (MOVDconst <y.Type> [63]) (CMPWUconst (MOVHZreg y) [64])))
        for {
-               t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
                v.reset(OpS390XSRAW)
-               v.Type = t
                v.AddArg(x)
-               v0 := b.NewValue0(v.Pos, OpS390XORW, y.Type)
+               v0 := b.NewValue0(v.Pos, OpS390XMOVDGE, y.Type)
                v0.AddArg(y)
-               v1 := b.NewValue0(v.Pos, OpS390XNOTW, y.Type)
-               v2 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, y.Type)
-               v3 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v3.AuxInt = 31
-               v4 := b.NewValue0(v.Pos, OpS390XMOVHZreg, typ.UInt64)
-               v4.AddArg(y)
-               v3.AddArg(v4)
-               v2.AddArg(v3)
-               v1.AddArg(v2)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, y.Type)
+               v1.AuxInt = 63
                v0.AddArg(v1)
+               v2 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
+               v2.AuxInt = 64
+               v3 := b.NewValue0(v.Pos, OpS390XMOVHZreg, typ.UInt64)
+               v3.AddArg(y)
+               v2.AddArg(v3)
+               v0.AddArg(v2)
                v.AddArg(v0)
                return true
        }
@@ -5452,27 +5952,39 @@ func rewriteValueS390X_OpRsh32x16_0(v *Value) bool {
 func rewriteValueS390X_OpRsh32x32_0(v *Value) bool {
        b := v.Block
        _ = b
-       // match: (Rsh32x32 <t> x y)
+       // match: (Rsh32x32 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRAW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRAW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (Rsh32x32 x y)
        // cond:
-       // result: (SRAW <t> x (ORW <y.Type> y (NOTW <y.Type> (SUBEWcarrymask <y.Type> (CMPWUconst y [31])))))
+       // result: (SRAW x (MOVDGE <y.Type> y (MOVDconst <y.Type> [63]) (CMPWUconst y [64])))
        for {
-               t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
                v.reset(OpS390XSRAW)
-               v.Type = t
                v.AddArg(x)
-               v0 := b.NewValue0(v.Pos, OpS390XORW, y.Type)
+               v0 := b.NewValue0(v.Pos, OpS390XMOVDGE, y.Type)
                v0.AddArg(y)
-               v1 := b.NewValue0(v.Pos, OpS390XNOTW, y.Type)
-               v2 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, y.Type)
-               v3 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v3.AuxInt = 31
-               v3.AddArg(y)
-               v2.AddArg(v3)
-               v1.AddArg(v2)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, y.Type)
+               v1.AuxInt = 63
                v0.AddArg(v1)
+               v2 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
+               v2.AuxInt = 64
+               v2.AddArg(y)
+               v0.AddArg(v2)
                v.AddArg(v0)
                return true
        }
@@ -5480,27 +5992,39 @@ func rewriteValueS390X_OpRsh32x32_0(v *Value) bool {
 func rewriteValueS390X_OpRsh32x64_0(v *Value) bool {
        b := v.Block
        _ = b
-       // match: (Rsh32x64 <t> x y)
+       // match: (Rsh32x64 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRAW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRAW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (Rsh32x64 x y)
        // cond:
-       // result: (SRAW <t> x (OR <y.Type> y (NOT <y.Type> (SUBEcarrymask <y.Type> (CMPUconst y [31])))))
+       // result: (SRAW x (MOVDGE <y.Type> y (MOVDconst <y.Type> [63]) (CMPUconst y [64])))
        for {
-               t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
                v.reset(OpS390XSRAW)
-               v.Type = t
                v.AddArg(x)
-               v0 := b.NewValue0(v.Pos, OpS390XOR, y.Type)
+               v0 := b.NewValue0(v.Pos, OpS390XMOVDGE, y.Type)
                v0.AddArg(y)
-               v1 := b.NewValue0(v.Pos, OpS390XNOT, y.Type)
-               v2 := b.NewValue0(v.Pos, OpS390XSUBEcarrymask, y.Type)
-               v3 := b.NewValue0(v.Pos, OpS390XCMPUconst, types.TypeFlags)
-               v3.AuxInt = 31
-               v3.AddArg(y)
-               v2.AddArg(v3)
-               v1.AddArg(v2)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, y.Type)
+               v1.AuxInt = 63
                v0.AddArg(v1)
+               v2 := b.NewValue0(v.Pos, OpS390XCMPUconst, types.TypeFlags)
+               v2.AuxInt = 64
+               v2.AddArg(y)
+               v0.AddArg(v2)
                v.AddArg(v0)
                return true
        }
@@ -5510,29 +6034,41 @@ func rewriteValueS390X_OpRsh32x8_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Rsh32x8 <t> x y)
+       // match: (Rsh32x8 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRAW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRAW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (Rsh32x8 x y)
        // cond:
-       // result: (SRAW <t> x (ORW <y.Type> y (NOTW <y.Type> (SUBEWcarrymask <y.Type> (CMPWUconst (MOVBZreg y) [31])))))
+       // result: (SRAW x (MOVDGE <y.Type> y (MOVDconst <y.Type> [63]) (CMPWUconst (MOVBZreg y) [64])))
        for {
-               t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
                v.reset(OpS390XSRAW)
-               v.Type = t
                v.AddArg(x)
-               v0 := b.NewValue0(v.Pos, OpS390XORW, y.Type)
+               v0 := b.NewValue0(v.Pos, OpS390XMOVDGE, y.Type)
                v0.AddArg(y)
-               v1 := b.NewValue0(v.Pos, OpS390XNOTW, y.Type)
-               v2 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, y.Type)
-               v3 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v3.AuxInt = 31
-               v4 := b.NewValue0(v.Pos, OpS390XMOVBZreg, typ.UInt64)
-               v4.AddArg(y)
-               v3.AddArg(v4)
-               v2.AddArg(v3)
-               v1.AddArg(v2)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, y.Type)
+               v1.AuxInt = 63
                v0.AddArg(v1)
+               v2 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
+               v2.AuxInt = 64
+               v3 := b.NewValue0(v.Pos, OpS390XMOVBZreg, typ.UInt64)
+               v3.AddArg(y)
+               v2.AddArg(v3)
+               v0.AddArg(v2)
                v.AddArg(v0)
                return true
        }
@@ -5542,77 +6078,132 @@ func rewriteValueS390X_OpRsh64Ux16_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
+       // match: (Rsh64Ux16 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
        // match: (Rsh64Ux16 <t> x y)
        // cond:
-       // result: (AND (SRD <t> x y) (SUBEcarrymask <t> (CMPWUconst (MOVHZreg y) [63])))
+       // result: (MOVDGE <t> (SRD <t> x y) (MOVDconst [0]) (CMPWUconst (MOVHZreg y) [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XAND)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSRD, t)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XSUBEcarrymask, t)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v1.AuxInt = 0
+               v.AddArg(v1)
                v2 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v2.AuxInt = 63
+               v2.AuxInt = 64
                v3 := b.NewValue0(v.Pos, OpS390XMOVHZreg, typ.UInt64)
                v3.AddArg(y)
                v2.AddArg(v3)
-               v1.AddArg(v2)
-               v.AddArg(v1)
+               v.AddArg(v2)
                return true
        }
 }
 func rewriteValueS390X_OpRsh64Ux32_0(v *Value) bool {
        b := v.Block
        _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Rsh64Ux32 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
        // match: (Rsh64Ux32 <t> x y)
        // cond:
-       // result: (AND (SRD <t> x y) (SUBEcarrymask <t> (CMPWUconst y [63])))
+       // result: (MOVDGE <t> (SRD <t> x y) (MOVDconst [0]) (CMPWUconst y [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XAND)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSRD, t)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XSUBEcarrymask, t)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v1.AuxInt = 0
+               v.AddArg(v1)
                v2 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v2.AuxInt = 63
+               v2.AuxInt = 64
                v2.AddArg(y)
-               v1.AddArg(v2)
-               v.AddArg(v1)
+               v.AddArg(v2)
                return true
        }
 }
 func rewriteValueS390X_OpRsh64Ux64_0(v *Value) bool {
        b := v.Block
        _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
+       // match: (Rsh64Ux64 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
        // match: (Rsh64Ux64 <t> x y)
        // cond:
-       // result: (AND (SRD <t> x y) (SUBEcarrymask <t> (CMPUconst y [63])))
+       // result: (MOVDGE <t> (SRD <t> x y) (MOVDconst [0]) (CMPUconst y [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XAND)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSRD, t)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XSUBEcarrymask, t)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v1.AuxInt = 0
+               v.AddArg(v1)
                v2 := b.NewValue0(v.Pos, OpS390XCMPUconst, types.TypeFlags)
-               v2.AuxInt = 63
+               v2.AuxInt = 64
                v2.AddArg(y)
-               v1.AddArg(v2)
-               v.AddArg(v1)
+               v.AddArg(v2)
                return true
        }
 }
@@ -5621,27 +6212,44 @@ func rewriteValueS390X_OpRsh64Ux8_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
+       // match: (Rsh64Ux8 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
        // match: (Rsh64Ux8 <t> x y)
        // cond:
-       // result: (AND (SRD <t> x y) (SUBEcarrymask <t> (CMPWUconst (MOVBZreg y) [63])))
+       // result: (MOVDGE <t> (SRD <t> x y) (MOVDconst [0]) (CMPWUconst (MOVBZreg y) [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XAND)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSRD, t)
                v0.AddArg(x)
                v0.AddArg(y)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XSUBEcarrymask, t)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v1.AuxInt = 0
+               v.AddArg(v1)
                v2 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v2.AuxInt = 63
+               v2.AuxInt = 64
                v3 := b.NewValue0(v.Pos, OpS390XMOVBZreg, typ.UInt64)
                v3.AddArg(y)
                v2.AddArg(v3)
-               v1.AddArg(v2)
-               v.AddArg(v1)
+               v.AddArg(v2)
                return true
        }
 }
@@ -5650,29 +6258,41 @@ func rewriteValueS390X_OpRsh64x16_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Rsh64x16 <t> x y)
+       // match: (Rsh64x16 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRAD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRAD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (Rsh64x16 x y)
        // cond:
-       // result: (SRAD <t> x (ORW <y.Type> y (NOTW <y.Type> (SUBEWcarrymask <y.Type> (CMPWUconst (MOVHZreg y) [63])))))
+       // result: (SRAD x (MOVDGE <y.Type> y (MOVDconst <y.Type> [63]) (CMPWUconst (MOVHZreg y) [64])))
        for {
-               t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
                v.reset(OpS390XSRAD)
-               v.Type = t
                v.AddArg(x)
-               v0 := b.NewValue0(v.Pos, OpS390XORW, y.Type)
+               v0 := b.NewValue0(v.Pos, OpS390XMOVDGE, y.Type)
                v0.AddArg(y)
-               v1 := b.NewValue0(v.Pos, OpS390XNOTW, y.Type)
-               v2 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, y.Type)
-               v3 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v3.AuxInt = 63
-               v4 := b.NewValue0(v.Pos, OpS390XMOVHZreg, typ.UInt64)
-               v4.AddArg(y)
-               v3.AddArg(v4)
-               v2.AddArg(v3)
-               v1.AddArg(v2)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, y.Type)
+               v1.AuxInt = 63
                v0.AddArg(v1)
+               v2 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
+               v2.AuxInt = 64
+               v3 := b.NewValue0(v.Pos, OpS390XMOVHZreg, typ.UInt64)
+               v3.AddArg(y)
+               v2.AddArg(v3)
+               v0.AddArg(v2)
                v.AddArg(v0)
                return true
        }
@@ -5680,27 +6300,39 @@ func rewriteValueS390X_OpRsh64x16_0(v *Value) bool {
 func rewriteValueS390X_OpRsh64x32_0(v *Value) bool {
        b := v.Block
        _ = b
-       // match: (Rsh64x32 <t> x y)
+       // match: (Rsh64x32 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRAD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRAD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (Rsh64x32 x y)
        // cond:
-       // result: (SRAD <t> x (ORW <y.Type> y (NOTW <y.Type> (SUBEWcarrymask <y.Type> (CMPWUconst y [63])))))
+       // result: (SRAD x (MOVDGE <y.Type> y (MOVDconst <y.Type> [63]) (CMPWUconst y [64])))
        for {
-               t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
                v.reset(OpS390XSRAD)
-               v.Type = t
                v.AddArg(x)
-               v0 := b.NewValue0(v.Pos, OpS390XORW, y.Type)
+               v0 := b.NewValue0(v.Pos, OpS390XMOVDGE, y.Type)
                v0.AddArg(y)
-               v1 := b.NewValue0(v.Pos, OpS390XNOTW, y.Type)
-               v2 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, y.Type)
-               v3 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v3.AuxInt = 63
-               v3.AddArg(y)
-               v2.AddArg(v3)
-               v1.AddArg(v2)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, y.Type)
+               v1.AuxInt = 63
                v0.AddArg(v1)
+               v2 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
+               v2.AuxInt = 64
+               v2.AddArg(y)
+               v0.AddArg(v2)
                v.AddArg(v0)
                return true
        }
@@ -5708,27 +6340,39 @@ func rewriteValueS390X_OpRsh64x32_0(v *Value) bool {
 func rewriteValueS390X_OpRsh64x64_0(v *Value) bool {
        b := v.Block
        _ = b
-       // match: (Rsh64x64 <t> x y)
+       // match: (Rsh64x64 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRAD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRAD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (Rsh64x64 x y)
        // cond:
-       // result: (SRAD <t> x (OR <y.Type> y (NOT <y.Type> (SUBEcarrymask <y.Type> (CMPUconst y [63])))))
+       // result: (SRAD x (MOVDGE <y.Type> y (MOVDconst <y.Type> [63]) (CMPUconst y [64])))
        for {
-               t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
                v.reset(OpS390XSRAD)
-               v.Type = t
                v.AddArg(x)
-               v0 := b.NewValue0(v.Pos, OpS390XOR, y.Type)
+               v0 := b.NewValue0(v.Pos, OpS390XMOVDGE, y.Type)
                v0.AddArg(y)
-               v1 := b.NewValue0(v.Pos, OpS390XNOT, y.Type)
-               v2 := b.NewValue0(v.Pos, OpS390XSUBEcarrymask, y.Type)
-               v3 := b.NewValue0(v.Pos, OpS390XCMPUconst, types.TypeFlags)
-               v3.AuxInt = 63
-               v3.AddArg(y)
-               v2.AddArg(v3)
-               v1.AddArg(v2)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, y.Type)
+               v1.AuxInt = 63
                v0.AddArg(v1)
+               v2 := b.NewValue0(v.Pos, OpS390XCMPUconst, types.TypeFlags)
+               v2.AuxInt = 64
+               v2.AddArg(y)
+               v0.AddArg(v2)
                v.AddArg(v0)
                return true
        }
@@ -5738,29 +6382,41 @@ func rewriteValueS390X_OpRsh64x8_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Rsh64x8 <t> x y)
-       // cond:
-       // result: (SRAD <t> x (ORW <y.Type> y (NOTW <y.Type> (SUBEWcarrymask <y.Type> (CMPWUconst (MOVBZreg y) [63])))))
+       // match: (Rsh64x8 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRAD x y)
        for {
-               t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
                v.reset(OpS390XSRAD)
-               v.Type = t
                v.AddArg(x)
-               v0 := b.NewValue0(v.Pos, OpS390XORW, y.Type)
-               v0.AddArg(y)
-               v1 := b.NewValue0(v.Pos, OpS390XNOTW, y.Type)
-               v2 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, y.Type)
-               v3 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v3.AuxInt = 63
-               v4 := b.NewValue0(v.Pos, OpS390XMOVBZreg, typ.UInt64)
-               v4.AddArg(y)
-               v3.AddArg(v4)
-               v2.AddArg(v3)
-               v1.AddArg(v2)
+               v.AddArg(y)
+               return true
+       }
+       // match: (Rsh64x8 x y)
+       // cond:
+       // result: (SRAD x (MOVDGE <y.Type> y (MOVDconst <y.Type> [63]) (CMPWUconst (MOVBZreg y) [64])))
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpS390XSRAD)
+               v.AddArg(x)
+               v0 := b.NewValue0(v.Pos, OpS390XMOVDGE, y.Type)
+               v0.AddArg(y)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDconst, y.Type)
+               v1.AuxInt = 63
                v0.AddArg(v1)
+               v2 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
+               v2.AuxInt = 64
+               v3 := b.NewValue0(v.Pos, OpS390XMOVBZreg, typ.UInt64)
+               v3.AddArg(y)
+               v2.AddArg(v3)
+               v0.AddArg(v2)
                v.AddArg(v0)
                return true
        }
@@ -5770,29 +6426,48 @@ func rewriteValueS390X_OpRsh8Ux16_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
+       // match: (Rsh8Ux16 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRW (MOVBZreg x) y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRW)
+               v0 := b.NewValue0(v.Pos, OpS390XMOVBZreg, typ.UInt64)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               v.AddArg(y)
+               return true
+       }
        // match: (Rsh8Ux16 <t> x y)
        // cond:
-       // result: (ANDW (SRW <t> (MOVBZreg x) y) (SUBEWcarrymask <t> (CMPWUconst (MOVHZreg y) [7])))
+       // result: (MOVDGE <t> (SRW <t> (MOVBZreg x) y) (MOVDconst [0]) (CMPWUconst (MOVHZreg y) [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XANDW)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSRW, t)
                v1 := b.NewValue0(v.Pos, OpS390XMOVBZreg, typ.UInt64)
                v1.AddArg(x)
                v0.AddArg(v1)
                v0.AddArg(y)
                v.AddArg(v0)
-               v2 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, t)
+               v2 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v2.AuxInt = 0
+               v.AddArg(v2)
                v3 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v3.AuxInt = 7
+               v3.AuxInt = 64
                v4 := b.NewValue0(v.Pos, OpS390XMOVHZreg, typ.UInt64)
                v4.AddArg(y)
                v3.AddArg(v4)
-               v2.AddArg(v3)
-               v.AddArg(v2)
+               v.AddArg(v3)
                return true
        }
 }
@@ -5801,27 +6476,46 @@ func rewriteValueS390X_OpRsh8Ux32_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
+       // match: (Rsh8Ux32 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRW (MOVBZreg x) y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRW)
+               v0 := b.NewValue0(v.Pos, OpS390XMOVBZreg, typ.UInt64)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               v.AddArg(y)
+               return true
+       }
        // match: (Rsh8Ux32 <t> x y)
        // cond:
-       // result: (ANDW (SRW <t> (MOVBZreg x) y) (SUBEWcarrymask <t> (CMPWUconst y [7])))
+       // result: (MOVDGE <t> (SRW <t> (MOVBZreg x) y) (MOVDconst [0]) (CMPWUconst y [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XANDW)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSRW, t)
                v1 := b.NewValue0(v.Pos, OpS390XMOVBZreg, typ.UInt64)
                v1.AddArg(x)
                v0.AddArg(v1)
                v0.AddArg(y)
                v.AddArg(v0)
-               v2 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, t)
+               v2 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v2.AuxInt = 0
+               v.AddArg(v2)
                v3 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v3.AuxInt = 7
+               v3.AuxInt = 64
                v3.AddArg(y)
-               v2.AddArg(v3)
-               v.AddArg(v2)
+               v.AddArg(v3)
                return true
        }
 }
@@ -5830,27 +6524,46 @@ func rewriteValueS390X_OpRsh8Ux64_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
+       // match: (Rsh8Ux64 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRW (MOVBZreg x) y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRW)
+               v0 := b.NewValue0(v.Pos, OpS390XMOVBZreg, typ.UInt64)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               v.AddArg(y)
+               return true
+       }
        // match: (Rsh8Ux64 <t> x y)
        // cond:
-       // result: (ANDW (SRW <t> (MOVBZreg x) y) (SUBEWcarrymask <t> (CMPUconst y [7])))
+       // result: (MOVDGE <t> (SRW <t> (MOVBZreg x) y) (MOVDconst [0]) (CMPUconst y [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XANDW)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSRW, t)
                v1 := b.NewValue0(v.Pos, OpS390XMOVBZreg, typ.UInt64)
                v1.AddArg(x)
                v0.AddArg(v1)
                v0.AddArg(y)
                v.AddArg(v0)
-               v2 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, t)
+               v2 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v2.AuxInt = 0
+               v.AddArg(v2)
                v3 := b.NewValue0(v.Pos, OpS390XCMPUconst, types.TypeFlags)
-               v3.AuxInt = 7
+               v3.AuxInt = 64
                v3.AddArg(y)
-               v2.AddArg(v3)
-               v.AddArg(v2)
+               v.AddArg(v3)
                return true
        }
 }
@@ -5859,29 +6572,48 @@ func rewriteValueS390X_OpRsh8Ux8_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
+       // match: (Rsh8Ux8 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRW (MOVBZreg x) y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRW)
+               v0 := b.NewValue0(v.Pos, OpS390XMOVBZreg, typ.UInt64)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               v.AddArg(y)
+               return true
+       }
        // match: (Rsh8Ux8 <t> x y)
        // cond:
-       // result: (ANDW (SRW <t> (MOVBZreg x) y) (SUBEWcarrymask <t> (CMPWUconst (MOVBZreg y) [7])))
+       // result: (MOVDGE <t> (SRW <t> (MOVBZreg x) y) (MOVDconst [0]) (CMPWUconst (MOVBZreg y) [64]))
        for {
                t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpS390XANDW)
+               v.reset(OpS390XMOVDGE)
+               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XSRW, t)
                v1 := b.NewValue0(v.Pos, OpS390XMOVBZreg, typ.UInt64)
                v1.AddArg(x)
                v0.AddArg(v1)
                v0.AddArg(y)
                v.AddArg(v0)
-               v2 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, t)
+               v2 := b.NewValue0(v.Pos, OpS390XMOVDconst, typ.UInt64)
+               v2.AuxInt = 0
+               v.AddArg(v2)
                v3 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v3.AuxInt = 7
+               v3.AuxInt = 64
                v4 := b.NewValue0(v.Pos, OpS390XMOVBZreg, typ.UInt64)
                v4.AddArg(y)
                v3.AddArg(v4)
-               v2.AddArg(v3)
-               v.AddArg(v2)
+               v.AddArg(v3)
                return true
        }
 }
@@ -5890,31 +6622,45 @@ func rewriteValueS390X_OpRsh8x16_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Rsh8x16 <t> x y)
+       // match: (Rsh8x16 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRAW (MOVBreg x) y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRAW)
+               v0 := b.NewValue0(v.Pos, OpS390XMOVBreg, typ.Int64)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               v.AddArg(y)
+               return true
+       }
+       // match: (Rsh8x16 x y)
        // cond:
-       // result: (SRAW <t> (MOVBreg x) (ORW <y.Type> y (NOTW <y.Type> (SUBEWcarrymask <y.Type> (CMPWUconst (MOVHZreg y) [7])))))
+       // result: (SRAW (MOVBreg x) (MOVDGE <y.Type> y (MOVDconst <y.Type> [63]) (CMPWUconst (MOVHZreg y) [64])))
        for {
-               t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
                v.reset(OpS390XSRAW)
-               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XMOVBreg, typ.Int64)
                v0.AddArg(x)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XORW, y.Type)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDGE, y.Type)
                v1.AddArg(y)
-               v2 := b.NewValue0(v.Pos, OpS390XNOTW, y.Type)
-               v3 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, y.Type)
-               v4 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v4.AuxInt = 7
-               v5 := b.NewValue0(v.Pos, OpS390XMOVHZreg, typ.UInt64)
-               v5.AddArg(y)
-               v4.AddArg(v5)
-               v3.AddArg(v4)
-               v2.AddArg(v3)
+               v2 := b.NewValue0(v.Pos, OpS390XMOVDconst, y.Type)
+               v2.AuxInt = 63
                v1.AddArg(v2)
+               v3 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
+               v3.AuxInt = 64
+               v4 := b.NewValue0(v.Pos, OpS390XMOVHZreg, typ.UInt64)
+               v4.AddArg(y)
+               v3.AddArg(v4)
+               v1.AddArg(v3)
                v.AddArg(v1)
                return true
        }
@@ -5924,29 +6670,43 @@ func rewriteValueS390X_OpRsh8x32_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Rsh8x32 <t> x y)
+       // match: (Rsh8x32 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRAW (MOVBreg x) y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRAW)
+               v0 := b.NewValue0(v.Pos, OpS390XMOVBreg, typ.Int64)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               v.AddArg(y)
+               return true
+       }
+       // match: (Rsh8x32 x y)
        // cond:
-       // result: (SRAW <t> (MOVBreg x) (ORW <y.Type> y (NOTW <y.Type> (SUBEWcarrymask <y.Type> (CMPWUconst y [7])))))
+       // result: (SRAW (MOVBreg x) (MOVDGE <y.Type> y (MOVDconst <y.Type> [63]) (CMPWUconst y [64])))
        for {
-               t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
                v.reset(OpS390XSRAW)
-               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XMOVBreg, typ.Int64)
                v0.AddArg(x)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XORW, y.Type)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDGE, y.Type)
                v1.AddArg(y)
-               v2 := b.NewValue0(v.Pos, OpS390XNOTW, y.Type)
-               v3 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, y.Type)
-               v4 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v4.AuxInt = 7
-               v4.AddArg(y)
-               v3.AddArg(v4)
-               v2.AddArg(v3)
+               v2 := b.NewValue0(v.Pos, OpS390XMOVDconst, y.Type)
+               v2.AuxInt = 63
                v1.AddArg(v2)
+               v3 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
+               v3.AuxInt = 64
+               v3.AddArg(y)
+               v1.AddArg(v3)
                v.AddArg(v1)
                return true
        }
@@ -5956,29 +6716,43 @@ func rewriteValueS390X_OpRsh8x64_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Rsh8x64 <t> x y)
+       // match: (Rsh8x64 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRAW (MOVBreg x) y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRAW)
+               v0 := b.NewValue0(v.Pos, OpS390XMOVBreg, typ.Int64)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               v.AddArg(y)
+               return true
+       }
+       // match: (Rsh8x64 x y)
        // cond:
-       // result: (SRAW <t> (MOVBreg x) (OR <y.Type> y (NOT <y.Type> (SUBEcarrymask <y.Type> (CMPUconst y [7])))))
+       // result: (SRAW (MOVBreg x) (MOVDGE <y.Type> y (MOVDconst <y.Type> [63]) (CMPUconst y [64])))
        for {
-               t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
                v.reset(OpS390XSRAW)
-               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XMOVBreg, typ.Int64)
                v0.AddArg(x)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XOR, y.Type)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDGE, y.Type)
                v1.AddArg(y)
-               v2 := b.NewValue0(v.Pos, OpS390XNOT, y.Type)
-               v3 := b.NewValue0(v.Pos, OpS390XSUBEcarrymask, y.Type)
-               v4 := b.NewValue0(v.Pos, OpS390XCMPUconst, types.TypeFlags)
-               v4.AuxInt = 7
-               v4.AddArg(y)
-               v3.AddArg(v4)
-               v2.AddArg(v3)
+               v2 := b.NewValue0(v.Pos, OpS390XMOVDconst, y.Type)
+               v2.AuxInt = 63
                v1.AddArg(v2)
+               v3 := b.NewValue0(v.Pos, OpS390XCMPUconst, types.TypeFlags)
+               v3.AuxInt = 64
+               v3.AddArg(y)
+               v1.AddArg(v3)
                v.AddArg(v1)
                return true
        }
@@ -5988,31 +6762,45 @@ func rewriteValueS390X_OpRsh8x8_0(v *Value) bool {
        _ = b
        typ := &b.Func.Config.Types
        _ = typ
-       // match: (Rsh8x8 <t> x y)
+       // match: (Rsh8x8 x y)
+       // cond: shiftIsBounded(v)
+       // result: (SRAW (MOVBreg x) y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               y := v.Args[1]
+               if !(shiftIsBounded(v)) {
+                       break
+               }
+               v.reset(OpS390XSRAW)
+               v0 := b.NewValue0(v.Pos, OpS390XMOVBreg, typ.Int64)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               v.AddArg(y)
+               return true
+       }
+       // match: (Rsh8x8 x y)
        // cond:
-       // result: (SRAW <t> (MOVBreg x) (ORW <y.Type> y (NOTW <y.Type> (SUBEWcarrymask <y.Type> (CMPWUconst (MOVBZreg y) [7])))))
+       // result: (SRAW (MOVBreg x) (MOVDGE <y.Type> y (MOVDconst <y.Type> [63]) (CMPWUconst (MOVBZreg y) [64])))
        for {
-               t := v.Type
                _ = v.Args[1]
                x := v.Args[0]
                y := v.Args[1]
                v.reset(OpS390XSRAW)
-               v.Type = t
                v0 := b.NewValue0(v.Pos, OpS390XMOVBreg, typ.Int64)
                v0.AddArg(x)
                v.AddArg(v0)
-               v1 := b.NewValue0(v.Pos, OpS390XORW, y.Type)
+               v1 := b.NewValue0(v.Pos, OpS390XMOVDGE, y.Type)
                v1.AddArg(y)
-               v2 := b.NewValue0(v.Pos, OpS390XNOTW, y.Type)
-               v3 := b.NewValue0(v.Pos, OpS390XSUBEWcarrymask, y.Type)
-               v4 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
-               v4.AuxInt = 7
-               v5 := b.NewValue0(v.Pos, OpS390XMOVBZreg, typ.UInt64)
-               v5.AddArg(y)
-               v4.AddArg(v5)
-               v3.AddArg(v4)
-               v2.AddArg(v3)
+               v2 := b.NewValue0(v.Pos, OpS390XMOVDconst, y.Type)
+               v2.AuxInt = 63
                v1.AddArg(v2)
+               v3 := b.NewValue0(v.Pos, OpS390XCMPWUconst, types.TypeFlags)
+               v3.AuxInt = 64
+               v4 := b.NewValue0(v.Pos, OpS390XMOVBZreg, typ.UInt64)
+               v4.AddArg(y)
+               v3.AddArg(v4)
+               v1.AddArg(v3)
                v.AddArg(v1)
                return true
        }
@@ -6966,6 +7754,10 @@ func rewriteValueS390X_OpS390XADDload_0(v *Value) bool {
        return false
 }
 func rewriteValueS390X_OpS390XAND_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
        // match: (AND x (MOVDconst [c]))
        // cond: is32Bit(c) && c < 0
        // result: (ANDconst [c] x)
@@ -7004,6 +7796,48 @@ func rewriteValueS390X_OpS390XAND_0(v *Value) bool {
                v.AddArg(x)
                return true
        }
+       // match: (AND x (MOVDconst [c]))
+       // cond: is32Bit(c) && c >= 0
+       // result: (MOVWZreg (ANDWconst <typ.UInt32> [int64(int32(c))] x))
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVDconst {
+                       break
+               }
+               c := v_1.AuxInt
+               if !(is32Bit(c) && c >= 0) {
+                       break
+               }
+               v.reset(OpS390XMOVWZreg)
+               v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32)
+               v0.AuxInt = int64(int32(c))
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (AND (MOVDconst [c]) x)
+       // cond: is32Bit(c) && c >= 0
+       // result: (MOVWZreg (ANDWconst <typ.UInt32> [int64(int32(c))] x))
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpS390XMOVDconst {
+                       break
+               }
+               c := v_0.AuxInt
+               x := v.Args[1]
+               if !(is32Bit(c) && c >= 0) {
+                       break
+               }
+               v.reset(OpS390XMOVWZreg)
+               v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32)
+               v0.AuxInt = int64(int32(c))
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
        // match: (AND x (MOVDconst [0xFF]))
        // cond:
        // result: (MOVBZreg x)
@@ -7106,6 +7940,9 @@ func rewriteValueS390X_OpS390XAND_0(v *Value) bool {
                v.AddArg(x)
                return true
        }
+       return false
+}
+func rewriteValueS390X_OpS390XAND_10(v *Value) bool {
        // match: (AND (MOVDconst [c]) (MOVDconst [d]))
        // cond:
        // result: (MOVDconst [c&d])
@@ -7144,9 +7981,6 @@ func rewriteValueS390X_OpS390XAND_0(v *Value) bool {
                v.AuxInt = c & d
                return true
        }
-       return false
-}
-func rewriteValueS390X_OpS390XAND_10(v *Value) bool {
        // match: (AND x x)
        // cond:
        // result: x
@@ -7977,6 +8811,140 @@ func rewriteValueS390X_OpS390XCMPUconst_0(v *Value) bool {
                v.reset(OpS390XFlagGT)
                return true
        }
+       // match: (CMPUconst (SRDconst _ [c]) [n])
+       // cond: c > 0 && c < 64 && (1<<uint(64-c)) <= uint64(n)
+       // result: (FlagLT)
+       for {
+               n := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpS390XSRDconst {
+                       break
+               }
+               c := v_0.AuxInt
+               if !(c > 0 && c < 64 && (1<<uint(64-c)) <= uint64(n)) {
+                       break
+               }
+               v.reset(OpS390XFlagLT)
+               return true
+       }
+       // match: (CMPUconst (MOVWZreg x) [c])
+       // cond:
+       // result: (CMPWUconst x [c])
+       for {
+               c := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpS390XMOVWZreg {
+                       break
+               }
+               x := v_0.Args[0]
+               v.reset(OpS390XCMPWUconst)
+               v.AuxInt = c
+               v.AddArg(x)
+               return true
+       }
+       // match: (CMPUconst x:(MOVHreg _) [c])
+       // cond:
+       // result: (CMPWUconst x [c])
+       for {
+               c := v.AuxInt
+               x := v.Args[0]
+               if x.Op != OpS390XMOVHreg {
+                       break
+               }
+               v.reset(OpS390XCMPWUconst)
+               v.AuxInt = c
+               v.AddArg(x)
+               return true
+       }
+       // match: (CMPUconst x:(MOVHZreg _) [c])
+       // cond:
+       // result: (CMPWUconst x [c])
+       for {
+               c := v.AuxInt
+               x := v.Args[0]
+               if x.Op != OpS390XMOVHZreg {
+                       break
+               }
+               v.reset(OpS390XCMPWUconst)
+               v.AuxInt = c
+               v.AddArg(x)
+               return true
+       }
+       // match: (CMPUconst x:(MOVBreg _) [c])
+       // cond:
+       // result: (CMPWUconst x [c])
+       for {
+               c := v.AuxInt
+               x := v.Args[0]
+               if x.Op != OpS390XMOVBreg {
+                       break
+               }
+               v.reset(OpS390XCMPWUconst)
+               v.AuxInt = c
+               v.AddArg(x)
+               return true
+       }
+       // match: (CMPUconst x:(MOVBZreg _) [c])
+       // cond:
+       // result: (CMPWUconst x [c])
+       for {
+               c := v.AuxInt
+               x := v.Args[0]
+               if x.Op != OpS390XMOVBZreg {
+                       break
+               }
+               v.reset(OpS390XCMPWUconst)
+               v.AuxInt = c
+               v.AddArg(x)
+               return true
+       }
+       // match: (CMPUconst (MOVWZreg x:(ANDWconst [m] _)) [c])
+       // cond: int32(m) >= 0
+       // result: (CMPWUconst x [c])
+       for {
+               c := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpS390XMOVWZreg {
+                       break
+               }
+               x := v_0.Args[0]
+               if x.Op != OpS390XANDWconst {
+                       break
+               }
+               m := x.AuxInt
+               if !(int32(m) >= 0) {
+                       break
+               }
+               v.reset(OpS390XCMPWUconst)
+               v.AuxInt = c
+               v.AddArg(x)
+               return true
+       }
+       return false
+}
+func rewriteValueS390X_OpS390XCMPUconst_10(v *Value) bool {
+       // match: (CMPUconst (MOVWreg x:(ANDWconst [m] _)) [c])
+       // cond: int32(m) >= 0
+       // result: (CMPWUconst x [c])
+       for {
+               c := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpS390XMOVWreg {
+                       break
+               }
+               x := v_0.Args[0]
+               if x.Op != OpS390XANDWconst {
+                       break
+               }
+               m := x.AuxInt
+               if !(int32(m) >= 0) {
+                       break
+               }
+               v.reset(OpS390XCMPWUconst)
+               v.AuxInt = c
+               v.AddArg(x)
+               return true
+       }
        return false
 }
 func rewriteValueS390X_OpS390XCMPW_0(v *Value) bool {
@@ -8016,6 +8984,70 @@ func rewriteValueS390X_OpS390XCMPW_0(v *Value) bool {
                v.AddArg(v0)
                return true
        }
+       // match: (CMPW x (MOVWreg y))
+       // cond:
+       // result: (CMPW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVWreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XCMPW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (CMPW x (MOVWZreg y))
+       // cond:
+       // result: (CMPW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVWZreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XCMPW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (CMPW (MOVWreg x) y)
+       // cond:
+       // result: (CMPW x y)
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpS390XMOVWreg {
+                       break
+               }
+               x := v_0.Args[0]
+               y := v.Args[1]
+               v.reset(OpS390XCMPW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (CMPW (MOVWZreg x) y)
+       // cond:
+       // result: (CMPW x y)
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpS390XMOVWZreg {
+                       break
+               }
+               x := v_0.Args[0]
+               y := v.Args[1]
+               v.reset(OpS390XCMPW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
        return false
 }
 func rewriteValueS390X_OpS390XCMPWU_0(v *Value) bool {
@@ -8055,6 +9087,70 @@ func rewriteValueS390X_OpS390XCMPWU_0(v *Value) bool {
                v.AddArg(v0)
                return true
        }
+       // match: (CMPWU x (MOVWreg y))
+       // cond:
+       // result: (CMPWU x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVWreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XCMPWU)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (CMPWU x (MOVWZreg y))
+       // cond:
+       // result: (CMPWU x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVWZreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XCMPWU)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (CMPWU (MOVWreg x) y)
+       // cond:
+       // result: (CMPWU x y)
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpS390XMOVWreg {
+                       break
+               }
+               x := v_0.Args[0]
+               y := v.Args[1]
+               v.reset(OpS390XCMPWU)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (CMPWU (MOVWZreg x) y)
+       // cond:
+       // result: (CMPWU x y)
+       for {
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpS390XMOVWZreg {
+                       break
+               }
+               x := v_0.Args[0]
+               y := v.Args[1]
+               v.reset(OpS390XCMPWU)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
        return false
 }
 func rewriteValueS390X_OpS390XCMPWUconst_0(v *Value) bool {
@@ -8106,6 +9202,98 @@ func rewriteValueS390X_OpS390XCMPWUconst_0(v *Value) bool {
                v.reset(OpS390XFlagGT)
                return true
        }
+       // match: (CMPWUconst (MOVBZreg _) [c])
+       // cond: 0xff < c
+       // result: (FlagLT)
+       for {
+               c := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpS390XMOVBZreg {
+                       break
+               }
+               if !(0xff < c) {
+                       break
+               }
+               v.reset(OpS390XFlagLT)
+               return true
+       }
+       // match: (CMPWUconst (MOVHZreg _) [c])
+       // cond: 0xffff < c
+       // result: (FlagLT)
+       for {
+               c := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpS390XMOVHZreg {
+                       break
+               }
+               if !(0xffff < c) {
+                       break
+               }
+               v.reset(OpS390XFlagLT)
+               return true
+       }
+       // match: (CMPWUconst (SRWconst _ [c]) [n])
+       // cond: c > 0 && c < 32 && (1<<uint(32-c)) <= uint32(n)
+       // result: (FlagLT)
+       for {
+               n := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpS390XSRWconst {
+                       break
+               }
+               c := v_0.AuxInt
+               if !(c > 0 && c < 32 && (1<<uint(32-c)) <= uint32(n)) {
+                       break
+               }
+               v.reset(OpS390XFlagLT)
+               return true
+       }
+       // match: (CMPWUconst (ANDWconst _ [m]) [n])
+       // cond: uint32(m) < uint32(n)
+       // result: (FlagLT)
+       for {
+               n := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpS390XANDWconst {
+                       break
+               }
+               m := v_0.AuxInt
+               if !(uint32(m) < uint32(n)) {
+                       break
+               }
+               v.reset(OpS390XFlagLT)
+               return true
+       }
+       // match: (CMPWUconst (MOVWreg x) [c])
+       // cond:
+       // result: (CMPWUconst x [c])
+       for {
+               c := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpS390XMOVWreg {
+                       break
+               }
+               x := v_0.Args[0]
+               v.reset(OpS390XCMPWUconst)
+               v.AuxInt = c
+               v.AddArg(x)
+               return true
+       }
+       // match: (CMPWUconst (MOVWZreg x) [c])
+       // cond:
+       // result: (CMPWUconst x [c])
+       for {
+               c := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpS390XMOVWZreg {
+                       break
+               }
+               x := v_0.Args[0]
+               v.reset(OpS390XCMPWUconst)
+               v.AuxInt = c
+               v.AddArg(x)
+               return true
+       }
        return false
 }
 func rewriteValueS390X_OpS390XCMPWconst_0(v *Value) bool {
@@ -8157,9 +9345,39 @@ func rewriteValueS390X_OpS390XCMPWconst_0(v *Value) bool {
                v.reset(OpS390XFlagGT)
                return true
        }
-       // match: (CMPWconst (SRWconst _ [c]) [n])
-       // cond: 0 <= n && 0 < c && c <= 32 && (1<<uint64(32-c)) <= uint64(n)
+       // match: (CMPWconst (MOVBZreg _) [c])
+       // cond: 0xff < c
+       // result: (FlagLT)
+       for {
+               c := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpS390XMOVBZreg {
+                       break
+               }
+               if !(0xff < c) {
+                       break
+               }
+               v.reset(OpS390XFlagLT)
+               return true
+       }
+       // match: (CMPWconst (MOVHZreg _) [c])
+       // cond: 0xffff < c
        // result: (FlagLT)
+       for {
+               c := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpS390XMOVHZreg {
+                       break
+               }
+               if !(0xffff < c) {
+                       break
+               }
+               v.reset(OpS390XFlagLT)
+               return true
+       }
+       // match: (CMPWconst (SRWconst _ [c]) [n])
+       // cond: c > 0 && n < 0
+       // result: (FlagGT)
        for {
                n := v.AuxInt
                v_0 := v.Args[0]
@@ -8167,14 +9385,14 @@ func rewriteValueS390X_OpS390XCMPWconst_0(v *Value) bool {
                        break
                }
                c := v_0.AuxInt
-               if !(0 <= n && 0 < c && c <= 32 && (1<<uint64(32-c)) <= uint64(n)) {
+               if !(c > 0 && n < 0) {
                        break
                }
-               v.reset(OpS390XFlagLT)
+               v.reset(OpS390XFlagGT)
                return true
        }
        // match: (CMPWconst (ANDWconst _ [m]) [n])
-       // cond: 0 <= int32(m) && int32(m) < int32(n)
+       // cond: int32(m) >= 0 && int32(m) < int32(n)
        // result: (FlagLT)
        for {
                n := v.AuxInt
@@ -8183,12 +9401,60 @@ func rewriteValueS390X_OpS390XCMPWconst_0(v *Value) bool {
                        break
                }
                m := v_0.AuxInt
-               if !(0 <= int32(m) && int32(m) < int32(n)) {
+               if !(int32(m) >= 0 && int32(m) < int32(n)) {
                        break
                }
                v.reset(OpS390XFlagLT)
                return true
        }
+       // match: (CMPWconst x:(SRWconst _ [c]) [n])
+       // cond: c > 0 && n >= 0
+       // result: (CMPWUconst x [n])
+       for {
+               n := v.AuxInt
+               x := v.Args[0]
+               if x.Op != OpS390XSRWconst {
+                       break
+               }
+               c := x.AuxInt
+               if !(c > 0 && n >= 0) {
+                       break
+               }
+               v.reset(OpS390XCMPWUconst)
+               v.AuxInt = n
+               v.AddArg(x)
+               return true
+       }
+       // match: (CMPWconst (MOVWreg x) [c])
+       // cond:
+       // result: (CMPWconst x [c])
+       for {
+               c := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpS390XMOVWreg {
+                       break
+               }
+               x := v_0.Args[0]
+               v.reset(OpS390XCMPWconst)
+               v.AuxInt = c
+               v.AddArg(x)
+               return true
+       }
+       // match: (CMPWconst (MOVWZreg x) [c])
+       // cond:
+       // result: (CMPWconst x [c])
+       for {
+               c := v.AuxInt
+               v_0 := v.Args[0]
+               if v_0.Op != OpS390XMOVWZreg {
+                       break
+               }
+               x := v_0.Args[0]
+               v.reset(OpS390XCMPWconst)
+               v.AuxInt = c
+               v.AddArg(x)
+               return true
+       }
        return false
 }
 func rewriteValueS390X_OpS390XCMPconst_0(v *Value) bool {
@@ -8240,81 +9506,156 @@ func rewriteValueS390X_OpS390XCMPconst_0(v *Value) bool {
                v.reset(OpS390XFlagGT)
                return true
        }
-       // match: (CMPconst (MOVBZreg _) [c])
-       // cond: 0xFF < c
-       // result: (FlagLT)
+       // match: (CMPconst (SRDconst _ [c]) [n])
+       // cond: c > 0 && n < 0
+       // result: (FlagGT)
        for {
-               c := v.AuxInt
+               n := v.AuxInt
                v_0 := v.Args[0]
-               if v_0.Op != OpS390XMOVBZreg {
+               if v_0.Op != OpS390XSRDconst {
                        break
                }
-               if !(0xFF < c) {
+               c := v_0.AuxInt
+               if !(c > 0 && n < 0) {
                        break
                }
-               v.reset(OpS390XFlagLT)
+               v.reset(OpS390XFlagGT)
                return true
        }
-       // match: (CMPconst (MOVHZreg _) [c])
-       // cond: 0xFFFF < c
-       // result: (FlagLT)
+       // match: (CMPconst (MOVWreg x) [c])
+       // cond:
+       // result: (CMPWconst x [c])
        for {
                c := v.AuxInt
                v_0 := v.Args[0]
-               if v_0.Op != OpS390XMOVHZreg {
+               if v_0.Op != OpS390XMOVWreg {
                        break
                }
-               if !(0xFFFF < c) {
+               x := v_0.Args[0]
+               v.reset(OpS390XCMPWconst)
+               v.AuxInt = c
+               v.AddArg(x)
+               return true
+       }
+       // match: (CMPconst x:(MOVHreg _) [c])
+       // cond:
+       // result: (CMPWconst x [c])
+       for {
+               c := v.AuxInt
+               x := v.Args[0]
+               if x.Op != OpS390XMOVHreg {
                        break
                }
-               v.reset(OpS390XFlagLT)
+               v.reset(OpS390XCMPWconst)
+               v.AuxInt = c
+               v.AddArg(x)
                return true
        }
-       // match: (CMPconst (MOVWZreg _) [c])
-       // cond: 0xFFFFFFFF < c
-       // result: (FlagLT)
+       // match: (CMPconst x:(MOVHZreg _) [c])
+       // cond:
+       // result: (CMPWconst x [c])
+       for {
+               c := v.AuxInt
+               x := v.Args[0]
+               if x.Op != OpS390XMOVHZreg {
+                       break
+               }
+               v.reset(OpS390XCMPWconst)
+               v.AuxInt = c
+               v.AddArg(x)
+               return true
+       }
+       // match: (CMPconst x:(MOVBreg _) [c])
+       // cond:
+       // result: (CMPWconst x [c])
+       for {
+               c := v.AuxInt
+               x := v.Args[0]
+               if x.Op != OpS390XMOVBreg {
+                       break
+               }
+               v.reset(OpS390XCMPWconst)
+               v.AuxInt = c
+               v.AddArg(x)
+               return true
+       }
+       // match: (CMPconst x:(MOVBZreg _) [c])
+       // cond:
+       // result: (CMPWconst x [c])
+       for {
+               c := v.AuxInt
+               x := v.Args[0]
+               if x.Op != OpS390XMOVBZreg {
+                       break
+               }
+               v.reset(OpS390XCMPWconst)
+               v.AuxInt = c
+               v.AddArg(x)
+               return true
+       }
+       // match: (CMPconst (MOVWZreg x:(ANDWconst [m] _)) [c])
+       // cond: int32(m) >= 0 && c >= 0
+       // result: (CMPWUconst x [c])
        for {
                c := v.AuxInt
                v_0 := v.Args[0]
                if v_0.Op != OpS390XMOVWZreg {
                        break
                }
-               if !(0xFFFFFFFF < c) {
+               x := v_0.Args[0]
+               if x.Op != OpS390XANDWconst {
                        break
                }
-               v.reset(OpS390XFlagLT)
+               m := x.AuxInt
+               if !(int32(m) >= 0 && c >= 0) {
+                       break
+               }
+               v.reset(OpS390XCMPWUconst)
+               v.AuxInt = c
+               v.AddArg(x)
                return true
        }
-       // match: (CMPconst (SRDconst _ [c]) [n])
-       // cond: 0 <= n && 0 < c && c <= 64 && (1<<uint64(64-c)) <= uint64(n)
-       // result: (FlagLT)
+       return false
+}
+func rewriteValueS390X_OpS390XCMPconst_10(v *Value) bool {
+       // match: (CMPconst (MOVWreg x:(ANDWconst [m] _)) [c])
+       // cond: int32(m) >= 0 && c >= 0
+       // result: (CMPWUconst x [c])
        for {
-               n := v.AuxInt
+               c := v.AuxInt
                v_0 := v.Args[0]
-               if v_0.Op != OpS390XSRDconst {
+               if v_0.Op != OpS390XMOVWreg {
                        break
                }
-               c := v_0.AuxInt
-               if !(0 <= n && 0 < c && c <= 64 && (1<<uint64(64-c)) <= uint64(n)) {
+               x := v_0.Args[0]
+               if x.Op != OpS390XANDWconst {
                        break
                }
-               v.reset(OpS390XFlagLT)
+               m := x.AuxInt
+               if !(int32(m) >= 0 && c >= 0) {
+                       break
+               }
+               v.reset(OpS390XCMPWUconst)
+               v.AuxInt = c
+               v.AddArg(x)
                return true
        }
-       // match: (CMPconst (ANDconst _ [m]) [n])
-       // cond: 0 <= m && m < n
-       // result: (FlagLT)
+       // match: (CMPconst x:(SRDconst _ [c]) [n])
+       // cond: c > 0 && n >= 0
+       // result: (CMPUconst x [n])
        for {
                n := v.AuxInt
-               v_0 := v.Args[0]
-               if v_0.Op != OpS390XANDconst {
+               x := v.Args[0]
+               if x.Op != OpS390XSRDconst {
                        break
                }
-               m := v_0.AuxInt
-               if !(0 <= m && m < n) {
+               c := x.AuxInt
+               if !(c > 0 && n >= 0) {
                        break
                }
-               v.reset(OpS390XFlagLT)
+               v.reset(OpS390XCMPUconst)
+               v.AuxInt = n
+               v.AddArg(x)
                return true
        }
        return false
@@ -9997,6 +11338,8 @@ func rewriteValueS390X_OpS390XMOVBZreg_0(v *Value) bool {
 func rewriteValueS390X_OpS390XMOVBZreg_10(v *Value) bool {
        b := v.Block
        _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
        // match: (MOVBZreg x:(MOVBZreg _))
        // cond:
        // result: (MOVDreg x)
@@ -10143,6 +11486,23 @@ func rewriteValueS390X_OpS390XMOVBZreg_10(v *Value) bool {
                v0.AddArg(mem)
                return true
        }
+       // match: (MOVBZreg (ANDWconst [m] x))
+       // cond:
+       // result: (MOVWZreg (ANDWconst <typ.UInt32> [int64( uint8(m))] x))
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpS390XANDWconst {
+                       break
+               }
+               m := v_0.AuxInt
+               x := v_0.Args[0]
+               v.reset(OpS390XMOVWZreg)
+               v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32)
+               v0.AuxInt = int64(uint8(m))
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
        return false
 }
 func rewriteValueS390X_OpS390XMOVBload_0(v *Value) bool {
@@ -10389,6 +11749,8 @@ func rewriteValueS390X_OpS390XMOVBloadidx_0(v *Value) bool {
 func rewriteValueS390X_OpS390XMOVBreg_0(v *Value) bool {
        b := v.Block
        _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
        // match: (MOVBreg x:(MOVBload _ _))
        // cond:
        // result: (MOVDreg x)
@@ -10564,6 +11926,26 @@ func rewriteValueS390X_OpS390XMOVBreg_0(v *Value) bool {
                v0.AddArg(mem)
                return true
        }
+       // match: (MOVBreg (ANDWconst [m] x))
+       // cond: int8(m) >= 0
+       // result: (MOVWZreg (ANDWconst <typ.UInt32> [int64( uint8(m))] x))
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpS390XANDWconst {
+                       break
+               }
+               m := v_0.AuxInt
+               x := v_0.Args[0]
+               if !(int8(m) >= 0) {
+                       break
+               }
+               v.reset(OpS390XMOVWZreg)
+               v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32)
+               v0.AuxInt = int64(uint8(m))
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
        return false
 }
 func rewriteValueS390X_OpS390XMOVBstore_0(v *Value) bool {
@@ -16539,6 +17921,8 @@ func rewriteValueS390X_OpS390XMOVHZreg_0(v *Value) bool {
 func rewriteValueS390X_OpS390XMOVHZreg_10(v *Value) bool {
        b := v.Block
        _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
        // match: (MOVHZreg x:(MOVHloadidx [off] {sym} ptr idx mem))
        // cond: x.Uses == 1 && clobber(x)
        // result: @x.Block (MOVHZloadidx <v.Type> [off] {sym} ptr idx mem)
@@ -16567,6 +17951,23 @@ func rewriteValueS390X_OpS390XMOVHZreg_10(v *Value) bool {
                v0.AddArg(mem)
                return true
        }
+       // match: (MOVHZreg (ANDWconst [m] x))
+       // cond:
+       // result: (MOVWZreg (ANDWconst <typ.UInt32> [int64(uint16(m))] x))
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpS390XANDWconst {
+                       break
+               }
+               m := v_0.AuxInt
+               x := v_0.Args[0]
+               v.reset(OpS390XMOVWZreg)
+               v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32)
+               v0.AuxInt = int64(uint16(m))
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
        return false
 }
 func rewriteValueS390X_OpS390XMOVHload_0(v *Value) bool {
@@ -16962,6 +18363,8 @@ func rewriteValueS390X_OpS390XMOVHreg_0(v *Value) bool {
 func rewriteValueS390X_OpS390XMOVHreg_10(v *Value) bool {
        b := v.Block
        _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
        // match: (MOVHreg x:(MOVHload [off] {sym} ptr mem))
        // cond: x.Uses == 1 && clobber(x)
        // result: @x.Block (MOVHload <v.Type> [off] {sym} ptr mem)
@@ -17044,6 +18447,26 @@ func rewriteValueS390X_OpS390XMOVHreg_10(v *Value) bool {
                v0.AddArg(mem)
                return true
        }
+       // match: (MOVHreg (ANDWconst [m] x))
+       // cond: int16(m) >= 0
+       // result: (MOVWZreg (ANDWconst <typ.UInt32> [int64(uint16(m))] x))
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpS390XANDWconst {
+                       break
+               }
+               m := v_0.AuxInt
+               x := v_0.Args[0]
+               if !(int16(m) >= 0) {
+                       break
+               }
+               v.reset(OpS390XMOVWZreg)
+               v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32)
+               v0.AuxInt = int64(uint16(m))
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
        return false
 }
 func rewriteValueS390X_OpS390XMOVHstore_0(v *Value) bool {
@@ -37118,9 +38541,13 @@ func rewriteValueS390X_OpS390XORload_0(v *Value) bool {
        return false
 }
 func rewriteValueS390X_OpS390XSLD_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
        // match: (SLD x (MOVDconst [c]))
        // cond:
-       // result: (SLDconst [c&63] x)
+       // result: (SLDconst x [c&63])
        for {
                _ = v.Args[1]
                x := v.Args[0]
@@ -37134,17 +38561,183 @@ func rewriteValueS390X_OpS390XSLD_0(v *Value) bool {
                v.AddArg(x)
                return true
        }
-       // match: (SLD x (ANDconst [63] y))
+       // match: (SLD x (AND (MOVDconst [c]) y))
+       // cond:
+       // result: (SLD x (ANDWconst <typ.UInt32> [c&63] y))
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XAND {
+                       break
+               }
+               _ = v_1.Args[1]
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpS390XMOVDconst {
+                       break
+               }
+               c := v_1_0.AuxInt
+               y := v_1.Args[1]
+               v.reset(OpS390XSLD)
+               v.AddArg(x)
+               v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32)
+               v0.AuxInt = c & 63
+               v0.AddArg(y)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (SLD x (AND y (MOVDconst [c])))
+       // cond:
+       // result: (SLD x (ANDWconst <typ.UInt32> [c&63] y))
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XAND {
+                       break
+               }
+               _ = v_1.Args[1]
+               y := v_1.Args[0]
+               v_1_1 := v_1.Args[1]
+               if v_1_1.Op != OpS390XMOVDconst {
+                       break
+               }
+               c := v_1_1.AuxInt
+               v.reset(OpS390XSLD)
+               v.AddArg(x)
+               v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32)
+               v0.AuxInt = c & 63
+               v0.AddArg(y)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (SLD x (ANDWconst [c] y))
+       // cond: c&63 == 63
+       // result: (SLD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XANDWconst {
+                       break
+               }
+               c := v_1.AuxInt
+               y := v_1.Args[0]
+               if !(c&63 == 63) {
+                       break
+               }
+               v.reset(OpS390XSLD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SLD x (MOVDreg y))
        // cond:
        // result: (SLD x y)
        for {
                _ = v.Args[1]
                x := v.Args[0]
                v_1 := v.Args[1]
-               if v_1.Op != OpS390XANDconst {
+               if v_1.Op != OpS390XMOVDreg {
                        break
                }
-               if v_1.AuxInt != 63 {
+               y := v_1.Args[0]
+               v.reset(OpS390XSLD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SLD x (MOVWreg y))
+       // cond:
+       // result: (SLD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVWreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSLD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SLD x (MOVHreg y))
+       // cond:
+       // result: (SLD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVHreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSLD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SLD x (MOVBreg y))
+       // cond:
+       // result: (SLD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVBreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSLD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SLD x (MOVWZreg y))
+       // cond:
+       // result: (SLD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVWZreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSLD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SLD x (MOVHZreg y))
+       // cond:
+       // result: (SLD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVHZreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSLD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       return false
+}
+func rewriteValueS390X_OpS390XSLD_10(v *Value) bool {
+       // match: (SLD x (MOVBZreg y))
+       // cond:
+       // result: (SLD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVBZreg {
                        break
                }
                y := v_1.Args[0]
@@ -37156,9 +38749,13 @@ func rewriteValueS390X_OpS390XSLD_0(v *Value) bool {
        return false
 }
 func rewriteValueS390X_OpS390XSLW_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
        // match: (SLW x (MOVDconst [c]))
        // cond:
-       // result: (SLWconst [c&63] x)
+       // result: (SLWconst x [c&63])
        for {
                _ = v.Args[1]
                x := v.Args[0]
@@ -37172,8 +38769,58 @@ func rewriteValueS390X_OpS390XSLW_0(v *Value) bool {
                v.AddArg(x)
                return true
        }
-       // match: (SLW x (ANDWconst [63] y))
+       // match: (SLW x (AND (MOVDconst [c]) y))
+       // cond:
+       // result: (SLW x (ANDWconst <typ.UInt32> [c&63] y))
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XAND {
+                       break
+               }
+               _ = v_1.Args[1]
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpS390XMOVDconst {
+                       break
+               }
+               c := v_1_0.AuxInt
+               y := v_1.Args[1]
+               v.reset(OpS390XSLW)
+               v.AddArg(x)
+               v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32)
+               v0.AuxInt = c & 63
+               v0.AddArg(y)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (SLW x (AND y (MOVDconst [c])))
        // cond:
+       // result: (SLW x (ANDWconst <typ.UInt32> [c&63] y))
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XAND {
+                       break
+               }
+               _ = v_1.Args[1]
+               y := v_1.Args[0]
+               v_1_1 := v_1.Args[1]
+               if v_1_1.Op != OpS390XMOVDconst {
+                       break
+               }
+               c := v_1_1.AuxInt
+               v.reset(OpS390XSLW)
+               v.AddArg(x)
+               v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32)
+               v0.AuxInt = c & 63
+               v0.AddArg(y)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (SLW x (ANDWconst [c] y))
+       // cond: c&63 == 63
        // result: (SLW x y)
        for {
                _ = v.Args[1]
@@ -37182,7 +38829,123 @@ func rewriteValueS390X_OpS390XSLW_0(v *Value) bool {
                if v_1.Op != OpS390XANDWconst {
                        break
                }
-               if v_1.AuxInt != 63 {
+               c := v_1.AuxInt
+               y := v_1.Args[0]
+               if !(c&63 == 63) {
+                       break
+               }
+               v.reset(OpS390XSLW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SLW x (MOVDreg y))
+       // cond:
+       // result: (SLW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVDreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSLW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SLW x (MOVWreg y))
+       // cond:
+       // result: (SLW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVWreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSLW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SLW x (MOVHreg y))
+       // cond:
+       // result: (SLW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVHreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSLW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SLW x (MOVBreg y))
+       // cond:
+       // result: (SLW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVBreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSLW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SLW x (MOVWZreg y))
+       // cond:
+       // result: (SLW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVWZreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSLW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SLW x (MOVHZreg y))
+       // cond:
+       // result: (SLW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVHZreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSLW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       return false
+}
+func rewriteValueS390X_OpS390XSLW_10(v *Value) bool {
+       // match: (SLW x (MOVBZreg y))
+       // cond:
+       // result: (SLW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVBZreg {
                        break
                }
                y := v_1.Args[0]
@@ -37194,9 +38957,13 @@ func rewriteValueS390X_OpS390XSLW_0(v *Value) bool {
        return false
 }
 func rewriteValueS390X_OpS390XSRAD_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
        // match: (SRAD x (MOVDconst [c]))
        // cond:
-       // result: (SRADconst [c&63] x)
+       // result: (SRADconst x [c&63])
        for {
                _ = v.Args[1]
                x := v.Args[0]
@@ -37210,17 +38977,183 @@ func rewriteValueS390X_OpS390XSRAD_0(v *Value) bool {
                v.AddArg(x)
                return true
        }
-       // match: (SRAD x (ANDconst [63] y))
+       // match: (SRAD x (AND (MOVDconst [c]) y))
+       // cond:
+       // result: (SRAD x (ANDWconst <typ.UInt32> [c&63] y))
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XAND {
+                       break
+               }
+               _ = v_1.Args[1]
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpS390XMOVDconst {
+                       break
+               }
+               c := v_1_0.AuxInt
+               y := v_1.Args[1]
+               v.reset(OpS390XSRAD)
+               v.AddArg(x)
+               v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32)
+               v0.AuxInt = c & 63
+               v0.AddArg(y)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (SRAD x (AND y (MOVDconst [c])))
+       // cond:
+       // result: (SRAD x (ANDWconst <typ.UInt32> [c&63] y))
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XAND {
+                       break
+               }
+               _ = v_1.Args[1]
+               y := v_1.Args[0]
+               v_1_1 := v_1.Args[1]
+               if v_1_1.Op != OpS390XMOVDconst {
+                       break
+               }
+               c := v_1_1.AuxInt
+               v.reset(OpS390XSRAD)
+               v.AddArg(x)
+               v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32)
+               v0.AuxInt = c & 63
+               v0.AddArg(y)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (SRAD x (ANDWconst [c] y))
+       // cond: c&63 == 63
+       // result: (SRAD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XANDWconst {
+                       break
+               }
+               c := v_1.AuxInt
+               y := v_1.Args[0]
+               if !(c&63 == 63) {
+                       break
+               }
+               v.reset(OpS390XSRAD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SRAD x (MOVDreg y))
        // cond:
        // result: (SRAD x y)
        for {
                _ = v.Args[1]
                x := v.Args[0]
                v_1 := v.Args[1]
-               if v_1.Op != OpS390XANDconst {
+               if v_1.Op != OpS390XMOVDreg {
                        break
                }
-               if v_1.AuxInt != 63 {
+               y := v_1.Args[0]
+               v.reset(OpS390XSRAD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SRAD x (MOVWreg y))
+       // cond:
+       // result: (SRAD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVWreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSRAD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SRAD x (MOVHreg y))
+       // cond:
+       // result: (SRAD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVHreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSRAD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SRAD x (MOVBreg y))
+       // cond:
+       // result: (SRAD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVBreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSRAD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SRAD x (MOVWZreg y))
+       // cond:
+       // result: (SRAD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVWZreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSRAD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SRAD x (MOVHZreg y))
+       // cond:
+       // result: (SRAD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVHZreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSRAD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       return false
+}
+func rewriteValueS390X_OpS390XSRAD_10(v *Value) bool {
+       // match: (SRAD x (MOVBZreg y))
+       // cond:
+       // result: (SRAD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVBZreg {
                        break
                }
                y := v_1.Args[0]
@@ -37249,9 +39182,13 @@ func rewriteValueS390X_OpS390XSRADconst_0(v *Value) bool {
        return false
 }
 func rewriteValueS390X_OpS390XSRAW_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
        // match: (SRAW x (MOVDconst [c]))
        // cond:
-       // result: (SRAWconst [c&63] x)
+       // result: (SRAWconst x [c&63])
        for {
                _ = v.Args[1]
                x := v.Args[0]
@@ -37265,8 +39202,58 @@ func rewriteValueS390X_OpS390XSRAW_0(v *Value) bool {
                v.AddArg(x)
                return true
        }
-       // match: (SRAW x (ANDWconst [63] y))
+       // match: (SRAW x (AND (MOVDconst [c]) y))
+       // cond:
+       // result: (SRAW x (ANDWconst <typ.UInt32> [c&63] y))
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XAND {
+                       break
+               }
+               _ = v_1.Args[1]
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpS390XMOVDconst {
+                       break
+               }
+               c := v_1_0.AuxInt
+               y := v_1.Args[1]
+               v.reset(OpS390XSRAW)
+               v.AddArg(x)
+               v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32)
+               v0.AuxInt = c & 63
+               v0.AddArg(y)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (SRAW x (AND y (MOVDconst [c])))
        // cond:
+       // result: (SRAW x (ANDWconst <typ.UInt32> [c&63] y))
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XAND {
+                       break
+               }
+               _ = v_1.Args[1]
+               y := v_1.Args[0]
+               v_1_1 := v_1.Args[1]
+               if v_1_1.Op != OpS390XMOVDconst {
+                       break
+               }
+               c := v_1_1.AuxInt
+               v.reset(OpS390XSRAW)
+               v.AddArg(x)
+               v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32)
+               v0.AuxInt = c & 63
+               v0.AddArg(y)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (SRAW x (ANDWconst [c] y))
+       // cond: c&63 == 63
        // result: (SRAW x y)
        for {
                _ = v.Args[1]
@@ -37275,7 +39262,123 @@ func rewriteValueS390X_OpS390XSRAW_0(v *Value) bool {
                if v_1.Op != OpS390XANDWconst {
                        break
                }
-               if v_1.AuxInt != 63 {
+               c := v_1.AuxInt
+               y := v_1.Args[0]
+               if !(c&63 == 63) {
+                       break
+               }
+               v.reset(OpS390XSRAW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SRAW x (MOVDreg y))
+       // cond:
+       // result: (SRAW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVDreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSRAW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SRAW x (MOVWreg y))
+       // cond:
+       // result: (SRAW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVWreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSRAW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SRAW x (MOVHreg y))
+       // cond:
+       // result: (SRAW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVHreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSRAW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SRAW x (MOVBreg y))
+       // cond:
+       // result: (SRAW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVBreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSRAW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SRAW x (MOVWZreg y))
+       // cond:
+       // result: (SRAW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVWZreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSRAW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SRAW x (MOVHZreg y))
+       // cond:
+       // result: (SRAW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVHZreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSRAW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       return false
+}
+func rewriteValueS390X_OpS390XSRAW_10(v *Value) bool {
+       // match: (SRAW x (MOVBZreg y))
+       // cond:
+       // result: (SRAW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVBZreg {
                        break
                }
                y := v_1.Args[0]
@@ -37304,9 +39407,13 @@ func rewriteValueS390X_OpS390XSRAWconst_0(v *Value) bool {
        return false
 }
 func rewriteValueS390X_OpS390XSRD_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
        // match: (SRD x (MOVDconst [c]))
        // cond:
-       // result: (SRDconst [c&63] x)
+       // result: (SRDconst x [c&63])
        for {
                _ = v.Args[1]
                x := v.Args[0]
@@ -37320,17 +39427,183 @@ func rewriteValueS390X_OpS390XSRD_0(v *Value) bool {
                v.AddArg(x)
                return true
        }
-       // match: (SRD x (ANDconst [63] y))
+       // match: (SRD x (AND (MOVDconst [c]) y))
        // cond:
+       // result: (SRD x (ANDWconst <typ.UInt32> [c&63] y))
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XAND {
+                       break
+               }
+               _ = v_1.Args[1]
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpS390XMOVDconst {
+                       break
+               }
+               c := v_1_0.AuxInt
+               y := v_1.Args[1]
+               v.reset(OpS390XSRD)
+               v.AddArg(x)
+               v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32)
+               v0.AuxInt = c & 63
+               v0.AddArg(y)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (SRD x (AND y (MOVDconst [c])))
+       // cond:
+       // result: (SRD x (ANDWconst <typ.UInt32> [c&63] y))
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XAND {
+                       break
+               }
+               _ = v_1.Args[1]
+               y := v_1.Args[0]
+               v_1_1 := v_1.Args[1]
+               if v_1_1.Op != OpS390XMOVDconst {
+                       break
+               }
+               c := v_1_1.AuxInt
+               v.reset(OpS390XSRD)
+               v.AddArg(x)
+               v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32)
+               v0.AuxInt = c & 63
+               v0.AddArg(y)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (SRD x (ANDWconst [c] y))
+       // cond: c&63 == 63
        // result: (SRD x y)
        for {
                _ = v.Args[1]
                x := v.Args[0]
                v_1 := v.Args[1]
-               if v_1.Op != OpS390XANDconst {
+               if v_1.Op != OpS390XANDWconst {
                        break
                }
-               if v_1.AuxInt != 63 {
+               c := v_1.AuxInt
+               y := v_1.Args[0]
+               if !(c&63 == 63) {
+                       break
+               }
+               v.reset(OpS390XSRD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SRD x (MOVDreg y))
+       // cond:
+       // result: (SRD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVDreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSRD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SRD x (MOVWreg y))
+       // cond:
+       // result: (SRD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVWreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSRD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SRD x (MOVHreg y))
+       // cond:
+       // result: (SRD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVHreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSRD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SRD x (MOVBreg y))
+       // cond:
+       // result: (SRD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVBreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSRD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SRD x (MOVWZreg y))
+       // cond:
+       // result: (SRD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVWZreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSRD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SRD x (MOVHZreg y))
+       // cond:
+       // result: (SRD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVHZreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSRD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       return false
+}
+func rewriteValueS390X_OpS390XSRD_10(v *Value) bool {
+       // match: (SRD x (MOVBZreg y))
+       // cond:
+       // result: (SRD x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVBZreg {
                        break
                }
                y := v_1.Args[0]
@@ -37374,9 +39647,13 @@ func rewriteValueS390X_OpS390XSRDconst_0(v *Value) bool {
        return false
 }
 func rewriteValueS390X_OpS390XSRW_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       typ := &b.Func.Config.Types
+       _ = typ
        // match: (SRW x (MOVDconst [c]))
        // cond:
-       // result: (SRWconst [c&63] x)
+       // result: (SRWconst x [c&63])
        for {
                _ = v.Args[1]
                x := v.Args[0]
@@ -37390,8 +39667,58 @@ func rewriteValueS390X_OpS390XSRW_0(v *Value) bool {
                v.AddArg(x)
                return true
        }
-       // match: (SRW x (ANDWconst [63] y))
+       // match: (SRW x (AND (MOVDconst [c]) y))
        // cond:
+       // result: (SRW x (ANDWconst <typ.UInt32> [c&63] y))
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XAND {
+                       break
+               }
+               _ = v_1.Args[1]
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpS390XMOVDconst {
+                       break
+               }
+               c := v_1_0.AuxInt
+               y := v_1.Args[1]
+               v.reset(OpS390XSRW)
+               v.AddArg(x)
+               v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32)
+               v0.AuxInt = c & 63
+               v0.AddArg(y)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (SRW x (AND y (MOVDconst [c])))
+       // cond:
+       // result: (SRW x (ANDWconst <typ.UInt32> [c&63] y))
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XAND {
+                       break
+               }
+               _ = v_1.Args[1]
+               y := v_1.Args[0]
+               v_1_1 := v_1.Args[1]
+               if v_1_1.Op != OpS390XMOVDconst {
+                       break
+               }
+               c := v_1_1.AuxInt
+               v.reset(OpS390XSRW)
+               v.AddArg(x)
+               v0 := b.NewValue0(v.Pos, OpS390XANDWconst, typ.UInt32)
+               v0.AuxInt = c & 63
+               v0.AddArg(y)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (SRW x (ANDWconst [c] y))
+       // cond: c&63 == 63
        // result: (SRW x y)
        for {
                _ = v.Args[1]
@@ -37400,7 +39727,123 @@ func rewriteValueS390X_OpS390XSRW_0(v *Value) bool {
                if v_1.Op != OpS390XANDWconst {
                        break
                }
-               if v_1.AuxInt != 63 {
+               c := v_1.AuxInt
+               y := v_1.Args[0]
+               if !(c&63 == 63) {
+                       break
+               }
+               v.reset(OpS390XSRW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SRW x (MOVDreg y))
+       // cond:
+       // result: (SRW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVDreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSRW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SRW x (MOVWreg y))
+       // cond:
+       // result: (SRW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVWreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSRW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SRW x (MOVHreg y))
+       // cond:
+       // result: (SRW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVHreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSRW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SRW x (MOVBreg y))
+       // cond:
+       // result: (SRW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVBreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSRW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SRW x (MOVWZreg y))
+       // cond:
+       // result: (SRW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVWZreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSRW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       // match: (SRW x (MOVHZreg y))
+       // cond:
+       // result: (SRW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVHZreg {
+                       break
+               }
+               y := v_1.Args[0]
+               v.reset(OpS390XSRW)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+       return false
+}
+func rewriteValueS390X_OpS390XSRW_10(v *Value) bool {
+       // match: (SRW x (MOVBZreg y))
+       // cond:
+       // result: (SRW x y)
+       for {
+               _ = v.Args[1]
+               x := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpS390XMOVBZreg {
                        break
                }
                y := v_1.Args[0]
@@ -37613,84 +40056,6 @@ func rewriteValueS390X_OpS390XSUB_0(v *Value) bool {
        }
        return false
 }
-func rewriteValueS390X_OpS390XSUBEWcarrymask_0(v *Value) bool {
-       // match: (SUBEWcarrymask (FlagEQ))
-       // cond:
-       // result: (MOVDconst [-1])
-       for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpS390XFlagEQ {
-                       break
-               }
-               v.reset(OpS390XMOVDconst)
-               v.AuxInt = -1
-               return true
-       }
-       // match: (SUBEWcarrymask (FlagLT))
-       // cond:
-       // result: (MOVDconst [-1])
-       for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpS390XFlagLT {
-                       break
-               }
-               v.reset(OpS390XMOVDconst)
-               v.AuxInt = -1
-               return true
-       }
-       // match: (SUBEWcarrymask (FlagGT))
-       // cond:
-       // result: (MOVDconst [0])
-       for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpS390XFlagGT {
-                       break
-               }
-               v.reset(OpS390XMOVDconst)
-               v.AuxInt = 0
-               return true
-       }
-       return false
-}
-func rewriteValueS390X_OpS390XSUBEcarrymask_0(v *Value) bool {
-       // match: (SUBEcarrymask (FlagEQ))
-       // cond:
-       // result: (MOVDconst [-1])
-       for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpS390XFlagEQ {
-                       break
-               }
-               v.reset(OpS390XMOVDconst)
-               v.AuxInt = -1
-               return true
-       }
-       // match: (SUBEcarrymask (FlagLT))
-       // cond:
-       // result: (MOVDconst [-1])
-       for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpS390XFlagLT {
-                       break
-               }
-               v.reset(OpS390XMOVDconst)
-               v.AuxInt = -1
-               return true
-       }
-       // match: (SUBEcarrymask (FlagGT))
-       // cond:
-       // result: (MOVDconst [0])
-       for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpS390XFlagGT {
-                       break
-               }
-               v.reset(OpS390XMOVDconst)
-               v.AuxInt = 0
-               return true
-       }
-       return false
-}
 func rewriteValueS390X_OpS390XSUBW_0(v *Value) bool {
        b := v.Block
        _ = b
diff --git a/test/codegen/shift.go b/test/codegen/shift.go
new file mode 100644 (file)
index 0000000..93fa828
--- /dev/null
@@ -0,0 +1,99 @@
+// asmcheck
+
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package codegen
+
+// ------------------ //
+//   masked shifts    //
+// ------------------ //
+
+func lshMask64x64(v int64, s uint64) int64 {
+       // s390x:-".*AND",-".*MOVDGE"
+       return v << (s&63)
+}
+
+func rshMask64Ux64(v uint64, s uint64) uint64 {
+       // s390x:-".*AND",-".*MOVDGE"
+       return v >> (s&63)
+}
+
+func rshMask64x64(v int64, s uint64) int64 {
+       // s390x:-".*AND",-".*MOVDGE"
+       return v >> (s&63)
+}
+
+func lshMask32x64(v int32, s uint64) int32 {
+       // s390x:-".*AND",-".*MOVDGE"
+       return v << (s&63)
+}
+
+func rshMask32Ux64(v uint32, s uint64) uint32 {
+       // s390x:-".*AND",-".*MOVDGE"
+       return v >> (s&63)
+}
+
+func rshMask32x64(v int32, s uint64) int32 {
+       // s390x:-".*AND",-".*MOVDGE"
+       return v >> (s&63)
+}
+
+func lshMask64x32(v int64, s uint32) int64 {
+       // s390x:-".*AND",-".*MOVDGE"
+       return v << (s&63)
+}
+
+func rshMask64Ux32(v uint64, s uint32) uint64 {
+       // s390x:-".*AND",-".*MOVDGE"
+       return v >> (s&63)
+}
+
+func rshMask64x32(v int64, s uint32) int64 {
+       // s390x:-".*AND",-".*MOVDGE"
+       return v >> (s&63)
+}
+
+func lshMask64x32Ext(v int64, s int32) int64 {
+       // s390x:-".*AND",-".*MOVDGE"
+       return v << uint(s&63)
+}
+
+func rshMask64Ux32Ext(v uint64, s int32) uint64 {
+       // s390x:-".*AND",-".*MOVDGE"
+       return v >> uint(s&63)
+}
+
+func rshMask64x32Ext(v int64, s int32) int64 {
+       // s390x:-".*AND",-".*MOVDGE"
+       return v >> uint(s&63)
+}
+
+// ------------------ //
+//   bounded shifts   //
+// ------------------ //
+
+func lshGuarded64(v int64, s uint) int64 {
+       if s < 64 {
+               // s390x:-".*AND",-".*MOVDGE"
+               return v >> s
+       }
+       panic("shift too large")
+}
+
+func rshGuarded64U(v uint64, s uint) uint64 {
+       if s < 64 {
+               // s390x:-".*AND",-".*MOVDGE"
+               return v >> s
+       }
+       panic("shift too large")
+}
+
+func rshGuarded64(v int64, s uint) int64 {
+       if s < 64 {
+               // s390x:-".*AND",-".*MOVDGE"
+               return v << s
+       }
+       panic("shift too large")
+}