// Special case setting bit as 1. An example is math.Copysign(c,-1)
(ORconst [c1] (ANDconst [c2] x)) && c2|c1 == ^0 => (ORconst [c1] x)
+// If the shift amount is larger than the datasize(32, 16, 8), we can optimize to constant 0.
+(MOVWUreg (SLLconst [lc] x)) && lc >= 32 => (MOVDconst [0])
+(MOVHUreg (SLLconst [lc] x)) && lc >= 16 => (MOVDconst [0])
+(MOVBUreg (SLLconst [lc] x)) && lc >= 8 => (MOVDconst [0])
+
+// After zero extension, the upper (64-datasize(32|16|8)) bits are zero, we can optimiza to constant 0.
+(SRLconst [rc] (MOVWUreg x)) && rc >= 32 => (MOVDconst [0])
+(SRLconst [rc] (MOVHUreg x)) && rc >= 16 => (MOVDconst [0])
+(SRLconst [rc] (MOVBUreg x)) && rc >= 8 => (MOVDconst [0])
+
// bitfield ops
// sbfiz
v.AddArg(x)
return true
}
+ // match: (MOVBUreg (SLLconst [lc] x))
+ // cond: lc >= 8
+ // result: (MOVDconst [0])
+ for {
+ if v_0.Op != OpARM64SLLconst {
+ break
+ }
+ lc := auxIntToInt64(v_0.AuxInt)
+ if !(lc >= 8) {
+ break
+ }
+ v.reset(OpARM64MOVDconst)
+ v.AuxInt = int64ToAuxInt(0)
+ return true
+ }
// match: (MOVBUreg (SLLconst [sc] x))
// cond: isARM64BFMask(sc, 1<<8-1, sc)
// result: (UBFIZ [armBFAuxInt(sc, arm64BFWidth(1<<8-1, sc))] x)
v.AuxInt = int64ToAuxInt(int64(uint16(c)))
return true
}
+ // match: (MOVHUreg (SLLconst [lc] x))
+ // cond: lc >= 16
+ // result: (MOVDconst [0])
+ for {
+ if v_0.Op != OpARM64SLLconst {
+ break
+ }
+ lc := auxIntToInt64(v_0.AuxInt)
+ if !(lc >= 16) {
+ break
+ }
+ v.reset(OpARM64MOVDconst)
+ v.AuxInt = int64ToAuxInt(0)
+ return true
+ }
// match: (MOVHUreg (SLLconst [sc] x))
// cond: isARM64BFMask(sc, 1<<16-1, sc)
// result: (UBFIZ [armBFAuxInt(sc, arm64BFWidth(1<<16-1, sc))] x)
v.AuxInt = int64ToAuxInt(int64(uint32(c)))
return true
}
+ // match: (MOVWUreg (SLLconst [lc] x))
+ // cond: lc >= 32
+ // result: (MOVDconst [0])
+ for {
+ if v_0.Op != OpARM64SLLconst {
+ break
+ }
+ lc := auxIntToInt64(v_0.AuxInt)
+ if !(lc >= 32) {
+ break
+ }
+ v.reset(OpARM64MOVDconst)
+ v.AuxInt = int64ToAuxInt(0)
+ return true
+ }
// match: (MOVWUreg (SLLconst [sc] x))
// cond: isARM64BFMask(sc, 1<<32-1, sc)
// result: (UBFIZ [armBFAuxInt(sc, arm64BFWidth(1<<32-1, sc))] x)
v.AddArg(x)
return true
}
+ // match: (SRLconst [rc] (MOVWUreg x))
+ // cond: rc >= 32
+ // result: (MOVDconst [0])
+ for {
+ rc := auxIntToInt64(v.AuxInt)
+ if v_0.Op != OpARM64MOVWUreg {
+ break
+ }
+ if !(rc >= 32) {
+ break
+ }
+ v.reset(OpARM64MOVDconst)
+ v.AuxInt = int64ToAuxInt(0)
+ return true
+ }
+ // match: (SRLconst [rc] (MOVHUreg x))
+ // cond: rc >= 16
+ // result: (MOVDconst [0])
+ for {
+ rc := auxIntToInt64(v.AuxInt)
+ if v_0.Op != OpARM64MOVHUreg {
+ break
+ }
+ if !(rc >= 16) {
+ break
+ }
+ v.reset(OpARM64MOVDconst)
+ v.AuxInt = int64ToAuxInt(0)
+ return true
+ }
+ // match: (SRLconst [rc] (MOVBUreg x))
+ // cond: rc >= 8
+ // result: (MOVDconst [0])
+ for {
+ rc := auxIntToInt64(v.AuxInt)
+ if v_0.Op != OpARM64MOVBUreg {
+ break
+ }
+ if !(rc >= 8) {
+ break
+ }
+ v.reset(OpARM64MOVDconst)
+ v.AuxInt = int64ToAuxInt(0)
+ return true
+ }
// match: (SRLconst [rc] (SLLconst [lc] x))
// cond: lc > rc
// result: (UBFIZ [armBFAuxInt(lc-rc, 64-lc)] x)