// ***************************
// TODO: Should the optimizations be a separate pass?
-// Fold unnecessary type conversions.
-(MOVDreg <t> x) && t.Compare(x.Type) == types.CMPeq -> x
-(MOVDnop <t> x) && t.Compare(x.Type) == types.CMPeq -> x
-
-// Propagate constants through type conversions.
-(MOVDreg (MOVDconst [c])) -> (MOVDconst [c])
-(MOVDnop (MOVDconst [c])) -> (MOVDconst [c])
-
-// If a register move has only 1 use, just use the same register without emitting instruction.
-// MOVDnop doesn't emit instruction, only for ensuring the type.
-(MOVDreg x) && x.Uses == 1 -> (MOVDnop x)
-
-// Fold type changes into loads.
-(MOVDreg <t> x:(MOVBZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBZload <t> [off] {sym} ptr mem)
-(MOVDreg <t> x:(MOVBload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBload <t> [off] {sym} ptr mem)
-(MOVDreg <t> x:(MOVHZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHZload <t> [off] {sym} ptr mem)
-(MOVDreg <t> x:(MOVHload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHload <t> [off] {sym} ptr mem)
-(MOVDreg <t> x:(MOVWZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWZload <t> [off] {sym} ptr mem)
-(MOVDreg <t> x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWload <t> [off] {sym} ptr mem)
-(MOVDreg <t> x:(MOVDload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVDload <t> [off] {sym} ptr mem)
-
-(MOVDnop <t> x:(MOVBZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBZload <t> [off] {sym} ptr mem)
-(MOVDnop <t> x:(MOVBload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBload <t> [off] {sym} ptr mem)
-(MOVDnop <t> x:(MOVHZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHZload <t> [off] {sym} ptr mem)
-(MOVDnop <t> x:(MOVHload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHload <t> [off] {sym} ptr mem)
-(MOVDnop <t> x:(MOVWZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWZload <t> [off] {sym} ptr mem)
-(MOVDnop <t> x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWload <t> [off] {sym} ptr mem)
-(MOVDnop <t> x:(MOVDload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVDload <t> [off] {sym} ptr mem)
-
-(MOVDreg <t> x:(MOVBZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBZloadidx <t> [off] {sym} ptr idx mem)
-(MOVDreg <t> x:(MOVBloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBloadidx <t> [off] {sym} ptr idx mem)
-(MOVDreg <t> x:(MOVHZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHZloadidx <t> [off] {sym} ptr idx mem)
-(MOVDreg <t> x:(MOVHloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHloadidx <t> [off] {sym} ptr idx mem)
-(MOVDreg <t> x:(MOVWZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWZloadidx <t> [off] {sym} ptr idx mem)
-(MOVDreg <t> x:(MOVWloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWloadidx <t> [off] {sym} ptr idx mem)
-(MOVDreg <t> x:(MOVDloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVDloadidx <t> [off] {sym} ptr idx mem)
-
-(MOVDnop <t> x:(MOVBZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBZloadidx <t> [off] {sym} ptr idx mem)
-(MOVDnop <t> x:(MOVBloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBloadidx <t> [off] {sym} ptr idx mem)
-(MOVDnop <t> x:(MOVHZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHZloadidx <t> [off] {sym} ptr idx mem)
-(MOVDnop <t> x:(MOVHloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHloadidx <t> [off] {sym} ptr idx mem)
-(MOVDnop <t> x:(MOVWZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWZloadidx <t> [off] {sym} ptr idx mem)
-(MOVDnop <t> x:(MOVWloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWloadidx <t> [off] {sym} ptr idx mem)
-(MOVDnop <t> x:(MOVDloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVDloadidx <t> [off] {sym} ptr idx mem)
-
-// Fold sign extensions into conditional moves of constants.
-// Designed to remove the MOVBZreg inserted by the If lowering.
-(MOVBZreg x:(MOVDLT (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x)
-(MOVBZreg x:(MOVDLE (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x)
-(MOVBZreg x:(MOVDGT (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x)
-(MOVBZreg x:(MOVDGE (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x)
-(MOVBZreg x:(MOVDEQ (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x)
-(MOVBZreg x:(MOVDNE (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x)
-(MOVBZreg x:(MOVDGTnoinv (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x)
-(MOVBZreg x:(MOVDGEnoinv (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x)
+// Note: when removing unnecessary sign/zero extensions.
+//
+// After a value is spilled it is restored using a sign- or zero-extension
+// to register-width as appropriate for its type. For example, a uint8 will
+// be restored using a MOVBZ (llgc) instruction which will zero extend the
+// 8-bit value to 64-bits.
+//
+// This is a hazard when folding sign- and zero-extensions since we need to
+// ensure not only that the value in the argument register is correctly
+// extended but also that it will still be correctly extended if it is
+// spilled and restored.
+//
+// In general this means we need type checks when the RHS of a rule is an
+// OpCopy (i.e. "(... x:(...) ...) -> x").
+
+// Merge double extensions.
+(MOV(H|HZ)reg e:(MOV(B|BZ)reg x)) && clobberIfDead(e) -> (MOV(B|BZ)reg x)
+(MOV(W|WZ)reg e:(MOV(B|BZ)reg x)) && clobberIfDead(e) -> (MOV(B|BZ)reg x)
+(MOV(W|WZ)reg e:(MOV(H|HZ)reg x)) && clobberIfDead(e) -> (MOV(H|HZ)reg x)
+
+// Bypass redundant sign extensions.
+(MOV(B|BZ)reg e:(MOVBreg x)) && clobberIfDead(e) -> (MOV(B|BZ)reg x)
+(MOV(B|BZ)reg e:(MOVHreg x)) && clobberIfDead(e) -> (MOV(B|BZ)reg x)
+(MOV(B|BZ)reg e:(MOVWreg x)) && clobberIfDead(e) -> (MOV(B|BZ)reg x)
+(MOV(H|HZ)reg e:(MOVHreg x)) && clobberIfDead(e) -> (MOV(H|HZ)reg x)
+(MOV(H|HZ)reg e:(MOVWreg x)) && clobberIfDead(e) -> (MOV(H|HZ)reg x)
+(MOV(W|WZ)reg e:(MOVWreg x)) && clobberIfDead(e) -> (MOV(W|WZ)reg x)
+
+// Bypass redundant zero extensions.
+(MOV(B|BZ)reg e:(MOVBZreg x)) && clobberIfDead(e) -> (MOV(B|BZ)reg x)
+(MOV(B|BZ)reg e:(MOVHZreg x)) && clobberIfDead(e) -> (MOV(B|BZ)reg x)
+(MOV(B|BZ)reg e:(MOVWZreg x)) && clobberIfDead(e) -> (MOV(B|BZ)reg x)
+(MOV(H|HZ)reg e:(MOVHZreg x)) && clobberIfDead(e) -> (MOV(H|HZ)reg x)
+(MOV(H|HZ)reg e:(MOVWZreg x)) && clobberIfDead(e) -> (MOV(H|HZ)reg x)
+(MOV(W|WZ)reg e:(MOVWZreg x)) && clobberIfDead(e) -> (MOV(W|WZ)reg x)
+
+// Remove zero extensions after zero extending load.
+// Note: take care that if x is spilled it is restored correctly.
+(MOV(B|H|W)Zreg x:(MOVBZload _ _)) && (!x.Type.IsSigned() || x.Type.Size() > 1) -> x
+(MOV(B|H|W)Zreg x:(MOVBZloadidx _ _ _)) && (!x.Type.IsSigned() || x.Type.Size() > 1) -> x
+(MOV(H|W)Zreg x:(MOVHZload _ _)) && (!x.Type.IsSigned() || x.Type.Size() > 2) -> x
+(MOV(H|W)Zreg x:(MOVHZloadidx _ _ _)) && (!x.Type.IsSigned() || x.Type.Size() > 2) -> x
+(MOVWZreg x:(MOVWZload _ _)) && (!x.Type.IsSigned() || x.Type.Size() > 4) -> x
+(MOVWZreg x:(MOVWZloadidx _ _ _)) && (!x.Type.IsSigned() || x.Type.Size() > 4) -> x
+
+// Remove sign extensions after sign extending load.
+// Note: take care that if x is spilled it is restored correctly.
+(MOV(B|H|W)reg x:(MOVBload _ _)) && (x.Type.IsSigned() || x.Type.Size() == 8) -> x
+(MOV(B|H|W)reg x:(MOVBloadidx _ _ _)) && (x.Type.IsSigned() || x.Type.Size() == 8) -> x
+(MOV(H|W)reg x:(MOVHload _ _)) && (x.Type.IsSigned() || x.Type.Size() == 8) -> x
+(MOV(H|W)reg x:(MOVHloadidx _ _ _)) && (x.Type.IsSigned() || x.Type.Size() == 8) -> x
+(MOVWreg x:(MOVWload _ _)) && (x.Type.IsSigned() || x.Type.Size() == 8) -> x
+(MOVWreg x:(MOVWloadidx _ _ _)) && (x.Type.IsSigned() || x.Type.Size() == 8) -> x
+
+// Remove sign extensions after zero extending load.
+// These type checks are probably unnecessary but do them anyway just in case.
+(MOV(H|W)reg x:(MOVBZload _ _)) && (!x.Type.IsSigned() || x.Type.Size() > 1) -> x
+(MOV(H|W)reg x:(MOVBZloadidx _ _ _)) && (!x.Type.IsSigned() || x.Type.Size() > 1) -> x
+(MOVWreg x:(MOVHZload _ _)) && (!x.Type.IsSigned() || x.Type.Size() > 2) -> x
+(MOVWreg x:(MOVHZloadidx _ _ _)) && (!x.Type.IsSigned() || x.Type.Size() > 2) -> x
+
+// Fold sign and zero extensions into loads.
+//
+// Note: The combined instruction must end up in the same block
+// as the original load. If not, we end up making a value with
+// memory type live in two different blocks, which can lead to
+// multiple memory values alive simultaneously.
+//
+// Make sure we don't combine these ops if the load has another use.
+// This prevents a single load from being split into multiple loads
+// which then might return different values. See test/atomicload.go.
+(MOV(B|H|W)Zreg <t> x:(MOV(B|H|W)load [o] {s} p mem))
+ && x.Uses == 1
+ && clobber(x)
+ -> @x.Block (MOV(B|H|W)Zload <t> [o] {s} p mem)
+(MOV(B|H|W)reg <t> x:(MOV(B|H|W)Zload [o] {s} p mem))
+ && x.Uses == 1
+ && clobber(x)
+ -> @x.Block (MOV(B|H|W)load <t> [o] {s} p mem)
+(MOV(B|H|W)Zreg <t> x:(MOV(B|H|W)loadidx [o] {s} p i mem))
+ && x.Uses == 1
+ && clobber(x)
+ -> @x.Block (MOV(B|H|W)Zloadidx <t> [o] {s} p i mem)
+(MOV(B|H|W)reg <t> x:(MOV(B|H|W)Zloadidx [o] {s} p i mem))
+ && x.Uses == 1
+ && clobber(x)
+ -> @x.Block (MOV(B|H|W)loadidx <t> [o] {s} p i mem)
+
+// Remove zero extensions after argument load.
+(MOVBZreg x:(Arg <t>)) && !t.IsSigned() && t.Size() == 1 -> x
+(MOVHZreg x:(Arg <t>)) && !t.IsSigned() && t.Size() <= 2 -> x
+(MOVWZreg x:(Arg <t>)) && !t.IsSigned() && t.Size() <= 4 -> x
+
+// Remove sign extensions after argument load.
+(MOVBreg x:(Arg <t>)) && t.IsSigned() && t.Size() == 1 -> x
+(MOVHreg x:(Arg <t>)) && t.IsSigned() && t.Size() <= 2 -> x
+(MOVWreg x:(Arg <t>)) && t.IsSigned() && t.Size() <= 4 -> x
+
+// Fold zero extensions into constants.
+(MOVBZreg (MOVDconst [c])) -> (MOVDconst [int64( uint8(c))])
+(MOVHZreg (MOVDconst [c])) -> (MOVDconst [int64(uint16(c))])
+(MOVWZreg (MOVDconst [c])) -> (MOVDconst [int64(uint32(c))])
+
+// Fold sign extensions into constants.
+(MOVBreg (MOVDconst [c])) -> (MOVDconst [int64( int8(c))])
+(MOVHreg (MOVDconst [c])) -> (MOVDconst [int64(int16(c))])
+(MOVWreg (MOVDconst [c])) -> (MOVDconst [int64(int32(c))])
+
+// Remove zero extension of conditional move.
+// Note: only for MOVBZreg for now since it is added as part of 'if' statement lowering.
+(MOVBZreg x:(MOVD(LT|LE|GT|GE|EQ|NE|GTnoinv|GEnoinv) (MOVDconst [c]) (MOVDconst [d]) _))
+ && int64(uint8(c)) == c
+ && int64(uint8(d)) == d
+ && (!x.Type.IsSigned() || x.Type.Size() > 1)
+ -> x
// Fold boolean tests into blocks.
(NE (CMPWconst [0] (MOVDLT (MOVDconst [0]) (MOVDconst [1]) cmp)) yes no) -> (LT cmp yes no)
-> (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)
+(SLD x (MOV(W|H|B|WZ|HZ|BZ)reg y)) -> (SLD x y)
+(SRD x (MOV(W|H|B|WZ|HZ|BZ)reg y)) -> (SRD x y)
+(SRAD x (MOV(W|H|B|WZ|HZ|BZ)reg y)) -> (SRAD x y)
+(SLW x (MOV(W|H|B|WZ|HZ|BZ)reg y)) -> (SLW x y)
+(SRW x (MOV(W|H|B|WZ|HZ|BZ)reg y)) -> (SRW x y)
+(SRAW x (MOV(W|H|B|WZ|HZ|BZ)reg y)) -> (SRAW x y)
// Constant rotate generation
(RLL x (MOVDconst [c])) -> (RLLconst x [c&31])
(MOVDEQ x y (InvertFlags cmp)) -> (MOVDEQ x y cmp)
(MOVDNE x y (InvertFlags cmp)) -> (MOVDNE x y cmp)
-// don't extend after proper load
-(MOVBreg x:(MOVBload _ _)) -> (MOVDreg x)
-(MOVBZreg x:(MOVBZload _ _)) -> (MOVDreg x)
-(MOVHreg x:(MOVBload _ _)) -> (MOVDreg x)
-(MOVHreg x:(MOVBZload _ _)) -> (MOVDreg x)
-(MOVHreg x:(MOVHload _ _)) -> (MOVDreg x)
-(MOVHZreg x:(MOVBZload _ _)) -> (MOVDreg x)
-(MOVHZreg x:(MOVHZload _ _)) -> (MOVDreg x)
-(MOVWreg x:(MOVBload _ _)) -> (MOVDreg x)
-(MOVWreg x:(MOVBZload _ _)) -> (MOVDreg x)
-(MOVWreg x:(MOVHload _ _)) -> (MOVDreg x)
-(MOVWreg x:(MOVHZload _ _)) -> (MOVDreg x)
-(MOVWreg x:(MOVWload _ _)) -> (MOVDreg x)
-(MOVWZreg x:(MOVBZload _ _)) -> (MOVDreg x)
-(MOVWZreg x:(MOVHZload _ _)) -> (MOVDreg x)
-(MOVWZreg x:(MOVWZload _ _)) -> (MOVDreg x)
-
-// don't extend if argument is already extended
-(MOVBreg x:(Arg <t>)) && is8BitInt(t) && isSigned(t) -> (MOVDreg x)
-(MOVBZreg x:(Arg <t>)) && is8BitInt(t) && !isSigned(t) -> (MOVDreg x)
-(MOVHreg x:(Arg <t>)) && (is8BitInt(t) || is16BitInt(t)) && isSigned(t) -> (MOVDreg x)
-(MOVHZreg x:(Arg <t>)) && (is8BitInt(t) || is16BitInt(t)) && !isSigned(t) -> (MOVDreg x)
-(MOVWreg x:(Arg <t>)) && (is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && isSigned(t) -> (MOVDreg x)
-(MOVWZreg x:(Arg <t>)) && (is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && !isSigned(t) -> (MOVDreg x)
-
-// fold double extensions
-(MOVBreg x:(MOVBreg _)) -> (MOVDreg x)
-(MOVBZreg x:(MOVBZreg _)) -> (MOVDreg x)
-(MOVHreg x:(MOVBreg _)) -> (MOVDreg x)
-(MOVHreg x:(MOVBZreg _)) -> (MOVDreg x)
-(MOVHreg x:(MOVHreg _)) -> (MOVDreg x)
-(MOVHZreg x:(MOVBZreg _)) -> (MOVDreg x)
-(MOVHZreg x:(MOVHZreg _)) -> (MOVDreg x)
-(MOVWreg x:(MOVBreg _)) -> (MOVDreg x)
-(MOVWreg x:(MOVBZreg _)) -> (MOVDreg x)
-(MOVWreg x:(MOVHreg _)) -> (MOVDreg x)
-(MOVWreg x:(MOVHZreg _)) -> (MOVDreg x)
-(MOVWreg x:(MOVWreg _)) -> (MOVDreg x)
-(MOVWZreg x:(MOVBZreg _)) -> (MOVDreg x)
-(MOVWZreg x:(MOVHZreg _)) -> (MOVDreg x)
-(MOVWZreg x:(MOVWZreg _)) -> (MOVDreg x)
-
-(MOVBreg (MOVBZreg x)) -> (MOVBreg x)
-(MOVBZreg (MOVBreg x)) -> (MOVBZreg x)
-(MOVHreg (MOVHZreg x)) -> (MOVHreg x)
-(MOVHZreg (MOVHreg x)) -> (MOVHZreg x)
-(MOVWreg (MOVWZreg x)) -> (MOVWreg x)
-(MOVWZreg (MOVWreg x)) -> (MOVWZreg x)
-
-// fold extensions into constants
-(MOVBreg (MOVDconst [c])) -> (MOVDconst [int64(int8(c))])
-(MOVBZreg (MOVDconst [c])) -> (MOVDconst [int64(uint8(c))])
-(MOVHreg (MOVDconst [c])) -> (MOVDconst [int64(int16(c))])
-(MOVHZreg (MOVDconst [c])) -> (MOVDconst [int64(uint16(c))])
-(MOVWreg (MOVDconst [c])) -> (MOVDconst [int64(int32(c))])
-(MOVWZreg (MOVDconst [c])) -> (MOVDconst [int64(uint32(c))])
-
-// sign extended loads
-// Note: The combined instruction must end up in the same block
-// as the original load. If not, we end up making a value with
-// memory type live in two different blocks, which can lead to
-// multiple memory values alive simultaneously.
-// Make sure we don't combine these ops if the load has another use.
-// This prevents a single load from being split into multiple loads
-// which then might return different values. See test/atomicload.go.
-(MOVBreg x:(MOVBZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBload <v.Type> [off] {sym} ptr mem)
-(MOVBreg x:(MOVBload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBload <v.Type> [off] {sym} ptr mem)
-(MOVBZreg x:(MOVBZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBZload <v.Type> [off] {sym} ptr mem)
-(MOVBZreg x:(MOVBload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBZload <v.Type> [off] {sym} ptr mem)
-(MOVHreg x:(MOVHZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHload <v.Type> [off] {sym} ptr mem)
-(MOVHreg x:(MOVHload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHload <v.Type> [off] {sym} ptr mem)
-(MOVHZreg x:(MOVHZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHZload <v.Type> [off] {sym} ptr mem)
-(MOVHZreg x:(MOVHload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHZload <v.Type> [off] {sym} ptr mem)
-(MOVWreg x:(MOVWZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWload <v.Type> [off] {sym} ptr mem)
-(MOVWreg x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWload <v.Type> [off] {sym} ptr mem)
-(MOVWZreg x:(MOVWZload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWZload <v.Type> [off] {sym} ptr mem)
-(MOVWZreg x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWZload <v.Type> [off] {sym} ptr mem)
-
-(MOVBreg x:(MOVBZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBloadidx <v.Type> [off] {sym} ptr idx mem)
-(MOVBreg x:(MOVBloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBloadidx <v.Type> [off] {sym} ptr idx mem)
-(MOVBZreg x:(MOVBZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBZloadidx <v.Type> [off] {sym} ptr idx mem)
-(MOVBZreg x:(MOVBloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVBZloadidx <v.Type> [off] {sym} ptr idx mem)
-(MOVHreg x:(MOVHZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHloadidx <v.Type> [off] {sym} ptr idx mem)
-(MOVHreg x:(MOVHloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHloadidx <v.Type> [off] {sym} ptr idx mem)
-(MOVHZreg x:(MOVHZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHZloadidx <v.Type> [off] {sym} ptr idx mem)
-(MOVHZreg x:(MOVHloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVHZloadidx <v.Type> [off] {sym} ptr idx mem)
-(MOVWreg x:(MOVWZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWloadidx <v.Type> [off] {sym} ptr idx mem)
-(MOVWreg x:(MOVWloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWloadidx <v.Type> [off] {sym} ptr idx mem)
-(MOVWZreg x:(MOVWZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWZloadidx <v.Type> [off] {sym} ptr idx mem)
-(MOVWZreg x:(MOVWloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWZloadidx <v.Type> [off] {sym} ptr idx mem)
-
// replace load from same location as preceding store with copy
-(MOVDload [off] {sym} ptr1 (MOVDstore [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) -> (MOVDreg x)
+(MOVDload [off] {sym} ptr1 (MOVDstore [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) -> x
(MOVWload [off] {sym} ptr1 (MOVWstore [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) -> (MOVWreg x)
(MOVHload [off] {sym} ptr1 (MOVHstore [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) -> (MOVHreg x)
(MOVBload [off] {sym} ptr1 (MOVBstore [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) -> (MOVBreg x)
// remove unnecessary FPR <-> GPR moves
(LDGR (LGDR x)) -> x
-(LGDR (LDGR x)) -> (MOVDreg x)
+(LGDR (LDGR x)) -> x
// Don't extend before storing
(MOVWstore [off] {sym} ptr (MOVWreg x) mem) -> (MOVWstore [off] {sym} ptr x mem)
case OpS390XMOVBZloadidx:
return rewriteValueS390X_OpS390XMOVBZloadidx_0(v)
case OpS390XMOVBZreg:
- return rewriteValueS390X_OpS390XMOVBZreg_0(v) || rewriteValueS390X_OpS390XMOVBZreg_10(v)
+ return rewriteValueS390X_OpS390XMOVBZreg_0(v) || rewriteValueS390X_OpS390XMOVBZreg_10(v) || rewriteValueS390X_OpS390XMOVBZreg_20(v)
case OpS390XMOVBload:
return rewriteValueS390X_OpS390XMOVBload_0(v)
case OpS390XMOVBloadidx:
return rewriteValueS390X_OpS390XMOVBloadidx_0(v)
case OpS390XMOVBreg:
- return rewriteValueS390X_OpS390XMOVBreg_0(v)
+ return rewriteValueS390X_OpS390XMOVBreg_0(v) || rewriteValueS390X_OpS390XMOVBreg_10(v)
case OpS390XMOVBstore:
return rewriteValueS390X_OpS390XMOVBstore_0(v) || rewriteValueS390X_OpS390XMOVBstore_10(v)
case OpS390XMOVBstoreconst:
return rewriteValueS390X_OpS390XMOVDload_0(v)
case OpS390XMOVDloadidx:
return rewriteValueS390X_OpS390XMOVDloadidx_0(v)
- case OpS390XMOVDnop:
- return rewriteValueS390X_OpS390XMOVDnop_0(v) || rewriteValueS390X_OpS390XMOVDnop_10(v)
- case OpS390XMOVDreg:
- return rewriteValueS390X_OpS390XMOVDreg_0(v) || rewriteValueS390X_OpS390XMOVDreg_10(v)
case OpS390XMOVDstore:
return rewriteValueS390X_OpS390XMOVDstore_0(v)
case OpS390XMOVDstoreconst:
case OpS390XMOVWloadidx:
return rewriteValueS390X_OpS390XMOVWloadidx_0(v)
case OpS390XMOVWreg:
- return rewriteValueS390X_OpS390XMOVWreg_0(v) || rewriteValueS390X_OpS390XMOVWreg_10(v)
+ return rewriteValueS390X_OpS390XMOVWreg_0(v) || rewriteValueS390X_OpS390XMOVWreg_10(v) || rewriteValueS390X_OpS390XMOVWreg_20(v)
case OpS390XMOVWstore:
return rewriteValueS390X_OpS390XMOVWstore_0(v) || rewriteValueS390X_OpS390XMOVWstore_10(v)
case OpS390XMOVWstoreconst:
case OpS390XRLLG:
return rewriteValueS390X_OpS390XRLLG_0(v)
case OpS390XSLD:
- return rewriteValueS390X_OpS390XSLD_0(v) || rewriteValueS390X_OpS390XSLD_10(v)
+ return rewriteValueS390X_OpS390XSLD_0(v)
case OpS390XSLW:
- return rewriteValueS390X_OpS390XSLW_0(v) || rewriteValueS390X_OpS390XSLW_10(v)
+ return rewriteValueS390X_OpS390XSLW_0(v)
case OpS390XSRAD:
- return rewriteValueS390X_OpS390XSRAD_0(v) || rewriteValueS390X_OpS390XSRAD_10(v)
+ return rewriteValueS390X_OpS390XSRAD_0(v)
case OpS390XSRADconst:
return rewriteValueS390X_OpS390XSRADconst_0(v)
case OpS390XSRAW:
- return rewriteValueS390X_OpS390XSRAW_0(v) || rewriteValueS390X_OpS390XSRAW_10(v)
+ return rewriteValueS390X_OpS390XSRAW_0(v)
case OpS390XSRAWconst:
return rewriteValueS390X_OpS390XSRAWconst_0(v)
case OpS390XSRD:
- return rewriteValueS390X_OpS390XSRD_0(v) || rewriteValueS390X_OpS390XSRD_10(v)
+ return rewriteValueS390X_OpS390XSRD_0(v)
case OpS390XSRDconst:
return rewriteValueS390X_OpS390XSRDconst_0(v)
case OpS390XSRW:
- return rewriteValueS390X_OpS390XSRW_0(v) || rewriteValueS390X_OpS390XSRW_10(v)
+ return rewriteValueS390X_OpS390XSRW_0(v)
case OpS390XSTM2:
return rewriteValueS390X_OpS390XSTM2_0(v)
case OpS390XSTMG2:
func rewriteValueS390X_OpS390XLGDR_0(v *Value) bool {
// match: (LGDR (LDGR x))
// cond:
- // result: (MOVDreg x)
+ // result: x
for {
v_0 := v.Args[0]
if v_0.Op != OpS390XLDGR {
break
}
x := v_0.Args[0]
- v.reset(OpS390XMOVDreg)
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
return false
}
func rewriteValueS390X_OpS390XMOVBZreg_0(v *Value) bool {
- // match: (MOVBZreg x:(MOVDLT (MOVDconst [c]) (MOVDconst [d]) _))
- // cond: int64(uint8(c)) == c && int64(uint8(d)) == d
- // result: (MOVDreg x)
+ b := v.Block
+ // match: (MOVBZreg e:(MOVBreg x))
+ // cond: clobberIfDead(e)
+ // result: (MOVBZreg x)
for {
- x := v.Args[0]
- if x.Op != OpS390XMOVDLT {
+ e := v.Args[0]
+ if e.Op != OpS390XMOVBreg {
break
}
- _ = x.Args[2]
- x_0 := x.Args[0]
- if x_0.Op != OpS390XMOVDconst {
+ x := e.Args[0]
+ if !(clobberIfDead(e)) {
break
}
- c := x_0.AuxInt
- x_1 := x.Args[1]
- if x_1.Op != OpS390XMOVDconst {
+ v.reset(OpS390XMOVBZreg)
+ v.AddArg(x)
+ return true
+ }
+ // match: (MOVBZreg e:(MOVHreg x))
+ // cond: clobberIfDead(e)
+ // result: (MOVBZreg x)
+ for {
+ e := v.Args[0]
+ if e.Op != OpS390XMOVHreg {
break
}
- d := x_1.AuxInt
- if !(int64(uint8(c)) == c && int64(uint8(d)) == d) {
+ x := e.Args[0]
+ if !(clobberIfDead(e)) {
break
}
- v.reset(OpS390XMOVDreg)
+ v.reset(OpS390XMOVBZreg)
v.AddArg(x)
return true
}
- // match: (MOVBZreg x:(MOVDLE (MOVDconst [c]) (MOVDconst [d]) _))
- // cond: int64(uint8(c)) == c && int64(uint8(d)) == d
- // result: (MOVDreg x)
+ // match: (MOVBZreg e:(MOVWreg x))
+ // cond: clobberIfDead(e)
+ // result: (MOVBZreg x)
for {
- x := v.Args[0]
- if x.Op != OpS390XMOVDLE {
+ e := v.Args[0]
+ if e.Op != OpS390XMOVWreg {
break
}
- _ = x.Args[2]
- x_0 := x.Args[0]
- if x_0.Op != OpS390XMOVDconst {
+ x := e.Args[0]
+ if !(clobberIfDead(e)) {
break
}
- c := x_0.AuxInt
- x_1 := x.Args[1]
- if x_1.Op != OpS390XMOVDconst {
+ v.reset(OpS390XMOVBZreg)
+ v.AddArg(x)
+ return true
+ }
+ // match: (MOVBZreg e:(MOVBZreg x))
+ // cond: clobberIfDead(e)
+ // result: (MOVBZreg x)
+ for {
+ e := v.Args[0]
+ if e.Op != OpS390XMOVBZreg {
break
}
- d := x_1.AuxInt
- if !(int64(uint8(c)) == c && int64(uint8(d)) == d) {
+ x := e.Args[0]
+ if !(clobberIfDead(e)) {
break
}
- v.reset(OpS390XMOVDreg)
+ v.reset(OpS390XMOVBZreg)
v.AddArg(x)
return true
}
- // match: (MOVBZreg x:(MOVDGT (MOVDconst [c]) (MOVDconst [d]) _))
- // cond: int64(uint8(c)) == c && int64(uint8(d)) == d
- // result: (MOVDreg x)
+ // match: (MOVBZreg e:(MOVHZreg x))
+ // cond: clobberIfDead(e)
+ // result: (MOVBZreg x)
+ for {
+ e := v.Args[0]
+ if e.Op != OpS390XMOVHZreg {
+ break
+ }
+ x := e.Args[0]
+ if !(clobberIfDead(e)) {
+ break
+ }
+ v.reset(OpS390XMOVBZreg)
+ v.AddArg(x)
+ return true
+ }
+ // match: (MOVBZreg e:(MOVWZreg x))
+ // cond: clobberIfDead(e)
+ // result: (MOVBZreg x)
+ for {
+ e := v.Args[0]
+ if e.Op != OpS390XMOVWZreg {
+ break
+ }
+ x := e.Args[0]
+ if !(clobberIfDead(e)) {
+ break
+ }
+ v.reset(OpS390XMOVBZreg)
+ v.AddArg(x)
+ return true
+ }
+ // match: (MOVBZreg x:(MOVBZload _ _))
+ // cond: (!x.Type.IsSigned() || x.Type.Size() > 1)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVDGT {
+ if x.Op != OpS390XMOVBZload {
break
}
- _ = x.Args[2]
- x_0 := x.Args[0]
- if x_0.Op != OpS390XMOVDconst {
+ _ = x.Args[1]
+ if !(!x.Type.IsSigned() || x.Type.Size() > 1) {
break
}
- c := x_0.AuxInt
- x_1 := x.Args[1]
- if x_1.Op != OpS390XMOVDconst {
+ v.reset(OpCopy)
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ // match: (MOVBZreg x:(MOVBZloadidx _ _ _))
+ // cond: (!x.Type.IsSigned() || x.Type.Size() > 1)
+ // result: x
+ for {
+ x := v.Args[0]
+ if x.Op != OpS390XMOVBZloadidx {
break
}
- d := x_1.AuxInt
- if !(int64(uint8(c)) == c && int64(uint8(d)) == d) {
+ _ = x.Args[2]
+ if !(!x.Type.IsSigned() || x.Type.Size() > 1) {
break
}
- v.reset(OpS390XMOVDreg)
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
- // match: (MOVBZreg x:(MOVDGE (MOVDconst [c]) (MOVDconst [d]) _))
- // cond: int64(uint8(c)) == c && int64(uint8(d)) == d
- // result: (MOVDreg x)
+ // match: (MOVBZreg x:(MOVBZloadidx _ _ _))
+ // cond: (!x.Type.IsSigned() || x.Type.Size() > 1)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVDGE {
+ if x.Op != OpS390XMOVBZloadidx {
break
}
_ = x.Args[2]
- x_0 := x.Args[0]
- if x_0.Op != OpS390XMOVDconst {
+ if !(!x.Type.IsSigned() || x.Type.Size() > 1) {
break
}
- c := x_0.AuxInt
- x_1 := x.Args[1]
- if x_1.Op != OpS390XMOVDconst {
+ v.reset(OpCopy)
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ // match: (MOVBZreg <t> x:(MOVBload [o] {s} p mem))
+ // cond: x.Uses == 1 && clobber(x)
+ // result: @x.Block (MOVBZload <t> [o] {s} p mem)
+ for {
+ t := v.Type
+ x := v.Args[0]
+ if x.Op != OpS390XMOVBload {
break
}
- d := x_1.AuxInt
- if !(int64(uint8(c)) == c && int64(uint8(d)) == d) {
+ o := x.AuxInt
+ s := x.Aux
+ mem := x.Args[1]
+ p := x.Args[0]
+ if !(x.Uses == 1 && clobber(x)) {
+ break
+ }
+ b = x.Block
+ v0 := b.NewValue0(x.Pos, OpS390XMOVBZload, t)
+ v.reset(OpCopy)
+ v.AddArg(v0)
+ v0.AuxInt = o
+ v0.Aux = s
+ v0.AddArg(p)
+ v0.AddArg(mem)
+ return true
+ }
+ return false
+}
+func rewriteValueS390X_OpS390XMOVBZreg_10(v *Value) bool {
+ b := v.Block
+ // match: (MOVBZreg <t> x:(MOVBloadidx [o] {s} p i mem))
+ // cond: x.Uses == 1 && clobber(x)
+ // result: @x.Block (MOVBZloadidx <t> [o] {s} p i mem)
+ for {
+ t := v.Type
+ x := v.Args[0]
+ if x.Op != OpS390XMOVBloadidx {
+ break
+ }
+ o := x.AuxInt
+ s := x.Aux
+ mem := x.Args[2]
+ p := x.Args[0]
+ i := x.Args[1]
+ if !(x.Uses == 1 && clobber(x)) {
+ break
+ }
+ b = x.Block
+ v0 := b.NewValue0(v.Pos, OpS390XMOVBZloadidx, t)
+ v.reset(OpCopy)
+ v.AddArg(v0)
+ v0.AuxInt = o
+ v0.Aux = s
+ v0.AddArg(p)
+ v0.AddArg(i)
+ v0.AddArg(mem)
+ return true
+ }
+ // match: (MOVBZreg x:(Arg <t>))
+ // cond: !t.IsSigned() && t.Size() == 1
+ // result: x
+ for {
+ x := v.Args[0]
+ if x.Op != OpArg {
break
}
- v.reset(OpS390XMOVDreg)
+ t := x.Type
+ if !(!t.IsSigned() && t.Size() == 1) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
- // match: (MOVBZreg x:(MOVDEQ (MOVDconst [c]) (MOVDconst [d]) _))
- // cond: int64(uint8(c)) == c && int64(uint8(d)) == d
- // result: (MOVDreg x)
+ // match: (MOVBZreg (MOVDconst [c]))
+ // cond:
+ // result: (MOVDconst [int64( uint8(c))])
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpS390XMOVDconst {
+ break
+ }
+ c := v_0.AuxInt
+ v.reset(OpS390XMOVDconst)
+ v.AuxInt = int64(uint8(c))
+ return true
+ }
+ // match: (MOVBZreg x:(MOVDLT (MOVDconst [c]) (MOVDconst [d]) _))
+ // cond: int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVDEQ {
+ if x.Op != OpS390XMOVDLT {
break
}
_ = x.Args[2]
break
}
d := x_1.AuxInt
- if !(int64(uint8(c)) == c && int64(uint8(d)) == d) {
+ if !(int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1)) {
break
}
- v.reset(OpS390XMOVDreg)
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
- // match: (MOVBZreg x:(MOVDNE (MOVDconst [c]) (MOVDconst [d]) _))
- // cond: int64(uint8(c)) == c && int64(uint8(d)) == d
- // result: (MOVDreg x)
+ // match: (MOVBZreg x:(MOVDLE (MOVDconst [c]) (MOVDconst [d]) _))
+ // cond: int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVDNE {
+ if x.Op != OpS390XMOVDLE {
break
}
_ = x.Args[2]
break
}
d := x_1.AuxInt
- if !(int64(uint8(c)) == c && int64(uint8(d)) == d) {
+ if !(int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1)) {
break
}
- v.reset(OpS390XMOVDreg)
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
- // match: (MOVBZreg x:(MOVDGTnoinv (MOVDconst [c]) (MOVDconst [d]) _))
- // cond: int64(uint8(c)) == c && int64(uint8(d)) == d
- // result: (MOVDreg x)
+ // match: (MOVBZreg x:(MOVDGT (MOVDconst [c]) (MOVDconst [d]) _))
+ // cond: int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVDGTnoinv {
+ if x.Op != OpS390XMOVDGT {
break
}
_ = x.Args[2]
break
}
d := x_1.AuxInt
- if !(int64(uint8(c)) == c && int64(uint8(d)) == d) {
+ if !(int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1)) {
break
}
- v.reset(OpS390XMOVDreg)
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
- // match: (MOVBZreg x:(MOVDGEnoinv (MOVDconst [c]) (MOVDconst [d]) _))
- // cond: int64(uint8(c)) == c && int64(uint8(d)) == d
- // result: (MOVDreg x)
+ // match: (MOVBZreg x:(MOVDGE (MOVDconst [c]) (MOVDconst [d]) _))
+ // cond: int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVDGEnoinv {
+ if x.Op != OpS390XMOVDGE {
break
}
_ = x.Args[2]
break
}
d := x_1.AuxInt
- if !(int64(uint8(c)) == c && int64(uint8(d)) == d) {
+ if !(int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1)) {
break
}
- v.reset(OpS390XMOVDreg)
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
- // match: (MOVBZreg x:(MOVBZload _ _))
- // cond:
- // result: (MOVDreg x)
+ // match: (MOVBZreg x:(MOVDEQ (MOVDconst [c]) (MOVDconst [d]) _))
+ // cond: int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVBZload {
+ if x.Op != OpS390XMOVDEQ {
break
}
- _ = x.Args[1]
- v.reset(OpS390XMOVDreg)
- v.AddArg(x)
- return true
- }
- // match: (MOVBZreg x:(Arg <t>))
- // cond: is8BitInt(t) && !isSigned(t)
- // result: (MOVDreg x)
- for {
- x := v.Args[0]
- if x.Op != OpArg {
+ _ = x.Args[2]
+ x_0 := x.Args[0]
+ if x_0.Op != OpS390XMOVDconst {
break
}
- t := x.Type
- if !(is8BitInt(t) && !isSigned(t)) {
+ c := x_0.AuxInt
+ x_1 := x.Args[1]
+ if x_1.Op != OpS390XMOVDconst {
break
}
- v.reset(OpS390XMOVDreg)
- v.AddArg(x)
- return true
- }
- return false
-}
-func rewriteValueS390X_OpS390XMOVBZreg_10(v *Value) bool {
- b := v.Block
- typ := &b.Func.Config.Types
- // match: (MOVBZreg x:(MOVBZreg _))
- // cond:
- // result: (MOVDreg x)
- for {
- x := v.Args[0]
- if x.Op != OpS390XMOVBZreg {
+ d := x_1.AuxInt
+ if !(int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1)) {
break
}
- v.reset(OpS390XMOVDreg)
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
- // match: (MOVBZreg (MOVBreg x))
- // cond:
- // result: (MOVBZreg x)
+ // match: (MOVBZreg x:(MOVDNE (MOVDconst [c]) (MOVDconst [d]) _))
+ // cond: int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1)
+ // result: x
for {
- v_0 := v.Args[0]
- if v_0.Op != OpS390XMOVBreg {
+ x := v.Args[0]
+ if x.Op != OpS390XMOVDNE {
break
}
- x := v_0.Args[0]
- v.reset(OpS390XMOVBZreg)
- v.AddArg(x)
- return true
- }
- // match: (MOVBZreg (MOVDconst [c]))
- // cond:
- // result: (MOVDconst [int64(uint8(c))])
- for {
- v_0 := v.Args[0]
- if v_0.Op != OpS390XMOVDconst {
+ _ = x.Args[2]
+ x_0 := x.Args[0]
+ if x_0.Op != OpS390XMOVDconst {
break
}
- c := v_0.AuxInt
- v.reset(OpS390XMOVDconst)
- v.AuxInt = int64(uint8(c))
- return true
- }
- // match: (MOVBZreg x:(MOVBZload [off] {sym} ptr mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVBZload <v.Type> [off] {sym} ptr mem)
- for {
- x := v.Args[0]
- if x.Op != OpS390XMOVBZload {
+ c := x_0.AuxInt
+ x_1 := x.Args[1]
+ if x_1.Op != OpS390XMOVDconst {
break
}
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[1]
- ptr := x.Args[0]
- if !(x.Uses == 1 && clobber(x)) {
+ d := x_1.AuxInt
+ if !(int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1)) {
break
}
- b = x.Block
- v0 := b.NewValue0(x.Pos, OpS390XMOVBZload, v.Type)
v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(mem)
+ v.Type = x.Type
+ v.AddArg(x)
return true
}
- // match: (MOVBZreg x:(MOVBload [off] {sym} ptr mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVBZload <v.Type> [off] {sym} ptr mem)
+ // match: (MOVBZreg x:(MOVDGTnoinv (MOVDconst [c]) (MOVDconst [d]) _))
+ // cond: int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVBload {
+ if x.Op != OpS390XMOVDGTnoinv {
break
}
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[1]
- ptr := x.Args[0]
- if !(x.Uses == 1 && clobber(x)) {
+ _ = x.Args[2]
+ x_0 := x.Args[0]
+ if x_0.Op != OpS390XMOVDconst {
break
}
- b = x.Block
- v0 := b.NewValue0(x.Pos, OpS390XMOVBZload, v.Type)
- v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(mem)
- return true
- }
- // match: (MOVBZreg x:(MOVBZloadidx [off] {sym} ptr idx mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVBZloadidx <v.Type> [off] {sym} ptr idx mem)
- for {
- x := v.Args[0]
- if x.Op != OpS390XMOVBZloadidx {
+ c := x_0.AuxInt
+ x_1 := x.Args[1]
+ if x_1.Op != OpS390XMOVDconst {
break
}
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[2]
- ptr := x.Args[0]
- idx := x.Args[1]
- if !(x.Uses == 1 && clobber(x)) {
+ d := x_1.AuxInt
+ if !(int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1)) {
break
}
- b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVBZloadidx, v.Type)
v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(idx)
- v0.AddArg(mem)
+ v.Type = x.Type
+ v.AddArg(x)
return true
}
- // match: (MOVBZreg x:(MOVBloadidx [off] {sym} ptr idx mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVBZloadidx <v.Type> [off] {sym} ptr idx mem)
+ return false
+}
+func rewriteValueS390X_OpS390XMOVBZreg_20(v *Value) bool {
+ b := v.Block
+ typ := &b.Func.Config.Types
+ // match: (MOVBZreg x:(MOVDGEnoinv (MOVDconst [c]) (MOVDconst [d]) _))
+ // cond: int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVBloadidx {
+ if x.Op != OpS390XMOVDGEnoinv {
break
}
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[2]
- ptr := x.Args[0]
- idx := x.Args[1]
- if !(x.Uses == 1 && clobber(x)) {
+ _ = x.Args[2]
+ x_0 := x.Args[0]
+ if x_0.Op != OpS390XMOVDconst {
+ break
+ }
+ c := x_0.AuxInt
+ x_1 := x.Args[1]
+ if x_1.Op != OpS390XMOVDconst {
+ break
+ }
+ d := x_1.AuxInt
+ if !(int64(uint8(c)) == c && int64(uint8(d)) == d && (!x.Type.IsSigned() || x.Type.Size() > 1)) {
break
}
- b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVBZloadidx, v.Type)
v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(idx)
- v0.AddArg(mem)
+ v.Type = x.Type
+ v.AddArg(x)
return true
}
// match: (MOVBZreg (ANDWconst [m] x))
}
func rewriteValueS390X_OpS390XMOVBreg_0(v *Value) bool {
b := v.Block
- typ := &b.Func.Config.Types
- // match: (MOVBreg x:(MOVBload _ _))
- // cond:
- // result: (MOVDreg x)
+ // match: (MOVBreg e:(MOVBreg x))
+ // cond: clobberIfDead(e)
+ // result: (MOVBreg x)
for {
- x := v.Args[0]
- if x.Op != OpS390XMOVBload {
+ e := v.Args[0]
+ if e.Op != OpS390XMOVBreg {
break
}
- _ = x.Args[1]
- v.reset(OpS390XMOVDreg)
+ x := e.Args[0]
+ if !(clobberIfDead(e)) {
+ break
+ }
+ v.reset(OpS390XMOVBreg)
v.AddArg(x)
return true
}
- // match: (MOVBreg x:(Arg <t>))
- // cond: is8BitInt(t) && isSigned(t)
- // result: (MOVDreg x)
+ // match: (MOVBreg e:(MOVHreg x))
+ // cond: clobberIfDead(e)
+ // result: (MOVBreg x)
for {
- x := v.Args[0]
- if x.Op != OpArg {
+ e := v.Args[0]
+ if e.Op != OpS390XMOVHreg {
break
}
- t := x.Type
- if !(is8BitInt(t) && isSigned(t)) {
+ x := e.Args[0]
+ if !(clobberIfDead(e)) {
break
}
- v.reset(OpS390XMOVDreg)
+ v.reset(OpS390XMOVBreg)
v.AddArg(x)
return true
}
- // match: (MOVBreg x:(MOVBreg _))
- // cond:
- // result: (MOVDreg x)
+ // match: (MOVBreg e:(MOVWreg x))
+ // cond: clobberIfDead(e)
+ // result: (MOVBreg x)
for {
- x := v.Args[0]
- if x.Op != OpS390XMOVBreg {
+ e := v.Args[0]
+ if e.Op != OpS390XMOVWreg {
+ break
+ }
+ x := e.Args[0]
+ if !(clobberIfDead(e)) {
break
}
- v.reset(OpS390XMOVDreg)
+ v.reset(OpS390XMOVBreg)
v.AddArg(x)
return true
}
- // match: (MOVBreg (MOVBZreg x))
- // cond:
+ // match: (MOVBreg e:(MOVBZreg x))
+ // cond: clobberIfDead(e)
// result: (MOVBreg x)
for {
- v_0 := v.Args[0]
- if v_0.Op != OpS390XMOVBZreg {
+ e := v.Args[0]
+ if e.Op != OpS390XMOVBZreg {
+ break
+ }
+ x := e.Args[0]
+ if !(clobberIfDead(e)) {
break
}
- x := v_0.Args[0]
v.reset(OpS390XMOVBreg)
v.AddArg(x)
return true
}
- // match: (MOVBreg (MOVDconst [c]))
- // cond:
- // result: (MOVDconst [int64(int8(c))])
+ // match: (MOVBreg e:(MOVHZreg x))
+ // cond: clobberIfDead(e)
+ // result: (MOVBreg x)
for {
- v_0 := v.Args[0]
- if v_0.Op != OpS390XMOVDconst {
+ e := v.Args[0]
+ if e.Op != OpS390XMOVHZreg {
break
}
- c := v_0.AuxInt
- v.reset(OpS390XMOVDconst)
- v.AuxInt = int64(int8(c))
+ x := e.Args[0]
+ if !(clobberIfDead(e)) {
+ break
+ }
+ v.reset(OpS390XMOVBreg)
+ v.AddArg(x)
return true
}
- // match: (MOVBreg x:(MOVBZload [off] {sym} ptr mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVBload <v.Type> [off] {sym} ptr mem)
+ // match: (MOVBreg e:(MOVWZreg x))
+ // cond: clobberIfDead(e)
+ // result: (MOVBreg x)
+ for {
+ e := v.Args[0]
+ if e.Op != OpS390XMOVWZreg {
+ break
+ }
+ x := e.Args[0]
+ if !(clobberIfDead(e)) {
+ break
+ }
+ v.reset(OpS390XMOVBreg)
+ v.AddArg(x)
+ return true
+ }
+ // match: (MOVBreg x:(MOVBload _ _))
+ // cond: (x.Type.IsSigned() || x.Type.Size() == 8)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVBZload {
+ if x.Op != OpS390XMOVBload {
break
}
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[1]
- ptr := x.Args[0]
- if !(x.Uses == 1 && clobber(x)) {
+ _ = x.Args[1]
+ if !(x.Type.IsSigned() || x.Type.Size() == 8) {
break
}
- b = x.Block
- v0 := b.NewValue0(x.Pos, OpS390XMOVBload, v.Type)
v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(mem)
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ // match: (MOVBreg x:(MOVBloadidx _ _ _))
+ // cond: (x.Type.IsSigned() || x.Type.Size() == 8)
+ // result: x
+ for {
+ x := v.Args[0]
+ if x.Op != OpS390XMOVBloadidx {
+ break
+ }
+ _ = x.Args[2]
+ if !(x.Type.IsSigned() || x.Type.Size() == 8) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ // match: (MOVBreg x:(MOVBloadidx _ _ _))
+ // cond: (x.Type.IsSigned() || x.Type.Size() == 8)
+ // result: x
+ for {
+ x := v.Args[0]
+ if x.Op != OpS390XMOVBloadidx {
+ break
+ }
+ _ = x.Args[2]
+ if !(x.Type.IsSigned() || x.Type.Size() == 8) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
+ v.AddArg(x)
return true
}
- // match: (MOVBreg x:(MOVBload [off] {sym} ptr mem))
+ // match: (MOVBreg <t> x:(MOVBZload [o] {s} p mem))
// cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVBload <v.Type> [off] {sym} ptr mem)
+ // result: @x.Block (MOVBload <t> [o] {s} p mem)
for {
+ t := v.Type
x := v.Args[0]
- if x.Op != OpS390XMOVBload {
+ if x.Op != OpS390XMOVBZload {
break
}
- off := x.AuxInt
- sym := x.Aux
+ o := x.AuxInt
+ s := x.Aux
mem := x.Args[1]
- ptr := x.Args[0]
+ p := x.Args[0]
if !(x.Uses == 1 && clobber(x)) {
break
}
b = x.Block
- v0 := b.NewValue0(x.Pos, OpS390XMOVBload, v.Type)
+ v0 := b.NewValue0(x.Pos, OpS390XMOVBload, t)
v.reset(OpCopy)
v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
+ v0.AuxInt = o
+ v0.Aux = s
+ v0.AddArg(p)
v0.AddArg(mem)
return true
}
- // match: (MOVBreg x:(MOVBZloadidx [off] {sym} ptr idx mem))
+ return false
+}
+func rewriteValueS390X_OpS390XMOVBreg_10(v *Value) bool {
+ b := v.Block
+ typ := &b.Func.Config.Types
+ // match: (MOVBreg <t> x:(MOVBZloadidx [o] {s} p i mem))
// cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVBloadidx <v.Type> [off] {sym} ptr idx mem)
+ // result: @x.Block (MOVBloadidx <t> [o] {s} p i mem)
for {
+ t := v.Type
x := v.Args[0]
if x.Op != OpS390XMOVBZloadidx {
break
}
- off := x.AuxInt
- sym := x.Aux
+ o := x.AuxInt
+ s := x.Aux
mem := x.Args[2]
- ptr := x.Args[0]
- idx := x.Args[1]
+ p := x.Args[0]
+ i := x.Args[1]
if !(x.Uses == 1 && clobber(x)) {
break
}
b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVBloadidx, v.Type)
+ v0 := b.NewValue0(v.Pos, OpS390XMOVBloadidx, t)
v.reset(OpCopy)
v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(idx)
+ v0.AuxInt = o
+ v0.Aux = s
+ v0.AddArg(p)
+ v0.AddArg(i)
v0.AddArg(mem)
return true
}
- // match: (MOVBreg x:(MOVBloadidx [off] {sym} ptr idx mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVBloadidx <v.Type> [off] {sym} ptr idx mem)
+ // match: (MOVBreg x:(Arg <t>))
+ // cond: t.IsSigned() && t.Size() == 1
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVBloadidx {
+ if x.Op != OpArg {
break
}
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[2]
- ptr := x.Args[0]
- idx := x.Args[1]
- if !(x.Uses == 1 && clobber(x)) {
+ t := x.Type
+ if !(t.IsSigned() && t.Size() == 1) {
break
}
- b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVBloadidx, v.Type)
v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(idx)
- v0.AddArg(mem)
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ // match: (MOVBreg (MOVDconst [c]))
+ // cond:
+ // result: (MOVDconst [int64( int8(c))])
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpS390XMOVDconst {
+ break
+ }
+ c := v_0.AuxInt
+ v.reset(OpS390XMOVDconst)
+ v.AuxInt = int64(int8(c))
return true
}
// match: (MOVBreg (ANDWconst [m] x))
func rewriteValueS390X_OpS390XMOVDload_0(v *Value) bool {
// match: (MOVDload [off] {sym} ptr1 (MOVDstore [off] {sym} ptr2 x _))
// cond: isSamePtr(ptr1, ptr2)
- // result: (MOVDreg x)
+ // result: x
for {
off := v.AuxInt
sym := v.Aux
if !(isSamePtr(ptr1, ptr2)) {
break
}
- v.reset(OpS390XMOVDreg)
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
}
return false
}
-func rewriteValueS390X_OpS390XMOVDnop_0(v *Value) bool {
- b := v.Block
- // match: (MOVDnop <t> x)
- // cond: t.Compare(x.Type) == types.CMPeq
- // result: x
- for {
- t := v.Type
- x := v.Args[0]
- if !(t.Compare(x.Type) == types.CMPeq) {
- break
- }
- v.reset(OpCopy)
- v.Type = x.Type
- v.AddArg(x)
- return true
- }
- // match: (MOVDnop (MOVDconst [c]))
- // cond:
- // result: (MOVDconst [c])
- for {
- v_0 := v.Args[0]
- if v_0.Op != OpS390XMOVDconst {
- break
- }
- c := v_0.AuxInt
- v.reset(OpS390XMOVDconst)
- v.AuxInt = c
- return true
- }
- // match: (MOVDnop <t> x:(MOVBZload [off] {sym} ptr mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVBZload <t> [off] {sym} ptr mem)
- for {
- t := v.Type
- x := v.Args[0]
- if x.Op != OpS390XMOVBZload {
- break
- }
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[1]
- ptr := x.Args[0]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(x.Pos, OpS390XMOVBZload, t)
- v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(mem)
- return true
- }
- // match: (MOVDnop <t> x:(MOVBload [off] {sym} ptr mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVBload <t> [off] {sym} ptr mem)
- for {
- t := v.Type
- x := v.Args[0]
- if x.Op != OpS390XMOVBload {
- break
- }
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[1]
- ptr := x.Args[0]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(x.Pos, OpS390XMOVBload, t)
- v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(mem)
- return true
- }
- // match: (MOVDnop <t> x:(MOVHZload [off] {sym} ptr mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVHZload <t> [off] {sym} ptr mem)
- for {
- t := v.Type
- x := v.Args[0]
- if x.Op != OpS390XMOVHZload {
- break
- }
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[1]
- ptr := x.Args[0]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(x.Pos, OpS390XMOVHZload, t)
- v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(mem)
- return true
- }
- // match: (MOVDnop <t> x:(MOVHload [off] {sym} ptr mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVHload <t> [off] {sym} ptr mem)
- for {
- t := v.Type
- x := v.Args[0]
- if x.Op != OpS390XMOVHload {
- break
- }
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[1]
- ptr := x.Args[0]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(x.Pos, OpS390XMOVHload, t)
- v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(mem)
- return true
- }
- // match: (MOVDnop <t> x:(MOVWZload [off] {sym} ptr mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVWZload <t> [off] {sym} ptr mem)
- for {
- t := v.Type
- x := v.Args[0]
- if x.Op != OpS390XMOVWZload {
- break
- }
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[1]
- ptr := x.Args[0]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(x.Pos, OpS390XMOVWZload, t)
- v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(mem)
- return true
- }
- // match: (MOVDnop <t> x:(MOVWload [off] {sym} ptr mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVWload <t> [off] {sym} ptr mem)
- for {
- t := v.Type
- x := v.Args[0]
- if x.Op != OpS390XMOVWload {
- break
- }
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[1]
- ptr := x.Args[0]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(x.Pos, OpS390XMOVWload, t)
- v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(mem)
- return true
- }
- // match: (MOVDnop <t> x:(MOVDload [off] {sym} ptr mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVDload <t> [off] {sym} ptr mem)
- for {
- t := v.Type
- x := v.Args[0]
- if x.Op != OpS390XMOVDload {
- break
- }
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[1]
- ptr := x.Args[0]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(x.Pos, OpS390XMOVDload, t)
- v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(mem)
- return true
- }
- // match: (MOVDnop <t> x:(MOVBZloadidx [off] {sym} ptr idx mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVBZloadidx <t> [off] {sym} ptr idx mem)
- for {
- t := v.Type
- x := v.Args[0]
- if x.Op != OpS390XMOVBZloadidx {
- break
- }
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[2]
- ptr := x.Args[0]
- idx := x.Args[1]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVBZloadidx, t)
- v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(idx)
- v0.AddArg(mem)
- return true
- }
- return false
-}
-func rewriteValueS390X_OpS390XMOVDnop_10(v *Value) bool {
- b := v.Block
- // match: (MOVDnop <t> x:(MOVBloadidx [off] {sym} ptr idx mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVBloadidx <t> [off] {sym} ptr idx mem)
- for {
- t := v.Type
- x := v.Args[0]
- if x.Op != OpS390XMOVBloadidx {
- break
- }
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[2]
- ptr := x.Args[0]
- idx := x.Args[1]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVBloadidx, t)
- v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(idx)
- v0.AddArg(mem)
- return true
- }
- // match: (MOVDnop <t> x:(MOVHZloadidx [off] {sym} ptr idx mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVHZloadidx <t> [off] {sym} ptr idx mem)
- for {
- t := v.Type
- x := v.Args[0]
- if x.Op != OpS390XMOVHZloadidx {
- break
- }
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[2]
- ptr := x.Args[0]
- idx := x.Args[1]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVHZloadidx, t)
- v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(idx)
- v0.AddArg(mem)
- return true
- }
- // match: (MOVDnop <t> x:(MOVHloadidx [off] {sym} ptr idx mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVHloadidx <t> [off] {sym} ptr idx mem)
- for {
- t := v.Type
- x := v.Args[0]
- if x.Op != OpS390XMOVHloadidx {
- break
- }
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[2]
- ptr := x.Args[0]
- idx := x.Args[1]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVHloadidx, t)
- v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(idx)
- v0.AddArg(mem)
- return true
- }
- // match: (MOVDnop <t> x:(MOVWZloadidx [off] {sym} ptr idx mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVWZloadidx <t> [off] {sym} ptr idx mem)
- for {
- t := v.Type
- x := v.Args[0]
- if x.Op != OpS390XMOVWZloadidx {
- break
- }
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[2]
- ptr := x.Args[0]
- idx := x.Args[1]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVWZloadidx, t)
- v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(idx)
- v0.AddArg(mem)
- return true
- }
- // match: (MOVDnop <t> x:(MOVWloadidx [off] {sym} ptr idx mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVWloadidx <t> [off] {sym} ptr idx mem)
- for {
- t := v.Type
- x := v.Args[0]
- if x.Op != OpS390XMOVWloadidx {
- break
- }
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[2]
- ptr := x.Args[0]
- idx := x.Args[1]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVWloadidx, t)
- v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(idx)
- v0.AddArg(mem)
- return true
- }
- // match: (MOVDnop <t> x:(MOVDloadidx [off] {sym} ptr idx mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVDloadidx <t> [off] {sym} ptr idx mem)
- for {
- t := v.Type
- x := v.Args[0]
- if x.Op != OpS390XMOVDloadidx {
- break
- }
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[2]
- ptr := x.Args[0]
- idx := x.Args[1]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVDloadidx, t)
- v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(idx)
- v0.AddArg(mem)
- return true
- }
- return false
-}
-func rewriteValueS390X_OpS390XMOVDreg_0(v *Value) bool {
- b := v.Block
- // match: (MOVDreg <t> x)
- // cond: t.Compare(x.Type) == types.CMPeq
- // result: x
- for {
- t := v.Type
- x := v.Args[0]
- if !(t.Compare(x.Type) == types.CMPeq) {
- break
- }
- v.reset(OpCopy)
- v.Type = x.Type
- v.AddArg(x)
- return true
- }
- // match: (MOVDreg (MOVDconst [c]))
- // cond:
- // result: (MOVDconst [c])
- for {
- v_0 := v.Args[0]
- if v_0.Op != OpS390XMOVDconst {
- break
- }
- c := v_0.AuxInt
- v.reset(OpS390XMOVDconst)
- v.AuxInt = c
- return true
- }
- // match: (MOVDreg x)
- // cond: x.Uses == 1
- // result: (MOVDnop x)
- for {
- x := v.Args[0]
- if !(x.Uses == 1) {
- break
- }
- v.reset(OpS390XMOVDnop)
- v.AddArg(x)
- return true
- }
- // match: (MOVDreg <t> x:(MOVBZload [off] {sym} ptr mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVBZload <t> [off] {sym} ptr mem)
- for {
- t := v.Type
- x := v.Args[0]
- if x.Op != OpS390XMOVBZload {
- break
- }
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[1]
- ptr := x.Args[0]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(x.Pos, OpS390XMOVBZload, t)
- v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(mem)
- return true
- }
- // match: (MOVDreg <t> x:(MOVBload [off] {sym} ptr mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVBload <t> [off] {sym} ptr mem)
- for {
- t := v.Type
- x := v.Args[0]
- if x.Op != OpS390XMOVBload {
- break
- }
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[1]
- ptr := x.Args[0]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(x.Pos, OpS390XMOVBload, t)
- v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(mem)
- return true
- }
- // match: (MOVDreg <t> x:(MOVHZload [off] {sym} ptr mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVHZload <t> [off] {sym} ptr mem)
- for {
- t := v.Type
- x := v.Args[0]
- if x.Op != OpS390XMOVHZload {
- break
- }
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[1]
- ptr := x.Args[0]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(x.Pos, OpS390XMOVHZload, t)
- v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(mem)
- return true
- }
- // match: (MOVDreg <t> x:(MOVHload [off] {sym} ptr mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVHload <t> [off] {sym} ptr mem)
- for {
- t := v.Type
- x := v.Args[0]
- if x.Op != OpS390XMOVHload {
- break
- }
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[1]
- ptr := x.Args[0]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(x.Pos, OpS390XMOVHload, t)
- v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(mem)
- return true
- }
- // match: (MOVDreg <t> x:(MOVWZload [off] {sym} ptr mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVWZload <t> [off] {sym} ptr mem)
- for {
- t := v.Type
- x := v.Args[0]
- if x.Op != OpS390XMOVWZload {
- break
- }
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[1]
- ptr := x.Args[0]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(x.Pos, OpS390XMOVWZload, t)
- v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(mem)
- return true
- }
- // match: (MOVDreg <t> x:(MOVWload [off] {sym} ptr mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVWload <t> [off] {sym} ptr mem)
- for {
- t := v.Type
- x := v.Args[0]
- if x.Op != OpS390XMOVWload {
- break
- }
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[1]
- ptr := x.Args[0]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(x.Pos, OpS390XMOVWload, t)
- v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(mem)
- return true
- }
- // match: (MOVDreg <t> x:(MOVDload [off] {sym} ptr mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVDload <t> [off] {sym} ptr mem)
- for {
- t := v.Type
- x := v.Args[0]
- if x.Op != OpS390XMOVDload {
- break
- }
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[1]
- ptr := x.Args[0]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(x.Pos, OpS390XMOVDload, t)
- v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(mem)
- return true
- }
- return false
-}
-func rewriteValueS390X_OpS390XMOVDreg_10(v *Value) bool {
- b := v.Block
- // match: (MOVDreg <t> x:(MOVBZloadidx [off] {sym} ptr idx mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVBZloadidx <t> [off] {sym} ptr idx mem)
- for {
- t := v.Type
- x := v.Args[0]
- if x.Op != OpS390XMOVBZloadidx {
- break
- }
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[2]
- ptr := x.Args[0]
- idx := x.Args[1]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVBZloadidx, t)
- v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(idx)
- v0.AddArg(mem)
- return true
- }
- // match: (MOVDreg <t> x:(MOVBloadidx [off] {sym} ptr idx mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVBloadidx <t> [off] {sym} ptr idx mem)
- for {
- t := v.Type
- x := v.Args[0]
- if x.Op != OpS390XMOVBloadidx {
- break
- }
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[2]
- ptr := x.Args[0]
- idx := x.Args[1]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVBloadidx, t)
- v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(idx)
- v0.AddArg(mem)
- return true
- }
- // match: (MOVDreg <t> x:(MOVHZloadidx [off] {sym} ptr idx mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVHZloadidx <t> [off] {sym} ptr idx mem)
- for {
- t := v.Type
- x := v.Args[0]
- if x.Op != OpS390XMOVHZloadidx {
- break
- }
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[2]
- ptr := x.Args[0]
- idx := x.Args[1]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVHZloadidx, t)
- v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(idx)
- v0.AddArg(mem)
- return true
- }
- // match: (MOVDreg <t> x:(MOVHloadidx [off] {sym} ptr idx mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVHloadidx <t> [off] {sym} ptr idx mem)
- for {
- t := v.Type
- x := v.Args[0]
- if x.Op != OpS390XMOVHloadidx {
- break
- }
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[2]
- ptr := x.Args[0]
- idx := x.Args[1]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVHloadidx, t)
- v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(idx)
- v0.AddArg(mem)
- return true
- }
- // match: (MOVDreg <t> x:(MOVWZloadidx [off] {sym} ptr idx mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVWZloadidx <t> [off] {sym} ptr idx mem)
- for {
- t := v.Type
- x := v.Args[0]
- if x.Op != OpS390XMOVWZloadidx {
- break
- }
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[2]
- ptr := x.Args[0]
- idx := x.Args[1]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVWZloadidx, t)
- v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(idx)
- v0.AddArg(mem)
- return true
- }
- // match: (MOVDreg <t> x:(MOVWloadidx [off] {sym} ptr idx mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVWloadidx <t> [off] {sym} ptr idx mem)
- for {
- t := v.Type
- x := v.Args[0]
- if x.Op != OpS390XMOVWloadidx {
- break
- }
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[2]
- ptr := x.Args[0]
- idx := x.Args[1]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVWloadidx, t)
- v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(idx)
- v0.AddArg(mem)
- return true
- }
- // match: (MOVDreg <t> x:(MOVDloadidx [off] {sym} ptr idx mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVDloadidx <t> [off] {sym} ptr idx mem)
- for {
- t := v.Type
- x := v.Args[0]
- if x.Op != OpS390XMOVDloadidx {
- break
- }
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[2]
- ptr := x.Args[0]
- idx := x.Args[1]
- if !(x.Uses == 1 && clobber(x)) {
- break
- }
- b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVDloadidx, t)
- v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(idx)
- v0.AddArg(mem)
- return true
- }
- return false
-}
func rewriteValueS390X_OpS390XMOVDstore_0(v *Value) bool {
// match: (MOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem)
// cond: is20Bit(off1+off2)
return false
}
func rewriteValueS390X_OpS390XMOVHZreg_0(v *Value) bool {
- b := v.Block
- // match: (MOVHZreg x:(MOVBZload _ _))
- // cond:
- // result: (MOVDreg x)
+ // match: (MOVHZreg e:(MOVBZreg x))
+ // cond: clobberIfDead(e)
+ // result: (MOVBZreg x)
for {
- x := v.Args[0]
- if x.Op != OpS390XMOVBZload {
+ e := v.Args[0]
+ if e.Op != OpS390XMOVBZreg {
break
}
- _ = x.Args[1]
- v.reset(OpS390XMOVDreg)
+ x := e.Args[0]
+ if !(clobberIfDead(e)) {
+ break
+ }
+ v.reset(OpS390XMOVBZreg)
v.AddArg(x)
return true
}
- // match: (MOVHZreg x:(MOVHZload _ _))
- // cond:
- // result: (MOVDreg x)
+ // match: (MOVHZreg e:(MOVHreg x))
+ // cond: clobberIfDead(e)
+ // result: (MOVHZreg x)
for {
- x := v.Args[0]
- if x.Op != OpS390XMOVHZload {
+ e := v.Args[0]
+ if e.Op != OpS390XMOVHreg {
break
}
- _ = x.Args[1]
- v.reset(OpS390XMOVDreg)
+ x := e.Args[0]
+ if !(clobberIfDead(e)) {
+ break
+ }
+ v.reset(OpS390XMOVHZreg)
v.AddArg(x)
return true
}
- // match: (MOVHZreg x:(Arg <t>))
- // cond: (is8BitInt(t) || is16BitInt(t)) && !isSigned(t)
- // result: (MOVDreg x)
+ // match: (MOVHZreg e:(MOVWreg x))
+ // cond: clobberIfDead(e)
+ // result: (MOVHZreg x)
+ for {
+ e := v.Args[0]
+ if e.Op != OpS390XMOVWreg {
+ break
+ }
+ x := e.Args[0]
+ if !(clobberIfDead(e)) {
+ break
+ }
+ v.reset(OpS390XMOVHZreg)
+ v.AddArg(x)
+ return true
+ }
+ // match: (MOVHZreg e:(MOVHZreg x))
+ // cond: clobberIfDead(e)
+ // result: (MOVHZreg x)
+ for {
+ e := v.Args[0]
+ if e.Op != OpS390XMOVHZreg {
+ break
+ }
+ x := e.Args[0]
+ if !(clobberIfDead(e)) {
+ break
+ }
+ v.reset(OpS390XMOVHZreg)
+ v.AddArg(x)
+ return true
+ }
+ // match: (MOVHZreg e:(MOVWZreg x))
+ // cond: clobberIfDead(e)
+ // result: (MOVHZreg x)
+ for {
+ e := v.Args[0]
+ if e.Op != OpS390XMOVWZreg {
+ break
+ }
+ x := e.Args[0]
+ if !(clobberIfDead(e)) {
+ break
+ }
+ v.reset(OpS390XMOVHZreg)
+ v.AddArg(x)
+ return true
+ }
+ // match: (MOVHZreg x:(MOVBZload _ _))
+ // cond: (!x.Type.IsSigned() || x.Type.Size() > 1)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpArg {
+ if x.Op != OpS390XMOVBZload {
break
}
- t := x.Type
- if !((is8BitInt(t) || is16BitInt(t)) && !isSigned(t)) {
+ _ = x.Args[1]
+ if !(!x.Type.IsSigned() || x.Type.Size() > 1) {
break
}
- v.reset(OpS390XMOVDreg)
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
- // match: (MOVHZreg x:(MOVBZreg _))
- // cond:
- // result: (MOVDreg x)
+ // match: (MOVHZreg x:(MOVBZloadidx _ _ _))
+ // cond: (!x.Type.IsSigned() || x.Type.Size() > 1)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVBZreg {
+ if x.Op != OpS390XMOVBZloadidx {
+ break
+ }
+ _ = x.Args[2]
+ if !(!x.Type.IsSigned() || x.Type.Size() > 1) {
break
}
- v.reset(OpS390XMOVDreg)
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
- // match: (MOVHZreg x:(MOVHZreg _))
- // cond:
- // result: (MOVDreg x)
+ // match: (MOVHZreg x:(MOVBZloadidx _ _ _))
+ // cond: (!x.Type.IsSigned() || x.Type.Size() > 1)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVHZreg {
+ if x.Op != OpS390XMOVBZloadidx {
+ break
+ }
+ _ = x.Args[2]
+ if !(!x.Type.IsSigned() || x.Type.Size() > 1) {
break
}
- v.reset(OpS390XMOVDreg)
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
- // match: (MOVHZreg (MOVHreg x))
- // cond:
- // result: (MOVHZreg x)
+ // match: (MOVHZreg x:(MOVHZload _ _))
+ // cond: (!x.Type.IsSigned() || x.Type.Size() > 2)
+ // result: x
for {
- v_0 := v.Args[0]
- if v_0.Op != OpS390XMOVHreg {
+ x := v.Args[0]
+ if x.Op != OpS390XMOVHZload {
break
}
- x := v_0.Args[0]
- v.reset(OpS390XMOVHZreg)
+ _ = x.Args[1]
+ if !(!x.Type.IsSigned() || x.Type.Size() > 2) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
- // match: (MOVHZreg (MOVDconst [c]))
- // cond:
- // result: (MOVDconst [int64(uint16(c))])
+ // match: (MOVHZreg x:(MOVHZloadidx _ _ _))
+ // cond: (!x.Type.IsSigned() || x.Type.Size() > 2)
+ // result: x
for {
- v_0 := v.Args[0]
- if v_0.Op != OpS390XMOVDconst {
+ x := v.Args[0]
+ if x.Op != OpS390XMOVHZloadidx {
break
}
- c := v_0.AuxInt
- v.reset(OpS390XMOVDconst)
- v.AuxInt = int64(uint16(c))
+ _ = x.Args[2]
+ if !(!x.Type.IsSigned() || x.Type.Size() > 2) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
+ v.AddArg(x)
return true
}
- // match: (MOVHZreg x:(MOVHZload [off] {sym} ptr mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVHZload <v.Type> [off] {sym} ptr mem)
+ return false
+}
+func rewriteValueS390X_OpS390XMOVHZreg_10(v *Value) bool {
+ b := v.Block
+ typ := &b.Func.Config.Types
+ // match: (MOVHZreg x:(MOVHZloadidx _ _ _))
+ // cond: (!x.Type.IsSigned() || x.Type.Size() > 2)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVHZload {
+ if x.Op != OpS390XMOVHZloadidx {
break
}
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[1]
- ptr := x.Args[0]
- if !(x.Uses == 1 && clobber(x)) {
+ _ = x.Args[2]
+ if !(!x.Type.IsSigned() || x.Type.Size() > 2) {
break
}
- b = x.Block
- v0 := b.NewValue0(x.Pos, OpS390XMOVHZload, v.Type)
v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(mem)
+ v.Type = x.Type
+ v.AddArg(x)
return true
}
- // match: (MOVHZreg x:(MOVHload [off] {sym} ptr mem))
+ // match: (MOVHZreg <t> x:(MOVHload [o] {s} p mem))
// cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVHZload <v.Type> [off] {sym} ptr mem)
+ // result: @x.Block (MOVHZload <t> [o] {s} p mem)
for {
+ t := v.Type
x := v.Args[0]
if x.Op != OpS390XMOVHload {
break
}
- off := x.AuxInt
- sym := x.Aux
+ o := x.AuxInt
+ s := x.Aux
mem := x.Args[1]
- ptr := x.Args[0]
+ p := x.Args[0]
if !(x.Uses == 1 && clobber(x)) {
break
}
b = x.Block
- v0 := b.NewValue0(x.Pos, OpS390XMOVHZload, v.Type)
+ v0 := b.NewValue0(x.Pos, OpS390XMOVHZload, t)
v.reset(OpCopy)
v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
+ v0.AuxInt = o
+ v0.Aux = s
+ v0.AddArg(p)
v0.AddArg(mem)
return true
}
- // match: (MOVHZreg x:(MOVHZloadidx [off] {sym} ptr idx mem))
+ // match: (MOVHZreg <t> x:(MOVHloadidx [o] {s} p i mem))
// cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVHZloadidx <v.Type> [off] {sym} ptr idx mem)
+ // result: @x.Block (MOVHZloadidx <t> [o] {s} p i mem)
for {
+ t := v.Type
x := v.Args[0]
- if x.Op != OpS390XMOVHZloadidx {
+ if x.Op != OpS390XMOVHloadidx {
break
}
- off := x.AuxInt
- sym := x.Aux
+ o := x.AuxInt
+ s := x.Aux
mem := x.Args[2]
- ptr := x.Args[0]
- idx := x.Args[1]
+ p := x.Args[0]
+ i := x.Args[1]
if !(x.Uses == 1 && clobber(x)) {
break
}
b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVHZloadidx, v.Type)
+ v0 := b.NewValue0(v.Pos, OpS390XMOVHZloadidx, t)
v.reset(OpCopy)
v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(idx)
+ v0.AuxInt = o
+ v0.Aux = s
+ v0.AddArg(p)
+ v0.AddArg(i)
v0.AddArg(mem)
return true
}
- return false
-}
-func rewriteValueS390X_OpS390XMOVHZreg_10(v *Value) bool {
- b := v.Block
- typ := &b.Func.Config.Types
- // 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)
+ // match: (MOVHZreg x:(Arg <t>))
+ // cond: !t.IsSigned() && t.Size() <= 2
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVHloadidx {
+ if x.Op != OpArg {
break
}
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[2]
- ptr := x.Args[0]
- idx := x.Args[1]
- if !(x.Uses == 1 && clobber(x)) {
+ t := x.Type
+ if !(!t.IsSigned() && t.Size() <= 2) {
break
}
- b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVHZloadidx, v.Type)
v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(idx)
- v0.AddArg(mem)
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ // match: (MOVHZreg (MOVDconst [c]))
+ // cond:
+ // result: (MOVDconst [int64(uint16(c))])
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpS390XMOVDconst {
+ break
+ }
+ c := v_0.AuxInt
+ v.reset(OpS390XMOVDconst)
+ v.AuxInt = int64(uint16(c))
return true
}
// match: (MOVHZreg (ANDWconst [m] x))
return false
}
func rewriteValueS390X_OpS390XMOVHreg_0(v *Value) bool {
- b := v.Block
- // match: (MOVHreg x:(MOVBload _ _))
- // cond:
- // result: (MOVDreg x)
+ // match: (MOVHreg e:(MOVBreg x))
+ // cond: clobberIfDead(e)
+ // result: (MOVBreg x)
for {
- x := v.Args[0]
- if x.Op != OpS390XMOVBload {
+ e := v.Args[0]
+ if e.Op != OpS390XMOVBreg {
break
}
- _ = x.Args[1]
- v.reset(OpS390XMOVDreg)
+ x := e.Args[0]
+ if !(clobberIfDead(e)) {
+ break
+ }
+ v.reset(OpS390XMOVBreg)
v.AddArg(x)
return true
}
- // match: (MOVHreg x:(MOVBZload _ _))
- // cond:
- // result: (MOVDreg x)
+ // match: (MOVHreg e:(MOVHreg x))
+ // cond: clobberIfDead(e)
+ // result: (MOVHreg x)
for {
- x := v.Args[0]
- if x.Op != OpS390XMOVBZload {
+ e := v.Args[0]
+ if e.Op != OpS390XMOVHreg {
break
}
- _ = x.Args[1]
- v.reset(OpS390XMOVDreg)
+ x := e.Args[0]
+ if !(clobberIfDead(e)) {
+ break
+ }
+ v.reset(OpS390XMOVHreg)
v.AddArg(x)
return true
}
- // match: (MOVHreg x:(MOVHload _ _))
- // cond:
- // result: (MOVDreg x)
+ // match: (MOVHreg e:(MOVWreg x))
+ // cond: clobberIfDead(e)
+ // result: (MOVHreg x)
for {
- x := v.Args[0]
- if x.Op != OpS390XMOVHload {
+ e := v.Args[0]
+ if e.Op != OpS390XMOVWreg {
break
}
- _ = x.Args[1]
- v.reset(OpS390XMOVDreg)
+ x := e.Args[0]
+ if !(clobberIfDead(e)) {
+ break
+ }
+ v.reset(OpS390XMOVHreg)
v.AddArg(x)
return true
}
- // match: (MOVHreg x:(Arg <t>))
- // cond: (is8BitInt(t) || is16BitInt(t)) && isSigned(t)
- // result: (MOVDreg x)
+ // match: (MOVHreg e:(MOVHZreg x))
+ // cond: clobberIfDead(e)
+ // result: (MOVHreg x)
for {
- x := v.Args[0]
- if x.Op != OpArg {
+ e := v.Args[0]
+ if e.Op != OpS390XMOVHZreg {
break
}
- t := x.Type
- if !((is8BitInt(t) || is16BitInt(t)) && isSigned(t)) {
+ x := e.Args[0]
+ if !(clobberIfDead(e)) {
break
}
- v.reset(OpS390XMOVDreg)
+ v.reset(OpS390XMOVHreg)
v.AddArg(x)
return true
}
- // match: (MOVHreg x:(MOVBreg _))
- // cond:
- // result: (MOVDreg x)
+ // match: (MOVHreg e:(MOVWZreg x))
+ // cond: clobberIfDead(e)
+ // result: (MOVHreg x)
for {
- x := v.Args[0]
- if x.Op != OpS390XMOVBreg {
+ e := v.Args[0]
+ if e.Op != OpS390XMOVWZreg {
+ break
+ }
+ x := e.Args[0]
+ if !(clobberIfDead(e)) {
break
}
- v.reset(OpS390XMOVDreg)
+ v.reset(OpS390XMOVHreg)
v.AddArg(x)
return true
}
- // match: (MOVHreg x:(MOVBZreg _))
- // cond:
- // result: (MOVDreg x)
+ // match: (MOVHreg x:(MOVBload _ _))
+ // cond: (x.Type.IsSigned() || x.Type.Size() == 8)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVBZreg {
+ if x.Op != OpS390XMOVBload {
break
}
- v.reset(OpS390XMOVDreg)
+ _ = x.Args[1]
+ if !(x.Type.IsSigned() || x.Type.Size() == 8) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
- // match: (MOVHreg x:(MOVHreg _))
- // cond:
- // result: (MOVDreg x)
+ // match: (MOVHreg x:(MOVBloadidx _ _ _))
+ // cond: (x.Type.IsSigned() || x.Type.Size() == 8)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVHreg {
+ if x.Op != OpS390XMOVBloadidx {
break
}
- v.reset(OpS390XMOVDreg)
+ _ = x.Args[2]
+ if !(x.Type.IsSigned() || x.Type.Size() == 8) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
- // match: (MOVHreg (MOVHZreg x))
- // cond:
- // result: (MOVHreg x)
+ // match: (MOVHreg x:(MOVBloadidx _ _ _))
+ // cond: (x.Type.IsSigned() || x.Type.Size() == 8)
+ // result: x
for {
- v_0 := v.Args[0]
- if v_0.Op != OpS390XMOVHZreg {
+ x := v.Args[0]
+ if x.Op != OpS390XMOVBloadidx {
break
}
- x := v_0.Args[0]
- v.reset(OpS390XMOVHreg)
+ _ = x.Args[2]
+ if !(x.Type.IsSigned() || x.Type.Size() == 8) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
- // match: (MOVHreg (MOVDconst [c]))
- // cond:
- // result: (MOVDconst [int64(int16(c))])
+ // match: (MOVHreg x:(MOVHload _ _))
+ // cond: (x.Type.IsSigned() || x.Type.Size() == 8)
+ // result: x
for {
- v_0 := v.Args[0]
- if v_0.Op != OpS390XMOVDconst {
+ x := v.Args[0]
+ if x.Op != OpS390XMOVHload {
break
}
- c := v_0.AuxInt
- v.reset(OpS390XMOVDconst)
- v.AuxInt = int64(int16(c))
+ _ = x.Args[1]
+ if !(x.Type.IsSigned() || x.Type.Size() == 8) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
+ v.AddArg(x)
return true
}
- // match: (MOVHreg x:(MOVHZload [off] {sym} ptr mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVHload <v.Type> [off] {sym} ptr mem)
+ // match: (MOVHreg x:(MOVHloadidx _ _ _))
+ // cond: (x.Type.IsSigned() || x.Type.Size() == 8)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVHZload {
+ if x.Op != OpS390XMOVHloadidx {
break
}
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[1]
- ptr := x.Args[0]
- if !(x.Uses == 1 && clobber(x)) {
+ _ = x.Args[2]
+ if !(x.Type.IsSigned() || x.Type.Size() == 8) {
break
}
- b = x.Block
- v0 := b.NewValue0(x.Pos, OpS390XMOVHload, v.Type)
v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(mem)
+ v.Type = x.Type
+ v.AddArg(x)
return true
}
return false
func rewriteValueS390X_OpS390XMOVHreg_10(v *Value) bool {
b := v.Block
typ := &b.Func.Config.Types
- // match: (MOVHreg x:(MOVHload [off] {sym} ptr mem))
+ // match: (MOVHreg x:(MOVHloadidx _ _ _))
+ // cond: (x.Type.IsSigned() || x.Type.Size() == 8)
+ // result: x
+ for {
+ x := v.Args[0]
+ if x.Op != OpS390XMOVHloadidx {
+ break
+ }
+ _ = x.Args[2]
+ if !(x.Type.IsSigned() || x.Type.Size() == 8) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ // match: (MOVHreg x:(MOVBZload _ _))
+ // cond: (!x.Type.IsSigned() || x.Type.Size() > 1)
+ // result: x
+ for {
+ x := v.Args[0]
+ if x.Op != OpS390XMOVBZload {
+ break
+ }
+ _ = x.Args[1]
+ if !(!x.Type.IsSigned() || x.Type.Size() > 1) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ // match: (MOVHreg x:(MOVBZloadidx _ _ _))
+ // cond: (!x.Type.IsSigned() || x.Type.Size() > 1)
+ // result: x
+ for {
+ x := v.Args[0]
+ if x.Op != OpS390XMOVBZloadidx {
+ break
+ }
+ _ = x.Args[2]
+ if !(!x.Type.IsSigned() || x.Type.Size() > 1) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ // match: (MOVHreg x:(MOVBZloadidx _ _ _))
+ // cond: (!x.Type.IsSigned() || x.Type.Size() > 1)
+ // result: x
+ for {
+ x := v.Args[0]
+ if x.Op != OpS390XMOVBZloadidx {
+ break
+ }
+ _ = x.Args[2]
+ if !(!x.Type.IsSigned() || x.Type.Size() > 1) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ // match: (MOVHreg <t> x:(MOVHZload [o] {s} p mem))
// cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVHload <v.Type> [off] {sym} ptr mem)
+ // result: @x.Block (MOVHload <t> [o] {s} p mem)
for {
+ t := v.Type
x := v.Args[0]
- if x.Op != OpS390XMOVHload {
+ if x.Op != OpS390XMOVHZload {
break
}
- off := x.AuxInt
- sym := x.Aux
+ o := x.AuxInt
+ s := x.Aux
mem := x.Args[1]
- ptr := x.Args[0]
+ p := x.Args[0]
if !(x.Uses == 1 && clobber(x)) {
break
}
b = x.Block
- v0 := b.NewValue0(x.Pos, OpS390XMOVHload, v.Type)
+ v0 := b.NewValue0(x.Pos, OpS390XMOVHload, t)
v.reset(OpCopy)
v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
+ v0.AuxInt = o
+ v0.Aux = s
+ v0.AddArg(p)
v0.AddArg(mem)
return true
}
- // match: (MOVHreg x:(MOVHZloadidx [off] {sym} ptr idx mem))
+ // match: (MOVHreg <t> x:(MOVHZloadidx [o] {s} p i mem))
// cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVHloadidx <v.Type> [off] {sym} ptr idx mem)
+ // result: @x.Block (MOVHloadidx <t> [o] {s} p i mem)
for {
+ t := v.Type
x := v.Args[0]
if x.Op != OpS390XMOVHZloadidx {
break
}
- off := x.AuxInt
- sym := x.Aux
+ o := x.AuxInt
+ s := x.Aux
mem := x.Args[2]
- ptr := x.Args[0]
- idx := x.Args[1]
+ p := x.Args[0]
+ i := x.Args[1]
if !(x.Uses == 1 && clobber(x)) {
break
}
b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVHloadidx, v.Type)
+ v0 := b.NewValue0(v.Pos, OpS390XMOVHloadidx, t)
v.reset(OpCopy)
v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(idx)
+ v0.AuxInt = o
+ v0.Aux = s
+ v0.AddArg(p)
+ v0.AddArg(i)
v0.AddArg(mem)
return true
}
- // match: (MOVHreg x:(MOVHloadidx [off] {sym} ptr idx mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVHloadidx <v.Type> [off] {sym} ptr idx mem)
+ // match: (MOVHreg x:(Arg <t>))
+ // cond: t.IsSigned() && t.Size() <= 2
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVHloadidx {
+ if x.Op != OpArg {
break
}
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[2]
- ptr := x.Args[0]
- idx := x.Args[1]
- if !(x.Uses == 1 && clobber(x)) {
+ t := x.Type
+ if !(t.IsSigned() && t.Size() <= 2) {
break
}
- b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVHloadidx, v.Type)
v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(idx)
- v0.AddArg(mem)
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ // match: (MOVHreg (MOVDconst [c]))
+ // cond:
+ // result: (MOVDconst [int64(int16(c))])
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpS390XMOVDconst {
+ break
+ }
+ c := v_0.AuxInt
+ v.reset(OpS390XMOVDconst)
+ v.AuxInt = int64(int16(c))
return true
}
// match: (MOVHreg (ANDWconst [m] x))
return false
}
func rewriteValueS390X_OpS390XMOVWZreg_0(v *Value) bool {
- b := v.Block
- // match: (MOVWZreg x:(MOVBZload _ _))
- // cond:
- // result: (MOVDreg x)
+ // match: (MOVWZreg e:(MOVBZreg x))
+ // cond: clobberIfDead(e)
+ // result: (MOVBZreg x)
for {
- x := v.Args[0]
- if x.Op != OpS390XMOVBZload {
+ e := v.Args[0]
+ if e.Op != OpS390XMOVBZreg {
break
}
- _ = x.Args[1]
- v.reset(OpS390XMOVDreg)
+ x := e.Args[0]
+ if !(clobberIfDead(e)) {
+ break
+ }
+ v.reset(OpS390XMOVBZreg)
v.AddArg(x)
return true
}
- // match: (MOVWZreg x:(MOVHZload _ _))
- // cond:
- // result: (MOVDreg x)
+ // match: (MOVWZreg e:(MOVHZreg x))
+ // cond: clobberIfDead(e)
+ // result: (MOVHZreg x)
for {
- x := v.Args[0]
- if x.Op != OpS390XMOVHZload {
+ e := v.Args[0]
+ if e.Op != OpS390XMOVHZreg {
break
}
- _ = x.Args[1]
- v.reset(OpS390XMOVDreg)
+ x := e.Args[0]
+ if !(clobberIfDead(e)) {
+ break
+ }
+ v.reset(OpS390XMOVHZreg)
v.AddArg(x)
return true
}
- // match: (MOVWZreg x:(MOVWZload _ _))
- // cond:
- // result: (MOVDreg x)
+ // match: (MOVWZreg e:(MOVWreg x))
+ // cond: clobberIfDead(e)
+ // result: (MOVWZreg x)
for {
- x := v.Args[0]
- if x.Op != OpS390XMOVWZload {
+ e := v.Args[0]
+ if e.Op != OpS390XMOVWreg {
break
}
- _ = x.Args[1]
- v.reset(OpS390XMOVDreg)
+ x := e.Args[0]
+ if !(clobberIfDead(e)) {
+ break
+ }
+ v.reset(OpS390XMOVWZreg)
v.AddArg(x)
return true
}
- // match: (MOVWZreg x:(Arg <t>))
- // cond: (is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && !isSigned(t)
- // result: (MOVDreg x)
+ // match: (MOVWZreg e:(MOVWZreg x))
+ // cond: clobberIfDead(e)
+ // result: (MOVWZreg x)
for {
- x := v.Args[0]
- if x.Op != OpArg {
+ e := v.Args[0]
+ if e.Op != OpS390XMOVWZreg {
break
}
- t := x.Type
- if !((is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && !isSigned(t)) {
+ x := e.Args[0]
+ if !(clobberIfDead(e)) {
break
}
- v.reset(OpS390XMOVDreg)
+ v.reset(OpS390XMOVWZreg)
v.AddArg(x)
return true
}
- // match: (MOVWZreg x:(MOVBZreg _))
- // cond:
- // result: (MOVDreg x)
+ // match: (MOVWZreg x:(MOVBZload _ _))
+ // cond: (!x.Type.IsSigned() || x.Type.Size() > 1)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVBZreg {
+ if x.Op != OpS390XMOVBZload {
break
}
- v.reset(OpS390XMOVDreg)
+ _ = x.Args[1]
+ if !(!x.Type.IsSigned() || x.Type.Size() > 1) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
- // match: (MOVWZreg x:(MOVHZreg _))
- // cond:
- // result: (MOVDreg x)
+ // match: (MOVWZreg x:(MOVBZloadidx _ _ _))
+ // cond: (!x.Type.IsSigned() || x.Type.Size() > 1)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVHZreg {
+ if x.Op != OpS390XMOVBZloadidx {
break
}
- v.reset(OpS390XMOVDreg)
+ _ = x.Args[2]
+ if !(!x.Type.IsSigned() || x.Type.Size() > 1) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
- // match: (MOVWZreg x:(MOVWZreg _))
- // cond:
- // result: (MOVDreg x)
+ // match: (MOVWZreg x:(MOVBZloadidx _ _ _))
+ // cond: (!x.Type.IsSigned() || x.Type.Size() > 1)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVWZreg {
+ if x.Op != OpS390XMOVBZloadidx {
+ break
+ }
+ _ = x.Args[2]
+ if !(!x.Type.IsSigned() || x.Type.Size() > 1) {
break
}
- v.reset(OpS390XMOVDreg)
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
- // match: (MOVWZreg (MOVWreg x))
- // cond:
- // result: (MOVWZreg x)
+ // match: (MOVWZreg x:(MOVHZload _ _))
+ // cond: (!x.Type.IsSigned() || x.Type.Size() > 2)
+ // result: x
for {
- v_0 := v.Args[0]
- if v_0.Op != OpS390XMOVWreg {
+ x := v.Args[0]
+ if x.Op != OpS390XMOVHZload {
break
}
- x := v_0.Args[0]
- v.reset(OpS390XMOVWZreg)
+ _ = x.Args[1]
+ if !(!x.Type.IsSigned() || x.Type.Size() > 2) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
- // match: (MOVWZreg (MOVDconst [c]))
- // cond:
- // result: (MOVDconst [int64(uint32(c))])
+ // match: (MOVWZreg x:(MOVHZloadidx _ _ _))
+ // cond: (!x.Type.IsSigned() || x.Type.Size() > 2)
+ // result: x
for {
- v_0 := v.Args[0]
- if v_0.Op != OpS390XMOVDconst {
+ x := v.Args[0]
+ if x.Op != OpS390XMOVHZloadidx {
break
}
- c := v_0.AuxInt
- v.reset(OpS390XMOVDconst)
- v.AuxInt = int64(uint32(c))
+ _ = x.Args[2]
+ if !(!x.Type.IsSigned() || x.Type.Size() > 2) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
+ v.AddArg(x)
return true
}
- // match: (MOVWZreg x:(MOVWZload [off] {sym} ptr mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVWZload <v.Type> [off] {sym} ptr mem)
+ // match: (MOVWZreg x:(MOVHZloadidx _ _ _))
+ // cond: (!x.Type.IsSigned() || x.Type.Size() > 2)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVWZload {
+ if x.Op != OpS390XMOVHZloadidx {
break
}
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[1]
- ptr := x.Args[0]
- if !(x.Uses == 1 && clobber(x)) {
+ _ = x.Args[2]
+ if !(!x.Type.IsSigned() || x.Type.Size() > 2) {
break
}
- b = x.Block
- v0 := b.NewValue0(x.Pos, OpS390XMOVWZload, v.Type)
v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(mem)
+ v.Type = x.Type
+ v.AddArg(x)
return true
}
return false
}
func rewriteValueS390X_OpS390XMOVWZreg_10(v *Value) bool {
b := v.Block
- // match: (MOVWZreg x:(MOVWload [off] {sym} ptr mem))
+ // match: (MOVWZreg x:(MOVWZload _ _))
+ // cond: (!x.Type.IsSigned() || x.Type.Size() > 4)
+ // result: x
+ for {
+ x := v.Args[0]
+ if x.Op != OpS390XMOVWZload {
+ break
+ }
+ _ = x.Args[1]
+ if !(!x.Type.IsSigned() || x.Type.Size() > 4) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ // match: (MOVWZreg x:(MOVWZloadidx _ _ _))
+ // cond: (!x.Type.IsSigned() || x.Type.Size() > 4)
+ // result: x
+ for {
+ x := v.Args[0]
+ if x.Op != OpS390XMOVWZloadidx {
+ break
+ }
+ _ = x.Args[2]
+ if !(!x.Type.IsSigned() || x.Type.Size() > 4) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ // match: (MOVWZreg x:(MOVWZloadidx _ _ _))
+ // cond: (!x.Type.IsSigned() || x.Type.Size() > 4)
+ // result: x
+ for {
+ x := v.Args[0]
+ if x.Op != OpS390XMOVWZloadidx {
+ break
+ }
+ _ = x.Args[2]
+ if !(!x.Type.IsSigned() || x.Type.Size() > 4) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ // match: (MOVWZreg <t> x:(MOVWload [o] {s} p mem))
// cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVWZload <v.Type> [off] {sym} ptr mem)
+ // result: @x.Block (MOVWZload <t> [o] {s} p mem)
for {
+ t := v.Type
x := v.Args[0]
if x.Op != OpS390XMOVWload {
break
}
- off := x.AuxInt
- sym := x.Aux
+ o := x.AuxInt
+ s := x.Aux
mem := x.Args[1]
- ptr := x.Args[0]
+ p := x.Args[0]
if !(x.Uses == 1 && clobber(x)) {
break
}
b = x.Block
- v0 := b.NewValue0(x.Pos, OpS390XMOVWZload, v.Type)
+ v0 := b.NewValue0(x.Pos, OpS390XMOVWZload, t)
v.reset(OpCopy)
v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
+ v0.AuxInt = o
+ v0.Aux = s
+ v0.AddArg(p)
v0.AddArg(mem)
return true
}
- // match: (MOVWZreg x:(MOVWZloadidx [off] {sym} ptr idx mem))
+ // match: (MOVWZreg <t> x:(MOVWloadidx [o] {s} p i mem))
// cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVWZloadidx <v.Type> [off] {sym} ptr idx mem)
+ // result: @x.Block (MOVWZloadidx <t> [o] {s} p i mem)
for {
+ t := v.Type
x := v.Args[0]
- if x.Op != OpS390XMOVWZloadidx {
+ if x.Op != OpS390XMOVWloadidx {
break
}
- off := x.AuxInt
- sym := x.Aux
+ o := x.AuxInt
+ s := x.Aux
mem := x.Args[2]
- ptr := x.Args[0]
- idx := x.Args[1]
+ p := x.Args[0]
+ i := x.Args[1]
if !(x.Uses == 1 && clobber(x)) {
break
}
b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVWZloadidx, v.Type)
+ v0 := b.NewValue0(v.Pos, OpS390XMOVWZloadidx, t)
v.reset(OpCopy)
v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(idx)
+ v0.AuxInt = o
+ v0.Aux = s
+ v0.AddArg(p)
+ v0.AddArg(i)
v0.AddArg(mem)
return true
}
- // match: (MOVWZreg x:(MOVWloadidx [off] {sym} ptr idx mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVWZloadidx <v.Type> [off] {sym} ptr idx mem)
+ // match: (MOVWZreg x:(Arg <t>))
+ // cond: !t.IsSigned() && t.Size() <= 4
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVWloadidx {
+ if x.Op != OpArg {
break
}
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[2]
- ptr := x.Args[0]
- idx := x.Args[1]
- if !(x.Uses == 1 && clobber(x)) {
+ t := x.Type
+ if !(!t.IsSigned() && t.Size() <= 4) {
break
}
- b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVWZloadidx, v.Type)
v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(idx)
- v0.AddArg(mem)
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ // match: (MOVWZreg (MOVDconst [c]))
+ // cond:
+ // result: (MOVDconst [int64(uint32(c))])
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpS390XMOVDconst {
+ break
+ }
+ c := v_0.AuxInt
+ v.reset(OpS390XMOVDconst)
+ v.AuxInt = int64(uint32(c))
return true
}
return false
return false
}
func rewriteValueS390X_OpS390XMOVWreg_0(v *Value) bool {
+ // match: (MOVWreg e:(MOVBreg x))
+ // cond: clobberIfDead(e)
+ // result: (MOVBreg x)
+ for {
+ e := v.Args[0]
+ if e.Op != OpS390XMOVBreg {
+ break
+ }
+ x := e.Args[0]
+ if !(clobberIfDead(e)) {
+ break
+ }
+ v.reset(OpS390XMOVBreg)
+ v.AddArg(x)
+ return true
+ }
+ // match: (MOVWreg e:(MOVHreg x))
+ // cond: clobberIfDead(e)
+ // result: (MOVHreg x)
+ for {
+ e := v.Args[0]
+ if e.Op != OpS390XMOVHreg {
+ break
+ }
+ x := e.Args[0]
+ if !(clobberIfDead(e)) {
+ break
+ }
+ v.reset(OpS390XMOVHreg)
+ v.AddArg(x)
+ return true
+ }
+ // match: (MOVWreg e:(MOVWreg x))
+ // cond: clobberIfDead(e)
+ // result: (MOVWreg x)
+ for {
+ e := v.Args[0]
+ if e.Op != OpS390XMOVWreg {
+ break
+ }
+ x := e.Args[0]
+ if !(clobberIfDead(e)) {
+ break
+ }
+ v.reset(OpS390XMOVWreg)
+ v.AddArg(x)
+ return true
+ }
+ // match: (MOVWreg e:(MOVWZreg x))
+ // cond: clobberIfDead(e)
+ // result: (MOVWreg x)
+ for {
+ e := v.Args[0]
+ if e.Op != OpS390XMOVWZreg {
+ break
+ }
+ x := e.Args[0]
+ if !(clobberIfDead(e)) {
+ break
+ }
+ v.reset(OpS390XMOVWreg)
+ v.AddArg(x)
+ return true
+ }
// match: (MOVWreg x:(MOVBload _ _))
- // cond:
- // result: (MOVDreg x)
+ // cond: (x.Type.IsSigned() || x.Type.Size() == 8)
+ // result: x
for {
x := v.Args[0]
if x.Op != OpS390XMOVBload {
break
}
_ = x.Args[1]
- v.reset(OpS390XMOVDreg)
+ if !(x.Type.IsSigned() || x.Type.Size() == 8) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
- // match: (MOVWreg x:(MOVBZload _ _))
- // cond:
- // result: (MOVDreg x)
+ // match: (MOVWreg x:(MOVBloadidx _ _ _))
+ // cond: (x.Type.IsSigned() || x.Type.Size() == 8)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVBZload {
+ if x.Op != OpS390XMOVBloadidx {
break
}
- _ = x.Args[1]
- v.reset(OpS390XMOVDreg)
+ _ = x.Args[2]
+ if !(x.Type.IsSigned() || x.Type.Size() == 8) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ // match: (MOVWreg x:(MOVBloadidx _ _ _))
+ // cond: (x.Type.IsSigned() || x.Type.Size() == 8)
+ // result: x
+ for {
+ x := v.Args[0]
+ if x.Op != OpS390XMOVBloadidx {
+ break
+ }
+ _ = x.Args[2]
+ if !(x.Type.IsSigned() || x.Type.Size() == 8) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
// match: (MOVWreg x:(MOVHload _ _))
- // cond:
- // result: (MOVDreg x)
+ // cond: (x.Type.IsSigned() || x.Type.Size() == 8)
+ // result: x
for {
x := v.Args[0]
if x.Op != OpS390XMOVHload {
break
}
_ = x.Args[1]
- v.reset(OpS390XMOVDreg)
+ if !(x.Type.IsSigned() || x.Type.Size() == 8) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
- // match: (MOVWreg x:(MOVHZload _ _))
- // cond:
- // result: (MOVDreg x)
+ // match: (MOVWreg x:(MOVHloadidx _ _ _))
+ // cond: (x.Type.IsSigned() || x.Type.Size() == 8)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVHZload {
+ if x.Op != OpS390XMOVHloadidx {
break
}
- _ = x.Args[1]
- v.reset(OpS390XMOVDreg)
+ _ = x.Args[2]
+ if !(x.Type.IsSigned() || x.Type.Size() == 8) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
- // match: (MOVWreg x:(MOVWload _ _))
- // cond:
- // result: (MOVDreg x)
+ // match: (MOVWreg x:(MOVHloadidx _ _ _))
+ // cond: (x.Type.IsSigned() || x.Type.Size() == 8)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVWload {
+ if x.Op != OpS390XMOVHloadidx {
break
}
- _ = x.Args[1]
- v.reset(OpS390XMOVDreg)
+ _ = x.Args[2]
+ if !(x.Type.IsSigned() || x.Type.Size() == 8) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
- // match: (MOVWreg x:(Arg <t>))
- // cond: (is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && isSigned(t)
- // result: (MOVDreg x)
+ return false
+}
+func rewriteValueS390X_OpS390XMOVWreg_10(v *Value) bool {
+ b := v.Block
+ // match: (MOVWreg x:(MOVWload _ _))
+ // cond: (x.Type.IsSigned() || x.Type.Size() == 8)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpArg {
+ if x.Op != OpS390XMOVWload {
break
}
- t := x.Type
- if !((is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && isSigned(t)) {
+ _ = x.Args[1]
+ if !(x.Type.IsSigned() || x.Type.Size() == 8) {
break
}
- v.reset(OpS390XMOVDreg)
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
- // match: (MOVWreg x:(MOVBreg _))
- // cond:
- // result: (MOVDreg x)
+ // match: (MOVWreg x:(MOVWloadidx _ _ _))
+ // cond: (x.Type.IsSigned() || x.Type.Size() == 8)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVBreg {
+ if x.Op != OpS390XMOVWloadidx {
+ break
+ }
+ _ = x.Args[2]
+ if !(x.Type.IsSigned() || x.Type.Size() == 8) {
break
}
- v.reset(OpS390XMOVDreg)
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
- // match: (MOVWreg x:(MOVBZreg _))
- // cond:
- // result: (MOVDreg x)
+ // match: (MOVWreg x:(MOVWloadidx _ _ _))
+ // cond: (x.Type.IsSigned() || x.Type.Size() == 8)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVBZreg {
+ if x.Op != OpS390XMOVWloadidx {
+ break
+ }
+ _ = x.Args[2]
+ if !(x.Type.IsSigned() || x.Type.Size() == 8) {
break
}
- v.reset(OpS390XMOVDreg)
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
- // match: (MOVWreg x:(MOVHreg _))
- // cond:
- // result: (MOVDreg x)
+ // match: (MOVWreg x:(MOVBZload _ _))
+ // cond: (!x.Type.IsSigned() || x.Type.Size() > 1)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVHreg {
+ if x.Op != OpS390XMOVBZload {
break
}
- v.reset(OpS390XMOVDreg)
+ _ = x.Args[1]
+ if !(!x.Type.IsSigned() || x.Type.Size() > 1) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
- // match: (MOVWreg x:(MOVHZreg _))
- // cond:
- // result: (MOVDreg x)
+ // match: (MOVWreg x:(MOVBZloadidx _ _ _))
+ // cond: (!x.Type.IsSigned() || x.Type.Size() > 1)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVHZreg {
+ if x.Op != OpS390XMOVBZloadidx {
+ break
+ }
+ _ = x.Args[2]
+ if !(!x.Type.IsSigned() || x.Type.Size() > 1) {
break
}
- v.reset(OpS390XMOVDreg)
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
- return false
-}
-func rewriteValueS390X_OpS390XMOVWreg_10(v *Value) bool {
- b := v.Block
- // match: (MOVWreg x:(MOVWreg _))
- // cond:
- // result: (MOVDreg x)
+ // match: (MOVWreg x:(MOVBZloadidx _ _ _))
+ // cond: (!x.Type.IsSigned() || x.Type.Size() > 1)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVWreg {
+ if x.Op != OpS390XMOVBZloadidx {
+ break
+ }
+ _ = x.Args[2]
+ if !(!x.Type.IsSigned() || x.Type.Size() > 1) {
break
}
- v.reset(OpS390XMOVDreg)
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
- // match: (MOVWreg (MOVWZreg x))
- // cond:
- // result: (MOVWreg x)
+ // match: (MOVWreg x:(MOVHZload _ _))
+ // cond: (!x.Type.IsSigned() || x.Type.Size() > 2)
+ // result: x
for {
- v_0 := v.Args[0]
- if v_0.Op != OpS390XMOVWZreg {
+ x := v.Args[0]
+ if x.Op != OpS390XMOVHZload {
break
}
- x := v_0.Args[0]
- v.reset(OpS390XMOVWreg)
+ _ = x.Args[1]
+ if !(!x.Type.IsSigned() || x.Type.Size() > 2) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
v.AddArg(x)
return true
}
- // match: (MOVWreg (MOVDconst [c]))
- // cond:
- // result: (MOVDconst [int64(int32(c))])
+ // match: (MOVWreg x:(MOVHZloadidx _ _ _))
+ // cond: (!x.Type.IsSigned() || x.Type.Size() > 2)
+ // result: x
for {
- v_0 := v.Args[0]
- if v_0.Op != OpS390XMOVDconst {
+ x := v.Args[0]
+ if x.Op != OpS390XMOVHZloadidx {
break
}
- c := v_0.AuxInt
- v.reset(OpS390XMOVDconst)
- v.AuxInt = int64(int32(c))
+ _ = x.Args[2]
+ if !(!x.Type.IsSigned() || x.Type.Size() > 2) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
+ v.AddArg(x)
return true
}
- // match: (MOVWreg x:(MOVWZload [off] {sym} ptr mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVWload <v.Type> [off] {sym} ptr mem)
+ // match: (MOVWreg x:(MOVHZloadidx _ _ _))
+ // cond: (!x.Type.IsSigned() || x.Type.Size() > 2)
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVWZload {
+ if x.Op != OpS390XMOVHZloadidx {
break
}
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[1]
- ptr := x.Args[0]
- if !(x.Uses == 1 && clobber(x)) {
+ _ = x.Args[2]
+ if !(!x.Type.IsSigned() || x.Type.Size() > 2) {
break
}
- b = x.Block
- v0 := b.NewValue0(x.Pos, OpS390XMOVWload, v.Type)
v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(mem)
+ v.Type = x.Type
+ v.AddArg(x)
return true
}
- // match: (MOVWreg x:(MOVWload [off] {sym} ptr mem))
+ // match: (MOVWreg <t> x:(MOVWZload [o] {s} p mem))
// cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVWload <v.Type> [off] {sym} ptr mem)
+ // result: @x.Block (MOVWload <t> [o] {s} p mem)
for {
+ t := v.Type
x := v.Args[0]
- if x.Op != OpS390XMOVWload {
+ if x.Op != OpS390XMOVWZload {
break
}
- off := x.AuxInt
- sym := x.Aux
+ o := x.AuxInt
+ s := x.Aux
mem := x.Args[1]
- ptr := x.Args[0]
+ p := x.Args[0]
if !(x.Uses == 1 && clobber(x)) {
break
}
b = x.Block
- v0 := b.NewValue0(x.Pos, OpS390XMOVWload, v.Type)
+ v0 := b.NewValue0(x.Pos, OpS390XMOVWload, t)
v.reset(OpCopy)
v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
+ v0.AuxInt = o
+ v0.Aux = s
+ v0.AddArg(p)
v0.AddArg(mem)
return true
}
- // match: (MOVWreg x:(MOVWZloadidx [off] {sym} ptr idx mem))
+ return false
+}
+func rewriteValueS390X_OpS390XMOVWreg_20(v *Value) bool {
+ b := v.Block
+ // match: (MOVWreg <t> x:(MOVWZloadidx [o] {s} p i mem))
// cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVWloadidx <v.Type> [off] {sym} ptr idx mem)
+ // result: @x.Block (MOVWloadidx <t> [o] {s} p i mem)
for {
+ t := v.Type
x := v.Args[0]
if x.Op != OpS390XMOVWZloadidx {
break
}
- off := x.AuxInt
- sym := x.Aux
+ o := x.AuxInt
+ s := x.Aux
mem := x.Args[2]
- ptr := x.Args[0]
- idx := x.Args[1]
+ p := x.Args[0]
+ i := x.Args[1]
if !(x.Uses == 1 && clobber(x)) {
break
}
b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVWloadidx, v.Type)
+ v0 := b.NewValue0(v.Pos, OpS390XMOVWloadidx, t)
v.reset(OpCopy)
v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(idx)
+ v0.AuxInt = o
+ v0.Aux = s
+ v0.AddArg(p)
+ v0.AddArg(i)
v0.AddArg(mem)
return true
}
- // match: (MOVWreg x:(MOVWloadidx [off] {sym} ptr idx mem))
- // cond: x.Uses == 1 && clobber(x)
- // result: @x.Block (MOVWloadidx <v.Type> [off] {sym} ptr idx mem)
+ // match: (MOVWreg x:(Arg <t>))
+ // cond: t.IsSigned() && t.Size() <= 4
+ // result: x
for {
x := v.Args[0]
- if x.Op != OpS390XMOVWloadidx {
+ if x.Op != OpArg {
break
}
- off := x.AuxInt
- sym := x.Aux
- mem := x.Args[2]
- ptr := x.Args[0]
- idx := x.Args[1]
- if !(x.Uses == 1 && clobber(x)) {
+ t := x.Type
+ if !(t.IsSigned() && t.Size() <= 4) {
break
}
- b = x.Block
- v0 := b.NewValue0(v.Pos, OpS390XMOVWloadidx, v.Type)
v.reset(OpCopy)
- v.AddArg(v0)
- v0.AuxInt = off
- v0.Aux = sym
- v0.AddArg(ptr)
- v0.AddArg(idx)
- v0.AddArg(mem)
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ // match: (MOVWreg (MOVDconst [c]))
+ // cond:
+ // result: (MOVDconst [int64(int32(c))])
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpS390XMOVDconst {
+ break
+ }
+ c := v_0.AuxInt
+ v.reset(OpS390XMOVDconst)
+ v.AuxInt = int64(int32(c))
return true
}
return false
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 != OpS390XMOVDreg {
- break
- }
- 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)
v.AddArg(y)
return true
}
- return false
-}
-func rewriteValueS390X_OpS390XSLD_10(v *Value) bool {
// match: (SLD x (MOVBZreg y))
// cond:
// result: (SLD x y)
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)
v.AddArg(y)
return true
}
- return false
-}
-func rewriteValueS390X_OpS390XSLW_10(v *Value) bool {
// match: (SLW x (MOVBZreg y))
// cond:
// result: (SLW x y)
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 != OpS390XMOVDreg {
- break
- }
- 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)
v.AddArg(y)
return true
}
- return false
-}
-func rewriteValueS390X_OpS390XSRAD_10(v *Value) bool {
// match: (SRAD x (MOVBZreg y))
// cond:
// result: (SRAD x y)
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)
v.AddArg(y)
return true
}
- return false
-}
-func rewriteValueS390X_OpS390XSRAW_10(v *Value) bool {
// match: (SRAW x (MOVBZreg y))
// cond:
// result: (SRAW x y)
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)
v.AddArg(y)
return true
}
- return false
-}
-func rewriteValueS390X_OpS390XSRD_10(v *Value) bool {
// match: (SRD x (MOVBZreg y))
// cond:
// result: (SRD x y)
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)
v.AddArg(y)
return true
}
- return false
-}
-func rewriteValueS390X_OpS390XSRW_10(v *Value) bool {
// match: (SRW x (MOVBZreg y))
// cond:
// result: (SRW x y)