// (x & ac) >> sc
(SRLconst [sc] (ANDconst [ac] x)) && isARM64BFMask(sc, ac, sc)
=> (UBFX [armBFAuxInt(sc, arm64BFWidth(ac, sc))] x)
-
+// merge ANDconst and ubfx into ubfx
+(ANDconst [c] (UBFX [bfc] x)) && isARM64BFMask(0, c, 0) =>
+ (UBFX [armBFAuxInt(bfc.getARM64BFlsb(), min(bfc.getARM64BFwidth(), arm64BFWidth(c, 0)))] x)
+(UBFX [bfc] (ANDconst [c] x)) && isARM64BFMask(0, c, 0) && bfc.getARM64BFlsb() + bfc.getARM64BFwidth() <= arm64BFWidth(c, 0) =>
+ (UBFX [bfc] x)
// merge ubfx and zerso-extension into ubfx
(MOVWUreg (UBFX [bfc] x)) && bfc.getARM64BFwidth() <= 32 => (UBFX [bfc] x)
(MOVHUreg (UBFX [bfc] x)) && bfc.getARM64BFwidth() <= 16 => (UBFX [bfc] x)
v.AddArg(x)
return true
}
+ // match: (ANDconst [c] (UBFX [bfc] x))
+ // cond: isARM64BFMask(0, c, 0)
+ // result: (UBFX [armBFAuxInt(bfc.getARM64BFlsb(), min(bfc.getARM64BFwidth(), arm64BFWidth(c, 0)))] x)
+ for {
+ c := auxIntToInt64(v.AuxInt)
+ if v_0.Op != OpARM64UBFX {
+ break
+ }
+ bfc := auxIntToArm64BitField(v_0.AuxInt)
+ x := v_0.Args[0]
+ if !(isARM64BFMask(0, c, 0)) {
+ break
+ }
+ v.reset(OpARM64UBFX)
+ v.AuxInt = arm64BitFieldToAuxInt(armBFAuxInt(bfc.getARM64BFlsb(), min(bfc.getARM64BFwidth(), arm64BFWidth(c, 0))))
+ v.AddArg(x)
+ return true
+ }
return false
}
func rewriteValueARM64_OpARM64ANDshiftLL(v *Value) bool {
}
func rewriteValueARM64_OpARM64UBFX(v *Value) bool {
v_0 := v.Args[0]
+ // match: (UBFX [bfc] (ANDconst [c] x))
+ // cond: isARM64BFMask(0, c, 0) && bfc.getARM64BFlsb() + bfc.getARM64BFwidth() <= arm64BFWidth(c, 0)
+ // result: (UBFX [bfc] x)
+ for {
+ bfc := auxIntToArm64BitField(v.AuxInt)
+ if v_0.Op != OpARM64ANDconst {
+ break
+ }
+ c := auxIntToInt64(v_0.AuxInt)
+ x := v_0.Args[0]
+ if !(isARM64BFMask(0, c, 0) && bfc.getARM64BFlsb()+bfc.getARM64BFwidth() <= arm64BFWidth(c, 0)) {
+ break
+ }
+ v.reset(OpARM64UBFX)
+ v.AuxInt = arm64BitFieldToAuxInt(bfc)
+ v.AddArg(x)
+ return true
+ }
// match: (UBFX [bfc] (SRLconst [sc] x))
// cond: sc+bfc.getARM64BFwidth()+bfc.getARM64BFlsb() < 64
// result: (UBFX [armBFAuxInt(bfc.getARM64BFlsb()+sc, bfc.getARM64BFwidth())] x)
return false
}
+// merge ANDconst and ubfx into ubfx
+func ubfx16(x uint64) uint64 {
+ // arm64:"UBFX\t[$]4, R[0-9]+, [$]6",-"AND\t[$]63"
+ return ((x >> 3) & 0xfff) >> 1 & 0x3f
+}
+
// Check that we don't emit comparisons for constant shifts.
//go:nosplit
func shift_no_cmp(x int) int {