(SRAconst [rc] (MOVWreg x)) && rc < 32 => (SBFX [armBFAuxInt(rc, 32-rc)] x)
(SRAconst [rc] (MOVHreg x)) && rc < 16 => (SBFX [armBFAuxInt(rc, 16-rc)] x)
(SRAconst [rc] (MOVBreg x)) && rc < 8 => (SBFX [armBFAuxInt(rc, 8-rc)] x)
+// merge sbfx and sign-extension into sbfx
+(MOVWreg (SBFX [bfc] x)) && bfc.getARM64BFwidth() <= 32 => (SBFX [bfc] x)
+(MOVHreg (SBFX [bfc] x)) && bfc.getARM64BFwidth() <= 16 => (SBFX [bfc] x)
+(MOVBreg (SBFX [bfc] x)) && bfc.getARM64BFwidth() <= 8 => (SBFX [bfc] x)
// sbfiz/sbfx combinations: merge shifts into bitfield ops
(SRAconst [sc] (SBFIZ [bfc] x)) && sc < bfc.getARM64BFlsb()
// (x << lc) >> rc
(SRLconst [rc] (SLLconst [lc] x)) && lc < rc => (UBFX [armBFAuxInt(rc-lc, 64-rc)] 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)
+(MOVBUreg (UBFX [bfc] x)) && bfc.getARM64BFwidth() <= 8 => (UBFX [bfc] x)
+
// ubfiz/ubfx combinations: merge shifts into bitfield ops
(SRLconst [sc] (UBFX [bfc] x)) && sc < bfc.getARM64BFwidth()
=> (UBFX [armBFAuxInt(bfc.getARM64BFlsb()+sc, bfc.getARM64BFwidth()-sc)] x)
v.AddArg(x)
return true
}
+ // match: (MOVBUreg (UBFX [bfc] x))
+ // cond: bfc.getARM64BFwidth() <= 8
+ // result: (UBFX [bfc] x)
+ for {
+ if v_0.Op != OpARM64UBFX {
+ break
+ }
+ bfc := auxIntToArm64BitField(v_0.AuxInt)
+ x := v_0.Args[0]
+ if !(bfc.getARM64BFwidth() <= 8) {
+ break
+ }
+ v.reset(OpARM64UBFX)
+ v.AuxInt = arm64BitFieldToAuxInt(bfc)
+ v.AddArg(x)
+ return true
+ }
return false
}
func rewriteValueARM64_OpARM64MOVBload(v *Value) bool {
v.AddArg(x)
return true
}
+ // match: (MOVBreg (SBFX [bfc] x))
+ // cond: bfc.getARM64BFwidth() <= 8
+ // result: (SBFX [bfc] x)
+ for {
+ if v_0.Op != OpARM64SBFX {
+ break
+ }
+ bfc := auxIntToArm64BitField(v_0.AuxInt)
+ x := v_0.Args[0]
+ if !(bfc.getARM64BFwidth() <= 8) {
+ break
+ }
+ v.reset(OpARM64SBFX)
+ v.AuxInt = arm64BitFieldToAuxInt(bfc)
+ v.AddArg(x)
+ return true
+ }
return false
}
func rewriteValueARM64_OpARM64MOVBstore(v *Value) bool {
v.AddArg(x)
return true
}
+ // match: (MOVHUreg (UBFX [bfc] x))
+ // cond: bfc.getARM64BFwidth() <= 16
+ // result: (UBFX [bfc] x)
+ for {
+ if v_0.Op != OpARM64UBFX {
+ break
+ }
+ bfc := auxIntToArm64BitField(v_0.AuxInt)
+ x := v_0.Args[0]
+ if !(bfc.getARM64BFwidth() <= 16) {
+ break
+ }
+ v.reset(OpARM64UBFX)
+ v.AuxInt = arm64BitFieldToAuxInt(bfc)
+ v.AddArg(x)
+ return true
+ }
return false
}
func rewriteValueARM64_OpARM64MOVHload(v *Value) bool {
v.AddArg(x)
return true
}
+ // match: (MOVHreg (SBFX [bfc] x))
+ // cond: bfc.getARM64BFwidth() <= 16
+ // result: (SBFX [bfc] x)
+ for {
+ if v_0.Op != OpARM64SBFX {
+ break
+ }
+ bfc := auxIntToArm64BitField(v_0.AuxInt)
+ x := v_0.Args[0]
+ if !(bfc.getARM64BFwidth() <= 16) {
+ break
+ }
+ v.reset(OpARM64SBFX)
+ v.AuxInt = arm64BitFieldToAuxInt(bfc)
+ v.AddArg(x)
+ return true
+ }
return false
}
func rewriteValueARM64_OpARM64MOVHstore(v *Value) bool {
v.AddArg(x)
return true
}
+ // match: (MOVWUreg (UBFX [bfc] x))
+ // cond: bfc.getARM64BFwidth() <= 32
+ // result: (UBFX [bfc] x)
+ for {
+ if v_0.Op != OpARM64UBFX {
+ break
+ }
+ bfc := auxIntToArm64BitField(v_0.AuxInt)
+ x := v_0.Args[0]
+ if !(bfc.getARM64BFwidth() <= 32) {
+ break
+ }
+ v.reset(OpARM64UBFX)
+ v.AuxInt = arm64BitFieldToAuxInt(bfc)
+ v.AddArg(x)
+ return true
+ }
return false
}
func rewriteValueARM64_OpARM64MOVWload(v *Value) bool {
v.AddArg(x)
return true
}
+ // match: (MOVWreg (SBFX [bfc] x))
+ // cond: bfc.getARM64BFwidth() <= 32
+ // result: (SBFX [bfc] x)
+ for {
+ if v_0.Op != OpARM64SBFX {
+ break
+ }
+ bfc := auxIntToArm64BitField(v_0.AuxInt)
+ x := v_0.Args[0]
+ if !(bfc.getARM64BFwidth() <= 32) {
+ break
+ }
+ v.reset(OpARM64SBFX)
+ v.AuxInt = arm64BitFieldToAuxInt(bfc)
+ v.AddArg(x)
+ return true
+ }
return false
}
func rewriteValueARM64_OpARM64MOVWstore(v *Value) bool {
return (x << 3) >> 4 // arm64:"SBFX\t[$]1, R[0-9]+, [$]28",-"LSL",-"ASR"
}
+// merge sbfx and sign-extension into sbfx.
+func sbfx7(x int32) int64 {
+ c := x + 5
+ return int64(c >> 20) // arm64"SBFX\t[$]20, R[0-9]+, [$]12",-"MOVW\tR[0-9]+, R[0-9]+"
+}
+
// ubfiz
func ubfiz1(x uint64) uint64 {
// arm64:"UBFIZ\t[$]3, R[0-9]+, [$]12",-"LSL",-"AND"
return ((x & 0xfffff) << 3) >> 4
}
+// merge ubfx and zero-extension into ubfx.
+func ubfx12(x uint64) bool {
+ midr := x + 10
+ part_num := uint16((midr >> 4) & 0xfff)
+ if part_num == 0xd0c { // arm64:"UBFX\t[$]4, R[0-9]+, [$]12",-"MOVHU\tR[0-9]+, R[0-9]+"
+ return true
+ }
+ return false
+}
+
// Check that we don't emit comparisons for constant shifts.
//go:nosplit
func shift_no_cmp(x int) int {