diff --git a/src/cmd/compile/internal/arm/ssa.go b/src/cmd/compile/internal/arm/ssa.go index 51722c4f35..5dcd8ca1ac 100644 --- a/src/cmd/compile/internal/arm/ssa.go +++ b/src/cmd/compile/internal/arm/ssa.go @@ -5,6 +5,7 @@ package arm import ( + "fmt" "math" "cmd/compile/internal/gc" @@ -108,6 +109,57 @@ func storeByType(t ssa.Type) obj.As { panic("bad store type") } +// shift type is used as Offset in obj.TYPE_SHIFT operands to encode shifted register operands +type shift int64 + +// copied from ../../../internal/obj/util.go:/TYPE_SHIFT +func (v shift) String() string { + op := "<<>>->@>"[((v>>5)&3)<<1:] + if v&(1<<4) != 0 { + // register shift + return fmt.Sprintf("R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15) + } else { + // constant shift + return fmt.Sprintf("R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31) + } +} + +// makeshift encodes a register shifted by a constant +func makeshift(reg int16, typ int64, s int64) shift { + return shift(int64(reg&0xf) | typ | (s&31)<<7) +} + +// genshift generates a Prog for r = r0 op (r1 shifted by s) +func genshift(as obj.As, r0, r1, r int16, typ int64, s int64) *obj.Prog { + p := gc.Prog(as) + p.From.Type = obj.TYPE_SHIFT + p.From.Offset = int64(makeshift(r1, typ, s)) + p.Reg = r0 + if r != 0 { + p.To.Type = obj.TYPE_REG + p.To.Reg = r + } + return p +} + +// makeregshift encodes a register shifted by a register +func makeregshift(r1 int16, typ int64, r2 int16) shift { + return shift(int64(r1&0xf) | typ | int64(r2&0xf)<<8 | 1<<4) +} + +// genregshift generates a Prog for r = r0 op (r1 shifted by r2) +func genregshift(as obj.As, r0, r1, r2, r int16, typ int64) *obj.Prog { + p := gc.Prog(as) + p.From.Type = obj.TYPE_SHIFT + p.From.Offset = int64(makeregshift(r1, typ, r2)) + p.Reg = r0 + if r != 0 { + p.To.Type = obj.TYPE_REG + p.To.Reg = r + } + return p +} + func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { s.SetLineno(v.Line) switch v.Op { @@ -237,45 +289,27 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { p.To.Type = obj.TYPE_REG p.To.Reg = r case ssa.OpARMSLL, - ssa.OpARMSRL: - // ARM shift instructions uses only the low-order byte of the shift amount - // generate conditional instructions to deal with large shifts - // CMP $32, Rarg1 - // SLL Rarg1, Rarg0, Rdst - // MOVW.HS $0, Rdst + ssa.OpARMSRL, + ssa.OpARMSRA: r := gc.SSARegNum(v) r1 := gc.SSARegNum(v.Args[0]) r2 := gc.SSARegNum(v.Args[1]) - p := gc.Prog(arm.ACMP) - p.From.Type = obj.TYPE_CONST - p.From.Offset = 32 - p.Reg = r2 - p = gc.Prog(v.Op.Asm()) + p := gc.Prog(v.Op.Asm()) p.From.Type = obj.TYPE_REG p.From.Reg = r2 p.Reg = r1 p.To.Type = obj.TYPE_REG p.To.Reg = r - p = gc.Prog(arm.AMOVW) - p.Scond = arm.C_SCOND_HS - p.From.Type = obj.TYPE_CONST - p.From.Offset = 0 - p.To.Type = obj.TYPE_REG - p.To.Reg = r - case ssa.OpARMSRA: + case ssa.OpARMSRAcond: // ARM shift instructions uses only the low-order byte of the shift amount // generate conditional instructions to deal with large shifts - // CMP $32, Rarg1 + // flag is already set // SRA.HS $31, Rarg0, Rdst // shift 31 bits to get the sign bit // SRA.LO Rarg1, Rarg0, Rdst r := gc.SSARegNum(v) r1 := gc.SSARegNum(v.Args[0]) r2 := gc.SSARegNum(v.Args[1]) - p := gc.Prog(arm.ACMP) - p.From.Type = obj.TYPE_CONST - p.From.Offset = 32 - p.Reg = r2 - p = gc.Prog(arm.ASRA) + p := gc.Prog(arm.ASRA) p.Scond = arm.C_SCOND_HS p.From.Type = obj.TYPE_CONST p.From.Offset = 31 @@ -319,11 +353,115 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { p.To.Type = obj.TYPE_REG p.To.Reg = gc.SSARegNum(v) case ssa.OpARMSRRconst: - p := gc.Prog(arm.AMOVW) - p.From.Type = obj.TYPE_SHIFT - p.From.Offset = int64(gc.SSARegNum(v.Args[0])&0xf) | arm.SHIFT_RR | (v.AuxInt&31)<<7 - p.To.Type = obj.TYPE_REG - p.To.Reg = gc.SSARegNum(v) + genshift(arm.AMOVW, 0, gc.SSARegNum(v.Args[0]), gc.SSARegNum(v), arm.SHIFT_RR, v.AuxInt) + case ssa.OpARMADDshiftLL, + ssa.OpARMADCshiftLL, + ssa.OpARMSUBshiftLL, + ssa.OpARMSBCshiftLL, + ssa.OpARMRSBshiftLL, + ssa.OpARMRSCshiftLL, + ssa.OpARMANDshiftLL, + ssa.OpARMORshiftLL, + ssa.OpARMXORshiftLL, + ssa.OpARMBICshiftLL: + genshift(v.Op.Asm(), gc.SSARegNum(v.Args[0]), gc.SSARegNum(v.Args[1]), gc.SSARegNum(v), arm.SHIFT_LL, v.AuxInt) + case ssa.OpARMADDSshiftLL, + ssa.OpARMSUBSshiftLL, + ssa.OpARMRSBSshiftLL: + p := genshift(v.Op.Asm(), gc.SSARegNum(v.Args[0]), gc.SSARegNum(v.Args[1]), gc.SSARegNum(v), arm.SHIFT_LL, v.AuxInt) + p.Scond = arm.C_SBIT + case ssa.OpARMADDshiftRL, + ssa.OpARMADCshiftRL, + ssa.OpARMSUBshiftRL, + ssa.OpARMSBCshiftRL, + ssa.OpARMRSBshiftRL, + ssa.OpARMRSCshiftRL, + ssa.OpARMANDshiftRL, + ssa.OpARMORshiftRL, + ssa.OpARMXORshiftRL, + ssa.OpARMBICshiftRL: + genshift(v.Op.Asm(), gc.SSARegNum(v.Args[0]), gc.SSARegNum(v.Args[1]), gc.SSARegNum(v), arm.SHIFT_LR, v.AuxInt) + case ssa.OpARMADDSshiftRL, + ssa.OpARMSUBSshiftRL, + ssa.OpARMRSBSshiftRL: + p := genshift(v.Op.Asm(), gc.SSARegNum(v.Args[0]), gc.SSARegNum(v.Args[1]), gc.SSARegNum(v), arm.SHIFT_LR, v.AuxInt) + p.Scond = arm.C_SBIT + case ssa.OpARMADDshiftRA, + ssa.OpARMADCshiftRA, + ssa.OpARMSUBshiftRA, + ssa.OpARMSBCshiftRA, + ssa.OpARMRSBshiftRA, + ssa.OpARMRSCshiftRA, + ssa.OpARMANDshiftRA, + ssa.OpARMORshiftRA, + ssa.OpARMXORshiftRA, + ssa.OpARMBICshiftRA: + genshift(v.Op.Asm(), gc.SSARegNum(v.Args[0]), gc.SSARegNum(v.Args[1]), gc.SSARegNum(v), arm.SHIFT_AR, v.AuxInt) + case ssa.OpARMADDSshiftRA, + ssa.OpARMSUBSshiftRA, + ssa.OpARMRSBSshiftRA: + p := genshift(v.Op.Asm(), gc.SSARegNum(v.Args[0]), gc.SSARegNum(v.Args[1]), gc.SSARegNum(v), arm.SHIFT_AR, v.AuxInt) + p.Scond = arm.C_SBIT + case ssa.OpARMMVNshiftLL: + genshift(v.Op.Asm(), 0, gc.SSARegNum(v.Args[0]), gc.SSARegNum(v), arm.SHIFT_LL, v.AuxInt) + case ssa.OpARMMVNshiftRL: + genshift(v.Op.Asm(), 0, gc.SSARegNum(v.Args[0]), gc.SSARegNum(v), arm.SHIFT_LR, v.AuxInt) + case ssa.OpARMMVNshiftRA: + genshift(v.Op.Asm(), 0, gc.SSARegNum(v.Args[0]), gc.SSARegNum(v), arm.SHIFT_AR, v.AuxInt) + case ssa.OpARMMVNshiftLLreg: + genregshift(v.Op.Asm(), 0, gc.SSARegNum(v.Args[0]), gc.SSARegNum(v.Args[1]), gc.SSARegNum(v), arm.SHIFT_LL) + case ssa.OpARMMVNshiftRLreg: + genregshift(v.Op.Asm(), 0, gc.SSARegNum(v.Args[0]), gc.SSARegNum(v.Args[1]), gc.SSARegNum(v), arm.SHIFT_LR) + case ssa.OpARMMVNshiftRAreg: + genregshift(v.Op.Asm(), 0, gc.SSARegNum(v.Args[0]), gc.SSARegNum(v.Args[1]), gc.SSARegNum(v), arm.SHIFT_AR) + case ssa.OpARMADDshiftLLreg, + ssa.OpARMADCshiftLLreg, + ssa.OpARMSUBshiftLLreg, + ssa.OpARMSBCshiftLLreg, + ssa.OpARMRSBshiftLLreg, + ssa.OpARMRSCshiftLLreg, + ssa.OpARMANDshiftLLreg, + ssa.OpARMORshiftLLreg, + ssa.OpARMXORshiftLLreg, + ssa.OpARMBICshiftLLreg: + genregshift(v.Op.Asm(), gc.SSARegNum(v.Args[0]), gc.SSARegNum(v.Args[1]), gc.SSARegNum(v.Args[2]), gc.SSARegNum(v), arm.SHIFT_LL) + case ssa.OpARMADDSshiftLLreg, + ssa.OpARMSUBSshiftLLreg, + ssa.OpARMRSBSshiftLLreg: + p := genregshift(v.Op.Asm(), gc.SSARegNum(v.Args[0]), gc.SSARegNum(v.Args[1]), gc.SSARegNum(v.Args[2]), gc.SSARegNum(v), arm.SHIFT_LL) + p.Scond = arm.C_SBIT + case ssa.OpARMADDshiftRLreg, + ssa.OpARMADCshiftRLreg, + ssa.OpARMSUBshiftRLreg, + ssa.OpARMSBCshiftRLreg, + ssa.OpARMRSBshiftRLreg, + ssa.OpARMRSCshiftRLreg, + ssa.OpARMANDshiftRLreg, + ssa.OpARMORshiftRLreg, + ssa.OpARMXORshiftRLreg, + ssa.OpARMBICshiftRLreg: + genregshift(v.Op.Asm(), gc.SSARegNum(v.Args[0]), gc.SSARegNum(v.Args[1]), gc.SSARegNum(v.Args[2]), gc.SSARegNum(v), arm.SHIFT_LR) + case ssa.OpARMADDSshiftRLreg, + ssa.OpARMSUBSshiftRLreg, + ssa.OpARMRSBSshiftRLreg: + p := genregshift(v.Op.Asm(), gc.SSARegNum(v.Args[0]), gc.SSARegNum(v.Args[1]), gc.SSARegNum(v.Args[2]), gc.SSARegNum(v), arm.SHIFT_LR) + p.Scond = arm.C_SBIT + case ssa.OpARMADDshiftRAreg, + ssa.OpARMADCshiftRAreg, + ssa.OpARMSUBshiftRAreg, + ssa.OpARMSBCshiftRAreg, + ssa.OpARMRSBshiftRAreg, + ssa.OpARMRSCshiftRAreg, + ssa.OpARMANDshiftRAreg, + ssa.OpARMORshiftRAreg, + ssa.OpARMXORshiftRAreg, + ssa.OpARMBICshiftRAreg: + genregshift(v.Op.Asm(), gc.SSARegNum(v.Args[0]), gc.SSARegNum(v.Args[1]), gc.SSARegNum(v.Args[2]), gc.SSARegNum(v), arm.SHIFT_AR) + case ssa.OpARMADDSshiftRAreg, + ssa.OpARMSUBSshiftRAreg, + ssa.OpARMRSBSshiftRAreg: + p := genregshift(v.Op.Asm(), gc.SSARegNum(v.Args[0]), gc.SSARegNum(v.Args[1]), gc.SSARegNum(v.Args[2]), gc.SSARegNum(v), arm.SHIFT_AR) + p.Scond = arm.C_SBIT case ssa.OpARMHMUL, ssa.OpARMHMULU: // 32-bit high multiplication @@ -385,6 +523,18 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { p.From.Type = obj.TYPE_CONST p.From.Offset = v.AuxInt p.Reg = gc.SSARegNum(v.Args[0]) + case ssa.OpARMCMPshiftLL: + genshift(v.Op.Asm(), gc.SSARegNum(v.Args[0]), gc.SSARegNum(v.Args[1]), 0, arm.SHIFT_LL, v.AuxInt) + case ssa.OpARMCMPshiftRL: + genshift(v.Op.Asm(), gc.SSARegNum(v.Args[0]), gc.SSARegNum(v.Args[1]), 0, arm.SHIFT_LR, v.AuxInt) + case ssa.OpARMCMPshiftRA: + genshift(v.Op.Asm(), gc.SSARegNum(v.Args[0]), gc.SSARegNum(v.Args[1]), 0, arm.SHIFT_AR, v.AuxInt) + case ssa.OpARMCMPshiftLLreg: + genregshift(v.Op.Asm(), gc.SSARegNum(v.Args[0]), gc.SSARegNum(v.Args[1]), gc.SSARegNum(v.Args[2]), 0, arm.SHIFT_LL) + case ssa.OpARMCMPshiftRLreg: + genregshift(v.Op.Asm(), gc.SSARegNum(v.Args[0]), gc.SSARegNum(v.Args[1]), gc.SSARegNum(v.Args[2]), 0, arm.SHIFT_LR) + case ssa.OpARMCMPshiftRAreg: + genregshift(v.Op.Asm(), gc.SSARegNum(v.Args[0]), gc.SSARegNum(v.Args[1]), gc.SSARegNum(v.Args[2]), 0, arm.SHIFT_AR) case ssa.OpARMMOVWaddr: p := gc.Prog(arm.AMOVW) p.From.Type = obj.TYPE_ADDR @@ -440,11 +590,72 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { p.To.Type = obj.TYPE_MEM p.To.Reg = gc.SSARegNum(v.Args[0]) gc.AddAux(&p.To, v) + case ssa.OpARMMOVWloadidx: + // this is just shift 0 bits + fallthrough + case ssa.OpARMMOVWloadshiftLL: + p := genshift(v.Op.Asm(), 0, gc.SSARegNum(v.Args[1]), gc.SSARegNum(v), arm.SHIFT_LL, v.AuxInt) + p.From.Reg = gc.SSARegNum(v.Args[0]) + case ssa.OpARMMOVWloadshiftRL: + p := genshift(v.Op.Asm(), 0, gc.SSARegNum(v.Args[1]), gc.SSARegNum(v), arm.SHIFT_LR, v.AuxInt) + p.From.Reg = gc.SSARegNum(v.Args[0]) + case ssa.OpARMMOVWloadshiftRA: + p := genshift(v.Op.Asm(), 0, gc.SSARegNum(v.Args[1]), gc.SSARegNum(v), arm.SHIFT_AR, v.AuxInt) + p.From.Reg = gc.SSARegNum(v.Args[0]) + case ssa.OpARMMOVWstoreidx: + // this is just shift 0 bits + fallthrough + case ssa.OpARMMOVWstoreshiftLL: + p := gc.Prog(v.Op.Asm()) + p.From.Type = obj.TYPE_REG + p.From.Reg = gc.SSARegNum(v.Args[2]) + p.To.Type = obj.TYPE_SHIFT + p.To.Reg = gc.SSARegNum(v.Args[0]) + p.To.Offset = int64(makeshift(gc.SSARegNum(v.Args[1]), arm.SHIFT_LL, v.AuxInt)) + case ssa.OpARMMOVWstoreshiftRL: + p := gc.Prog(v.Op.Asm()) + p.From.Type = obj.TYPE_REG + p.From.Reg = gc.SSARegNum(v.Args[2]) + p.To.Type = obj.TYPE_SHIFT + p.To.Reg = gc.SSARegNum(v.Args[0]) + p.To.Offset = int64(makeshift(gc.SSARegNum(v.Args[1]), arm.SHIFT_LR, v.AuxInt)) + case ssa.OpARMMOVWstoreshiftRA: + p := gc.Prog(v.Op.Asm()) + p.From.Type = obj.TYPE_REG + p.From.Reg = gc.SSARegNum(v.Args[2]) + p.To.Type = obj.TYPE_SHIFT + p.To.Reg = gc.SSARegNum(v.Args[0]) + p.To.Offset = int64(makeshift(gc.SSARegNum(v.Args[1]), arm.SHIFT_AR, v.AuxInt)) case ssa.OpARMMOVBreg, ssa.OpARMMOVBUreg, ssa.OpARMMOVHreg, - ssa.OpARMMOVHUreg, - ssa.OpARMMVN, + ssa.OpARMMOVHUreg: + a := v.Args[0] + for a.Op == ssa.OpCopy || a.Op == ssa.OpARMMOVWreg { + a = a.Args[0] + } + if a.Op == ssa.OpLoadReg { + t := a.Type + switch { + case v.Op == ssa.OpARMMOVBreg && t.Size() == 1 && t.IsSigned(), + v.Op == ssa.OpARMMOVBUreg && t.Size() == 1 && !t.IsSigned(), + v.Op == ssa.OpARMMOVHreg && t.Size() == 2 && t.IsSigned(), + v.Op == ssa.OpARMMOVHUreg && t.Size() == 2 && !t.IsSigned(): + // arg is a proper-typed load, already zero/sign-extended, don't extend again + if gc.SSARegNum(v) == gc.SSARegNum(v.Args[0]) { + return + } + p := gc.Prog(arm.AMOVW) + p.From.Type = obj.TYPE_REG + p.From.Reg = gc.SSARegNum(v.Args[0]) + p.To.Type = obj.TYPE_REG + p.To.Reg = gc.SSARegNum(v) + return + default: + } + } + fallthrough + case ssa.OpARMMVN, ssa.OpARMSQRTD, ssa.OpARMMOVWF, ssa.OpARMMOVWD, @@ -467,6 +678,20 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { p.From.Reg = gc.SSARegNum(v.Args[0]) p.To.Type = obj.TYPE_REG p.To.Reg = gc.SSARegNum(v) + case ssa.OpARMCMOVWHSconst: + p := gc.Prog(arm.AMOVW) + p.Scond = arm.C_SCOND_HS + p.From.Type = obj.TYPE_CONST + p.From.Offset = v.AuxInt + p.To.Type = obj.TYPE_REG + p.To.Reg = gc.SSARegNum(v) + case ssa.OpARMCMOVWLSconst: + p := gc.Prog(arm.AMOVW) + p.Scond = arm.C_SCOND_LS + p.From.Type = obj.TYPE_CONST + p.From.Offset = v.AuxInt + p.To.Type = obj.TYPE_REG + p.To.Reg = gc.SSARegNum(v) case ssa.OpARMCALLstatic: if v.Aux.(*gc.Sym) == gc.Deferreturn.Sym { // Deferred calls will appear to be returning to @@ -657,24 +882,6 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { p4 := gc.Prog(arm.ABLT) p4.To.Type = obj.TYPE_BRANCH gc.Patch(p4, p) - case ssa.OpARMLoweredZeromask: - // int32(arg0>>1 - arg0) >> 31 - // RSB r0>>1, r0, r - // SRA $31, r, r - r0 := gc.SSARegNum(v.Args[0]) - r := gc.SSARegNum(v) - p := gc.Prog(arm.ARSB) - p.From.Type = obj.TYPE_SHIFT - p.From.Offset = int64(r0&0xf) | arm.SHIFT_LR | 1<<7 // unsigned r0>>1 - p.Reg = r0 - p.To.Type = obj.TYPE_REG - p.To.Reg = r - p = gc.Prog(arm.ASRA) - p.From.Type = obj.TYPE_CONST - p.From.Offset = 31 - p.Reg = r - p.To.Type = obj.TYPE_REG - p.To.Reg = r case ssa.OpVarDef: gc.Gvardef(v.Aux.(*gc.Node)) case ssa.OpVarKill: diff --git a/src/cmd/compile/internal/gc/testdata/arith_ssa.go b/src/cmd/compile/internal/gc/testdata/arith_ssa.go index 7c82bbd6ce..d850ce27b2 100644 --- a/src/cmd/compile/internal/gc/testdata/arith_ssa.go +++ b/src/cmd/compile/internal/gc/testdata/arith_ssa.go @@ -553,6 +553,445 @@ func testOrPhi() { } } +//go:noinline +func addshiftLL_ssa(a, b uint32) uint32 { + return a + b<<3 +} + +//go:noinline +func subshiftLL_ssa(a, b uint32) uint32 { + return a - b<<3 +} + +//go:noinline +func rsbshiftLL_ssa(a, b uint32) uint32 { + return a<<3 - b +} + +//go:noinline +func andshiftLL_ssa(a, b uint32) uint32 { + return a & (b << 3) +} + +//go:noinline +func orshiftLL_ssa(a, b uint32) uint32 { + return a | b<<3 +} + +//go:noinline +func xorshiftLL_ssa(a, b uint32) uint32 { + return a ^ b<<3 +} + +//go:noinline +func bicshiftLL_ssa(a, b uint32) uint32 { + return a &^ (b << 3) +} + +//go:noinline +func notshiftLL_ssa(a uint32) uint32 { + return ^(a << 3) +} + +//go:noinline +func addshiftRL_ssa(a, b uint32) uint32 { + return a + b>>3 +} + +//go:noinline +func subshiftRL_ssa(a, b uint32) uint32 { + return a - b>>3 +} + +//go:noinline +func rsbshiftRL_ssa(a, b uint32) uint32 { + return a>>3 - b +} + +//go:noinline +func andshiftRL_ssa(a, b uint32) uint32 { + return a & (b >> 3) +} + +//go:noinline +func orshiftRL_ssa(a, b uint32) uint32 { + return a | b>>3 +} + +//go:noinline +func xorshiftRL_ssa(a, b uint32) uint32 { + return a ^ b>>3 +} + +//go:noinline +func bicshiftRL_ssa(a, b uint32) uint32 { + return a &^ (b >> 3) +} + +//go:noinline +func notshiftRL_ssa(a uint32) uint32 { + return ^(a >> 3) +} + +//go:noinline +func addshiftRA_ssa(a, b int32) int32 { + return a + b>>3 +} + +//go:noinline +func subshiftRA_ssa(a, b int32) int32 { + return a - b>>3 +} + +//go:noinline +func rsbshiftRA_ssa(a, b int32) int32 { + return a>>3 - b +} + +//go:noinline +func andshiftRA_ssa(a, b int32) int32 { + return a & (b >> 3) +} + +//go:noinline +func orshiftRA_ssa(a, b int32) int32 { + return a | b>>3 +} + +//go:noinline +func xorshiftRA_ssa(a, b int32) int32 { + return a ^ b>>3 +} + +//go:noinline +func bicshiftRA_ssa(a, b int32) int32 { + return a &^ (b >> 3) +} + +//go:noinline +func notshiftRA_ssa(a int32) int32 { + return ^(a >> 3) +} + +//go:noinline +func addshiftLLreg_ssa(a, b uint32, s uint8) uint32 { + return a + b<>s +} + +//go:noinline +func subshiftRLreg_ssa(a, b uint32, s uint8) uint32 { + return a - b>>s +} + +//go:noinline +func rsbshiftRLreg_ssa(a, b uint32, s uint8) uint32 { + return a>>s - b +} + +//go:noinline +func andshiftRLreg_ssa(a, b uint32, s uint8) uint32 { + return a & (b >> s) +} + +//go:noinline +func orshiftRLreg_ssa(a, b uint32, s uint8) uint32 { + return a | b>>s +} + +//go:noinline +func xorshiftRLreg_ssa(a, b uint32, s uint8) uint32 { + return a ^ b>>s +} + +//go:noinline +func bicshiftRLreg_ssa(a, b uint32, s uint8) uint32 { + return a &^ (b >> s) +} + +//go:noinline +func notshiftRLreg_ssa(a uint32, s uint8) uint32 { + return ^(a >> s) +} + +//go:noinline +func addshiftRAreg_ssa(a, b int32, s uint8) int32 { + return a + b>>s +} + +//go:noinline +func subshiftRAreg_ssa(a, b int32, s uint8) int32 { + return a - b>>s +} + +//go:noinline +func rsbshiftRAreg_ssa(a, b int32, s uint8) int32 { + return a>>s - b +} + +//go:noinline +func andshiftRAreg_ssa(a, b int32, s uint8) int32 { + return a & (b >> s) +} + +//go:noinline +func orshiftRAreg_ssa(a, b int32, s uint8) int32 { + return a | b>>s +} + +//go:noinline +func xorshiftRAreg_ssa(a, b int32, s uint8) int32 { + return a ^ b>>s +} + +//go:noinline +func bicshiftRAreg_ssa(a, b int32, s uint8) int32 { + return a &^ (b >> s) +} + +//go:noinline +func notshiftRAreg_ssa(a int32, s uint8) int32 { + return ^(a >> s) +} + +// test ARM shifted ops +func testShiftedOps() { + a, b := uint32(10), uint32(42) + if want, got := a+b<<3, addshiftLL_ssa(a, b); got != want { + println("addshiftLL_ssa(10, 42) =", got, " want ", want) + failed = true + } + if want, got := a-b<<3, subshiftLL_ssa(a, b); got != want { + println("subshiftLL_ssa(10, 42) =", got, " want ", want) + failed = true + } + if want, got := a<<3-b, rsbshiftLL_ssa(a, b); got != want { + println("rsbshiftLL_ssa(10, 42) =", got, " want ", want) + failed = true + } + if want, got := a&(b<<3), andshiftLL_ssa(a, b); got != want { + println("andshiftLL_ssa(10, 42) =", got, " want ", want) + failed = true + } + if want, got := a|b<<3, orshiftLL_ssa(a, b); got != want { + println("orshiftLL_ssa(10, 42) =", got, " want ", want) + failed = true + } + if want, got := a^b<<3, xorshiftLL_ssa(a, b); got != want { + println("xorshiftLL_ssa(10, 42) =", got, " want ", want) + failed = true + } + if want, got := a&^(b<<3), bicshiftLL_ssa(a, b); got != want { + println("bicshiftLL_ssa(10, 42) =", got, " want ", want) + failed = true + } + if want, got := ^(a << 3), notshiftLL_ssa(a); got != want { + println("notshiftLL_ssa(10) =", got, " want ", want) + failed = true + } + if want, got := a+b>>3, addshiftRL_ssa(a, b); got != want { + println("addshiftRL_ssa(10, 42) =", got, " want ", want) + failed = true + } + if want, got := a-b>>3, subshiftRL_ssa(a, b); got != want { + println("subshiftRL_ssa(10, 42) =", got, " want ", want) + failed = true + } + if want, got := a>>3-b, rsbshiftRL_ssa(a, b); got != want { + println("rsbshiftRL_ssa(10, 42) =", got, " want ", want) + failed = true + } + if want, got := a&(b>>3), andshiftRL_ssa(a, b); got != want { + println("andshiftRL_ssa(10, 42) =", got, " want ", want) + failed = true + } + if want, got := a|b>>3, orshiftRL_ssa(a, b); got != want { + println("orshiftRL_ssa(10, 42) =", got, " want ", want) + failed = true + } + if want, got := a^b>>3, xorshiftRL_ssa(a, b); got != want { + println("xorshiftRL_ssa(10, 42) =", got, " want ", want) + failed = true + } + if want, got := a&^(b>>3), bicshiftRL_ssa(a, b); got != want { + println("bicshiftRL_ssa(10, 42) =", got, " want ", want) + failed = true + } + if want, got := ^(a >> 3), notshiftRL_ssa(a); got != want { + println("notshiftRL_ssa(10) =", got, " want ", want) + failed = true + } + c, d := int32(10), int32(-42) + if want, got := c+d>>3, addshiftRA_ssa(c, d); got != want { + println("addshiftRA_ssa(10, -42) =", got, " want ", want) + failed = true + } + if want, got := c-d>>3, subshiftRA_ssa(c, d); got != want { + println("subshiftRA_ssa(10, -42) =", got, " want ", want) + failed = true + } + if want, got := c>>3-d, rsbshiftRA_ssa(c, d); got != want { + println("rsbshiftRA_ssa(10, -42) =", got, " want ", want) + failed = true + } + if want, got := c&(d>>3), andshiftRA_ssa(c, d); got != want { + println("andshiftRA_ssa(10, -42) =", got, " want ", want) + failed = true + } + if want, got := c|d>>3, orshiftRA_ssa(c, d); got != want { + println("orshiftRA_ssa(10, -42) =", got, " want ", want) + failed = true + } + if want, got := c^d>>3, xorshiftRA_ssa(c, d); got != want { + println("xorshiftRA_ssa(10, -42) =", got, " want ", want) + failed = true + } + if want, got := c&^(d>>3), bicshiftRA_ssa(c, d); got != want { + println("bicshiftRA_ssa(10, -42) =", got, " want ", want) + failed = true + } + if want, got := ^(d >> 3), notshiftRA_ssa(d); got != want { + println("notshiftRA_ssa(-42) =", got, " want ", want) + failed = true + } + s := uint8(3) + if want, got := a+b<>s, addshiftRLreg_ssa(a, b, s); got != want { + println("addshiftRLreg_ssa(10, 42, 3) =", got, " want ", want) + failed = true + } + if want, got := a-b>>s, subshiftRLreg_ssa(a, b, s); got != want { + println("subshiftRLreg_ssa(10, 42, 3) =", got, " want ", want) + failed = true + } + if want, got := a>>s-b, rsbshiftRLreg_ssa(a, b, s); got != want { + println("rsbshiftRLreg_ssa(10, 42, 3) =", got, " want ", want) + failed = true + } + if want, got := a&(b>>s), andshiftRLreg_ssa(a, b, s); got != want { + println("andshiftRLreg_ssa(10, 42, 3) =", got, " want ", want) + failed = true + } + if want, got := a|b>>s, orshiftRLreg_ssa(a, b, s); got != want { + println("orshiftRLreg_ssa(10, 42, 3) =", got, " want ", want) + failed = true + } + if want, got := a^b>>s, xorshiftRLreg_ssa(a, b, s); got != want { + println("xorshiftRLreg_ssa(10, 42, 3) =", got, " want ", want) + failed = true + } + if want, got := a&^(b>>s), bicshiftRLreg_ssa(a, b, s); got != want { + println("bicshiftRLreg_ssa(10, 42, 3) =", got, " want ", want) + failed = true + } + if want, got := ^(a >> s), notshiftRLreg_ssa(a, s); got != want { + println("notshiftRLreg_ssa(10) =", got, " want ", want) + failed = true + } + if want, got := c+d>>s, addshiftRAreg_ssa(c, d, s); got != want { + println("addshiftRAreg_ssa(10, -42, 3) =", got, " want ", want) + failed = true + } + if want, got := c-d>>s, subshiftRAreg_ssa(c, d, s); got != want { + println("subshiftRAreg_ssa(10, -42, 3) =", got, " want ", want) + failed = true + } + if want, got := c>>s-d, rsbshiftRAreg_ssa(c, d, s); got != want { + println("rsbshiftRAreg_ssa(10, -42, 3) =", got, " want ", want) + failed = true + } + if want, got := c&(d>>s), andshiftRAreg_ssa(c, d, s); got != want { + println("andshiftRAreg_ssa(10, -42, 3) =", got, " want ", want) + failed = true + } + if want, got := c|d>>s, orshiftRAreg_ssa(c, d, s); got != want { + println("orshiftRAreg_ssa(10, -42, 3) =", got, " want ", want) + failed = true + } + if want, got := c^d>>s, xorshiftRAreg_ssa(c, d, s); got != want { + println("xorshiftRAreg_ssa(10, -42, 3) =", got, " want ", want) + failed = true + } + if want, got := c&^(d>>s), bicshiftRAreg_ssa(c, d, s); got != want { + println("bicshiftRAreg_ssa(10, -42, 3) =", got, " want ", want) + failed = true + } + if want, got := ^(d >> s), notshiftRAreg_ssa(d, s); got != want { + println("notshiftRAreg_ssa(-42, 3) =", got, " want ", want) + failed = true + } +} + var failed = false func main() { @@ -573,6 +1012,7 @@ func main() { testLoadCombine() testLoadSymCombine() testShiftRemoval() + testShiftedOps() if failed { panic("failed") diff --git a/src/cmd/compile/internal/ssa/gen/ARM.rules b/src/cmd/compile/internal/ssa/gen/ARM.rules index ee68ad540f..7ec0e502ec 100644 --- a/src/cmd/compile/internal/ssa/gen/ARM.rules +++ b/src/cmd/compile/internal/ssa/gen/ARM.rules @@ -87,40 +87,42 @@ (Not x) -> (XORconst [1] x) // shifts -(Lsh32x32 x y) -> (SLL x y) -(Lsh32x16 x y) -> (SLL x (ZeroExt16to32 y)) +// hardware instruction uses only the low byte of the shift +// we compare to 256 to ensure Go semantics for large shifts +(Lsh32x32 x y) -> (CMOVWHSconst (SLL x y) (CMPconst [256] y) [0]) +(Lsh32x16 x y) -> (CMOVWHSconst (SLL x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0]) (Lsh32x8 x y) -> (SLL x (ZeroExt8to32 y)) -(Lsh16x32 x y) -> (SLL x y) -(Lsh16x16 x y) -> (SLL x (ZeroExt16to32 y)) +(Lsh16x32 x y) -> (CMOVWHSconst (SLL x y) (CMPconst [256] y) [0]) +(Lsh16x16 x y) -> (CMOVWHSconst (SLL x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0]) (Lsh16x8 x y) -> (SLL x (ZeroExt8to32 y)) -(Lsh8x32 x y) -> (SLL x y) -(Lsh8x16 x y) -> (SLL x (ZeroExt16to32 y)) +(Lsh8x32 x y) -> (CMOVWHSconst (SLL x y) (CMPconst [256] y) [0]) +(Lsh8x16 x y) -> (CMOVWHSconst (SLL x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0]) (Lsh8x8 x y) -> (SLL x (ZeroExt8to32 y)) -(Rsh32Ux32 x y) -> (SRL x y) -(Rsh32Ux16 x y) -> (SRL x (ZeroExt16to32 y)) +(Rsh32Ux32 x y) -> (CMOVWHSconst (SRL x y) (CMPconst [256] y) [0]) +(Rsh32Ux16 x y) -> (CMOVWHSconst (SRL x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0]) (Rsh32Ux8 x y) -> (SRL x (ZeroExt8to32 y)) -(Rsh16Ux32 x y) -> (SRL (ZeroExt16to32 x) y) -(Rsh16Ux16 x y) -> (SRL (ZeroExt16to32 x) (ZeroExt16to32 y)) +(Rsh16Ux32 x y) -> (CMOVWHSconst (SRL (ZeroExt16to32 x) y) (CMPconst [256] y) [0]) +(Rsh16Ux16 x y) -> (CMOVWHSconst (SRL (ZeroExt16to32 x) (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0]) (Rsh16Ux8 x y) -> (SRL (ZeroExt16to32 x) (ZeroExt8to32 y)) -(Rsh8Ux32 x y) -> (SRL (ZeroExt8to32 x) y) -(Rsh8Ux16 x y) -> (SRL (ZeroExt8to32 x) (ZeroExt16to32 y)) +(Rsh8Ux32 x y) -> (CMOVWHSconst (SRL (ZeroExt8to32 x) y) (CMPconst [256] y) [0]) +(Rsh8Ux16 x y) -> (CMOVWHSconst (SRL (ZeroExt8to32 x) (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0]) (Rsh8Ux8 x y) -> (SRL (ZeroExt8to32 x) (ZeroExt8to32 y)) -(Rsh32x32 x y) -> (SRA x y) -(Rsh32x16 x y) -> (SRA x (ZeroExt16to32 y)) +(Rsh32x32 x y) -> (SRAcond x y (CMPconst [256] y)) +(Rsh32x16 x y) -> (SRAcond x (ZeroExt16to32 y) (CMPconst [256] (ZeroExt16to32 y))) (Rsh32x8 x y) -> (SRA x (ZeroExt8to32 y)) -(Rsh16x32 x y) -> (SRA (SignExt16to32 x) y) -(Rsh16x16 x y) -> (SRA (SignExt16to32 x) (ZeroExt16to32 y)) +(Rsh16x32 x y) -> (SRAcond (SignExt16to32 x) y (CMPconst [256] y)) +(Rsh16x16 x y) -> (SRAcond (SignExt16to32 x) (ZeroExt16to32 y) (CMPconst [256] (ZeroExt16to32 y))) (Rsh16x8 x y) -> (SRA (SignExt16to32 x) (ZeroExt8to32 y)) -(Rsh8x32 x y) -> (SRA (SignExt8to32 x) y) -(Rsh8x16 x y) -> (SRA (SignExt8to32 x) (ZeroExt16to32 y)) +(Rsh8x32 x y) -> (SRAcond (SignExt8to32 x) y (CMPconst [256] y)) +(Rsh8x16 x y) -> (SRAcond (SignExt8to32 x) (ZeroExt16to32 y) (CMPconst [256] (ZeroExt16to32 y))) (Rsh8x8 x y) -> (SRA (SignExt8to32 x) (ZeroExt8to32 y)) // constant shifts @@ -177,7 +179,7 @@ (SignExt16to32 x) -> (MOVHreg x) (Signmask x) -> (SRAconst x [31]) -(Zeromask x) -> (LoweredZeromask x) +(Zeromask x) -> (SRAconst (RSBshiftRL x x [1]) [31]) // sign bit of uint32(x)>>1 - x // float <-> int conversion (Cvt32to32F x) -> (MOVWF x) @@ -452,6 +454,11 @@ (MOVFload [off] {sym} ptr (MOVFstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> x (MOVDload [off] {sym} ptr (MOVDstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> x +(MOVWloadidx ptr idx (MOVWstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) -> x +(MOVWloadshiftLL ptr idx [c] (MOVWstoreshiftLL ptr2 idx [d] x _)) && c==d && isSamePtr(ptr, ptr2) -> x +(MOVWloadshiftRL ptr idx [c] (MOVWstoreshiftRL ptr2 idx [d] x _)) && c==d && isSamePtr(ptr, ptr2) -> x +(MOVWloadshiftRA ptr idx [c] (MOVWstoreshiftRA ptr2 idx [d] x _)) && c==d && isSamePtr(ptr, ptr2) -> x + // fold constant into arithmatic ops (ADD (MOVWconst [c]) x) -> (ADDconst [c] x) (ADD x (MOVWconst [c])) -> (ADDconst [c] x) @@ -485,9 +492,6 @@ (CMP x (MOVWconst [c])) -> (CMPconst [c] x) (CMP (MOVWconst [c]) x) -> (InvertFlags (CMPconst [c] x)) -(LoweredZeromask (MOVWconst [0])) -> (MOVWconst [0]) -(LoweredZeromask (MOVWconst [c])) && c != 0 -> (MOVWconst [0xffffffff]) - // don't extend after proper load // MOVWreg instruction is not emitted if src and dst registers are same, but it ensures the type. (MOVBreg x:(MOVBload _ _)) -> (MOVWreg x) @@ -504,6 +508,15 @@ (MOVBreg (ANDconst [c] x)) && c & 0x80 == 0 -> (ANDconst [c&0x7f] x) (MOVHreg (ANDconst [c] x)) && c & 0x8000 == 0 -> (ANDconst [c&0x7fff] x) +// fold double extensions +(MOVBreg x:(MOVBreg _)) -> (MOVWreg x) +(MOVBUreg x:(MOVBUreg _)) -> (MOVWreg x) +(MOVHreg x:(MOVBreg _)) -> (MOVWreg x) +(MOVHreg x:(MOVBUreg _)) -> (MOVWreg x) +(MOVHreg x:(MOVHreg _)) -> (MOVWreg x) +(MOVHUreg x:(MOVBUreg _)) -> (MOVWreg x) +(MOVHUreg x:(MOVHUreg _)) -> (MOVWreg x) + // don't extend before store (MOVBstore [off] {sym} ptr (MOVBreg x) mem) -> (MOVBstore [off] {sym} ptr x mem) (MOVBstore [off] {sym} ptr (MOVBUreg x) mem) -> (MOVBstore [off] {sym} ptr x mem) @@ -513,25 +526,49 @@ (MOVHstore [off] {sym} ptr (MOVHUreg x) mem) -> (MOVHstore [off] {sym} ptr x mem) // mul by constant -(MUL x (MOVWconst [-1])) -> (RSBconst [0] x) +(MUL x (MOVWconst [c])) && int32(c) == -1 -> (RSBconst [0] x) (MUL _ (MOVWconst [0])) -> (MOVWconst [0]) (MUL x (MOVWconst [1])) -> x (MUL x (MOVWconst [c])) && isPowerOfTwo(c) -> (SLLconst [log2(c)] x) +(MUL x (MOVWconst [c])) && isPowerOfTwo(c-1) && int32(c) >= 3 -> (ADDshiftLL x x [log2(c-1)]) +(MUL x (MOVWconst [c])) && isPowerOfTwo(c+1) && int32(c) >= 7 -> (RSBshiftLL x x [log2(c+1)]) +(MUL x (MOVWconst [c])) && c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) -> (SLLconst [log2(c/3)] (ADDshiftLL x x [1])) +(MUL x (MOVWconst [c])) && c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) -> (SLLconst [log2(c/5)] (ADDshiftLL x x [2])) +(MUL x (MOVWconst [c])) && c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) -> (SLLconst [log2(c/7)] (RSBshiftLL x x [3])) +(MUL x (MOVWconst [c])) && c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) -> (SLLconst [log2(c/9)] (ADDshiftLL x x [3])) -(MUL (MOVWconst [-1]) x) -> (RSBconst [0] x) +(MUL (MOVWconst [c]) x) && int32(c) == -1 -> (RSBconst [0] x) (MUL (MOVWconst [0]) _) -> (MOVWconst [0]) (MUL (MOVWconst [1]) x) -> x (MUL (MOVWconst [c]) x) && isPowerOfTwo(c) -> (SLLconst [log2(c)] x) +(MUL (MOVWconst [c]) x) && isPowerOfTwo(c-1) && int32(c) >= 3 -> (ADDshiftLL x x [log2(c-1)]) +(MUL (MOVWconst [c]) x) && isPowerOfTwo(c+1) && int32(c) >= 7 -> (RSBshiftLL x x [log2(c+1)]) +(MUL (MOVWconst [c]) x) && c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) -> (SLLconst [log2(c/3)] (ADDshiftLL x x [1])) +(MUL (MOVWconst [c]) x) && c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) -> (SLLconst [log2(c/5)] (ADDshiftLL x x [2])) +(MUL (MOVWconst [c]) x) && c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) -> (SLLconst [log2(c/7)] (RSBshiftLL x x [3])) +(MUL (MOVWconst [c]) x) && c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) -> (SLLconst [log2(c/9)] (ADDshiftLL x x [3])) -(MULA x (MOVWconst [-1]) a) -> (SUB a x) +(MULA x (MOVWconst [c]) a) && int32(c) == -1 -> (SUB a x) (MULA _ (MOVWconst [0]) a) -> a (MULA x (MOVWconst [1]) a) -> (ADD x a) (MULA x (MOVWconst [c]) a) && isPowerOfTwo(c) -> (ADD (SLLconst [log2(c)] x) a) +(MULA x (MOVWconst [c]) a) && isPowerOfTwo(c-1) && int32(c) >= 3 -> (ADD (ADDshiftLL x x [log2(c-1)]) a) +(MULA x (MOVWconst [c]) a) && isPowerOfTwo(c+1) && int32(c) >= 7 -> (ADD (RSBshiftLL x x [log2(c+1)]) a) +(MULA x (MOVWconst [c]) a) && c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) -> (ADD (SLLconst [log2(c/3)] (ADDshiftLL x x [1])) a) +(MULA x (MOVWconst [c]) a) && c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) -> (ADD (SLLconst [log2(c/5)] (ADDshiftLL x x [2])) a) +(MULA x (MOVWconst [c]) a) && c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) -> (ADD (SLLconst [log2(c/7)] (RSBshiftLL x x [3])) a) +(MULA x (MOVWconst [c]) a) && c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) -> (ADD (SLLconst [log2(c/9)] (ADDshiftLL x x [3])) a) -(MULA (MOVWconst [-1]) x a) -> (SUB a x) +(MULA (MOVWconst [c]) x a) && int32(c) == -1 -> (SUB a x) (MULA (MOVWconst [0]) _ a) -> a (MULA (MOVWconst [1]) x a) -> (ADD x a) (MULA (MOVWconst [c]) x a) && isPowerOfTwo(c) -> (ADD (SLLconst [log2(c)] x) a) +(MULA (MOVWconst [c]) x a) && isPowerOfTwo(c-1) && int32(c) >= 3 -> (ADD (ADDshiftLL x x [log2(c-1)]) a) +(MULA (MOVWconst [c]) x a) && isPowerOfTwo(c+1) && int32(c) >= 7 -> (ADD (RSBshiftLL x x [log2(c+1)]) a) +(MULA (MOVWconst [c]) x a) && c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) -> (ADD (SLLconst [log2(c/3)] (ADDshiftLL x x [1])) a) +(MULA (MOVWconst [c]) x a) && c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) -> (ADD (SLLconst [log2(c/5)] (ADDshiftLL x x [2])) a) +(MULA (MOVWconst [c]) x a) && c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) -> (ADD (SLLconst [log2(c/7)] (RSBshiftLL x x [3])) a) +(MULA (MOVWconst [c]) x a) && c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) -> (ADD (SLLconst [log2(c/9)] (ADDshiftLL x x [3])) a) // div by constant (DIVU x (MOVWconst [1])) -> x @@ -696,6 +733,28 @@ (GreaterEqual (InvertFlags x)) -> (LessEqual x) (GreaterEqualU (InvertFlags x)) -> (LessEqualU x) +// absorb flag constants into conditional instructions +(CMOVWLSconst _ (FlagEQ) [c]) -> (MOVWconst [c]) +(CMOVWLSconst _ (FlagLT_ULT) [c]) -> (MOVWconst [c]) +(CMOVWLSconst x (FlagLT_UGT)) -> x +(CMOVWLSconst _ (FlagGT_ULT) [c]) -> (MOVWconst [c]) +(CMOVWLSconst x (FlagGT_UGT)) -> x + +(CMOVWHSconst _ (FlagEQ) [c]) -> (MOVWconst [c]) +(CMOVWHSconst x (FlagLT_ULT)) -> x +(CMOVWHSconst _ (FlagLT_UGT) [c]) -> (MOVWconst [c]) +(CMOVWHSconst x (FlagGT_ULT)) -> x +(CMOVWHSconst _ (FlagGT_UGT) [c]) -> (MOVWconst [c]) + +(CMOVWLSconst x (InvertFlags flags) [c]) -> (CMOVWHSconst x flags [c]) +(CMOVWHSconst x (InvertFlags flags) [c]) -> (CMOVWLSconst x flags [c]) + +(SRAcond x _ (FlagEQ)) -> (SRAconst x [31]) +(SRAcond x y (FlagLT_ULT)) -> (SRA x y) +(SRAcond x _ (FlagLT_UGT)) -> (SRAconst x [31]) +(SRAcond x y (FlagGT_ULT)) -> (SRA x y) +(SRAcond x _ (FlagGT_UGT)) -> (SRAconst x [31]) + // remove redundant *const ops (ADDconst [0] x) -> x (SUBconst [0] x) -> x @@ -741,10 +800,377 @@ (XORconst [c] (XORconst [d] x)) -> (XORconst [c^d] x) (BICconst [c] (MOVWconst [d])) -> (MOVWconst [d&^c]) (MVN (MOVWconst [c])) -> (MOVWconst [^c]) +(MOVBreg (MOVWconst [c])) -> (MOVWconst [int64(int8(c))]) +(MOVBUreg (MOVWconst [c])) -> (MOVWconst [int64(uint8(c))]) +(MOVHreg (MOVWconst [c])) -> (MOVWconst [int64(int16(c))]) +(MOVHUreg (MOVWconst [c])) -> (MOVWconst [int64(uint16(c))]) +(MOVWreg (MOVWconst [c])) -> (MOVWconst [c]) + +// absorb shifts into ops +(ADD x (SLLconst [c] y)) -> (ADDshiftLL x y [c]) +(ADD (SLLconst [c] y) x) -> (ADDshiftLL x y [c]) +(ADD x (SRLconst [c] y)) -> (ADDshiftRL x y [c]) +(ADD (SRLconst [c] y) x) -> (ADDshiftRL x y [c]) +(ADD x (SRAconst [c] y)) -> (ADDshiftRA x y [c]) +(ADD (SRAconst [c] y) x) -> (ADDshiftRA x y [c]) +(ADD x (SLL y z)) -> (ADDshiftLLreg x y z) +(ADD (SLL y z) x) -> (ADDshiftLLreg x y z) +(ADD x (SRL y z)) -> (ADDshiftRLreg x y z) +(ADD (SRL y z) x) -> (ADDshiftRLreg x y z) +(ADD x (SRA y z)) -> (ADDshiftRAreg x y z) +(ADD (SRA y z) x) -> (ADDshiftRAreg x y z) +(ADC x (SLLconst [c] y) flags) -> (ADCshiftLL x y [c] flags) +(ADC (SLLconst [c] y) x flags) -> (ADCshiftLL x y [c] flags) +(ADC x (SRLconst [c] y) flags) -> (ADCshiftRL x y [c] flags) +(ADC (SRLconst [c] y) x flags) -> (ADCshiftRL x y [c] flags) +(ADC x (SRAconst [c] y) flags) -> (ADCshiftRA x y [c] flags) +(ADC (SRAconst [c] y) x flags) -> (ADCshiftRA x y [c] flags) +(ADC x (SLL y z) flags) -> (ADCshiftLLreg x y z flags) +(ADC (SLL y z) x flags) -> (ADCshiftLLreg x y z flags) +(ADC x (SRL y z) flags) -> (ADCshiftRLreg x y z flags) +(ADC (SRL y z) x flags) -> (ADCshiftRLreg x y z flags) +(ADC x (SRA y z) flags) -> (ADCshiftRAreg x y z flags) +(ADC (SRA y z) x flags) -> (ADCshiftRAreg x y z flags) +(ADDS x (SLLconst [c] y)) -> (ADDSshiftLL x y [c]) +(ADDS (SLLconst [c] y) x) -> (ADDSshiftLL x y [c]) +(ADDS x (SRLconst [c] y)) -> (ADDSshiftRL x y [c]) +(ADDS (SRLconst [c] y) x) -> (ADDSshiftRL x y [c]) +(ADDS x (SRAconst [c] y)) -> (ADDSshiftRA x y [c]) +(ADDS (SRAconst [c] y) x) -> (ADDSshiftRA x y [c]) +(ADDS x (SLL y z)) -> (ADDSshiftLLreg x y z) +(ADDS (SLL y z) x) -> (ADDSshiftLLreg x y z) +(ADDS x (SRL y z)) -> (ADDSshiftRLreg x y z) +(ADDS (SRL y z) x) -> (ADDSshiftRLreg x y z) +(ADDS x (SRA y z)) -> (ADDSshiftRAreg x y z) +(ADDS (SRA y z) x) -> (ADDSshiftRAreg x y z) +(SUB x (SLLconst [c] y)) -> (SUBshiftLL x y [c]) +(SUB (SLLconst [c] y) x) -> (RSBshiftLL x y [c]) +(SUB x (SRLconst [c] y)) -> (SUBshiftRL x y [c]) +(SUB (SRLconst [c] y) x) -> (RSBshiftRL x y [c]) +(SUB x (SRAconst [c] y)) -> (SUBshiftRA x y [c]) +(SUB (SRAconst [c] y) x) -> (RSBshiftRA x y [c]) +(SUB x (SLL y z)) -> (SUBshiftLLreg x y z) +(SUB (SLL y z) x) -> (RSBshiftLLreg x y z) +(SUB x (SRL y z)) -> (SUBshiftRLreg x y z) +(SUB (SRL y z) x) -> (RSBshiftRLreg x y z) +(SUB x (SRA y z)) -> (SUBshiftRAreg x y z) +(SUB (SRA y z) x) -> (RSBshiftRAreg x y z) +(SBC x (SLLconst [c] y) flags) -> (SBCshiftLL x y [c] flags) +(SBC (SLLconst [c] y) x flags) -> (RSCshiftLL x y [c] flags) +(SBC x (SRLconst [c] y) flags) -> (SBCshiftRL x y [c] flags) +(SBC (SRLconst [c] y) x flags) -> (RSCshiftRL x y [c] flags) +(SBC x (SRAconst [c] y) flags) -> (SBCshiftRA x y [c] flags) +(SBC (SRAconst [c] y) x flags) -> (RSCshiftRA x y [c] flags) +(SBC x (SLL y z) flags) -> (SBCshiftLLreg x y z flags) +(SBC (SLL y z) x flags) -> (RSCshiftLLreg x y z flags) +(SBC x (SRL y z) flags) -> (SBCshiftRLreg x y z flags) +(SBC (SRL y z) x flags) -> (RSCshiftRLreg x y z flags) +(SBC x (SRA y z) flags) -> (SBCshiftRAreg x y z flags) +(SBC (SRA y z) x flags) -> (RSCshiftRAreg x y z flags) +(SUBS x (SLLconst [c] y)) -> (SUBSshiftLL x y [c]) +(SUBS (SLLconst [c] y) x) -> (RSBSshiftLL x y [c]) +(SUBS x (SRLconst [c] y)) -> (SUBSshiftRL x y [c]) +(SUBS (SRLconst [c] y) x) -> (RSBSshiftRL x y [c]) +(SUBS x (SRAconst [c] y)) -> (SUBSshiftRA x y [c]) +(SUBS (SRAconst [c] y) x) -> (RSBSshiftRA x y [c]) +(SUBS x (SLL y z)) -> (SUBSshiftLLreg x y z) +(SUBS (SLL y z) x) -> (RSBSshiftLLreg x y z) +(SUBS x (SRL y z)) -> (SUBSshiftRLreg x y z) +(SUBS (SRL y z) x) -> (RSBSshiftRLreg x y z) +(SUBS x (SRA y z)) -> (SUBSshiftRAreg x y z) +(SUBS (SRA y z) x) -> (RSBSshiftRAreg x y z) +(RSB x (SLLconst [c] y)) -> (RSBshiftLL x y [c]) +(RSB (SLLconst [c] y) x) -> (SUBshiftLL x y [c]) +(RSB x (SRLconst [c] y)) -> (RSBshiftRL x y [c]) +(RSB (SRLconst [c] y) x) -> (SUBshiftRL x y [c]) +(RSB x (SRAconst [c] y)) -> (RSBshiftRA x y [c]) +(RSB (SRAconst [c] y) x) -> (SUBshiftRA x y [c]) +(RSB x (SLL y z)) -> (RSBshiftLLreg x y z) +(RSB (SLL y z) x) -> (SUBshiftLLreg x y z) +(RSB x (SRL y z)) -> (RSBshiftRLreg x y z) +(RSB (SRL y z) x) -> (SUBshiftRLreg x y z) +(RSB x (SRA y z)) -> (RSBshiftRAreg x y z) +(RSB (SRA y z) x) -> (SUBshiftRAreg x y z) +(AND x (SLLconst [c] y)) -> (ANDshiftLL x y [c]) +(AND (SLLconst [c] y) x) -> (ANDshiftLL x y [c]) +(AND x (SRLconst [c] y)) -> (ANDshiftRL x y [c]) +(AND (SRLconst [c] y) x) -> (ANDshiftRL x y [c]) +(AND x (SRAconst [c] y)) -> (ANDshiftRA x y [c]) +(AND (SRAconst [c] y) x) -> (ANDshiftRA x y [c]) +(AND x (SLL y z)) -> (ANDshiftLLreg x y z) +(AND (SLL y z) x) -> (ANDshiftLLreg x y z) +(AND x (SRL y z)) -> (ANDshiftRLreg x y z) +(AND (SRL y z) x) -> (ANDshiftRLreg x y z) +(AND x (SRA y z)) -> (ANDshiftRAreg x y z) +(AND (SRA y z) x) -> (ANDshiftRAreg x y z) +(OR x (SLLconst [c] y)) -> (ORshiftLL x y [c]) +(OR (SLLconst [c] y) x) -> (ORshiftLL x y [c]) +(OR x (SRLconst [c] y)) -> (ORshiftRL x y [c]) +(OR (SRLconst [c] y) x) -> (ORshiftRL x y [c]) +(OR x (SRAconst [c] y)) -> (ORshiftRA x y [c]) +(OR (SRAconst [c] y) x) -> (ORshiftRA x y [c]) +(OR x (SLL y z)) -> (ORshiftLLreg x y z) +(OR (SLL y z) x) -> (ORshiftLLreg x y z) +(OR x (SRL y z)) -> (ORshiftRLreg x y z) +(OR (SRL y z) x) -> (ORshiftRLreg x y z) +(OR x (SRA y z)) -> (ORshiftRAreg x y z) +(OR (SRA y z) x) -> (ORshiftRAreg x y z) +(XOR x (SLLconst [c] y)) -> (XORshiftLL x y [c]) +(XOR (SLLconst [c] y) x) -> (XORshiftLL x y [c]) +(XOR x (SRLconst [c] y)) -> (XORshiftRL x y [c]) +(XOR (SRLconst [c] y) x) -> (XORshiftRL x y [c]) +(XOR x (SRAconst [c] y)) -> (XORshiftRA x y [c]) +(XOR (SRAconst [c] y) x) -> (XORshiftRA x y [c]) +(XOR x (SLL y z)) -> (XORshiftLLreg x y z) +(XOR (SLL y z) x) -> (XORshiftLLreg x y z) +(XOR x (SRL y z)) -> (XORshiftRLreg x y z) +(XOR (SRL y z) x) -> (XORshiftRLreg x y z) +(XOR x (SRA y z)) -> (XORshiftRAreg x y z) +(XOR (SRA y z) x) -> (XORshiftRAreg x y z) +(BIC x (SLLconst [c] y)) -> (BICshiftLL x y [c]) +(BIC x (SRLconst [c] y)) -> (BICshiftRL x y [c]) +(BIC x (SRAconst [c] y)) -> (BICshiftRA x y [c]) +(BIC x (SLL y z)) -> (BICshiftLLreg x y z) +(BIC x (SRL y z)) -> (BICshiftRLreg x y z) +(BIC x (SRA y z)) -> (BICshiftRAreg x y z) +(MVN (SLLconst [c] x)) -> (MVNshiftLL x [c]) +(MVN (SRLconst [c] x)) -> (MVNshiftRL x [c]) +(MVN (SRAconst [c] x)) -> (MVNshiftRA x [c]) +(MVN (SLL x y)) -> (MVNshiftLLreg x y) +(MVN (SRL x y)) -> (MVNshiftRLreg x y) +(MVN (SRA x y)) -> (MVNshiftRAreg x y) + +(CMP x (SLLconst [c] y)) -> (CMPshiftLL x y [c]) +(CMP (SLLconst [c] y) x) -> (InvertFlags (CMPshiftLL x y [c])) +(CMP x (SRLconst [c] y)) -> (CMPshiftRL x y [c]) +(CMP (SRLconst [c] y) x) -> (InvertFlags (CMPshiftRL x y [c])) +(CMP x (SRAconst [c] y)) -> (CMPshiftRA x y [c]) +(CMP (SRAconst [c] y) x) -> (InvertFlags (CMPshiftRA x y [c])) +(CMP x (SLL y z)) -> (CMPshiftLLreg x y z) +(CMP (SLL y z) x) -> (InvertFlags (CMPshiftLLreg x y z)) +(CMP x (SRL y z)) -> (CMPshiftRLreg x y z) +(CMP (SRL y z) x) -> (InvertFlags (CMPshiftRLreg x y z)) +(CMP x (SRA y z)) -> (CMPshiftRAreg x y z) +(CMP (SRA y z) x) -> (InvertFlags (CMPshiftRAreg x y z)) + +// prefer *const ops to *shift ops +(ADDshiftLL (MOVWconst [c]) x [d]) -> (ADDconst [c] (SLLconst x [d])) +(ADDshiftRL (MOVWconst [c]) x [d]) -> (ADDconst [c] (SRLconst x [d])) +(ADDshiftRA (MOVWconst [c]) x [d]) -> (ADDconst [c] (SRAconst x [d])) +(ADCshiftLL (MOVWconst [c]) x [d] flags) -> (ADCconst [c] (SLLconst x [d]) flags) +(ADCshiftRL (MOVWconst [c]) x [d] flags) -> (ADCconst [c] (SRLconst x [d]) flags) +(ADCshiftRA (MOVWconst [c]) x [d] flags) -> (ADCconst [c] (SRAconst x [d]) flags) +(ADDSshiftLL (MOVWconst [c]) x [d]) -> (ADDSconst [c] (SLLconst x [d])) +(ADDSshiftRL (MOVWconst [c]) x [d]) -> (ADDSconst [c] (SRLconst x [d])) +(ADDSshiftRA (MOVWconst [c]) x [d]) -> (ADDSconst [c] (SRAconst x [d])) +(SUBshiftLL (MOVWconst [c]) x [d]) -> (RSBconst [c] (SLLconst x [d])) +(SUBshiftRL (MOVWconst [c]) x [d]) -> (RSBconst [c] (SRLconst x [d])) +(SUBshiftRA (MOVWconst [c]) x [d]) -> (RSBconst [c] (SRAconst x [d])) +(SBCshiftLL (MOVWconst [c]) x [d] flags) -> (RSCconst [c] (SLLconst x [d]) flags) +(SBCshiftRL (MOVWconst [c]) x [d] flags) -> (RSCconst [c] (SRLconst x [d]) flags) +(SBCshiftRA (MOVWconst [c]) x [d] flags) -> (RSCconst [c] (SRAconst x [d]) flags) +(SUBSshiftLL (MOVWconst [c]) x [d]) -> (RSBSconst [c] (SLLconst x [d])) +(SUBSshiftRL (MOVWconst [c]) x [d]) -> (RSBSconst [c] (SRLconst x [d])) +(SUBSshiftRA (MOVWconst [c]) x [d]) -> (RSBSconst [c] (SRAconst x [d])) +(RSBshiftLL (MOVWconst [c]) x [d]) -> (SUBconst [c] (SLLconst x [d])) +(RSBshiftRL (MOVWconst [c]) x [d]) -> (SUBconst [c] (SRLconst x [d])) +(RSBshiftRA (MOVWconst [c]) x [d]) -> (SUBconst [c] (SRAconst x [d])) +(RSCshiftLL (MOVWconst [c]) x [d] flags) -> (SBCconst [c] (SLLconst x [d]) flags) +(RSCshiftRL (MOVWconst [c]) x [d] flags) -> (SBCconst [c] (SRLconst x [d]) flags) +(RSCshiftRA (MOVWconst [c]) x [d] flags) -> (SBCconst [c] (SRAconst x [d]) flags) +(RSBSshiftLL (MOVWconst [c]) x [d]) -> (SUBSconst [c] (SLLconst x [d])) +(RSBSshiftRL (MOVWconst [c]) x [d]) -> (SUBSconst [c] (SRLconst x [d])) +(RSBSshiftRA (MOVWconst [c]) x [d]) -> (SUBSconst [c] (SRAconst x [d])) +(ANDshiftLL (MOVWconst [c]) x [d]) -> (ANDconst [c] (SLLconst x [d])) +(ANDshiftRL (MOVWconst [c]) x [d]) -> (ANDconst [c] (SRLconst x [d])) +(ANDshiftRA (MOVWconst [c]) x [d]) -> (ANDconst [c] (SRAconst x [d])) +(ORshiftLL (MOVWconst [c]) x [d]) -> (ORconst [c] (SLLconst x [d])) +(ORshiftRL (MOVWconst [c]) x [d]) -> (ORconst [c] (SRLconst x [d])) +(ORshiftRA (MOVWconst [c]) x [d]) -> (ORconst [c] (SRAconst x [d])) +(XORshiftLL (MOVWconst [c]) x [d]) -> (XORconst [c] (SLLconst x [d])) +(XORshiftRL (MOVWconst [c]) x [d]) -> (XORconst [c] (SRLconst x [d])) +(XORshiftRA (MOVWconst [c]) x [d]) -> (XORconst [c] (SRAconst x [d])) +(CMPshiftLL (MOVWconst [c]) x [d]) -> (InvertFlags (CMPconst [c] (SLLconst x [d]))) +(CMPshiftRL (MOVWconst [c]) x [d]) -> (InvertFlags (CMPconst [c] (SRLconst x [d]))) +(CMPshiftRA (MOVWconst [c]) x [d]) -> (InvertFlags (CMPconst [c] (SRAconst x [d]))) + +(ADDshiftLLreg (MOVWconst [c]) x y) -> (ADDconst [c] (SLL x y)) +(ADDshiftRLreg (MOVWconst [c]) x y) -> (ADDconst [c] (SRL x y)) +(ADDshiftRAreg (MOVWconst [c]) x y) -> (ADDconst [c] (SRA x y)) +(ADCshiftLLreg (MOVWconst [c]) x y flags) -> (ADCconst [c] (SLL x y) flags) +(ADCshiftRLreg (MOVWconst [c]) x y flags) -> (ADCconst [c] (SRL x y) flags) +(ADCshiftRAreg (MOVWconst [c]) x y flags) -> (ADCconst [c] (SRA x y) flags) +(ADDSshiftLLreg (MOVWconst [c]) x y) -> (ADDSconst [c] (SLL x y)) +(ADDSshiftRLreg (MOVWconst [c]) x y) -> (ADDSconst [c] (SRL x y)) +(ADDSshiftRAreg (MOVWconst [c]) x y) -> (ADDSconst [c] (SRA x y)) +(SUBshiftLLreg (MOVWconst [c]) x y) -> (RSBconst [c] (SLL x y)) +(SUBshiftRLreg (MOVWconst [c]) x y) -> (RSBconst [c] (SRL x y)) +(SUBshiftRAreg (MOVWconst [c]) x y) -> (RSBconst [c] (SRA x y)) +(SBCshiftLLreg (MOVWconst [c]) x y flags) -> (RSCconst [c] (SLL x y) flags) +(SBCshiftRLreg (MOVWconst [c]) x y flags) -> (RSCconst [c] (SRL x y) flags) +(SBCshiftRAreg (MOVWconst [c]) x y flags) -> (RSCconst [c] (SRA x y) flags) +(SUBSshiftLLreg (MOVWconst [c]) x y) -> (RSBSconst [c] (SLL x y)) +(SUBSshiftRLreg (MOVWconst [c]) x y) -> (RSBSconst [c] (SRL x y)) +(SUBSshiftRAreg (MOVWconst [c]) x y) -> (RSBSconst [c] (SRA x y)) +(RSBshiftLLreg (MOVWconst [c]) x y) -> (SUBconst [c] (SLL x y)) +(RSBshiftRLreg (MOVWconst [c]) x y) -> (SUBconst [c] (SRL x y)) +(RSBshiftRAreg (MOVWconst [c]) x y) -> (SUBconst [c] (SRA x y)) +(RSCshiftLLreg (MOVWconst [c]) x y flags) -> (SBCconst [c] (SLL x y) flags) +(RSCshiftRLreg (MOVWconst [c]) x y flags) -> (SBCconst [c] (SRL x y) flags) +(RSCshiftRAreg (MOVWconst [c]) x y flags) -> (SBCconst [c] (SRA x y) flags) +(RSBSshiftLLreg (MOVWconst [c]) x y) -> (SUBSconst [c] (SLL x y)) +(RSBSshiftRLreg (MOVWconst [c]) x y) -> (SUBSconst [c] (SRL x y)) +(RSBSshiftRAreg (MOVWconst [c]) x y) -> (SUBSconst [c] (SRA x y)) +(ANDshiftLLreg (MOVWconst [c]) x y) -> (ANDconst [c] (SLL x y)) +(ANDshiftRLreg (MOVWconst [c]) x y) -> (ANDconst [c] (SRL x y)) +(ANDshiftRAreg (MOVWconst [c]) x y) -> (ANDconst [c] (SRA x y)) +(ORshiftLLreg (MOVWconst [c]) x y) -> (ORconst [c] (SLL x y)) +(ORshiftRLreg (MOVWconst [c]) x y) -> (ORconst [c] (SRL x y)) +(ORshiftRAreg (MOVWconst [c]) x y) -> (ORconst [c] (SRA x y)) +(XORshiftLLreg (MOVWconst [c]) x y) -> (XORconst [c] (SLL x y)) +(XORshiftRLreg (MOVWconst [c]) x y) -> (XORconst [c] (SRL x y)) +(XORshiftRAreg (MOVWconst [c]) x y) -> (XORconst [c] (SRA x y)) +(CMPshiftLLreg (MOVWconst [c]) x y) -> (InvertFlags (CMPconst [c] (SLL x y))) +(CMPshiftRLreg (MOVWconst [c]) x y) -> (InvertFlags (CMPconst [c] (SRL x y))) +(CMPshiftRAreg (MOVWconst [c]) x y) -> (InvertFlags (CMPconst [c] (SRA x y))) + +// constant folding in *shift ops +(ADDshiftLL x (MOVWconst [c]) [d]) -> (ADDconst x [int64(uint32(c)< (ADDconst x [int64(uint32(c)>>uint64(d))]) +(ADDshiftRA x (MOVWconst [c]) [d]) -> (ADDconst x [int64(int32(c)>>uint64(d))]) +(ADCshiftLL x (MOVWconst [c]) [d] flags) -> (ADCconst x [int64(uint32(c)< (ADCconst x [int64(uint32(c)>>uint64(d))] flags) +(ADCshiftRA x (MOVWconst [c]) [d] flags) -> (ADCconst x [int64(int32(c)>>uint64(d))] flags) +(ADDSshiftLL x (MOVWconst [c]) [d]) -> (ADDSconst x [int64(uint32(c)< (ADDSconst x [int64(uint32(c)>>uint64(d))]) +(ADDSshiftRA x (MOVWconst [c]) [d]) -> (ADDSconst x [int64(int32(c)>>uint64(d))]) +(SUBshiftLL x (MOVWconst [c]) [d]) -> (SUBconst x [int64(uint32(c)< (SUBconst x [int64(uint32(c)>>uint64(d))]) +(SUBshiftRA x (MOVWconst [c]) [d]) -> (SUBconst x [int64(int32(c)>>uint64(d))]) +(SBCshiftLL x (MOVWconst [c]) [d] flags) -> (SBCconst x [int64(uint32(c)< (SBCconst x [int64(uint32(c)>>uint64(d))] flags) +(SBCshiftRA x (MOVWconst [c]) [d] flags) -> (SBCconst x [int64(int32(c)>>uint64(d))] flags) +(SUBSshiftLL x (MOVWconst [c]) [d]) -> (SUBSconst x [int64(uint32(c)< (SUBSconst x [int64(uint32(c)>>uint64(d))]) +(SUBSshiftRA x (MOVWconst [c]) [d]) -> (SUBSconst x [int64(int32(c)>>uint64(d))]) +(RSBshiftLL x (MOVWconst [c]) [d]) -> (RSBconst x [int64(uint32(c)< (RSBconst x [int64(uint32(c)>>uint64(d))]) +(RSBshiftRA x (MOVWconst [c]) [d]) -> (RSBconst x [int64(int32(c)>>uint64(d))]) +(RSCshiftLL x (MOVWconst [c]) [d] flags) -> (RSCconst x [int64(uint32(c)< (RSCconst x [int64(uint32(c)>>uint64(d))] flags) +(RSCshiftRA x (MOVWconst [c]) [d] flags) -> (RSCconst x [int64(int32(c)>>uint64(d))] flags) +(RSBSshiftLL x (MOVWconst [c]) [d]) -> (RSBSconst x [int64(uint32(c)< (RSBSconst x [int64(uint32(c)>>uint64(d))]) +(RSBSshiftRA x (MOVWconst [c]) [d]) -> (RSBSconst x [int64(int32(c)>>uint64(d))]) +(ANDshiftLL x (MOVWconst [c]) [d]) -> (ANDconst x [int64(uint32(c)< (ANDconst x [int64(uint32(c)>>uint64(d))]) +(ANDshiftRA x (MOVWconst [c]) [d]) -> (ANDconst x [int64(int32(c)>>uint64(d))]) +(ORshiftLL x (MOVWconst [c]) [d]) -> (ORconst x [int64(uint32(c)< (ORconst x [int64(uint32(c)>>uint64(d))]) +(ORshiftRA x (MOVWconst [c]) [d]) -> (ORconst x [int64(int32(c)>>uint64(d))]) +(XORshiftLL x (MOVWconst [c]) [d]) -> (XORconst x [int64(uint32(c)< (XORconst x [int64(uint32(c)>>uint64(d))]) +(XORshiftRA x (MOVWconst [c]) [d]) -> (XORconst x [int64(int32(c)>>uint64(d))]) +(BICshiftLL x (MOVWconst [c]) [d]) -> (BICconst x [int64(uint32(c)< (BICconst x [int64(uint32(c)>>uint64(d))]) +(BICshiftRA x (MOVWconst [c]) [d]) -> (BICconst x [int64(int32(c)>>uint64(d))]) +(MVNshiftLL (MOVWconst [c]) [d]) -> (MOVWconst [^int64(uint32(c)< (MOVWconst [^int64(uint32(c)>>uint64(d))]) +(MVNshiftRA (MOVWconst [c]) [d]) -> (MOVWconst [^int64(int32(c)>>uint64(d))]) +(CMPshiftLL x (MOVWconst [c]) [d]) -> (CMPconst x [int64(uint32(c)< (CMPconst x [int64(uint32(c)>>uint64(d))]) +(CMPshiftRA x (MOVWconst [c]) [d]) -> (CMPconst x [int64(int32(c)>>uint64(d))]) + +(ADDshiftLLreg x y (MOVWconst [c])) -> (ADDshiftLL x y [c]) +(ADDshiftRLreg x y (MOVWconst [c])) -> (ADDshiftRL x y [c]) +(ADDshiftRAreg x y (MOVWconst [c])) -> (ADDshiftRA x y [c]) +(ADCshiftLLreg x y (MOVWconst [c]) flags) -> (ADCshiftLL x y [c] flags) +(ADCshiftRLreg x y (MOVWconst [c]) flags) -> (ADCshiftRL x y [c] flags) +(ADCshiftRAreg x y (MOVWconst [c]) flags) -> (ADCshiftRA x y [c] flags) +(ADDSshiftLLreg x y (MOVWconst [c])) -> (ADDSshiftLL x y [c]) +(ADDSshiftRLreg x y (MOVWconst [c])) -> (ADDSshiftRL x y [c]) +(ADDSshiftRAreg x y (MOVWconst [c])) -> (ADDSshiftRA x y [c]) +(SUBshiftLLreg x y (MOVWconst [c])) -> (SUBshiftLL x y [c]) +(SUBshiftRLreg x y (MOVWconst [c])) -> (SUBshiftRL x y [c]) +(SUBshiftRAreg x y (MOVWconst [c])) -> (SUBshiftRA x y [c]) +(SBCshiftLLreg x y (MOVWconst [c]) flags) -> (SBCshiftLL x y [c] flags) +(SBCshiftRLreg x y (MOVWconst [c]) flags) -> (SBCshiftRL x y [c] flags) +(SBCshiftRAreg x y (MOVWconst [c]) flags) -> (SBCshiftRA x y [c] flags) +(SUBSshiftLLreg x y (MOVWconst [c])) -> (SUBSshiftLL x y [c]) +(SUBSshiftRLreg x y (MOVWconst [c])) -> (SUBSshiftRL x y [c]) +(SUBSshiftRAreg x y (MOVWconst [c])) -> (SUBSshiftRA x y [c]) +(RSBshiftLLreg x y (MOVWconst [c])) -> (RSBshiftLL x y [c]) +(RSBshiftRLreg x y (MOVWconst [c])) -> (RSBshiftRL x y [c]) +(RSBshiftRAreg x y (MOVWconst [c])) -> (RSBshiftRA x y [c]) +(RSCshiftLLreg x y (MOVWconst [c]) flags) -> (RSCshiftLL x y [c] flags) +(RSCshiftRLreg x y (MOVWconst [c]) flags) -> (RSCshiftRL x y [c] flags) +(RSCshiftRAreg x y (MOVWconst [c]) flags) -> (RSCshiftRA x y [c] flags) +(RSBSshiftLLreg x y (MOVWconst [c])) -> (RSBSshiftLL x y [c]) +(RSBSshiftRLreg x y (MOVWconst [c])) -> (RSBSshiftRL x y [c]) +(RSBSshiftRAreg x y (MOVWconst [c])) -> (RSBSshiftRA x y [c]) +(ANDshiftLLreg x y (MOVWconst [c])) -> (ANDshiftLL x y [c]) +(ANDshiftRLreg x y (MOVWconst [c])) -> (ANDshiftRL x y [c]) +(ANDshiftRAreg x y (MOVWconst [c])) -> (ANDshiftRA x y [c]) +(ORshiftLLreg x y (MOVWconst [c])) -> (ORshiftLL x y [c]) +(ORshiftRLreg x y (MOVWconst [c])) -> (ORshiftRL x y [c]) +(ORshiftRAreg x y (MOVWconst [c])) -> (ORshiftRA x y [c]) +(XORshiftLLreg x y (MOVWconst [c])) -> (XORshiftLL x y [c]) +(XORshiftRLreg x y (MOVWconst [c])) -> (XORshiftRL x y [c]) +(XORshiftRAreg x y (MOVWconst [c])) -> (XORshiftRA x y [c]) +(BICshiftLLreg x y (MOVWconst [c])) -> (BICshiftLL x y [c]) +(BICshiftRLreg x y (MOVWconst [c])) -> (BICshiftRL x y [c]) +(BICshiftRAreg x y (MOVWconst [c])) -> (BICshiftRA x y [c]) +(MVNshiftLLreg x (MOVWconst [c])) -> (MVNshiftLL x [c]) +(MVNshiftRLreg x (MOVWconst [c])) -> (MVNshiftRL x [c]) +(MVNshiftRAreg x (MOVWconst [c])) -> (MVNshiftRA x [c]) +(CMPshiftLLreg x y (MOVWconst [c])) -> (CMPshiftLL x y [c]) +(CMPshiftRLreg x y (MOVWconst [c])) -> (CMPshiftRL x y [c]) +(CMPshiftRAreg x y (MOVWconst [c])) -> (CMPshiftRA x y [c]) + +// use indexed loads and stores +(MOVWload [0] {sym} (ADD ptr idx) mem) && sym == nil -> (MOVWloadidx ptr idx mem) +(MOVWstore [0] {sym} (ADD ptr idx) val mem) && sym == nil -> (MOVWstoreidx ptr idx val mem) +(MOVWload [0] {sym} (ADDshiftLL ptr idx [c]) mem) && sym == nil -> (MOVWloadshiftLL ptr idx [c] mem) +(MOVWload [0] {sym} (ADDshiftRL ptr idx [c]) mem) && sym == nil -> (MOVWloadshiftRL ptr idx [c] mem) +(MOVWload [0] {sym} (ADDshiftRA ptr idx [c]) mem) && sym == nil -> (MOVWloadshiftRA ptr idx [c] mem) +(MOVWstore [0] {sym} (ADDshiftLL ptr idx [c]) val mem) && sym == nil -> (MOVWstoreshiftLL ptr idx [c] val mem) +(MOVWstore [0] {sym} (ADDshiftRL ptr idx [c]) val mem) && sym == nil -> (MOVWstoreshiftRL ptr idx [c] val mem) +(MOVWstore [0] {sym} (ADDshiftRA ptr idx [c]) val mem) && sym == nil -> (MOVWstoreshiftRA ptr idx [c] val mem) + +// constant folding in indexed loads and stores +(MOVWloadidx ptr (MOVWconst [c]) mem) -> (MOVWload [c] ptr mem) +(MOVWloadidx (MOVWconst [c]) ptr mem) -> (MOVWload [c] ptr mem) + +(MOVWstoreidx ptr (MOVWconst [c]) val mem) -> (MOVWstore [c] ptr val mem) +(MOVWstoreidx (MOVWconst [c]) ptr val mem) -> (MOVWstore [c] ptr val mem) + +(MOVWloadidx ptr (SLLconst idx [c]) mem) -> (MOVWloadshiftLL ptr idx [c] mem) +(MOVWloadidx (SLLconst idx [c]) ptr mem) -> (MOVWloadshiftLL ptr idx [c] mem) +(MOVWloadidx ptr (SRLconst idx [c]) mem) -> (MOVWloadshiftRL ptr idx [c] mem) +(MOVWloadidx (SRLconst idx [c]) ptr mem) -> (MOVWloadshiftRL ptr idx [c] mem) +(MOVWloadidx ptr (SRAconst idx [c]) mem) -> (MOVWloadshiftRA ptr idx [c] mem) +(MOVWloadidx (SRAconst idx [c]) ptr mem) -> (MOVWloadshiftRA ptr idx [c] mem) + +(MOVWstoreidx ptr (SLLconst idx [c]) val mem) -> (MOVWstoreshiftLL ptr idx [c] val mem) +(MOVWstoreidx (SLLconst idx [c]) ptr val mem) -> (MOVWstoreshiftLL ptr idx [c] val mem) +(MOVWstoreidx ptr (SRLconst idx [c]) val mem) -> (MOVWstoreshiftRL ptr idx [c] val mem) +(MOVWstoreidx (SRLconst idx [c]) ptr val mem) -> (MOVWstoreshiftRL ptr idx [c] val mem) +(MOVWstoreidx ptr (SRAconst idx [c]) val mem) -> (MOVWstoreshiftRA ptr idx [c] val mem) +(MOVWstoreidx (SRAconst idx [c]) ptr val mem) -> (MOVWstoreshiftRA ptr idx [c] val mem) + +(MOVWloadshiftLL ptr (MOVWconst [c]) [d] mem) -> (MOVWload [int64(uint32(c)< (MOVWload [int64(uint32(c)>>uint64(d))] ptr mem) +(MOVWloadshiftRA ptr (MOVWconst [c]) [d] mem) -> (MOVWload [int64(int32(c)>>uint64(d))] ptr mem) + +(MOVWstoreshiftLL ptr (MOVWconst [c]) [d] val mem) -> (MOVWstore [int64(uint32(c)< (MOVWstore [int64(uint32(c)>>uint64(d))] ptr val mem) +(MOVWstoreshiftRA ptr (MOVWconst [c]) [d] val mem) -> (MOVWstore [int64(int32(c)>>uint64(d))] ptr val mem) // generic simplifications (ADD x (RSBconst [0] y)) -> (SUB x y) +(ADD (RSBconst [0] y) x) -> (SUB x y) (SUB x x) -> (MOVWconst [0]) +(RSB x x) -> (MOVWconst [0]) (AND x x) -> x (OR x x) -> x (XOR x x) -> (MOVWconst [0]) @@ -754,3 +1180,26 @@ (ADD a (MUL x y)) -> (MULA x y a) (AND x (MVN y)) -> (BIC x y) + +// simplification with *shift ops +(SUBshiftLL x (SLLconst x [c]) [d]) && c==d -> (MOVWconst [0]) +(SUBshiftRL x (SRLconst x [c]) [d]) && c==d -> (MOVWconst [0]) +(SUBshiftRA x (SRAconst x [c]) [d]) && c==d -> (MOVWconst [0]) +(RSBshiftLL x (SLLconst x [c]) [d]) && c==d -> (MOVWconst [0]) +(RSBshiftRL x (SRLconst x [c]) [d]) && c==d -> (MOVWconst [0]) +(RSBshiftRA x (SRAconst x [c]) [d]) && c==d -> (MOVWconst [0]) +(ANDshiftLL x y:(SLLconst x [c]) [d]) && c==d -> y +(ANDshiftRL x y:(SRLconst x [c]) [d]) && c==d -> y +(ANDshiftRA x y:(SRAconst x [c]) [d]) && c==d -> y +(ORshiftLL x y:(SLLconst x [c]) [d]) && c==d -> y +(ORshiftRL x y:(SRLconst x [c]) [d]) && c==d -> y +(ORshiftRA x y:(SRAconst x [c]) [d]) && c==d -> y +(XORshiftLL x (SLLconst x [c]) [d]) && c==d -> (MOVWconst [0]) +(XORshiftRL x (SRLconst x [c]) [d]) && c==d -> (MOVWconst [0]) +(XORshiftRA x (SRAconst x [c]) [d]) && c==d -> (MOVWconst [0]) +(BICshiftLL x (SLLconst x [c]) [d]) && c==d -> (MOVWconst [0]) +(BICshiftRL x (SRLconst x [c]) [d]) && c==d -> (MOVWconst [0]) +(BICshiftRA x (SRAconst x [c]) [d]) && c==d -> (MOVWconst [0]) +(AND x (MVNshiftLL y [c])) -> (BICshiftLL x y [c]) +(AND x (MVNshiftRL y [c])) -> (BICshiftRL x y [c]) +(AND x (MVNshiftRA y [c])) -> (BICshiftRA x y [c]) diff --git a/src/cmd/compile/internal/ssa/gen/ARMOps.go b/src/cmd/compile/internal/ssa/gen/ARMOps.go index a58bdf8b58..89576daf0e 100644 --- a/src/cmd/compile/internal/ssa/gen/ARMOps.go +++ b/src/cmd/compile/internal/ssa/gen/ARMOps.go @@ -110,8 +110,13 @@ func init() { gp2flags = regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{flags}} gp2flags1 = regInfo{inputs: []regMask{gp, gp, flags}, outputs: []regMask{gp}} gp31 = regInfo{inputs: []regMask{gp, gp, gp}, outputs: []regMask{gp}} + gp31cf = regInfo{inputs: []regMask{gp, gp, gp}, outputs: []regMask{gp}, clobbers: flags} // cf: clobbers flags + gp3flags = regInfo{inputs: []regMask{gp, gp, gp}, outputs: []regMask{flags}} + gp3flags1 = regInfo{inputs: []regMask{gp, gp, gp, flags}, outputs: []regMask{gp}} gpload = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}} gpstore = regInfo{inputs: []regMask{gpspsbg, gpg}, outputs: []regMask{}} + gp2load = regInfo{inputs: []regMask{gpspsbg, gpg}, outputs: []regMask{gp}} + gp2store = regInfo{inputs: []regMask{gpspsbg, gpg, gpg}, outputs: []regMask{}} fp01 = regInfo{inputs: []regMask{}, outputs: []regMask{fp}} fp11 = regInfo{inputs: []regMask{fp}, outputs: []regMask{fp}} fpgp = regInfo{inputs: []regMask{fp}, outputs: []regMask{gp}} @@ -176,14 +181,105 @@ func init() { {name: "SQRTD", argLength: 1, reg: fp11, asm: "SQRTD"}, // sqrt(arg0), float64 // shifts - {name: "SLL", argLength: 2, reg: gp21cf, asm: "SLL"}, // arg0 << arg1, results 0 for large shift + {name: "SLL", argLength: 2, reg: gp21, asm: "SLL"}, // arg0 << arg1, shift amount is mod 256 {name: "SLLconst", argLength: 1, reg: gp11, asm: "SLL", aux: "Int32"}, // arg0 << auxInt - {name: "SRL", argLength: 2, reg: gp21cf, asm: "SRL"}, // arg0 >> arg1, unsigned, results 0 for large shift + {name: "SRL", argLength: 2, reg: gp21, asm: "SRL"}, // arg0 >> arg1, unsigned, shift amount is mod 256 {name: "SRLconst", argLength: 1, reg: gp11, asm: "SRL", aux: "Int32"}, // arg0 >> auxInt, unsigned - {name: "SRA", argLength: 2, reg: gp21cf, asm: "SRA"}, // arg0 >> arg1, signed, results 0/-1 for large shift + {name: "SRA", argLength: 2, reg: gp21cf, asm: "SRA"}, // arg0 >> arg1, signed, shift amount is mod 256 {name: "SRAconst", argLength: 1, reg: gp11, asm: "SRA", aux: "Int32"}, // arg0 >> auxInt, signed {name: "SRRconst", argLength: 1, reg: gp11, aux: "Int32"}, // arg0 right rotate by auxInt bits + {name: "ADDshiftLL", argLength: 2, reg: gp21, asm: "ADD", aux: "Int32"}, // arg0 + arg1<>auxInt, unsigned shift + {name: "ADDshiftRA", argLength: 2, reg: gp21, asm: "ADD", aux: "Int32"}, // arg0 + arg1>>auxInt, signed shift + {name: "SUBshiftLL", argLength: 2, reg: gp21, asm: "SUB", aux: "Int32"}, // arg0 - arg1<>auxInt, unsigned shift + {name: "SUBshiftRA", argLength: 2, reg: gp21, asm: "SUB", aux: "Int32"}, // arg0 - arg1>>auxInt, signed shift + {name: "RSBshiftLL", argLength: 2, reg: gp21, asm: "RSB", aux: "Int32"}, // arg1<>auxInt - arg0, unsigned shift + {name: "RSBshiftRA", argLength: 2, reg: gp21, asm: "RSB", aux: "Int32"}, // arg1>>auxInt - arg0, signed shift + {name: "ANDshiftLL", argLength: 2, reg: gp21, asm: "AND", aux: "Int32"}, // arg0 & (arg1<>auxInt), unsigned shift + {name: "ANDshiftRA", argLength: 2, reg: gp21, asm: "AND", aux: "Int32"}, // arg0 & (arg1>>auxInt), signed shift + {name: "ORshiftLL", argLength: 2, reg: gp21, asm: "ORR", aux: "Int32"}, // arg0 | arg1<>auxInt, unsigned shift + {name: "ORshiftRA", argLength: 2, reg: gp21, asm: "ORR", aux: "Int32"}, // arg0 | arg1>>auxInt, signed shift + {name: "XORshiftLL", argLength: 2, reg: gp21, asm: "EOR", aux: "Int32"}, // arg0 ^ arg1<>auxInt, unsigned shift + {name: "XORshiftRA", argLength: 2, reg: gp21, asm: "EOR", aux: "Int32"}, // arg0 ^ arg1>>auxInt, signed shift + {name: "BICshiftLL", argLength: 2, reg: gp21, asm: "BIC", aux: "Int32"}, // arg0 &^ (arg1<>auxInt), unsigned shift + {name: "BICshiftRA", argLength: 2, reg: gp21, asm: "BIC", aux: "Int32"}, // arg0 &^ (arg1>>auxInt), signed shift + {name: "MVNshiftLL", argLength: 1, reg: gp11, asm: "MVN", aux: "Int32"}, // ^(arg0<>auxInt), unsigned shift + {name: "MVNshiftRA", argLength: 1, reg: gp11, asm: "MVN", aux: "Int32"}, // ^(arg0>>auxInt), signed shift + + {name: "ADCshiftLL", argLength: 3, reg: gp2flags1, asm: "ADC", aux: "Int32"}, // arg0 + arg1<>auxInt + carry, unsigned shift, arg2=flags + {name: "ADCshiftRA", argLength: 3, reg: gp2flags1, asm: "ADC", aux: "Int32"}, // arg0 + arg1>>auxInt + carry, signed shift, arg2=flags + {name: "SBCshiftLL", argLength: 3, reg: gp2flags1, asm: "SBC", aux: "Int32"}, // arg0 - arg1<>auxInt - carry, unsigned shift, arg2=flags + {name: "SBCshiftRA", argLength: 3, reg: gp2flags1, asm: "SBC", aux: "Int32"}, // arg0 - arg1>>auxInt - carry, signed shift, arg2=flags + {name: "RSCshiftLL", argLength: 3, reg: gp2flags1, asm: "RSC", aux: "Int32"}, // arg1<>auxInt - arg0 - carry, unsigned shift, arg2=flags + {name: "RSCshiftRA", argLength: 3, reg: gp2flags1, asm: "RSC", aux: "Int32"}, // arg1>>auxInt - arg0 - carry, signed shift, arg2=flags + + {name: "ADDSshiftLL", argLength: 2, reg: gp21cf, asm: "ADD", aux: "Int32"}, // arg0 + arg1<>auxInt, unsigned shift, set carry flag + {name: "ADDSshiftRA", argLength: 2, reg: gp21cf, asm: "ADD", aux: "Int32"}, // arg0 + arg1>>auxInt, signed shift, set carry flag + {name: "SUBSshiftLL", argLength: 2, reg: gp21cf, asm: "SUB", aux: "Int32"}, // arg0 - arg1<>auxInt, unsigned shift, set carry flag + {name: "SUBSshiftRA", argLength: 2, reg: gp21cf, asm: "SUB", aux: "Int32"}, // arg0 - arg1>>auxInt, signed shift, set carry flag + {name: "RSBSshiftLL", argLength: 2, reg: gp21cf, asm: "RSB", aux: "Int32"}, // arg1<>auxInt - arg0, unsigned shift, set carry flag + {name: "RSBSshiftRA", argLength: 2, reg: gp21cf, asm: "RSB", aux: "Int32"}, // arg1>>auxInt - arg0, signed shift, set carry flag + + {name: "ADDshiftLLreg", argLength: 3, reg: gp31, asm: "ADD"}, // arg0 + arg1<>arg2, unsigned shift + {name: "ADDshiftRAreg", argLength: 3, reg: gp31, asm: "ADD"}, // arg0 + arg1>>arg2, signed shift + {name: "SUBshiftLLreg", argLength: 3, reg: gp31, asm: "SUB"}, // arg0 - arg1<>arg2, unsigned shift + {name: "SUBshiftRAreg", argLength: 3, reg: gp31, asm: "SUB"}, // arg0 - arg1>>arg2, signed shift + {name: "RSBshiftLLreg", argLength: 3, reg: gp31, asm: "RSB"}, // arg1<>arg2 - arg0, unsigned shift + {name: "RSBshiftRAreg", argLength: 3, reg: gp31, asm: "RSB"}, // arg1>>arg2 - arg0, signed shift + {name: "ANDshiftLLreg", argLength: 3, reg: gp31, asm: "AND"}, // arg0 & (arg1<>arg2), unsigned shift + {name: "ANDshiftRAreg", argLength: 3, reg: gp31, asm: "AND"}, // arg0 & (arg1>>arg2), signed shift + {name: "ORshiftLLreg", argLength: 3, reg: gp31, asm: "ORR"}, // arg0 | arg1<>arg2, unsigned shift + {name: "ORshiftRAreg", argLength: 3, reg: gp31, asm: "ORR"}, // arg0 | arg1>>arg2, signed shift + {name: "XORshiftLLreg", argLength: 3, reg: gp31, asm: "EOR"}, // arg0 ^ arg1<>arg2, unsigned shift + {name: "XORshiftRAreg", argLength: 3, reg: gp31, asm: "EOR"}, // arg0 ^ arg1>>arg2, signed shift + {name: "BICshiftLLreg", argLength: 3, reg: gp31, asm: "BIC"}, // arg0 &^ (arg1<>arg2), unsigned shift + {name: "BICshiftRAreg", argLength: 3, reg: gp31, asm: "BIC"}, // arg0 &^ (arg1>>arg2), signed shift + {name: "MVNshiftLLreg", argLength: 2, reg: gp21, asm: "MVN"}, // ^(arg0<>arg1), unsigned shift + {name: "MVNshiftRAreg", argLength: 2, reg: gp21, asm: "MVN"}, // ^(arg0>>arg1), signed shift + + {name: "ADCshiftLLreg", argLength: 4, reg: gp3flags1, asm: "ADC"}, // arg0 + arg1<>arg2 + carry, unsigned shift, arg3=flags + {name: "ADCshiftRAreg", argLength: 4, reg: gp3flags1, asm: "ADC"}, // arg0 + arg1>>arg2 + carry, signed shift, arg3=flags + {name: "SBCshiftLLreg", argLength: 4, reg: gp3flags1, asm: "SBC"}, // arg0 - arg1<>arg2 - carry, unsigned shift, arg3=flags + {name: "SBCshiftRAreg", argLength: 4, reg: gp3flags1, asm: "SBC"}, // arg0 - arg1>>arg2 - carry, signed shift, arg3=flags + {name: "RSCshiftLLreg", argLength: 4, reg: gp3flags1, asm: "RSC"}, // arg1<>arg2 - arg0 - carry, unsigned shift, arg3=flags + {name: "RSCshiftRAreg", argLength: 4, reg: gp3flags1, asm: "RSC"}, // arg1>>arg2 - arg0 - carry, signed shift, arg3=flags + + {name: "ADDSshiftLLreg", argLength: 3, reg: gp31cf, asm: "ADD"}, // arg0 + arg1<>arg2, unsigned shift, set carry flag + {name: "ADDSshiftRAreg", argLength: 3, reg: gp31cf, asm: "ADD"}, // arg0 + arg1>>arg2, signed shift, set carry flag + {name: "SUBSshiftLLreg", argLength: 3, reg: gp31cf, asm: "SUB"}, // arg0 - arg1<>arg2, unsigned shift, set carry flag + {name: "SUBSshiftRAreg", argLength: 3, reg: gp31cf, asm: "SUB"}, // arg0 - arg1>>arg2, signed shift, set carry flag + {name: "RSBSshiftLLreg", argLength: 3, reg: gp31cf, asm: "RSB"}, // arg1<>arg2 - arg0, unsigned shift, set carry flag + {name: "RSBSshiftRAreg", argLength: 3, reg: gp31cf, asm: "RSB"}, // arg1>>arg2 - arg0, signed shift, set carry flag + + // comparisons {name: "CMP", argLength: 2, reg: gp2flags, asm: "CMP", typ: "Flags"}, // arg0 compare to arg1 {name: "CMPconst", argLength: 1, reg: gp1flags, asm: "CMP", aux: "Int32", typ: "Flags"}, // arg0 compare to auxInt {name: "CMN", argLength: 2, reg: gp2flags, asm: "CMN", typ: "Flags"}, // arg0 compare to -arg1 @@ -195,6 +291,15 @@ func init() { {name: "CMPF", argLength: 2, reg: fp2flags, asm: "CMPF", typ: "Flags"}, // arg0 compare to arg1, float32 {name: "CMPD", argLength: 2, reg: fp2flags, asm: "CMPD", typ: "Flags"}, // arg0 compare to arg1, float64 + {name: "CMPshiftLL", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int32", typ: "Flags"}, // arg0 compare to arg1<>auxInt, unsigned shift + {name: "CMPshiftRA", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int32", typ: "Flags"}, // arg0 compare to arg1>>auxInt, signed shift + + {name: "CMPshiftLLreg", argLength: 3, reg: gp3flags, asm: "CMP", typ: "Flags"}, // arg0 compare to arg1<>arg2, unsigned shift + {name: "CMPshiftRAreg", argLength: 3, reg: gp3flags, asm: "CMP", typ: "Flags"}, // arg0 compare to arg1>>arg2, signed shift + + // moves {name: "MOVWconst", argLength: 0, reg: gp01, aux: "Int32", asm: "MOVW", typ: "UInt32", rematerializeable: true}, // 32 low bits of auxint {name: "MOVFconst", argLength: 0, reg: fp01, aux: "Float64", asm: "MOVF", typ: "Float32", rematerializeable: true}, // auxint as 64-bit float, convert to 32-bit float {name: "MOVDconst", argLength: 0, reg: fp01, aux: "Float64", asm: "MOVD", typ: "Float64", rematerializeable: true}, // auxint as 64-bit float @@ -215,6 +320,16 @@ func init() { {name: "MOVFstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "MOVF", typ: "Mem"}, // store 4 bytes of arg1 to arg0 + auxInt + aux. arg2=mem. {name: "MOVDstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "MOVD", typ: "Mem"}, // store 8 bytes of arg1 to arg0 + auxInt + aux. arg2=mem. + {name: "MOVWloadidx", argLength: 3, reg: gp2load, asm: "MOVW"}, // load from arg0 + arg1. arg2=mem + {name: "MOVWloadshiftLL", argLength: 3, reg: gp2load, asm: "MOVW", aux: "Int32"}, // load from arg0 + arg1<>auxInt, unsigned shift. arg2=mem + {name: "MOVWloadshiftRA", argLength: 3, reg: gp2load, asm: "MOVW", aux: "Int32"}, // load from arg0 + arg1>>auxInt, signed shift. arg2=mem + + {name: "MOVWstoreidx", argLength: 4, reg: gp2store, asm: "MOVW"}, // store arg2 to arg0 + arg1. arg3=mem + {name: "MOVWstoreshiftLL", argLength: 4, reg: gp2store, asm: "MOVW", aux: "Int32"}, // store arg2 to arg0 + arg1<>auxInt, unsigned shift. arg3=mem + {name: "MOVWstoreshiftRA", argLength: 4, reg: gp2store, asm: "MOVW", aux: "Int32"}, // store arg2 to arg0 + arg1>>auxInt, signed shift. arg3=mem + {name: "MOVBreg", argLength: 1, reg: gp11, asm: "MOVBS"}, // move from arg0, sign-extended from byte {name: "MOVBUreg", argLength: 1, reg: gp11, asm: "MOVBU"}, // move from arg0, unsign-extended from byte {name: "MOVHreg", argLength: 1, reg: gp11, asm: "MOVHS"}, // move from arg0, sign-extended from half @@ -232,6 +347,12 @@ func init() { {name: "MOVFD", argLength: 1, reg: fp11, asm: "MOVFD"}, // float32 -> float64 {name: "MOVDF", argLength: 1, reg: fp11, asm: "MOVDF"}, // float64 -> float32 + // conditional instructions, for lowering shifts + {name: "CMOVWHSconst", argLength: 2, reg: gp1flags1, asm: "MOVW", aux: "Int32", resultInArg0: true}, // replace arg0 w/ const if flags indicates HS, arg1=flags + {name: "CMOVWLSconst", argLength: 2, reg: gp1flags1, asm: "MOVW", aux: "Int32", resultInArg0: true}, // replace arg0 w/ const if flags indicates LS, arg1=flags + {name: "SRAcond", argLength: 3, reg: gp2flags1, asm: "SRA"}, // arg0 >> 31 if flags indicates HS, arg0 >> arg1 otherwise, signed shift, arg2=flags + + // function calls {name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "SymOff"}, // call static function aux.(*gc.Sym). arg0=mem, auxint=argsize, returns mem {name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{gpsp, buildReg("R7"), 0}, clobbers: callerSave}, aux: "Int64"}, // call function via closure. arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem {name: "CALLdefer", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "Int64"}, // call deferproc. arg0=mem, auxint=argsize, returns mem @@ -256,8 +377,6 @@ func init() { {name: "LoweredSelect0", argLength: 1, reg: regInfo{inputs: []regMask{}, outputs: []regMask{buildReg("R0")}}}, // the first component of a tuple, implicitly in R0, arg0=tuple {name: "LoweredSelect1", argLength: 1, reg: regInfo{inputs: []regMask{gp}, outputs: []regMask{gp}}, resultInArg0: true}, // the second component of a tuple, arg0=tuple - {name: "LoweredZeromask", argLength: 1, reg: gp11}, // 0 if arg0 == 1, 0xffffffff if arg0 != 0 - // duffzero (must be 4-byte aligned) // arg0 = address of memory to zero (in R1, changed as side effect) // arg1 = value to store (always zero) diff --git a/src/cmd/compile/internal/ssa/op.go b/src/cmd/compile/internal/ssa/op.go index 07c439de4b..a7c2b6e3de 100644 --- a/src/cmd/compile/internal/ssa/op.go +++ b/src/cmd/compile/internal/ssa/op.go @@ -157,7 +157,13 @@ func (op Op) isTupleGenerator() bool { switch op { case OpAdd32carry, OpSub32carry, OpMul32uhilo, OpARMADDS, OpARMSUBS, OpARMMULLU, - OpARMADDSconst, OpARMSUBSconst, OpARMRSBSconst: + OpARMADDSconst, OpARMSUBSconst, OpARMRSBSconst, + OpARMADDSshiftLL, OpARMSUBSshiftLL, OpARMRSBSshiftLL, + OpARMADDSshiftRL, OpARMSUBSshiftRL, OpARMRSBSshiftRL, + OpARMADDSshiftRA, OpARMSUBSshiftRA, OpARMRSBSshiftRA, + OpARMADDSshiftLLreg, OpARMSUBSshiftLLreg, OpARMRSBSshiftLLreg, + OpARMADDSshiftRLreg, OpARMSUBSshiftRLreg, OpARMRSBSshiftRLreg, + OpARMADDSshiftRAreg, OpARMSUBSshiftRAreg, OpARMRSBSshiftRAreg: return true } return false diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go index 7ea67a99b9..159e1b26b4 100644 --- a/src/cmd/compile/internal/ssa/opGen.go +++ b/src/cmd/compile/internal/ssa/opGen.go @@ -596,6 +596,90 @@ const ( OpARMSRA OpARMSRAconst OpARMSRRconst + OpARMADDshiftLL + OpARMADDshiftRL + OpARMADDshiftRA + OpARMSUBshiftLL + OpARMSUBshiftRL + OpARMSUBshiftRA + OpARMRSBshiftLL + OpARMRSBshiftRL + OpARMRSBshiftRA + OpARMANDshiftLL + OpARMANDshiftRL + OpARMANDshiftRA + OpARMORshiftLL + OpARMORshiftRL + OpARMORshiftRA + OpARMXORshiftLL + OpARMXORshiftRL + OpARMXORshiftRA + OpARMBICshiftLL + OpARMBICshiftRL + OpARMBICshiftRA + OpARMMVNshiftLL + OpARMMVNshiftRL + OpARMMVNshiftRA + OpARMADCshiftLL + OpARMADCshiftRL + OpARMADCshiftRA + OpARMSBCshiftLL + OpARMSBCshiftRL + OpARMSBCshiftRA + OpARMRSCshiftLL + OpARMRSCshiftRL + OpARMRSCshiftRA + OpARMADDSshiftLL + OpARMADDSshiftRL + OpARMADDSshiftRA + OpARMSUBSshiftLL + OpARMSUBSshiftRL + OpARMSUBSshiftRA + OpARMRSBSshiftLL + OpARMRSBSshiftRL + OpARMRSBSshiftRA + OpARMADDshiftLLreg + OpARMADDshiftRLreg + OpARMADDshiftRAreg + OpARMSUBshiftLLreg + OpARMSUBshiftRLreg + OpARMSUBshiftRAreg + OpARMRSBshiftLLreg + OpARMRSBshiftRLreg + OpARMRSBshiftRAreg + OpARMANDshiftLLreg + OpARMANDshiftRLreg + OpARMANDshiftRAreg + OpARMORshiftLLreg + OpARMORshiftRLreg + OpARMORshiftRAreg + OpARMXORshiftLLreg + OpARMXORshiftRLreg + OpARMXORshiftRAreg + OpARMBICshiftLLreg + OpARMBICshiftRLreg + OpARMBICshiftRAreg + OpARMMVNshiftLLreg + OpARMMVNshiftRLreg + OpARMMVNshiftRAreg + OpARMADCshiftLLreg + OpARMADCshiftRLreg + OpARMADCshiftRAreg + OpARMSBCshiftLLreg + OpARMSBCshiftRLreg + OpARMSBCshiftRAreg + OpARMRSCshiftLLreg + OpARMRSCshiftRLreg + OpARMRSCshiftRAreg + OpARMADDSshiftLLreg + OpARMADDSshiftRLreg + OpARMADDSshiftRAreg + OpARMSUBSshiftLLreg + OpARMSUBSshiftRLreg + OpARMSUBSshiftRAreg + OpARMRSBSshiftLLreg + OpARMRSBSshiftRLreg + OpARMRSBSshiftRAreg OpARMCMP OpARMCMPconst OpARMCMN @@ -606,6 +690,12 @@ const ( OpARMTEQconst OpARMCMPF OpARMCMPD + OpARMCMPshiftLL + OpARMCMPshiftRL + OpARMCMPshiftRA + OpARMCMPshiftLLreg + OpARMCMPshiftRLreg + OpARMCMPshiftRAreg OpARMMOVWconst OpARMMOVFconst OpARMMOVDconst @@ -622,6 +712,14 @@ const ( OpARMMOVWstore OpARMMOVFstore OpARMMOVDstore + OpARMMOVWloadidx + OpARMMOVWloadshiftLL + OpARMMOVWloadshiftRL + OpARMMOVWloadshiftRA + OpARMMOVWstoreidx + OpARMMOVWstoreshiftLL + OpARMMOVWstoreshiftRL + OpARMMOVWstoreshiftRA OpARMMOVBreg OpARMMOVBUreg OpARMMOVHreg @@ -637,6 +735,9 @@ const ( OpARMMOVDWU OpARMMOVFD OpARMMOVDF + OpARMCMOVWHSconst + OpARMCMOVWLSconst + OpARMSRAcond OpARMCALLstatic OpARMCALLclosure OpARMCALLdefer @@ -656,7 +757,6 @@ const ( OpARMCarry OpARMLoweredSelect0 OpARMLoweredSelect1 - OpARMLoweredZeromask OpARMDUFFZERO OpARMDUFFCOPY OpARMLoweredZero @@ -7155,7 +7255,6 @@ var opcodeTable = [...]opInfo{ {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 }, - clobbers: 4294967296, // FLAGS outputs: []regMask{ 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 }, @@ -7184,7 +7283,6 @@ var opcodeTable = [...]opInfo{ {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 }, - clobbers: 4294967296, // FLAGS outputs: []regMask{ 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 }, @@ -7246,6 +7344,1296 @@ var opcodeTable = [...]opInfo{ }, }, }, + { + name: "ADDshiftLL", + auxType: auxInt32, + argLen: 2, + asm: arm.AADD, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "ADDshiftRL", + auxType: auxInt32, + argLen: 2, + asm: arm.AADD, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "ADDshiftRA", + auxType: auxInt32, + argLen: 2, + asm: arm.AADD, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "SUBshiftLL", + auxType: auxInt32, + argLen: 2, + asm: arm.ASUB, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "SUBshiftRL", + auxType: auxInt32, + argLen: 2, + asm: arm.ASUB, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "SUBshiftRA", + auxType: auxInt32, + argLen: 2, + asm: arm.ASUB, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "RSBshiftLL", + auxType: auxInt32, + argLen: 2, + asm: arm.ARSB, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "RSBshiftRL", + auxType: auxInt32, + argLen: 2, + asm: arm.ARSB, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "RSBshiftRA", + auxType: auxInt32, + argLen: 2, + asm: arm.ARSB, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "ANDshiftLL", + auxType: auxInt32, + argLen: 2, + asm: arm.AAND, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "ANDshiftRL", + auxType: auxInt32, + argLen: 2, + asm: arm.AAND, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "ANDshiftRA", + auxType: auxInt32, + argLen: 2, + asm: arm.AAND, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "ORshiftLL", + auxType: auxInt32, + argLen: 2, + asm: arm.AORR, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "ORshiftRL", + auxType: auxInt32, + argLen: 2, + asm: arm.AORR, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "ORshiftRA", + auxType: auxInt32, + argLen: 2, + asm: arm.AORR, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "XORshiftLL", + auxType: auxInt32, + argLen: 2, + asm: arm.AEOR, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "XORshiftRL", + auxType: auxInt32, + argLen: 2, + asm: arm.AEOR, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "XORshiftRA", + auxType: auxInt32, + argLen: 2, + asm: arm.AEOR, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "BICshiftLL", + auxType: auxInt32, + argLen: 2, + asm: arm.ABIC, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "BICshiftRL", + auxType: auxInt32, + argLen: 2, + asm: arm.ABIC, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "BICshiftRA", + auxType: auxInt32, + argLen: 2, + asm: arm.ABIC, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "MVNshiftLL", + auxType: auxInt32, + argLen: 1, + asm: arm.AMVN, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "MVNshiftRL", + auxType: auxInt32, + argLen: 1, + asm: arm.AMVN, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "MVNshiftRA", + auxType: auxInt32, + argLen: 1, + asm: arm.AMVN, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "ADCshiftLL", + auxType: auxInt32, + argLen: 3, + asm: arm.AADC, + reg: regInfo{ + inputs: []inputInfo{ + {2, 4294967296}, // FLAGS + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "ADCshiftRL", + auxType: auxInt32, + argLen: 3, + asm: arm.AADC, + reg: regInfo{ + inputs: []inputInfo{ + {2, 4294967296}, // FLAGS + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "ADCshiftRA", + auxType: auxInt32, + argLen: 3, + asm: arm.AADC, + reg: regInfo{ + inputs: []inputInfo{ + {2, 4294967296}, // FLAGS + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "SBCshiftLL", + auxType: auxInt32, + argLen: 3, + asm: arm.ASBC, + reg: regInfo{ + inputs: []inputInfo{ + {2, 4294967296}, // FLAGS + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "SBCshiftRL", + auxType: auxInt32, + argLen: 3, + asm: arm.ASBC, + reg: regInfo{ + inputs: []inputInfo{ + {2, 4294967296}, // FLAGS + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "SBCshiftRA", + auxType: auxInt32, + argLen: 3, + asm: arm.ASBC, + reg: regInfo{ + inputs: []inputInfo{ + {2, 4294967296}, // FLAGS + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "RSCshiftLL", + auxType: auxInt32, + argLen: 3, + asm: arm.ARSC, + reg: regInfo{ + inputs: []inputInfo{ + {2, 4294967296}, // FLAGS + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "RSCshiftRL", + auxType: auxInt32, + argLen: 3, + asm: arm.ARSC, + reg: regInfo{ + inputs: []inputInfo{ + {2, 4294967296}, // FLAGS + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "RSCshiftRA", + auxType: auxInt32, + argLen: 3, + asm: arm.ARSC, + reg: regInfo{ + inputs: []inputInfo{ + {2, 4294967296}, // FLAGS + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "ADDSshiftLL", + auxType: auxInt32, + argLen: 2, + asm: arm.AADD, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + clobbers: 4294967296, // FLAGS + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "ADDSshiftRL", + auxType: auxInt32, + argLen: 2, + asm: arm.AADD, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + clobbers: 4294967296, // FLAGS + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "ADDSshiftRA", + auxType: auxInt32, + argLen: 2, + asm: arm.AADD, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + clobbers: 4294967296, // FLAGS + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "SUBSshiftLL", + auxType: auxInt32, + argLen: 2, + asm: arm.ASUB, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + clobbers: 4294967296, // FLAGS + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "SUBSshiftRL", + auxType: auxInt32, + argLen: 2, + asm: arm.ASUB, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + clobbers: 4294967296, // FLAGS + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "SUBSshiftRA", + auxType: auxInt32, + argLen: 2, + asm: arm.ASUB, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + clobbers: 4294967296, // FLAGS + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "RSBSshiftLL", + auxType: auxInt32, + argLen: 2, + asm: arm.ARSB, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + clobbers: 4294967296, // FLAGS + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "RSBSshiftRL", + auxType: auxInt32, + argLen: 2, + asm: arm.ARSB, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + clobbers: 4294967296, // FLAGS + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "RSBSshiftRA", + auxType: auxInt32, + argLen: 2, + asm: arm.ARSB, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + clobbers: 4294967296, // FLAGS + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "ADDshiftLLreg", + argLen: 3, + asm: arm.AADD, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "ADDshiftRLreg", + argLen: 3, + asm: arm.AADD, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "ADDshiftRAreg", + argLen: 3, + asm: arm.AADD, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "SUBshiftLLreg", + argLen: 3, + asm: arm.ASUB, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "SUBshiftRLreg", + argLen: 3, + asm: arm.ASUB, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "SUBshiftRAreg", + argLen: 3, + asm: arm.ASUB, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "RSBshiftLLreg", + argLen: 3, + asm: arm.ARSB, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "RSBshiftRLreg", + argLen: 3, + asm: arm.ARSB, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "RSBshiftRAreg", + argLen: 3, + asm: arm.ARSB, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "ANDshiftLLreg", + argLen: 3, + asm: arm.AAND, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "ANDshiftRLreg", + argLen: 3, + asm: arm.AAND, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "ANDshiftRAreg", + argLen: 3, + asm: arm.AAND, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "ORshiftLLreg", + argLen: 3, + asm: arm.AORR, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "ORshiftRLreg", + argLen: 3, + asm: arm.AORR, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "ORshiftRAreg", + argLen: 3, + asm: arm.AORR, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "XORshiftLLreg", + argLen: 3, + asm: arm.AEOR, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "XORshiftRLreg", + argLen: 3, + asm: arm.AEOR, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "XORshiftRAreg", + argLen: 3, + asm: arm.AEOR, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "BICshiftLLreg", + argLen: 3, + asm: arm.ABIC, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "BICshiftRLreg", + argLen: 3, + asm: arm.ABIC, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "BICshiftRAreg", + argLen: 3, + asm: arm.ABIC, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "MVNshiftLLreg", + argLen: 2, + asm: arm.AMVN, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "MVNshiftRLreg", + argLen: 2, + asm: arm.AMVN, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "MVNshiftRAreg", + argLen: 2, + asm: arm.AMVN, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "ADCshiftLLreg", + argLen: 4, + asm: arm.AADC, + reg: regInfo{ + inputs: []inputInfo{ + {3, 4294967296}, // FLAGS + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "ADCshiftRLreg", + argLen: 4, + asm: arm.AADC, + reg: regInfo{ + inputs: []inputInfo{ + {3, 4294967296}, // FLAGS + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "ADCshiftRAreg", + argLen: 4, + asm: arm.AADC, + reg: regInfo{ + inputs: []inputInfo{ + {3, 4294967296}, // FLAGS + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "SBCshiftLLreg", + argLen: 4, + asm: arm.ASBC, + reg: regInfo{ + inputs: []inputInfo{ + {3, 4294967296}, // FLAGS + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "SBCshiftRLreg", + argLen: 4, + asm: arm.ASBC, + reg: regInfo{ + inputs: []inputInfo{ + {3, 4294967296}, // FLAGS + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "SBCshiftRAreg", + argLen: 4, + asm: arm.ASBC, + reg: regInfo{ + inputs: []inputInfo{ + {3, 4294967296}, // FLAGS + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "RSCshiftLLreg", + argLen: 4, + asm: arm.ARSC, + reg: regInfo{ + inputs: []inputInfo{ + {3, 4294967296}, // FLAGS + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "RSCshiftRLreg", + argLen: 4, + asm: arm.ARSC, + reg: regInfo{ + inputs: []inputInfo{ + {3, 4294967296}, // FLAGS + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "RSCshiftRAreg", + argLen: 4, + asm: arm.ARSC, + reg: regInfo{ + inputs: []inputInfo{ + {3, 4294967296}, // FLAGS + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "ADDSshiftLLreg", + argLen: 3, + asm: arm.AADD, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + clobbers: 4294967296, // FLAGS + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "ADDSshiftRLreg", + argLen: 3, + asm: arm.AADD, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + clobbers: 4294967296, // FLAGS + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "ADDSshiftRAreg", + argLen: 3, + asm: arm.AADD, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + clobbers: 4294967296, // FLAGS + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "SUBSshiftLLreg", + argLen: 3, + asm: arm.ASUB, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + clobbers: 4294967296, // FLAGS + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "SUBSshiftRLreg", + argLen: 3, + asm: arm.ASUB, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + clobbers: 4294967296, // FLAGS + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "SUBSshiftRAreg", + argLen: 3, + asm: arm.ASUB, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + clobbers: 4294967296, // FLAGS + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "RSBSshiftLLreg", + argLen: 3, + asm: arm.ARSB, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + clobbers: 4294967296, // FLAGS + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "RSBSshiftRLreg", + argLen: 3, + asm: arm.ARSB, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + clobbers: 4294967296, // FLAGS + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "RSBSshiftRAreg", + argLen: 3, + asm: arm.ARSB, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + clobbers: 4294967296, // FLAGS + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, { name: "CMP", argLen: 2, @@ -7388,6 +8776,96 @@ var opcodeTable = [...]opInfo{ }, }, }, + { + name: "CMPshiftLL", + auxType: auxInt32, + argLen: 2, + asm: arm.ACMP, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + outputs: []regMask{ + 4294967296, // FLAGS + }, + }, + }, + { + name: "CMPshiftRL", + auxType: auxInt32, + argLen: 2, + asm: arm.ACMP, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + outputs: []regMask{ + 4294967296, // FLAGS + }, + }, + }, + { + name: "CMPshiftRA", + auxType: auxInt32, + argLen: 2, + asm: arm.ACMP, + reg: regInfo{ + inputs: []inputInfo{ + {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + }, + outputs: []regMask{ + 4294967296, // FLAGS + }, + }, + }, + { + name: "CMPshiftLLreg", + argLen: 3, + asm: arm.ACMP, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 4294967296, // FLAGS + }, + }, + }, + { + name: "CMPshiftRLreg", + argLen: 3, + asm: arm.ACMP, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 4294967296, // FLAGS + }, + }, + }, + { + name: "CMPshiftRAreg", + argLen: 3, + asm: arm.ACMP, + reg: regInfo{ + inputs: []inputInfo{ + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 4294967296, // FLAGS + }, + }, + }, { name: "MOVWconst", auxType: auxInt32, @@ -7597,6 +9075,116 @@ var opcodeTable = [...]opInfo{ }, }, }, + { + name: "MOVWloadidx", + argLen: 3, + asm: arm.AMOVW, + reg: regInfo{ + inputs: []inputInfo{ + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {0, 8589948927}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 SP SB + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "MOVWloadshiftLL", + auxType: auxInt32, + argLen: 3, + asm: arm.AMOVW, + reg: regInfo{ + inputs: []inputInfo{ + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {0, 8589948927}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 SP SB + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "MOVWloadshiftRL", + auxType: auxInt32, + argLen: 3, + asm: arm.AMOVW, + reg: regInfo{ + inputs: []inputInfo{ + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {0, 8589948927}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 SP SB + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "MOVWloadshiftRA", + auxType: auxInt32, + argLen: 3, + asm: arm.AMOVW, + reg: regInfo{ + inputs: []inputInfo{ + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {0, 8589948927}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 SP SB + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "MOVWstoreidx", + argLen: 4, + asm: arm.AMOVW, + reg: regInfo{ + inputs: []inputInfo{ + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {2, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {0, 8589948927}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 SP SB + }, + }, + }, + { + name: "MOVWstoreshiftLL", + auxType: auxInt32, + argLen: 4, + asm: arm.AMOVW, + reg: regInfo{ + inputs: []inputInfo{ + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {2, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {0, 8589948927}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 SP SB + }, + }, + }, + { + name: "MOVWstoreshiftRL", + auxType: auxInt32, + argLen: 4, + asm: arm.AMOVW, + reg: regInfo{ + inputs: []inputInfo{ + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {2, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {0, 8589948927}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 SP SB + }, + }, + }, + { + name: "MOVWstoreshiftRA", + auxType: auxInt32, + argLen: 4, + asm: arm.AMOVW, + reg: regInfo{ + inputs: []inputInfo{ + {1, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {2, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 + {0, 8589948927}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 SP SB + }, + }, + }, { name: "MOVBreg", argLen: 1, @@ -7792,6 +9380,53 @@ var opcodeTable = [...]opInfo{ }, }, }, + { + name: "CMOVWHSconst", + auxType: auxInt32, + argLen: 2, + resultInArg0: true, + asm: arm.AMOVW, + reg: regInfo{ + inputs: []inputInfo{ + {1, 4294967296}, // FLAGS + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "CMOVWLSconst", + auxType: auxInt32, + argLen: 2, + resultInArg0: true, + asm: arm.AMOVW, + reg: regInfo{ + inputs: []inputInfo{ + {1, 4294967296}, // FLAGS + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, + { + name: "SRAcond", + argLen: 3, + asm: arm.ASRA, + reg: regInfo{ + inputs: []inputInfo{ + {2, 4294967296}, // FLAGS + {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + outputs: []regMask{ + 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 + }, + }, + }, { name: "CALLstatic", auxType: auxSymOff, @@ -7999,18 +9634,6 @@ var opcodeTable = [...]opInfo{ }, }, }, - { - name: "LoweredZeromask", - argLen: 1, - reg: regInfo{ - inputs: []inputInfo{ - {0, 6143}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 - }, - outputs: []regMask{ - 5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 - }, - }, - }, { name: "DUFFZERO", auxType: auxInt64, diff --git a/src/cmd/compile/internal/ssa/rewriteARM.go b/src/cmd/compile/internal/ssa/rewriteARM.go index c36976c953..ceac5839ef 100644 --- a/src/cmd/compile/internal/ssa/rewriteARM.go +++ b/src/cmd/compile/internal/ssa/rewriteARM.go @@ -12,16 +12,64 @@ func rewriteValueARM(v *Value, config *Config) bool { return rewriteValueARM_OpARMADC(v, config) case OpARMADCconst: return rewriteValueARM_OpARMADCconst(v, config) + case OpARMADCshiftLL: + return rewriteValueARM_OpARMADCshiftLL(v, config) + case OpARMADCshiftLLreg: + return rewriteValueARM_OpARMADCshiftLLreg(v, config) + case OpARMADCshiftRA: + return rewriteValueARM_OpARMADCshiftRA(v, config) + case OpARMADCshiftRAreg: + return rewriteValueARM_OpARMADCshiftRAreg(v, config) + case OpARMADCshiftRL: + return rewriteValueARM_OpARMADCshiftRL(v, config) + case OpARMADCshiftRLreg: + return rewriteValueARM_OpARMADCshiftRLreg(v, config) case OpARMADD: return rewriteValueARM_OpARMADD(v, config) case OpARMADDS: return rewriteValueARM_OpARMADDS(v, config) + case OpARMADDSshiftLL: + return rewriteValueARM_OpARMADDSshiftLL(v, config) + case OpARMADDSshiftLLreg: + return rewriteValueARM_OpARMADDSshiftLLreg(v, config) + case OpARMADDSshiftRA: + return rewriteValueARM_OpARMADDSshiftRA(v, config) + case OpARMADDSshiftRAreg: + return rewriteValueARM_OpARMADDSshiftRAreg(v, config) + case OpARMADDSshiftRL: + return rewriteValueARM_OpARMADDSshiftRL(v, config) + case OpARMADDSshiftRLreg: + return rewriteValueARM_OpARMADDSshiftRLreg(v, config) case OpARMADDconst: return rewriteValueARM_OpARMADDconst(v, config) + case OpARMADDshiftLL: + return rewriteValueARM_OpARMADDshiftLL(v, config) + case OpARMADDshiftLLreg: + return rewriteValueARM_OpARMADDshiftLLreg(v, config) + case OpARMADDshiftRA: + return rewriteValueARM_OpARMADDshiftRA(v, config) + case OpARMADDshiftRAreg: + return rewriteValueARM_OpARMADDshiftRAreg(v, config) + case OpARMADDshiftRL: + return rewriteValueARM_OpARMADDshiftRL(v, config) + case OpARMADDshiftRLreg: + return rewriteValueARM_OpARMADDshiftRLreg(v, config) case OpARMAND: return rewriteValueARM_OpARMAND(v, config) case OpARMANDconst: return rewriteValueARM_OpARMANDconst(v, config) + case OpARMANDshiftLL: + return rewriteValueARM_OpARMANDshiftLL(v, config) + case OpARMANDshiftLLreg: + return rewriteValueARM_OpARMANDshiftLLreg(v, config) + case OpARMANDshiftRA: + return rewriteValueARM_OpARMANDshiftRA(v, config) + case OpARMANDshiftRAreg: + return rewriteValueARM_OpARMANDshiftRAreg(v, config) + case OpARMANDshiftRL: + return rewriteValueARM_OpARMANDshiftRL(v, config) + case OpARMANDshiftRLreg: + return rewriteValueARM_OpARMANDshiftRLreg(v, config) case OpAdd16: return rewriteValueARM_OpAdd16(v, config) case OpAdd32: @@ -52,10 +100,38 @@ func rewriteValueARM(v *Value, config *Config) bool { return rewriteValueARM_OpARMBIC(v, config) case OpARMBICconst: return rewriteValueARM_OpARMBICconst(v, config) + case OpARMBICshiftLL: + return rewriteValueARM_OpARMBICshiftLL(v, config) + case OpARMBICshiftLLreg: + return rewriteValueARM_OpARMBICshiftLLreg(v, config) + case OpARMBICshiftRA: + return rewriteValueARM_OpARMBICshiftRA(v, config) + case OpARMBICshiftRAreg: + return rewriteValueARM_OpARMBICshiftRAreg(v, config) + case OpARMBICshiftRL: + return rewriteValueARM_OpARMBICshiftRL(v, config) + case OpARMBICshiftRLreg: + return rewriteValueARM_OpARMBICshiftRLreg(v, config) + case OpARMCMOVWHSconst: + return rewriteValueARM_OpARMCMOVWHSconst(v, config) + case OpARMCMOVWLSconst: + return rewriteValueARM_OpARMCMOVWLSconst(v, config) case OpARMCMP: return rewriteValueARM_OpARMCMP(v, config) case OpARMCMPconst: return rewriteValueARM_OpARMCMPconst(v, config) + case OpARMCMPshiftLL: + return rewriteValueARM_OpARMCMPshiftLL(v, config) + case OpARMCMPshiftLLreg: + return rewriteValueARM_OpARMCMPshiftLLreg(v, config) + case OpARMCMPshiftRA: + return rewriteValueARM_OpARMCMPshiftRA(v, config) + case OpARMCMPshiftRAreg: + return rewriteValueARM_OpARMCMPshiftRAreg(v, config) + case OpARMCMPshiftRL: + return rewriteValueARM_OpARMCMPshiftRL(v, config) + case OpARMCMPshiftRLreg: + return rewriteValueARM_OpARMCMPshiftRLreg(v, config) case OpClosureCall: return rewriteValueARM_OpClosureCall(v, config) case OpCom16: @@ -244,8 +320,6 @@ func rewriteValueARM(v *Value, config *Config) bool { return rewriteValueARM_OpARMLessThanU(v, config) case OpLoad: return rewriteValueARM_OpLoad(v, config) - case OpARMLoweredZeromask: - return rewriteValueARM_OpARMLoweredZeromask(v, config) case OpLrot16: return rewriteValueARM_OpLrot16(v, config) case OpLrot32: @@ -306,14 +380,44 @@ func rewriteValueARM(v *Value, config *Config) bool { return rewriteValueARM_OpARMMOVHstore(v, config) case OpARMMOVWload: return rewriteValueARM_OpARMMOVWload(v, config) + case OpARMMOVWloadidx: + return rewriteValueARM_OpARMMOVWloadidx(v, config) + case OpARMMOVWloadshiftLL: + return rewriteValueARM_OpARMMOVWloadshiftLL(v, config) + case OpARMMOVWloadshiftRA: + return rewriteValueARM_OpARMMOVWloadshiftRA(v, config) + case OpARMMOVWloadshiftRL: + return rewriteValueARM_OpARMMOVWloadshiftRL(v, config) + case OpARMMOVWreg: + return rewriteValueARM_OpARMMOVWreg(v, config) case OpARMMOVWstore: return rewriteValueARM_OpARMMOVWstore(v, config) + case OpARMMOVWstoreidx: + return rewriteValueARM_OpARMMOVWstoreidx(v, config) + case OpARMMOVWstoreshiftLL: + return rewriteValueARM_OpARMMOVWstoreshiftLL(v, config) + case OpARMMOVWstoreshiftRA: + return rewriteValueARM_OpARMMOVWstoreshiftRA(v, config) + case OpARMMOVWstoreshiftRL: + return rewriteValueARM_OpARMMOVWstoreshiftRL(v, config) case OpARMMUL: return rewriteValueARM_OpARMMUL(v, config) case OpARMMULA: return rewriteValueARM_OpARMMULA(v, config) case OpARMMVN: return rewriteValueARM_OpARMMVN(v, config) + case OpARMMVNshiftLL: + return rewriteValueARM_OpARMMVNshiftLL(v, config) + case OpARMMVNshiftLLreg: + return rewriteValueARM_OpARMMVNshiftLLreg(v, config) + case OpARMMVNshiftRA: + return rewriteValueARM_OpARMMVNshiftRA(v, config) + case OpARMMVNshiftRAreg: + return rewriteValueARM_OpARMMVNshiftRAreg(v, config) + case OpARMMVNshiftRL: + return rewriteValueARM_OpARMMVNshiftRL(v, config) + case OpARMMVNshiftRLreg: + return rewriteValueARM_OpARMMVNshiftRLreg(v, config) case OpMod16: return rewriteValueARM_OpMod16(v, config) case OpMod16u: @@ -374,6 +478,18 @@ func rewriteValueARM(v *Value, config *Config) bool { return rewriteValueARM_OpARMOR(v, config) case OpARMORconst: return rewriteValueARM_OpARMORconst(v, config) + case OpARMORshiftLL: + return rewriteValueARM_OpARMORshiftLL(v, config) + case OpARMORshiftLLreg: + return rewriteValueARM_OpARMORshiftLLreg(v, config) + case OpARMORshiftRA: + return rewriteValueARM_OpARMORshiftRA(v, config) + case OpARMORshiftRAreg: + return rewriteValueARM_OpARMORshiftRAreg(v, config) + case OpARMORshiftRL: + return rewriteValueARM_OpARMORshiftRL(v, config) + case OpARMORshiftRLreg: + return rewriteValueARM_OpARMORshiftRLreg(v, config) case OpOffPtr: return rewriteValueARM_OpOffPtr(v, config) case OpOr16: @@ -386,10 +502,46 @@ func rewriteValueARM(v *Value, config *Config) bool { return rewriteValueARM_OpOrB(v, config) case OpARMRSB: return rewriteValueARM_OpARMRSB(v, config) + case OpARMRSBSshiftLL: + return rewriteValueARM_OpARMRSBSshiftLL(v, config) + case OpARMRSBSshiftLLreg: + return rewriteValueARM_OpARMRSBSshiftLLreg(v, config) + case OpARMRSBSshiftRA: + return rewriteValueARM_OpARMRSBSshiftRA(v, config) + case OpARMRSBSshiftRAreg: + return rewriteValueARM_OpARMRSBSshiftRAreg(v, config) + case OpARMRSBSshiftRL: + return rewriteValueARM_OpARMRSBSshiftRL(v, config) + case OpARMRSBSshiftRLreg: + return rewriteValueARM_OpARMRSBSshiftRLreg(v, config) case OpARMRSBconst: return rewriteValueARM_OpARMRSBconst(v, config) + case OpARMRSBshiftLL: + return rewriteValueARM_OpARMRSBshiftLL(v, config) + case OpARMRSBshiftLLreg: + return rewriteValueARM_OpARMRSBshiftLLreg(v, config) + case OpARMRSBshiftRA: + return rewriteValueARM_OpARMRSBshiftRA(v, config) + case OpARMRSBshiftRAreg: + return rewriteValueARM_OpARMRSBshiftRAreg(v, config) + case OpARMRSBshiftRL: + return rewriteValueARM_OpARMRSBshiftRL(v, config) + case OpARMRSBshiftRLreg: + return rewriteValueARM_OpARMRSBshiftRLreg(v, config) case OpARMRSCconst: return rewriteValueARM_OpARMRSCconst(v, config) + case OpARMRSCshiftLL: + return rewriteValueARM_OpARMRSCshiftLL(v, config) + case OpARMRSCshiftLLreg: + return rewriteValueARM_OpARMRSCshiftLLreg(v, config) + case OpARMRSCshiftRA: + return rewriteValueARM_OpARMRSCshiftRA(v, config) + case OpARMRSCshiftRAreg: + return rewriteValueARM_OpARMRSCshiftRAreg(v, config) + case OpARMRSCshiftRL: + return rewriteValueARM_OpARMRSCshiftRL(v, config) + case OpARMRSCshiftRLreg: + return rewriteValueARM_OpARMRSCshiftRLreg(v, config) case OpRsh16Ux16: return rewriteValueARM_OpRsh16Ux16(v, config) case OpRsh16Ux32: @@ -442,12 +594,26 @@ func rewriteValueARM(v *Value, config *Config) bool { return rewriteValueARM_OpARMSBC(v, config) case OpARMSBCconst: return rewriteValueARM_OpARMSBCconst(v, config) + case OpARMSBCshiftLL: + return rewriteValueARM_OpARMSBCshiftLL(v, config) + case OpARMSBCshiftLLreg: + return rewriteValueARM_OpARMSBCshiftLLreg(v, config) + case OpARMSBCshiftRA: + return rewriteValueARM_OpARMSBCshiftRA(v, config) + case OpARMSBCshiftRAreg: + return rewriteValueARM_OpARMSBCshiftRAreg(v, config) + case OpARMSBCshiftRL: + return rewriteValueARM_OpARMSBCshiftRL(v, config) + case OpARMSBCshiftRLreg: + return rewriteValueARM_OpARMSBCshiftRLreg(v, config) case OpARMSLL: return rewriteValueARM_OpARMSLL(v, config) case OpARMSLLconst: return rewriteValueARM_OpARMSLLconst(v, config) case OpARMSRA: return rewriteValueARM_OpARMSRA(v, config) + case OpARMSRAcond: + return rewriteValueARM_OpARMSRAcond(v, config) case OpARMSRAconst: return rewriteValueARM_OpARMSRAconst(v, config) case OpARMSRL: @@ -458,8 +624,32 @@ func rewriteValueARM(v *Value, config *Config) bool { return rewriteValueARM_OpARMSUB(v, config) case OpARMSUBS: return rewriteValueARM_OpARMSUBS(v, config) + case OpARMSUBSshiftLL: + return rewriteValueARM_OpARMSUBSshiftLL(v, config) + case OpARMSUBSshiftLLreg: + return rewriteValueARM_OpARMSUBSshiftLLreg(v, config) + case OpARMSUBSshiftRA: + return rewriteValueARM_OpARMSUBSshiftRA(v, config) + case OpARMSUBSshiftRAreg: + return rewriteValueARM_OpARMSUBSshiftRAreg(v, config) + case OpARMSUBSshiftRL: + return rewriteValueARM_OpARMSUBSshiftRL(v, config) + case OpARMSUBSshiftRLreg: + return rewriteValueARM_OpARMSUBSshiftRLreg(v, config) case OpARMSUBconst: return rewriteValueARM_OpARMSUBconst(v, config) + case OpARMSUBshiftLL: + return rewriteValueARM_OpARMSUBshiftLL(v, config) + case OpARMSUBshiftLLreg: + return rewriteValueARM_OpARMSUBshiftLLreg(v, config) + case OpARMSUBshiftRA: + return rewriteValueARM_OpARMSUBshiftRA(v, config) + case OpARMSUBshiftRAreg: + return rewriteValueARM_OpARMSUBshiftRAreg(v, config) + case OpARMSUBshiftRL: + return rewriteValueARM_OpARMSUBshiftRL(v, config) + case OpARMSUBshiftRLreg: + return rewriteValueARM_OpARMSUBshiftRLreg(v, config) case OpSelect0: return rewriteValueARM_OpSelect0(v, config) case OpSelect1: @@ -504,6 +694,18 @@ func rewriteValueARM(v *Value, config *Config) bool { return rewriteValueARM_OpARMXOR(v, config) case OpARMXORconst: return rewriteValueARM_OpARMXORconst(v, config) + case OpARMXORshiftLL: + return rewriteValueARM_OpARMXORshiftLL(v, config) + case OpARMXORshiftLLreg: + return rewriteValueARM_OpARMXORshiftLLreg(v, config) + case OpARMXORshiftRA: + return rewriteValueARM_OpARMXORshiftRA(v, config) + case OpARMXORshiftRAreg: + return rewriteValueARM_OpARMXORshiftRAreg(v, config) + case OpARMXORshiftRL: + return rewriteValueARM_OpARMXORshiftRL(v, config) + case OpARMXORshiftRLreg: + return rewriteValueARM_OpARMXORshiftRLreg(v, config) case OpXor16: return rewriteValueARM_OpXor16(v, config) case OpXor32: @@ -560,6 +762,234 @@ func rewriteValueARM_OpARMADC(v *Value, config *Config) bool { v.AddArg(flags) return true } + // match: (ADC x (SLLconst [c] y) flags) + // cond: + // result: (ADCshiftLL x y [c] flags) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSLLconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + flags := v.Args[2] + v.reset(OpARMADCshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + v.AddArg(flags) + return true + } + // match: (ADC (SLLconst [c] y) x flags) + // cond: + // result: (ADCshiftLL x y [c] flags) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSLLconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + flags := v.Args[2] + v.reset(OpARMADCshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + v.AddArg(flags) + return true + } + // match: (ADC x (SRLconst [c] y) flags) + // cond: + // result: (ADCshiftRL x y [c] flags) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRLconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + flags := v.Args[2] + v.reset(OpARMADCshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + v.AddArg(flags) + return true + } + // match: (ADC (SRLconst [c] y) x flags) + // cond: + // result: (ADCshiftRL x y [c] flags) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRLconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + flags := v.Args[2] + v.reset(OpARMADCshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + v.AddArg(flags) + return true + } + // match: (ADC x (SRAconst [c] y) flags) + // cond: + // result: (ADCshiftRA x y [c] flags) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRAconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + flags := v.Args[2] + v.reset(OpARMADCshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + v.AddArg(flags) + return true + } + // match: (ADC (SRAconst [c] y) x flags) + // cond: + // result: (ADCshiftRA x y [c] flags) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRAconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + flags := v.Args[2] + v.reset(OpARMADCshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + v.AddArg(flags) + return true + } + // match: (ADC x (SLL y z) flags) + // cond: + // result: (ADCshiftLLreg x y z flags) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSLL { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + flags := v.Args[2] + v.reset(OpARMADCshiftLLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + v.AddArg(flags) + return true + } + // match: (ADC (SLL y z) x flags) + // cond: + // result: (ADCshiftLLreg x y z flags) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSLL { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + flags := v.Args[2] + v.reset(OpARMADCshiftLLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + v.AddArg(flags) + return true + } + // match: (ADC x (SRL y z) flags) + // cond: + // result: (ADCshiftRLreg x y z flags) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRL { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + flags := v.Args[2] + v.reset(OpARMADCshiftRLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + v.AddArg(flags) + return true + } + // match: (ADC (SRL y z) x flags) + // cond: + // result: (ADCshiftRLreg x y z flags) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRL { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + flags := v.Args[2] + v.reset(OpARMADCshiftRLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + v.AddArg(flags) + return true + } + // match: (ADC x (SRA y z) flags) + // cond: + // result: (ADCshiftRAreg x y z flags) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRA { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + flags := v.Args[2] + v.reset(OpARMADCshiftRAreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + v.AddArg(flags) + return true + } + // match: (ADC (SRA y z) x flags) + // cond: + // result: (ADCshiftRAreg x y z flags) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRA { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + flags := v.Args[2] + v.reset(OpARMADCshiftRAreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + v.AddArg(flags) + return true + } return false } func rewriteValueARM_OpARMADCconst(v *Value, config *Config) bool { @@ -603,6 +1033,273 @@ func rewriteValueARM_OpARMADCconst(v *Value, config *Config) bool { } return false } +func rewriteValueARM_OpARMADCshiftLL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (ADCshiftLL (MOVWconst [c]) x [d] flags) + // cond: + // result: (ADCconst [c] (SLLconst x [d]) flags) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + flags := v.Args[2] + v.reset(OpARMADCconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSLLconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + v.AddArg(flags) + return true + } + // match: (ADCshiftLL x (MOVWconst [c]) [d] flags) + // cond: + // result: (ADCconst x [int64(uint32(c)< x y) flags) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + flags := v.Args[3] + v.reset(OpARMADCconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSLL, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + v.AddArg(flags) + return true + } + // match: (ADCshiftLLreg x y (MOVWconst [c]) flags) + // cond: + // result: (ADCshiftLL x y [c] flags) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + flags := v.Args[3] + v.reset(OpARMADCshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + v.AddArg(flags) + return true + } + return false +} +func rewriteValueARM_OpARMADCshiftRA(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (ADCshiftRA (MOVWconst [c]) x [d] flags) + // cond: + // result: (ADCconst [c] (SRAconst x [d]) flags) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + flags := v.Args[2] + v.reset(OpARMADCconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRAconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + v.AddArg(flags) + return true + } + // match: (ADCshiftRA x (MOVWconst [c]) [d] flags) + // cond: + // result: (ADCconst x [int64(int32(c)>>uint64(d))] flags) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + flags := v.Args[2] + v.reset(OpARMADCconst) + v.AddArg(x) + v.AuxInt = int64(int32(c) >> uint64(d)) + v.AddArg(flags) + return true + } + return false +} +func rewriteValueARM_OpARMADCshiftRAreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (ADCshiftRAreg (MOVWconst [c]) x y flags) + // cond: + // result: (ADCconst [c] (SRA x y) flags) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + flags := v.Args[3] + v.reset(OpARMADCconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRA, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + v.AddArg(flags) + return true + } + // match: (ADCshiftRAreg x y (MOVWconst [c]) flags) + // cond: + // result: (ADCshiftRA x y [c] flags) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + flags := v.Args[3] + v.reset(OpARMADCshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + v.AddArg(flags) + return true + } + return false +} +func rewriteValueARM_OpARMADCshiftRL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (ADCshiftRL (MOVWconst [c]) x [d] flags) + // cond: + // result: (ADCconst [c] (SRLconst x [d]) flags) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + flags := v.Args[2] + v.reset(OpARMADCconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRLconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + v.AddArg(flags) + return true + } + // match: (ADCshiftRL x (MOVWconst [c]) [d] flags) + // cond: + // result: (ADCconst x [int64(uint32(c)>>uint64(d))] flags) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + flags := v.Args[2] + v.reset(OpARMADCconst) + v.AddArg(x) + v.AuxInt = int64(uint32(c) >> uint64(d)) + v.AddArg(flags) + return true + } + return false +} +func rewriteValueARM_OpARMADCshiftRLreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (ADCshiftRLreg (MOVWconst [c]) x y flags) + // cond: + // result: (ADCconst [c] (SRL x y) flags) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + flags := v.Args[3] + v.reset(OpARMADCconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRL, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + v.AddArg(flags) + return true + } + // match: (ADCshiftRLreg x y (MOVWconst [c]) flags) + // cond: + // result: (ADCshiftRL x y [c] flags) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + flags := v.Args[3] + v.reset(OpARMADCshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + v.AddArg(flags) + return true + } + return false +} func rewriteValueARM_OpARMADD(v *Value, config *Config) bool { b := v.Block _ = b @@ -636,6 +1333,210 @@ func rewriteValueARM_OpARMADD(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (ADD x (SLLconst [c] y)) + // cond: + // result: (ADDshiftLL x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSLLconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + v.reset(OpARMADDshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (ADD (SLLconst [c] y) x) + // cond: + // result: (ADDshiftLL x y [c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSLLconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + v.reset(OpARMADDshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (ADD x (SRLconst [c] y)) + // cond: + // result: (ADDshiftRL x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRLconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + v.reset(OpARMADDshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (ADD (SRLconst [c] y) x) + // cond: + // result: (ADDshiftRL x y [c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRLconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + v.reset(OpARMADDshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (ADD x (SRAconst [c] y)) + // cond: + // result: (ADDshiftRA x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRAconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + v.reset(OpARMADDshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (ADD (SRAconst [c] y) x) + // cond: + // result: (ADDshiftRA x y [c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRAconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + v.reset(OpARMADDshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (ADD x (SLL y z)) + // cond: + // result: (ADDshiftLLreg x y z) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSLL { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + v.reset(OpARMADDshiftLLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (ADD (SLL y z) x) + // cond: + // result: (ADDshiftLLreg x y z) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSLL { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + v.reset(OpARMADDshiftLLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (ADD x (SRL y z)) + // cond: + // result: (ADDshiftRLreg x y z) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRL { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + v.reset(OpARMADDshiftRLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (ADD (SRL y z) x) + // cond: + // result: (ADDshiftRLreg x y z) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRL { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + v.reset(OpARMADDshiftRLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (ADD x (SRA y z)) + // cond: + // result: (ADDshiftRAreg x y z) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRA { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + v.reset(OpARMADDshiftRAreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (ADD (SRA y z) x) + // cond: + // result: (ADDshiftRAreg x y z) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRA { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + v.reset(OpARMADDshiftRAreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } // match: (ADD x (RSBconst [0] y)) // cond: // result: (SUB x y) @@ -654,6 +1555,24 @@ func rewriteValueARM_OpARMADD(v *Value, config *Config) bool { v.AddArg(y) return true } + // match: (ADD (RSBconst [0] y) x) + // cond: + // result: (SUB x y) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMRSBconst { + break + } + if v_0.AuxInt != 0 { + break + } + y := v_0.Args[0] + x := v.Args[1] + v.reset(OpARMSUB) + v.AddArg(x) + v.AddArg(y) + return true + } // match: (ADD (MUL x y) a) // cond: // result: (MULA x y a) @@ -723,6 +1642,453 @@ func rewriteValueARM_OpARMADDS(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (ADDS x (SLLconst [c] y)) + // cond: + // result: (ADDSshiftLL x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSLLconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + v.reset(OpARMADDSshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (ADDS (SLLconst [c] y) x) + // cond: + // result: (ADDSshiftLL x y [c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSLLconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + v.reset(OpARMADDSshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (ADDS x (SRLconst [c] y)) + // cond: + // result: (ADDSshiftRL x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRLconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + v.reset(OpARMADDSshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (ADDS (SRLconst [c] y) x) + // cond: + // result: (ADDSshiftRL x y [c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRLconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + v.reset(OpARMADDSshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (ADDS x (SRAconst [c] y)) + // cond: + // result: (ADDSshiftRA x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRAconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + v.reset(OpARMADDSshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (ADDS (SRAconst [c] y) x) + // cond: + // result: (ADDSshiftRA x y [c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRAconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + v.reset(OpARMADDSshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (ADDS x (SLL y z)) + // cond: + // result: (ADDSshiftLLreg x y z) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSLL { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + v.reset(OpARMADDSshiftLLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (ADDS (SLL y z) x) + // cond: + // result: (ADDSshiftLLreg x y z) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSLL { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + v.reset(OpARMADDSshiftLLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (ADDS x (SRL y z)) + // cond: + // result: (ADDSshiftRLreg x y z) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRL { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + v.reset(OpARMADDSshiftRLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (ADDS (SRL y z) x) + // cond: + // result: (ADDSshiftRLreg x y z) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRL { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + v.reset(OpARMADDSshiftRLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (ADDS x (SRA y z)) + // cond: + // result: (ADDSshiftRAreg x y z) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRA { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + v.reset(OpARMADDSshiftRAreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (ADDS (SRA y z) x) + // cond: + // result: (ADDSshiftRAreg x y z) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRA { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + v.reset(OpARMADDSshiftRAreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + return false +} +func rewriteValueARM_OpARMADDSshiftLL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (ADDSshiftLL (MOVWconst [c]) x [d]) + // cond: + // result: (ADDSconst [c] (SLLconst x [d])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + v.reset(OpARMADDSconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSLLconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + return true + } + // match: (ADDSshiftLL x (MOVWconst [c]) [d]) + // cond: + // result: (ADDSconst x [int64(uint32(c)< x y)) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + v.reset(OpARMADDSconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSLL, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + return true + } + // match: (ADDSshiftLLreg x y (MOVWconst [c])) + // cond: + // result: (ADDSshiftLL x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMADDSshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + return false +} +func rewriteValueARM_OpARMADDSshiftRA(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (ADDSshiftRA (MOVWconst [c]) x [d]) + // cond: + // result: (ADDSconst [c] (SRAconst x [d])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + v.reset(OpARMADDSconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRAconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + return true + } + // match: (ADDSshiftRA x (MOVWconst [c]) [d]) + // cond: + // result: (ADDSconst x [int64(int32(c)>>uint64(d))]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + v.reset(OpARMADDSconst) + v.AddArg(x) + v.AuxInt = int64(int32(c) >> uint64(d)) + return true + } + return false +} +func rewriteValueARM_OpARMADDSshiftRAreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (ADDSshiftRAreg (MOVWconst [c]) x y) + // cond: + // result: (ADDSconst [c] (SRA x y)) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + v.reset(OpARMADDSconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRA, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + return true + } + // match: (ADDSshiftRAreg x y (MOVWconst [c])) + // cond: + // result: (ADDSshiftRA x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMADDSshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + return false +} +func rewriteValueARM_OpARMADDSshiftRL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (ADDSshiftRL (MOVWconst [c]) x [d]) + // cond: + // result: (ADDSconst [c] (SRLconst x [d])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + v.reset(OpARMADDSconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRLconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + return true + } + // match: (ADDSshiftRL x (MOVWconst [c]) [d]) + // cond: + // result: (ADDSconst x [int64(uint32(c)>>uint64(d))]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + v.reset(OpARMADDSconst) + v.AddArg(x) + v.AuxInt = int64(uint32(c) >> uint64(d)) + return true + } + return false +} +func rewriteValueARM_OpARMADDSshiftRLreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (ADDSshiftRLreg (MOVWconst [c]) x y) + // cond: + // result: (ADDSconst [c] (SRL x y)) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + v.reset(OpARMADDSconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRL, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + return true + } + // match: (ADDSshiftRLreg x y (MOVWconst [c])) + // cond: + // result: (ADDSshiftRL x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMADDSshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } return false } func rewriteValueARM_OpARMADDconst(v *Value, config *Config) bool { @@ -823,6 +2189,249 @@ func rewriteValueARM_OpARMADDconst(v *Value, config *Config) bool { } return false } +func rewriteValueARM_OpARMADDshiftLL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (ADDshiftLL (MOVWconst [c]) x [d]) + // cond: + // result: (ADDconst [c] (SLLconst x [d])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + v.reset(OpARMADDconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSLLconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + return true + } + // match: (ADDshiftLL x (MOVWconst [c]) [d]) + // cond: + // result: (ADDconst x [int64(uint32(c)< x y)) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + v.reset(OpARMADDconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSLL, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + return true + } + // match: (ADDshiftLLreg x y (MOVWconst [c])) + // cond: + // result: (ADDshiftLL x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMADDshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + return false +} +func rewriteValueARM_OpARMADDshiftRA(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (ADDshiftRA (MOVWconst [c]) x [d]) + // cond: + // result: (ADDconst [c] (SRAconst x [d])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + v.reset(OpARMADDconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRAconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + return true + } + // match: (ADDshiftRA x (MOVWconst [c]) [d]) + // cond: + // result: (ADDconst x [int64(int32(c)>>uint64(d))]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + v.reset(OpARMADDconst) + v.AddArg(x) + v.AuxInt = int64(int32(c) >> uint64(d)) + return true + } + return false +} +func rewriteValueARM_OpARMADDshiftRAreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (ADDshiftRAreg (MOVWconst [c]) x y) + // cond: + // result: (ADDconst [c] (SRA x y)) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + v.reset(OpARMADDconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRA, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + return true + } + // match: (ADDshiftRAreg x y (MOVWconst [c])) + // cond: + // result: (ADDshiftRA x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMADDshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + return false +} +func rewriteValueARM_OpARMADDshiftRL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (ADDshiftRL (MOVWconst [c]) x [d]) + // cond: + // result: (ADDconst [c] (SRLconst x [d])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + v.reset(OpARMADDconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRLconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + return true + } + // match: (ADDshiftRL x (MOVWconst [c]) [d]) + // cond: + // result: (ADDconst x [int64(uint32(c)>>uint64(d))]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + v.reset(OpARMADDconst) + v.AddArg(x) + v.AuxInt = int64(uint32(c) >> uint64(d)) + return true + } + return false +} +func rewriteValueARM_OpARMADDshiftRLreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (ADDshiftRLreg (MOVWconst [c]) x y) + // cond: + // result: (ADDconst [c] (SRL x y)) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + v.reset(OpARMADDconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRL, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + return true + } + // match: (ADDshiftRLreg x y (MOVWconst [c])) + // cond: + // result: (ADDshiftRL x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMADDshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + return false +} func rewriteValueARM_OpARMAND(v *Value, config *Config) bool { b := v.Block _ = b @@ -856,6 +2465,210 @@ func rewriteValueARM_OpARMAND(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (AND x (SLLconst [c] y)) + // cond: + // result: (ANDshiftLL x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSLLconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + v.reset(OpARMANDshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (AND (SLLconst [c] y) x) + // cond: + // result: (ANDshiftLL x y [c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSLLconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + v.reset(OpARMANDshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (AND x (SRLconst [c] y)) + // cond: + // result: (ANDshiftRL x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRLconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + v.reset(OpARMANDshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (AND (SRLconst [c] y) x) + // cond: + // result: (ANDshiftRL x y [c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRLconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + v.reset(OpARMANDshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (AND x (SRAconst [c] y)) + // cond: + // result: (ANDshiftRA x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRAconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + v.reset(OpARMANDshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (AND (SRAconst [c] y) x) + // cond: + // result: (ANDshiftRA x y [c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRAconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + v.reset(OpARMANDshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (AND x (SLL y z)) + // cond: + // result: (ANDshiftLLreg x y z) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSLL { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + v.reset(OpARMANDshiftLLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (AND (SLL y z) x) + // cond: + // result: (ANDshiftLLreg x y z) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSLL { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + v.reset(OpARMANDshiftLLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (AND x (SRL y z)) + // cond: + // result: (ANDshiftRLreg x y z) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRL { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + v.reset(OpARMANDshiftRLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (AND (SRL y z) x) + // cond: + // result: (ANDshiftRLreg x y z) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRL { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + v.reset(OpARMANDshiftRLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (AND x (SRA y z)) + // cond: + // result: (ANDshiftRAreg x y z) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRA { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + v.reset(OpARMANDshiftRAreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (AND (SRA y z) x) + // cond: + // result: (ANDshiftRAreg x y z) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRA { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + v.reset(OpARMANDshiftRAreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } // match: (AND x x) // cond: // result: x @@ -884,6 +2697,57 @@ func rewriteValueARM_OpARMAND(v *Value, config *Config) bool { v.AddArg(y) return true } + // match: (AND x (MVNshiftLL y [c])) + // cond: + // result: (BICshiftLL x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMVNshiftLL { + break + } + y := v_1.Args[0] + c := v_1.AuxInt + v.reset(OpARMBICshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (AND x (MVNshiftRL y [c])) + // cond: + // result: (BICshiftRL x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMVNshiftRL { + break + } + y := v_1.Args[0] + c := v_1.AuxInt + v.reset(OpARMBICshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (AND x (MVNshiftRA y [c])) + // cond: + // result: (BICshiftRA x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMVNshiftRA { + break + } + y := v_1.Args[0] + c := v_1.AuxInt + v.reset(OpARMBICshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } return false } func rewriteValueARM_OpARMANDconst(v *Value, config *Config) bool { @@ -946,6 +2810,315 @@ func rewriteValueARM_OpARMANDconst(v *Value, config *Config) bool { } return false } +func rewriteValueARM_OpARMANDshiftLL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (ANDshiftLL (MOVWconst [c]) x [d]) + // cond: + // result: (ANDconst [c] (SLLconst x [d])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + v.reset(OpARMANDconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSLLconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + return true + } + // match: (ANDshiftLL x (MOVWconst [c]) [d]) + // cond: + // result: (ANDconst x [int64(uint32(c)< x y)) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + v.reset(OpARMANDconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSLL, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + return true + } + // match: (ANDshiftLLreg x y (MOVWconst [c])) + // cond: + // result: (ANDshiftLL x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMANDshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + return false +} +func rewriteValueARM_OpARMANDshiftRA(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (ANDshiftRA (MOVWconst [c]) x [d]) + // cond: + // result: (ANDconst [c] (SRAconst x [d])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + v.reset(OpARMANDconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRAconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + return true + } + // match: (ANDshiftRA x (MOVWconst [c]) [d]) + // cond: + // result: (ANDconst x [int64(int32(c)>>uint64(d))]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + v.reset(OpARMANDconst) + v.AddArg(x) + v.AuxInt = int64(int32(c) >> uint64(d)) + return true + } + // match: (ANDshiftRA x y:(SRAconst x [c]) [d]) + // cond: c==d + // result: y + for { + x := v.Args[0] + y := v.Args[1] + if y.Op != OpARMSRAconst { + break + } + if x != y.Args[0] { + break + } + c := y.AuxInt + d := v.AuxInt + if !(c == d) { + break + } + v.reset(OpCopy) + v.Type = y.Type + v.AddArg(y) + return true + } + return false +} +func rewriteValueARM_OpARMANDshiftRAreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (ANDshiftRAreg (MOVWconst [c]) x y) + // cond: + // result: (ANDconst [c] (SRA x y)) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + v.reset(OpARMANDconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRA, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + return true + } + // match: (ANDshiftRAreg x y (MOVWconst [c])) + // cond: + // result: (ANDshiftRA x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMANDshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + return false +} +func rewriteValueARM_OpARMANDshiftRL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (ANDshiftRL (MOVWconst [c]) x [d]) + // cond: + // result: (ANDconst [c] (SRLconst x [d])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + v.reset(OpARMANDconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRLconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + return true + } + // match: (ANDshiftRL x (MOVWconst [c]) [d]) + // cond: + // result: (ANDconst x [int64(uint32(c)>>uint64(d))]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + v.reset(OpARMANDconst) + v.AddArg(x) + v.AuxInt = int64(uint32(c) >> uint64(d)) + return true + } + // match: (ANDshiftRL x y:(SRLconst x [c]) [d]) + // cond: c==d + // result: y + for { + x := v.Args[0] + y := v.Args[1] + if y.Op != OpARMSRLconst { + break + } + if x != y.Args[0] { + break + } + c := y.AuxInt + d := v.AuxInt + if !(c == d) { + break + } + v.reset(OpCopy) + v.Type = y.Type + v.AddArg(y) + return true + } + return false +} +func rewriteValueARM_OpARMANDshiftRLreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (ANDshiftRLreg (MOVWconst [c]) x y) + // cond: + // result: (ANDconst [c] (SRL x y)) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + v.reset(OpARMANDconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRL, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + return true + } + // match: (ANDshiftRLreg x y (MOVWconst [c])) + // cond: + // result: (ANDshiftRL x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMANDshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + return false +} func rewriteValueARM_OpAdd16(v *Value, config *Config) bool { b := v.Block _ = b @@ -1161,6 +3334,108 @@ func rewriteValueARM_OpARMBIC(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (BIC x (SLLconst [c] y)) + // cond: + // result: (BICshiftLL x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSLLconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + v.reset(OpARMBICshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (BIC x (SRLconst [c] y)) + // cond: + // result: (BICshiftRL x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRLconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + v.reset(OpARMBICshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (BIC x (SRAconst [c] y)) + // cond: + // result: (BICshiftRA x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRAconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + v.reset(OpARMBICshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (BIC x (SLL y z)) + // cond: + // result: (BICshiftLLreg x y z) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSLL { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + v.reset(OpARMBICshiftLLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (BIC x (SRL y z)) + // cond: + // result: (BICshiftRLreg x y z) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRL { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + v.reset(OpARMBICshiftRLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (BIC x (SRA y z)) + // cond: + // result: (BICshiftRAreg x y z) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRA { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + v.reset(OpARMBICshiftRAreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } // match: (BIC x x) // cond: // result: (MOVWconst [0]) @@ -1219,6 +3494,376 @@ func rewriteValueARM_OpARMBICconst(v *Value, config *Config) bool { } return false } +func rewriteValueARM_OpARMBICshiftLL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (BICshiftLL x (MOVWconst [c]) [d]) + // cond: + // result: (BICconst x [int64(uint32(c)<>uint64(d))]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + v.reset(OpARMBICconst) + v.AddArg(x) + v.AuxInt = int64(int32(c) >> uint64(d)) + return true + } + // match: (BICshiftRA x (SRAconst x [c]) [d]) + // cond: c==d + // result: (MOVWconst [0]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRAconst { + break + } + if x != v_1.Args[0] { + break + } + c := v_1.AuxInt + d := v.AuxInt + if !(c == d) { + break + } + v.reset(OpARMMOVWconst) + v.AuxInt = 0 + return true + } + return false +} +func rewriteValueARM_OpARMBICshiftRAreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (BICshiftRAreg x y (MOVWconst [c])) + // cond: + // result: (BICshiftRA x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMBICshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + return false +} +func rewriteValueARM_OpARMBICshiftRL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (BICshiftRL x (MOVWconst [c]) [d]) + // cond: + // result: (BICconst x [int64(uint32(c)>>uint64(d))]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + v.reset(OpARMBICconst) + v.AddArg(x) + v.AuxInt = int64(uint32(c) >> uint64(d)) + return true + } + // match: (BICshiftRL x (SRLconst x [c]) [d]) + // cond: c==d + // result: (MOVWconst [0]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRLconst { + break + } + if x != v_1.Args[0] { + break + } + c := v_1.AuxInt + d := v.AuxInt + if !(c == d) { + break + } + v.reset(OpARMMOVWconst) + v.AuxInt = 0 + return true + } + return false +} +func rewriteValueARM_OpARMBICshiftRLreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (BICshiftRLreg x y (MOVWconst [c])) + // cond: + // result: (BICshiftRL x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMBICshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + return false +} +func rewriteValueARM_OpARMCMOVWHSconst(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (CMOVWHSconst _ (FlagEQ) [c]) + // cond: + // result: (MOVWconst [c]) + for { + v_1 := v.Args[1] + if v_1.Op != OpARMFlagEQ { + break + } + c := v.AuxInt + v.reset(OpARMMOVWconst) + v.AuxInt = c + return true + } + // match: (CMOVWHSconst x (FlagLT_ULT)) + // cond: + // result: x + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMFlagLT_ULT { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + // match: (CMOVWHSconst _ (FlagLT_UGT) [c]) + // cond: + // result: (MOVWconst [c]) + for { + v_1 := v.Args[1] + if v_1.Op != OpARMFlagLT_UGT { + break + } + c := v.AuxInt + v.reset(OpARMMOVWconst) + v.AuxInt = c + return true + } + // match: (CMOVWHSconst x (FlagGT_ULT)) + // cond: + // result: x + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMFlagGT_ULT { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + // match: (CMOVWHSconst _ (FlagGT_UGT) [c]) + // cond: + // result: (MOVWconst [c]) + for { + v_1 := v.Args[1] + if v_1.Op != OpARMFlagGT_UGT { + break + } + c := v.AuxInt + v.reset(OpARMMOVWconst) + v.AuxInt = c + return true + } + // match: (CMOVWHSconst x (InvertFlags flags) [c]) + // cond: + // result: (CMOVWLSconst x flags [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMInvertFlags { + break + } + flags := v_1.Args[0] + c := v.AuxInt + v.reset(OpARMCMOVWLSconst) + v.AddArg(x) + v.AddArg(flags) + v.AuxInt = c + return true + } + return false +} +func rewriteValueARM_OpARMCMOVWLSconst(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (CMOVWLSconst _ (FlagEQ) [c]) + // cond: + // result: (MOVWconst [c]) + for { + v_1 := v.Args[1] + if v_1.Op != OpARMFlagEQ { + break + } + c := v.AuxInt + v.reset(OpARMMOVWconst) + v.AuxInt = c + return true + } + // match: (CMOVWLSconst _ (FlagLT_ULT) [c]) + // cond: + // result: (MOVWconst [c]) + for { + v_1 := v.Args[1] + if v_1.Op != OpARMFlagLT_ULT { + break + } + c := v.AuxInt + v.reset(OpARMMOVWconst) + v.AuxInt = c + return true + } + // match: (CMOVWLSconst x (FlagLT_UGT)) + // cond: + // result: x + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMFlagLT_UGT { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + // match: (CMOVWLSconst _ (FlagGT_ULT) [c]) + // cond: + // result: (MOVWconst [c]) + for { + v_1 := v.Args[1] + if v_1.Op != OpARMFlagGT_ULT { + break + } + c := v.AuxInt + v.reset(OpARMMOVWconst) + v.AuxInt = c + return true + } + // match: (CMOVWLSconst x (FlagGT_UGT)) + // cond: + // result: x + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMFlagGT_UGT { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + // match: (CMOVWLSconst x (InvertFlags flags) [c]) + // cond: + // result: (CMOVWHSconst x flags [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMInvertFlags { + break + } + flags := v_1.Args[0] + c := v.AuxInt + v.reset(OpARMCMOVWHSconst) + v.AddArg(x) + v.AddArg(flags) + v.AuxInt = c + return true + } + return false +} func rewriteValueARM_OpARMCMP(v *Value, config *Config) bool { b := v.Block _ = b @@ -1254,6 +3899,222 @@ func rewriteValueARM_OpARMCMP(v *Value, config *Config) bool { v.AddArg(v0) return true } + // match: (CMP x (SLLconst [c] y)) + // cond: + // result: (CMPshiftLL x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSLLconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + v.reset(OpARMCMPshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (CMP (SLLconst [c] y) x) + // cond: + // result: (InvertFlags (CMPshiftLL x y [c])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSLLconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + v.reset(OpARMInvertFlags) + v0 := b.NewValue0(v.Line, OpARMCMPshiftLL, TypeFlags) + v0.AddArg(x) + v0.AddArg(y) + v0.AuxInt = c + v.AddArg(v0) + return true + } + // match: (CMP x (SRLconst [c] y)) + // cond: + // result: (CMPshiftRL x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRLconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + v.reset(OpARMCMPshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (CMP (SRLconst [c] y) x) + // cond: + // result: (InvertFlags (CMPshiftRL x y [c])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRLconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + v.reset(OpARMInvertFlags) + v0 := b.NewValue0(v.Line, OpARMCMPshiftRL, TypeFlags) + v0.AddArg(x) + v0.AddArg(y) + v0.AuxInt = c + v.AddArg(v0) + return true + } + // match: (CMP x (SRAconst [c] y)) + // cond: + // result: (CMPshiftRA x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRAconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + v.reset(OpARMCMPshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (CMP (SRAconst [c] y) x) + // cond: + // result: (InvertFlags (CMPshiftRA x y [c])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRAconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + v.reset(OpARMInvertFlags) + v0 := b.NewValue0(v.Line, OpARMCMPshiftRA, TypeFlags) + v0.AddArg(x) + v0.AddArg(y) + v0.AuxInt = c + v.AddArg(v0) + return true + } + // match: (CMP x (SLL y z)) + // cond: + // result: (CMPshiftLLreg x y z) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSLL { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + v.reset(OpARMCMPshiftLLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (CMP (SLL y z) x) + // cond: + // result: (InvertFlags (CMPshiftLLreg x y z)) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSLL { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + v.reset(OpARMInvertFlags) + v0 := b.NewValue0(v.Line, OpARMCMPshiftLLreg, TypeFlags) + v0.AddArg(x) + v0.AddArg(y) + v0.AddArg(z) + v.AddArg(v0) + return true + } + // match: (CMP x (SRL y z)) + // cond: + // result: (CMPshiftRLreg x y z) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRL { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + v.reset(OpARMCMPshiftRLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (CMP (SRL y z) x) + // cond: + // result: (InvertFlags (CMPshiftRLreg x y z)) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRL { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + v.reset(OpARMInvertFlags) + v0 := b.NewValue0(v.Line, OpARMCMPshiftRLreg, TypeFlags) + v0.AddArg(x) + v0.AddArg(y) + v0.AddArg(z) + v.AddArg(v0) + return true + } + // match: (CMP x (SRA y z)) + // cond: + // result: (CMPshiftRAreg x y z) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRA { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + v.reset(OpARMCMPshiftRAreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (CMP (SRA y z) x) + // cond: + // result: (InvertFlags (CMPshiftRAreg x y z)) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRA { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + v.reset(OpARMInvertFlags) + v0 := b.NewValue0(v.Line, OpARMCMPshiftRAreg, TypeFlags) + v0.AddArg(x) + v0.AddArg(y) + v0.AddArg(z) + v.AddArg(v0) + return true + } return false } func rewriteValueARM_OpARMCMPconst(v *Value, config *Config) bool { @@ -1403,6 +4264,261 @@ func rewriteValueARM_OpARMCMPconst(v *Value, config *Config) bool { } return false } +func rewriteValueARM_OpARMCMPshiftLL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (CMPshiftLL (MOVWconst [c]) x [d]) + // cond: + // result: (InvertFlags (CMPconst [c] (SLLconst x [d]))) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + v.reset(OpARMInvertFlags) + v0 := b.NewValue0(v.Line, OpARMCMPconst, TypeFlags) + v0.AuxInt = c + v1 := b.NewValue0(v.Line, OpARMSLLconst, x.Type) + v1.AddArg(x) + v1.AuxInt = d + v0.AddArg(v1) + v.AddArg(v0) + return true + } + // match: (CMPshiftLL x (MOVWconst [c]) [d]) + // cond: + // result: (CMPconst x [int64(uint32(c)< x y))) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + v.reset(OpARMInvertFlags) + v0 := b.NewValue0(v.Line, OpARMCMPconst, TypeFlags) + v0.AuxInt = c + v1 := b.NewValue0(v.Line, OpARMSLL, x.Type) + v1.AddArg(x) + v1.AddArg(y) + v0.AddArg(v1) + v.AddArg(v0) + return true + } + // match: (CMPshiftLLreg x y (MOVWconst [c])) + // cond: + // result: (CMPshiftLL x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMCMPshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + return false +} +func rewriteValueARM_OpARMCMPshiftRA(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (CMPshiftRA (MOVWconst [c]) x [d]) + // cond: + // result: (InvertFlags (CMPconst [c] (SRAconst x [d]))) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + v.reset(OpARMInvertFlags) + v0 := b.NewValue0(v.Line, OpARMCMPconst, TypeFlags) + v0.AuxInt = c + v1 := b.NewValue0(v.Line, OpARMSRAconst, x.Type) + v1.AddArg(x) + v1.AuxInt = d + v0.AddArg(v1) + v.AddArg(v0) + return true + } + // match: (CMPshiftRA x (MOVWconst [c]) [d]) + // cond: + // result: (CMPconst x [int64(int32(c)>>uint64(d))]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + v.reset(OpARMCMPconst) + v.AddArg(x) + v.AuxInt = int64(int32(c) >> uint64(d)) + return true + } + return false +} +func rewriteValueARM_OpARMCMPshiftRAreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (CMPshiftRAreg (MOVWconst [c]) x y) + // cond: + // result: (InvertFlags (CMPconst [c] (SRA x y))) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + v.reset(OpARMInvertFlags) + v0 := b.NewValue0(v.Line, OpARMCMPconst, TypeFlags) + v0.AuxInt = c + v1 := b.NewValue0(v.Line, OpARMSRA, x.Type) + v1.AddArg(x) + v1.AddArg(y) + v0.AddArg(v1) + v.AddArg(v0) + return true + } + // match: (CMPshiftRAreg x y (MOVWconst [c])) + // cond: + // result: (CMPshiftRA x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMCMPshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + return false +} +func rewriteValueARM_OpARMCMPshiftRL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (CMPshiftRL (MOVWconst [c]) x [d]) + // cond: + // result: (InvertFlags (CMPconst [c] (SRLconst x [d]))) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + v.reset(OpARMInvertFlags) + v0 := b.NewValue0(v.Line, OpARMCMPconst, TypeFlags) + v0.AuxInt = c + v1 := b.NewValue0(v.Line, OpARMSRLconst, x.Type) + v1.AddArg(x) + v1.AuxInt = d + v0.AddArg(v1) + v.AddArg(v0) + return true + } + // match: (CMPshiftRL x (MOVWconst [c]) [d]) + // cond: + // result: (CMPconst x [int64(uint32(c)>>uint64(d))]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + v.reset(OpARMCMPconst) + v.AddArg(x) + v.AuxInt = int64(uint32(c) >> uint64(d)) + return true + } + return false +} +func rewriteValueARM_OpARMCMPshiftRLreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (CMPshiftRLreg (MOVWconst [c]) x y) + // cond: + // result: (InvertFlags (CMPconst [c] (SRL x y))) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + v.reset(OpARMInvertFlags) + v0 := b.NewValue0(v.Line, OpARMCMPconst, TypeFlags) + v0.AuxInt = c + v1 := b.NewValue0(v.Line, OpARMSRL, x.Type) + v1.AddArg(x) + v1.AddArg(y) + v0.AddArg(v1) + v.AddArg(v0) + return true + } + // match: (CMPshiftRLreg x y (MOVWconst [c])) + // cond: + // result: (CMPshiftRL x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMCMPshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + return false +} func rewriteValueARM_OpClosureCall(v *Value, config *Config) bool { b := v.Block _ = b @@ -3702,42 +6818,6 @@ func rewriteValueARM_OpLoad(v *Value, config *Config) bool { } return false } -func rewriteValueARM_OpARMLoweredZeromask(v *Value, config *Config) bool { - b := v.Block - _ = b - // match: (LoweredZeromask (MOVWconst [0])) - // cond: - // result: (MOVWconst [0]) - for { - v_0 := v.Args[0] - if v_0.Op != OpARMMOVWconst { - break - } - if v_0.AuxInt != 0 { - break - } - v.reset(OpARMMOVWconst) - v.AuxInt = 0 - return true - } - // match: (LoweredZeromask (MOVWconst [c])) - // cond: c != 0 - // result: (MOVWconst [0xffffffff]) - for { - v_0 := v.Args[0] - if v_0.Op != OpARMMOVWconst { - break - } - c := v_0.AuxInt - if !(c != 0) { - break - } - v.reset(OpARMMOVWconst) - v.AuxInt = 0xffffffff - return true - } - return false -} func rewriteValueARM_OpLrot16(v *Value, config *Config) bool { b := v.Block _ = b @@ -3802,15 +6882,24 @@ func rewriteValueARM_OpLsh16x16(v *Value, config *Config) bool { _ = b // match: (Lsh16x16 x y) // cond: - // result: (SLL x (ZeroExt16to32 y)) + // result: (CMOVWHSconst (SLL x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0]) for { x := v.Args[0] y := v.Args[1] - v.reset(OpARMSLL) - v.AddArg(x) - v0 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32()) - v0.AddArg(y) + v.reset(OpARMCMOVWHSconst) + v0 := b.NewValue0(v.Line, OpARMSLL, x.Type) + v0.AddArg(x) + v1 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32()) + v1.AddArg(y) + v0.AddArg(v1) v.AddArg(v0) + v2 := b.NewValue0(v.Line, OpARMCMPconst, TypeFlags) + v2.AuxInt = 256 + v3 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32()) + v3.AddArg(y) + v2.AddArg(v3) + v.AddArg(v2) + v.AuxInt = 0 return true } } @@ -3819,13 +6908,20 @@ func rewriteValueARM_OpLsh16x32(v *Value, config *Config) bool { _ = b // match: (Lsh16x32 x y) // cond: - // result: (SLL x y) + // result: (CMOVWHSconst (SLL x y) (CMPconst [256] y) [0]) for { x := v.Args[0] y := v.Args[1] - v.reset(OpARMSLL) - v.AddArg(x) - v.AddArg(y) + v.reset(OpARMCMOVWHSconst) + v0 := b.NewValue0(v.Line, OpARMSLL, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + v1 := b.NewValue0(v.Line, OpARMCMPconst, TypeFlags) + v1.AuxInt = 256 + v1.AddArg(y) + v.AddArg(v1) + v.AuxInt = 0 return true } } @@ -3890,15 +6986,24 @@ func rewriteValueARM_OpLsh32x16(v *Value, config *Config) bool { _ = b // match: (Lsh32x16 x y) // cond: - // result: (SLL x (ZeroExt16to32 y)) + // result: (CMOVWHSconst (SLL x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0]) for { x := v.Args[0] y := v.Args[1] - v.reset(OpARMSLL) - v.AddArg(x) - v0 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32()) - v0.AddArg(y) + v.reset(OpARMCMOVWHSconst) + v0 := b.NewValue0(v.Line, OpARMSLL, x.Type) + v0.AddArg(x) + v1 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32()) + v1.AddArg(y) + v0.AddArg(v1) v.AddArg(v0) + v2 := b.NewValue0(v.Line, OpARMCMPconst, TypeFlags) + v2.AuxInt = 256 + v3 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32()) + v3.AddArg(y) + v2.AddArg(v3) + v.AddArg(v2) + v.AuxInt = 0 return true } } @@ -3907,13 +7012,20 @@ func rewriteValueARM_OpLsh32x32(v *Value, config *Config) bool { _ = b // match: (Lsh32x32 x y) // cond: - // result: (SLL x y) + // result: (CMOVWHSconst (SLL x y) (CMPconst [256] y) [0]) for { x := v.Args[0] y := v.Args[1] - v.reset(OpARMSLL) - v.AddArg(x) - v.AddArg(y) + v.reset(OpARMCMOVWHSconst) + v0 := b.NewValue0(v.Line, OpARMSLL, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + v1 := b.NewValue0(v.Line, OpARMCMPconst, TypeFlags) + v1.AuxInt = 256 + v1.AddArg(y) + v.AddArg(v1) + v.AuxInt = 0 return true } } @@ -3978,15 +7090,24 @@ func rewriteValueARM_OpLsh8x16(v *Value, config *Config) bool { _ = b // match: (Lsh8x16 x y) // cond: - // result: (SLL x (ZeroExt16to32 y)) + // result: (CMOVWHSconst (SLL x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0]) for { x := v.Args[0] y := v.Args[1] - v.reset(OpARMSLL) - v.AddArg(x) - v0 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32()) - v0.AddArg(y) + v.reset(OpARMCMOVWHSconst) + v0 := b.NewValue0(v.Line, OpARMSLL, x.Type) + v0.AddArg(x) + v1 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32()) + v1.AddArg(y) + v0.AddArg(v1) v.AddArg(v0) + v2 := b.NewValue0(v.Line, OpARMCMPconst, TypeFlags) + v2.AuxInt = 256 + v3 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32()) + v3.AddArg(y) + v2.AddArg(v3) + v.AddArg(v2) + v.AuxInt = 0 return true } } @@ -3995,13 +7116,20 @@ func rewriteValueARM_OpLsh8x32(v *Value, config *Config) bool { _ = b // match: (Lsh8x32 x y) // cond: - // result: (SLL x y) + // result: (CMOVWHSconst (SLL x y) (CMPconst [256] y) [0]) for { x := v.Args[0] y := v.Args[1] - v.reset(OpARMSLL) - v.AddArg(x) - v.AddArg(y) + v.reset(OpARMCMOVWHSconst) + v0 := b.NewValue0(v.Line, OpARMSLL, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + v1 := b.NewValue0(v.Line, OpARMCMPconst, TypeFlags) + v1.AuxInt = 256 + v1.AddArg(y) + v.AddArg(v1) + v.AuxInt = 0 return true } } @@ -4163,6 +7291,31 @@ func rewriteValueARM_OpARMMOVBUreg(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (MOVBUreg x:(MOVBUreg _)) + // cond: + // result: (MOVWreg x) + for { + x := v.Args[0] + if x.Op != OpARMMOVBUreg { + break + } + v.reset(OpARMMOVWreg) + v.AddArg(x) + return true + } + // match: (MOVBUreg (MOVWconst [c])) + // cond: + // result: (MOVWconst [int64(uint8(c))]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + v.reset(OpARMMOVWconst) + v.AuxInt = int64(uint8(c)) + return true + } return false } func rewriteValueARM_OpARMMOVBload(v *Value, config *Config) bool { @@ -4270,6 +7423,31 @@ func rewriteValueARM_OpARMMOVBreg(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (MOVBreg x:(MOVBreg _)) + // cond: + // result: (MOVWreg x) + for { + x := v.Args[0] + if x.Op != OpARMMOVBreg { + break + } + v.reset(OpARMMOVWreg) + v.AddArg(x) + return true + } + // match: (MOVBreg (MOVWconst [c])) + // cond: + // result: (MOVWconst [int64(int8(c))]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + v.reset(OpARMMOVWconst) + v.AuxInt = int64(int8(c)) + return true + } return false } func rewriteValueARM_OpARMMOVBstore(v *Value, config *Config) bool { @@ -4773,6 +7951,43 @@ func rewriteValueARM_OpARMMOVHUreg(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (MOVHUreg x:(MOVBUreg _)) + // cond: + // result: (MOVWreg x) + for { + x := v.Args[0] + if x.Op != OpARMMOVBUreg { + break + } + v.reset(OpARMMOVWreg) + v.AddArg(x) + return true + } + // match: (MOVHUreg x:(MOVHUreg _)) + // cond: + // result: (MOVWreg x) + for { + x := v.Args[0] + if x.Op != OpARMMOVHUreg { + break + } + v.reset(OpARMMOVWreg) + v.AddArg(x) + return true + } + // match: (MOVHUreg (MOVWconst [c])) + // cond: + // result: (MOVWconst [int64(uint16(c))]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + v.reset(OpARMMOVWconst) + v.AuxInt = int64(uint16(c)) + return true + } return false } func rewriteValueARM_OpARMMOVHload(v *Value, config *Config) bool { @@ -4904,6 +8119,55 @@ func rewriteValueARM_OpARMMOVHreg(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (MOVHreg x:(MOVBreg _)) + // cond: + // result: (MOVWreg x) + for { + x := v.Args[0] + if x.Op != OpARMMOVBreg { + break + } + v.reset(OpARMMOVWreg) + v.AddArg(x) + return true + } + // match: (MOVHreg x:(MOVBUreg _)) + // cond: + // result: (MOVWreg x) + for { + x := v.Args[0] + if x.Op != OpARMMOVBUreg { + break + } + v.reset(OpARMMOVWreg) + v.AddArg(x) + return true + } + // match: (MOVHreg x:(MOVHreg _)) + // cond: + // result: (MOVWreg x) + for { + x := v.Args[0] + if x.Op != OpARMMOVHreg { + break + } + v.reset(OpARMMOVWreg) + v.AddArg(x) + return true + } + // match: (MOVHreg (MOVWconst [c])) + // cond: + // result: (MOVWconst [int64(int16(c))]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + v.reset(OpARMMOVWconst) + v.AuxInt = int64(int16(c)) + return true + } return false } func rewriteValueARM_OpARMMOVHstore(v *Value, config *Config) bool { @@ -5071,6 +8335,446 @@ func rewriteValueARM_OpARMMOVWload(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (MOVWload [0] {sym} (ADD ptr idx) mem) + // cond: sym == nil + // result: (MOVWloadidx ptr idx mem) + for { + if v.AuxInt != 0 { + break + } + sym := v.Aux + v_0 := v.Args[0] + if v_0.Op != OpARMADD { + break + } + ptr := v_0.Args[0] + idx := v_0.Args[1] + mem := v.Args[1] + if !(sym == nil) { + break + } + v.reset(OpARMMOVWloadidx) + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(mem) + return true + } + // match: (MOVWload [0] {sym} (ADDshiftLL ptr idx [c]) mem) + // cond: sym == nil + // result: (MOVWloadshiftLL ptr idx [c] mem) + for { + if v.AuxInt != 0 { + break + } + sym := v.Aux + v_0 := v.Args[0] + if v_0.Op != OpARMADDshiftLL { + break + } + ptr := v_0.Args[0] + idx := v_0.Args[1] + c := v_0.AuxInt + mem := v.Args[1] + if !(sym == nil) { + break + } + v.reset(OpARMMOVWloadshiftLL) + v.AddArg(ptr) + v.AddArg(idx) + v.AuxInt = c + v.AddArg(mem) + return true + } + // match: (MOVWload [0] {sym} (ADDshiftRL ptr idx [c]) mem) + // cond: sym == nil + // result: (MOVWloadshiftRL ptr idx [c] mem) + for { + if v.AuxInt != 0 { + break + } + sym := v.Aux + v_0 := v.Args[0] + if v_0.Op != OpARMADDshiftRL { + break + } + ptr := v_0.Args[0] + idx := v_0.Args[1] + c := v_0.AuxInt + mem := v.Args[1] + if !(sym == nil) { + break + } + v.reset(OpARMMOVWloadshiftRL) + v.AddArg(ptr) + v.AddArg(idx) + v.AuxInt = c + v.AddArg(mem) + return true + } + // match: (MOVWload [0] {sym} (ADDshiftRA ptr idx [c]) mem) + // cond: sym == nil + // result: (MOVWloadshiftRA ptr idx [c] mem) + for { + if v.AuxInt != 0 { + break + } + sym := v.Aux + v_0 := v.Args[0] + if v_0.Op != OpARMADDshiftRA { + break + } + ptr := v_0.Args[0] + idx := v_0.Args[1] + c := v_0.AuxInt + mem := v.Args[1] + if !(sym == nil) { + break + } + v.reset(OpARMMOVWloadshiftRA) + v.AddArg(ptr) + v.AddArg(idx) + v.AuxInt = c + v.AddArg(mem) + return true + } + return false +} +func rewriteValueARM_OpARMMOVWloadidx(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (MOVWloadidx ptr idx (MOVWstoreidx ptr2 idx x _)) + // cond: isSamePtr(ptr, ptr2) + // result: x + for { + ptr := v.Args[0] + idx := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWstoreidx { + break + } + ptr2 := v_2.Args[0] + if idx != v_2.Args[1] { + break + } + x := v_2.Args[2] + if !(isSamePtr(ptr, ptr2)) { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + // match: (MOVWloadidx ptr (MOVWconst [c]) mem) + // cond: + // result: (MOVWload [c] ptr mem) + for { + ptr := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + mem := v.Args[2] + v.reset(OpARMMOVWload) + v.AuxInt = c + v.AddArg(ptr) + v.AddArg(mem) + return true + } + // match: (MOVWloadidx (MOVWconst [c]) ptr mem) + // cond: + // result: (MOVWload [c] ptr mem) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + ptr := v.Args[1] + mem := v.Args[2] + v.reset(OpARMMOVWload) + v.AuxInt = c + v.AddArg(ptr) + v.AddArg(mem) + return true + } + // match: (MOVWloadidx ptr (SLLconst idx [c]) mem) + // cond: + // result: (MOVWloadshiftLL ptr idx [c] mem) + for { + ptr := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSLLconst { + break + } + idx := v_1.Args[0] + c := v_1.AuxInt + mem := v.Args[2] + v.reset(OpARMMOVWloadshiftLL) + v.AddArg(ptr) + v.AddArg(idx) + v.AuxInt = c + v.AddArg(mem) + return true + } + // match: (MOVWloadidx (SLLconst idx [c]) ptr mem) + // cond: + // result: (MOVWloadshiftLL ptr idx [c] mem) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSLLconst { + break + } + idx := v_0.Args[0] + c := v_0.AuxInt + ptr := v.Args[1] + mem := v.Args[2] + v.reset(OpARMMOVWloadshiftLL) + v.AddArg(ptr) + v.AddArg(idx) + v.AuxInt = c + v.AddArg(mem) + return true + } + // match: (MOVWloadidx ptr (SRLconst idx [c]) mem) + // cond: + // result: (MOVWloadshiftRL ptr idx [c] mem) + for { + ptr := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRLconst { + break + } + idx := v_1.Args[0] + c := v_1.AuxInt + mem := v.Args[2] + v.reset(OpARMMOVWloadshiftRL) + v.AddArg(ptr) + v.AddArg(idx) + v.AuxInt = c + v.AddArg(mem) + return true + } + // match: (MOVWloadidx (SRLconst idx [c]) ptr mem) + // cond: + // result: (MOVWloadshiftRL ptr idx [c] mem) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRLconst { + break + } + idx := v_0.Args[0] + c := v_0.AuxInt + ptr := v.Args[1] + mem := v.Args[2] + v.reset(OpARMMOVWloadshiftRL) + v.AddArg(ptr) + v.AddArg(idx) + v.AuxInt = c + v.AddArg(mem) + return true + } + // match: (MOVWloadidx ptr (SRAconst idx [c]) mem) + // cond: + // result: (MOVWloadshiftRA ptr idx [c] mem) + for { + ptr := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRAconst { + break + } + idx := v_1.Args[0] + c := v_1.AuxInt + mem := v.Args[2] + v.reset(OpARMMOVWloadshiftRA) + v.AddArg(ptr) + v.AddArg(idx) + v.AuxInt = c + v.AddArg(mem) + return true + } + // match: (MOVWloadidx (SRAconst idx [c]) ptr mem) + // cond: + // result: (MOVWloadshiftRA ptr idx [c] mem) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRAconst { + break + } + idx := v_0.Args[0] + c := v_0.AuxInt + ptr := v.Args[1] + mem := v.Args[2] + v.reset(OpARMMOVWloadshiftRA) + v.AddArg(ptr) + v.AddArg(idx) + v.AuxInt = c + v.AddArg(mem) + return true + } + return false +} +func rewriteValueARM_OpARMMOVWloadshiftLL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (MOVWloadshiftLL ptr idx [c] (MOVWstoreshiftLL ptr2 idx [d] x _)) + // cond: c==d && isSamePtr(ptr, ptr2) + // result: x + for { + ptr := v.Args[0] + idx := v.Args[1] + c := v.AuxInt + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWstoreshiftLL { + break + } + ptr2 := v_2.Args[0] + if idx != v_2.Args[1] { + break + } + d := v_2.AuxInt + x := v_2.Args[2] + if !(c == d && isSamePtr(ptr, ptr2)) { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + // match: (MOVWloadshiftLL ptr (MOVWconst [c]) [d] mem) + // cond: + // result: (MOVWload [int64(uint32(c)<>uint64(d))] ptr mem) + for { + ptr := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + mem := v.Args[2] + v.reset(OpARMMOVWload) + v.AuxInt = int64(int32(c) >> uint64(d)) + v.AddArg(ptr) + v.AddArg(mem) + return true + } + return false +} +func rewriteValueARM_OpARMMOVWloadshiftRL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (MOVWloadshiftRL ptr idx [c] (MOVWstoreshiftRL ptr2 idx [d] x _)) + // cond: c==d && isSamePtr(ptr, ptr2) + // result: x + for { + ptr := v.Args[0] + idx := v.Args[1] + c := v.AuxInt + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWstoreshiftRL { + break + } + ptr2 := v_2.Args[0] + if idx != v_2.Args[1] { + break + } + d := v_2.AuxInt + x := v_2.Args[2] + if !(c == d && isSamePtr(ptr, ptr2)) { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + // match: (MOVWloadshiftRL ptr (MOVWconst [c]) [d] mem) + // cond: + // result: (MOVWload [int64(uint32(c)>>uint64(d))] ptr mem) + for { + ptr := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + mem := v.Args[2] + v.reset(OpARMMOVWload) + v.AuxInt = int64(uint32(c) >> uint64(d)) + v.AddArg(ptr) + v.AddArg(mem) + return true + } + return false +} +func rewriteValueARM_OpARMMOVWreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (MOVWreg (MOVWconst [c])) + // cond: + // result: (MOVWconst [c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + v.reset(OpARMMOVWconst) + v.AuxInt = c + return true + } return false } func rewriteValueARM_OpARMMOVWstore(v *Value, config *Config) bool { @@ -5124,13 +8828,367 @@ func rewriteValueARM_OpARMMOVWstore(v *Value, config *Config) bool { v.AddArg(mem) return true } + // match: (MOVWstore [0] {sym} (ADD ptr idx) val mem) + // cond: sym == nil + // result: (MOVWstoreidx ptr idx val mem) + for { + if v.AuxInt != 0 { + break + } + sym := v.Aux + v_0 := v.Args[0] + if v_0.Op != OpARMADD { + break + } + ptr := v_0.Args[0] + idx := v_0.Args[1] + val := v.Args[1] + mem := v.Args[2] + if !(sym == nil) { + break + } + v.reset(OpARMMOVWstoreidx) + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(val) + v.AddArg(mem) + return true + } + // match: (MOVWstore [0] {sym} (ADDshiftLL ptr idx [c]) val mem) + // cond: sym == nil + // result: (MOVWstoreshiftLL ptr idx [c] val mem) + for { + if v.AuxInt != 0 { + break + } + sym := v.Aux + v_0 := v.Args[0] + if v_0.Op != OpARMADDshiftLL { + break + } + ptr := v_0.Args[0] + idx := v_0.Args[1] + c := v_0.AuxInt + val := v.Args[1] + mem := v.Args[2] + if !(sym == nil) { + break + } + v.reset(OpARMMOVWstoreshiftLL) + v.AddArg(ptr) + v.AddArg(idx) + v.AuxInt = c + v.AddArg(val) + v.AddArg(mem) + return true + } + // match: (MOVWstore [0] {sym} (ADDshiftRL ptr idx [c]) val mem) + // cond: sym == nil + // result: (MOVWstoreshiftRL ptr idx [c] val mem) + for { + if v.AuxInt != 0 { + break + } + sym := v.Aux + v_0 := v.Args[0] + if v_0.Op != OpARMADDshiftRL { + break + } + ptr := v_0.Args[0] + idx := v_0.Args[1] + c := v_0.AuxInt + val := v.Args[1] + mem := v.Args[2] + if !(sym == nil) { + break + } + v.reset(OpARMMOVWstoreshiftRL) + v.AddArg(ptr) + v.AddArg(idx) + v.AuxInt = c + v.AddArg(val) + v.AddArg(mem) + return true + } + // match: (MOVWstore [0] {sym} (ADDshiftRA ptr idx [c]) val mem) + // cond: sym == nil + // result: (MOVWstoreshiftRA ptr idx [c] val mem) + for { + if v.AuxInt != 0 { + break + } + sym := v.Aux + v_0 := v.Args[0] + if v_0.Op != OpARMADDshiftRA { + break + } + ptr := v_0.Args[0] + idx := v_0.Args[1] + c := v_0.AuxInt + val := v.Args[1] + mem := v.Args[2] + if !(sym == nil) { + break + } + v.reset(OpARMMOVWstoreshiftRA) + v.AddArg(ptr) + v.AddArg(idx) + v.AuxInt = c + v.AddArg(val) + v.AddArg(mem) + return true + } + return false +} +func rewriteValueARM_OpARMMOVWstoreidx(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (MOVWstoreidx ptr (MOVWconst [c]) val mem) + // cond: + // result: (MOVWstore [c] ptr val mem) + for { + ptr := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + val := v.Args[2] + mem := v.Args[3] + v.reset(OpARMMOVWstore) + v.AuxInt = c + v.AddArg(ptr) + v.AddArg(val) + v.AddArg(mem) + return true + } + // match: (MOVWstoreidx (MOVWconst [c]) ptr val mem) + // cond: + // result: (MOVWstore [c] ptr val mem) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + ptr := v.Args[1] + val := v.Args[2] + mem := v.Args[3] + v.reset(OpARMMOVWstore) + v.AuxInt = c + v.AddArg(ptr) + v.AddArg(val) + v.AddArg(mem) + return true + } + // match: (MOVWstoreidx ptr (SLLconst idx [c]) val mem) + // cond: + // result: (MOVWstoreshiftLL ptr idx [c] val mem) + for { + ptr := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSLLconst { + break + } + idx := v_1.Args[0] + c := v_1.AuxInt + val := v.Args[2] + mem := v.Args[3] + v.reset(OpARMMOVWstoreshiftLL) + v.AddArg(ptr) + v.AddArg(idx) + v.AuxInt = c + v.AddArg(val) + v.AddArg(mem) + return true + } + // match: (MOVWstoreidx (SLLconst idx [c]) ptr val mem) + // cond: + // result: (MOVWstoreshiftLL ptr idx [c] val mem) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSLLconst { + break + } + idx := v_0.Args[0] + c := v_0.AuxInt + ptr := v.Args[1] + val := v.Args[2] + mem := v.Args[3] + v.reset(OpARMMOVWstoreshiftLL) + v.AddArg(ptr) + v.AddArg(idx) + v.AuxInt = c + v.AddArg(val) + v.AddArg(mem) + return true + } + // match: (MOVWstoreidx ptr (SRLconst idx [c]) val mem) + // cond: + // result: (MOVWstoreshiftRL ptr idx [c] val mem) + for { + ptr := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRLconst { + break + } + idx := v_1.Args[0] + c := v_1.AuxInt + val := v.Args[2] + mem := v.Args[3] + v.reset(OpARMMOVWstoreshiftRL) + v.AddArg(ptr) + v.AddArg(idx) + v.AuxInt = c + v.AddArg(val) + v.AddArg(mem) + return true + } + // match: (MOVWstoreidx (SRLconst idx [c]) ptr val mem) + // cond: + // result: (MOVWstoreshiftRL ptr idx [c] val mem) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRLconst { + break + } + idx := v_0.Args[0] + c := v_0.AuxInt + ptr := v.Args[1] + val := v.Args[2] + mem := v.Args[3] + v.reset(OpARMMOVWstoreshiftRL) + v.AddArg(ptr) + v.AddArg(idx) + v.AuxInt = c + v.AddArg(val) + v.AddArg(mem) + return true + } + // match: (MOVWstoreidx ptr (SRAconst idx [c]) val mem) + // cond: + // result: (MOVWstoreshiftRA ptr idx [c] val mem) + for { + ptr := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRAconst { + break + } + idx := v_1.Args[0] + c := v_1.AuxInt + val := v.Args[2] + mem := v.Args[3] + v.reset(OpARMMOVWstoreshiftRA) + v.AddArg(ptr) + v.AddArg(idx) + v.AuxInt = c + v.AddArg(val) + v.AddArg(mem) + return true + } + // match: (MOVWstoreidx (SRAconst idx [c]) ptr val mem) + // cond: + // result: (MOVWstoreshiftRA ptr idx [c] val mem) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRAconst { + break + } + idx := v_0.Args[0] + c := v_0.AuxInt + ptr := v.Args[1] + val := v.Args[2] + mem := v.Args[3] + v.reset(OpARMMOVWstoreshiftRA) + v.AddArg(ptr) + v.AddArg(idx) + v.AuxInt = c + v.AddArg(val) + v.AddArg(mem) + return true + } + return false +} +func rewriteValueARM_OpARMMOVWstoreshiftLL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (MOVWstoreshiftLL ptr (MOVWconst [c]) [d] val mem) + // cond: + // result: (MOVWstore [int64(uint32(c)<>uint64(d))] ptr val mem) + for { + ptr := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + val := v.Args[2] + mem := v.Args[3] + v.reset(OpARMMOVWstore) + v.AuxInt = int64(int32(c) >> uint64(d)) + v.AddArg(ptr) + v.AddArg(val) + v.AddArg(mem) + return true + } + return false +} +func rewriteValueARM_OpARMMOVWstoreshiftRL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (MOVWstoreshiftRL ptr (MOVWconst [c]) [d] val mem) + // cond: + // result: (MOVWstore [int64(uint32(c)>>uint64(d))] ptr val mem) + for { + ptr := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + val := v.Args[2] + mem := v.Args[3] + v.reset(OpARMMOVWstore) + v.AuxInt = int64(uint32(c) >> uint64(d)) + v.AddArg(ptr) + v.AddArg(val) + v.AddArg(mem) + return true + } return false } func rewriteValueARM_OpARMMUL(v *Value, config *Config) bool { b := v.Block _ = b - // match: (MUL x (MOVWconst [-1])) - // cond: + // match: (MUL x (MOVWconst [c])) + // cond: int32(c) == -1 // result: (RSBconst [0] x) for { x := v.Args[0] @@ -5138,7 +9196,8 @@ func rewriteValueARM_OpARMMUL(v *Value, config *Config) bool { if v_1.Op != OpARMMOVWconst { break } - if v_1.AuxInt != -1 { + c := v_1.AuxInt + if !(int32(c) == -1) { break } v.reset(OpARMRSBconst) @@ -5196,18 +9255,145 @@ func rewriteValueARM_OpARMMUL(v *Value, config *Config) bool { v.AddArg(x) return true } - // match: (MUL (MOVWconst [-1]) x) - // cond: + // match: (MUL x (MOVWconst [c])) + // cond: isPowerOfTwo(c-1) && int32(c) >= 3 + // result: (ADDshiftLL x x [log2(c-1)]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + if !(isPowerOfTwo(c-1) && int32(c) >= 3) { + break + } + v.reset(OpARMADDshiftLL) + v.AddArg(x) + v.AddArg(x) + v.AuxInt = log2(c - 1) + return true + } + // match: (MUL x (MOVWconst [c])) + // cond: isPowerOfTwo(c+1) && int32(c) >= 7 + // result: (RSBshiftLL x x [log2(c+1)]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + if !(isPowerOfTwo(c+1) && int32(c) >= 7) { + break + } + v.reset(OpARMRSBshiftLL) + v.AddArg(x) + v.AddArg(x) + v.AuxInt = log2(c + 1) + return true + } + // match: (MUL x (MOVWconst [c])) + // cond: c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) + // result: (SLLconst [log2(c/3)] (ADDshiftLL x x [1])) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + if !(c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c)) { + break + } + v.reset(OpARMSLLconst) + v.AuxInt = log2(c / 3) + v0 := b.NewValue0(v.Line, OpARMADDshiftLL, x.Type) + v0.AddArg(x) + v0.AddArg(x) + v0.AuxInt = 1 + v.AddArg(v0) + return true + } + // match: (MUL x (MOVWconst [c])) + // cond: c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) + // result: (SLLconst [log2(c/5)] (ADDshiftLL x x [2])) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + if !(c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c)) { + break + } + v.reset(OpARMSLLconst) + v.AuxInt = log2(c / 5) + v0 := b.NewValue0(v.Line, OpARMADDshiftLL, x.Type) + v0.AddArg(x) + v0.AddArg(x) + v0.AuxInt = 2 + v.AddArg(v0) + return true + } + // match: (MUL x (MOVWconst [c])) + // cond: c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) + // result: (SLLconst [log2(c/7)] (RSBshiftLL x x [3])) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + if !(c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c)) { + break + } + v.reset(OpARMSLLconst) + v.AuxInt = log2(c / 7) + v0 := b.NewValue0(v.Line, OpARMRSBshiftLL, x.Type) + v0.AddArg(x) + v0.AddArg(x) + v0.AuxInt = 3 + v.AddArg(v0) + return true + } + // match: (MUL x (MOVWconst [c])) + // cond: c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) + // result: (SLLconst [log2(c/9)] (ADDshiftLL x x [3])) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + if !(c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c)) { + break + } + v.reset(OpARMSLLconst) + v.AuxInt = log2(c / 9) + v0 := b.NewValue0(v.Line, OpARMADDshiftLL, x.Type) + v0.AddArg(x) + v0.AddArg(x) + v0.AuxInt = 3 + v.AddArg(v0) + return true + } + // match: (MUL (MOVWconst [c]) x) + // cond: int32(c) == -1 // result: (RSBconst [0] x) for { v_0 := v.Args[0] if v_0.Op != OpARMMOVWconst { break } - if v_0.AuxInt != -1 { + c := v_0.AuxInt + x := v.Args[1] + if !(int32(c) == -1) { break } - x := v.Args[1] v.reset(OpARMRSBconst) v.AuxInt = 0 v.AddArg(x) @@ -5263,6 +9449,132 @@ func rewriteValueARM_OpARMMUL(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (MUL (MOVWconst [c]) x) + // cond: isPowerOfTwo(c-1) && int32(c) >= 3 + // result: (ADDshiftLL x x [log2(c-1)]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + if !(isPowerOfTwo(c-1) && int32(c) >= 3) { + break + } + v.reset(OpARMADDshiftLL) + v.AddArg(x) + v.AddArg(x) + v.AuxInt = log2(c - 1) + return true + } + // match: (MUL (MOVWconst [c]) x) + // cond: isPowerOfTwo(c+1) && int32(c) >= 7 + // result: (RSBshiftLL x x [log2(c+1)]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + if !(isPowerOfTwo(c+1) && int32(c) >= 7) { + break + } + v.reset(OpARMRSBshiftLL) + v.AddArg(x) + v.AddArg(x) + v.AuxInt = log2(c + 1) + return true + } + // match: (MUL (MOVWconst [c]) x) + // cond: c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) + // result: (SLLconst [log2(c/3)] (ADDshiftLL x x [1])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + if !(c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c)) { + break + } + v.reset(OpARMSLLconst) + v.AuxInt = log2(c / 3) + v0 := b.NewValue0(v.Line, OpARMADDshiftLL, x.Type) + v0.AddArg(x) + v0.AddArg(x) + v0.AuxInt = 1 + v.AddArg(v0) + return true + } + // match: (MUL (MOVWconst [c]) x) + // cond: c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) + // result: (SLLconst [log2(c/5)] (ADDshiftLL x x [2])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + if !(c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c)) { + break + } + v.reset(OpARMSLLconst) + v.AuxInt = log2(c / 5) + v0 := b.NewValue0(v.Line, OpARMADDshiftLL, x.Type) + v0.AddArg(x) + v0.AddArg(x) + v0.AuxInt = 2 + v.AddArg(v0) + return true + } + // match: (MUL (MOVWconst [c]) x) + // cond: c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) + // result: (SLLconst [log2(c/7)] (RSBshiftLL x x [3])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + if !(c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c)) { + break + } + v.reset(OpARMSLLconst) + v.AuxInt = log2(c / 7) + v0 := b.NewValue0(v.Line, OpARMRSBshiftLL, x.Type) + v0.AddArg(x) + v0.AddArg(x) + v0.AuxInt = 3 + v.AddArg(v0) + return true + } + // match: (MUL (MOVWconst [c]) x) + // cond: c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) + // result: (SLLconst [log2(c/9)] (ADDshiftLL x x [3])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + if !(c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c)) { + break + } + v.reset(OpARMSLLconst) + v.AuxInt = log2(c / 9) + v0 := b.NewValue0(v.Line, OpARMADDshiftLL, x.Type) + v0.AddArg(x) + v0.AddArg(x) + v0.AuxInt = 3 + v.AddArg(v0) + return true + } // match: (MUL (MOVWconst [c]) (MOVWconst [d])) // cond: // result: (MOVWconst [int64(int32(c*d))]) @@ -5286,8 +9598,8 @@ func rewriteValueARM_OpARMMUL(v *Value, config *Config) bool { func rewriteValueARM_OpARMMULA(v *Value, config *Config) bool { b := v.Block _ = b - // match: (MULA x (MOVWconst [-1]) a) - // cond: + // match: (MULA x (MOVWconst [c]) a) + // cond: int32(c) == -1 // result: (SUB a x) for { x := v.Args[0] @@ -5295,10 +9607,11 @@ func rewriteValueARM_OpARMMULA(v *Value, config *Config) bool { if v_1.Op != OpARMMOVWconst { break } - if v_1.AuxInt != -1 { + c := v_1.AuxInt + a := v.Args[2] + if !(int32(c) == -1) { break } - a := v.Args[2] v.reset(OpARMSUB) v.AddArg(a) v.AddArg(x) @@ -5361,19 +9674,170 @@ func rewriteValueARM_OpARMMULA(v *Value, config *Config) bool { v.AddArg(a) return true } - // match: (MULA (MOVWconst [-1]) x a) - // cond: + // match: (MULA x (MOVWconst [c]) a) + // cond: isPowerOfTwo(c-1) && int32(c) >= 3 + // result: (ADD (ADDshiftLL x x [log2(c-1)]) a) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + a := v.Args[2] + if !(isPowerOfTwo(c-1) && int32(c) >= 3) { + break + } + v.reset(OpARMADD) + v0 := b.NewValue0(v.Line, OpARMADDshiftLL, x.Type) + v0.AddArg(x) + v0.AddArg(x) + v0.AuxInt = log2(c - 1) + v.AddArg(v0) + v.AddArg(a) + return true + } + // match: (MULA x (MOVWconst [c]) a) + // cond: isPowerOfTwo(c+1) && int32(c) >= 7 + // result: (ADD (RSBshiftLL x x [log2(c+1)]) a) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + a := v.Args[2] + if !(isPowerOfTwo(c+1) && int32(c) >= 7) { + break + } + v.reset(OpARMADD) + v0 := b.NewValue0(v.Line, OpARMRSBshiftLL, x.Type) + v0.AddArg(x) + v0.AddArg(x) + v0.AuxInt = log2(c + 1) + v.AddArg(v0) + v.AddArg(a) + return true + } + // match: (MULA x (MOVWconst [c]) a) + // cond: c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) + // result: (ADD (SLLconst [log2(c/3)] (ADDshiftLL x x [1])) a) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + a := v.Args[2] + if !(c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c)) { + break + } + v.reset(OpARMADD) + v0 := b.NewValue0(v.Line, OpARMSLLconst, x.Type) + v0.AuxInt = log2(c / 3) + v1 := b.NewValue0(v.Line, OpARMADDshiftLL, x.Type) + v1.AddArg(x) + v1.AddArg(x) + v1.AuxInt = 1 + v0.AddArg(v1) + v.AddArg(v0) + v.AddArg(a) + return true + } + // match: (MULA x (MOVWconst [c]) a) + // cond: c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) + // result: (ADD (SLLconst [log2(c/5)] (ADDshiftLL x x [2])) a) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + a := v.Args[2] + if !(c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c)) { + break + } + v.reset(OpARMADD) + v0 := b.NewValue0(v.Line, OpARMSLLconst, x.Type) + v0.AuxInt = log2(c / 5) + v1 := b.NewValue0(v.Line, OpARMADDshiftLL, x.Type) + v1.AddArg(x) + v1.AddArg(x) + v1.AuxInt = 2 + v0.AddArg(v1) + v.AddArg(v0) + v.AddArg(a) + return true + } + // match: (MULA x (MOVWconst [c]) a) + // cond: c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) + // result: (ADD (SLLconst [log2(c/7)] (RSBshiftLL x x [3])) a) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + a := v.Args[2] + if !(c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c)) { + break + } + v.reset(OpARMADD) + v0 := b.NewValue0(v.Line, OpARMSLLconst, x.Type) + v0.AuxInt = log2(c / 7) + v1 := b.NewValue0(v.Line, OpARMRSBshiftLL, x.Type) + v1.AddArg(x) + v1.AddArg(x) + v1.AuxInt = 3 + v0.AddArg(v1) + v.AddArg(v0) + v.AddArg(a) + return true + } + // match: (MULA x (MOVWconst [c]) a) + // cond: c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) + // result: (ADD (SLLconst [log2(c/9)] (ADDshiftLL x x [3])) a) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + a := v.Args[2] + if !(c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c)) { + break + } + v.reset(OpARMADD) + v0 := b.NewValue0(v.Line, OpARMSLLconst, x.Type) + v0.AuxInt = log2(c / 9) + v1 := b.NewValue0(v.Line, OpARMADDshiftLL, x.Type) + v1.AddArg(x) + v1.AddArg(x) + v1.AuxInt = 3 + v0.AddArg(v1) + v.AddArg(v0) + v.AddArg(a) + return true + } + // match: (MULA (MOVWconst [c]) x a) + // cond: int32(c) == -1 // result: (SUB a x) for { v_0 := v.Args[0] if v_0.Op != OpARMMOVWconst { break } - if v_0.AuxInt != -1 { - break - } + c := v_0.AuxInt x := v.Args[1] a := v.Args[2] + if !(int32(c) == -1) { + break + } v.reset(OpARMSUB) v.AddArg(a) v.AddArg(x) @@ -5436,6 +9900,156 @@ func rewriteValueARM_OpARMMULA(v *Value, config *Config) bool { v.AddArg(a) return true } + // match: (MULA (MOVWconst [c]) x a) + // cond: isPowerOfTwo(c-1) && int32(c) >= 3 + // result: (ADD (ADDshiftLL x x [log2(c-1)]) a) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + a := v.Args[2] + if !(isPowerOfTwo(c-1) && int32(c) >= 3) { + break + } + v.reset(OpARMADD) + v0 := b.NewValue0(v.Line, OpARMADDshiftLL, x.Type) + v0.AddArg(x) + v0.AddArg(x) + v0.AuxInt = log2(c - 1) + v.AddArg(v0) + v.AddArg(a) + return true + } + // match: (MULA (MOVWconst [c]) x a) + // cond: isPowerOfTwo(c+1) && int32(c) >= 7 + // result: (ADD (RSBshiftLL x x [log2(c+1)]) a) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + a := v.Args[2] + if !(isPowerOfTwo(c+1) && int32(c) >= 7) { + break + } + v.reset(OpARMADD) + v0 := b.NewValue0(v.Line, OpARMRSBshiftLL, x.Type) + v0.AddArg(x) + v0.AddArg(x) + v0.AuxInt = log2(c + 1) + v.AddArg(v0) + v.AddArg(a) + return true + } + // match: (MULA (MOVWconst [c]) x a) + // cond: c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c) + // result: (ADD (SLLconst [log2(c/3)] (ADDshiftLL x x [1])) a) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + a := v.Args[2] + if !(c%3 == 0 && isPowerOfTwo(c/3) && is32Bit(c)) { + break + } + v.reset(OpARMADD) + v0 := b.NewValue0(v.Line, OpARMSLLconst, x.Type) + v0.AuxInt = log2(c / 3) + v1 := b.NewValue0(v.Line, OpARMADDshiftLL, x.Type) + v1.AddArg(x) + v1.AddArg(x) + v1.AuxInt = 1 + v0.AddArg(v1) + v.AddArg(v0) + v.AddArg(a) + return true + } + // match: (MULA (MOVWconst [c]) x a) + // cond: c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c) + // result: (ADD (SLLconst [log2(c/5)] (ADDshiftLL x x [2])) a) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + a := v.Args[2] + if !(c%5 == 0 && isPowerOfTwo(c/5) && is32Bit(c)) { + break + } + v.reset(OpARMADD) + v0 := b.NewValue0(v.Line, OpARMSLLconst, x.Type) + v0.AuxInt = log2(c / 5) + v1 := b.NewValue0(v.Line, OpARMADDshiftLL, x.Type) + v1.AddArg(x) + v1.AddArg(x) + v1.AuxInt = 2 + v0.AddArg(v1) + v.AddArg(v0) + v.AddArg(a) + return true + } + // match: (MULA (MOVWconst [c]) x a) + // cond: c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c) + // result: (ADD (SLLconst [log2(c/7)] (RSBshiftLL x x [3])) a) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + a := v.Args[2] + if !(c%7 == 0 && isPowerOfTwo(c/7) && is32Bit(c)) { + break + } + v.reset(OpARMADD) + v0 := b.NewValue0(v.Line, OpARMSLLconst, x.Type) + v0.AuxInt = log2(c / 7) + v1 := b.NewValue0(v.Line, OpARMRSBshiftLL, x.Type) + v1.AddArg(x) + v1.AddArg(x) + v1.AuxInt = 3 + v0.AddArg(v1) + v.AddArg(v0) + v.AddArg(a) + return true + } + // match: (MULA (MOVWconst [c]) x a) + // cond: c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) + // result: (ADD (SLLconst [log2(c/9)] (ADDshiftLL x x [3])) a) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + a := v.Args[2] + if !(c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c)) { + break + } + v.reset(OpARMADD) + v0 := b.NewValue0(v.Line, OpARMSLLconst, x.Type) + v0.AuxInt = log2(c / 9) + v1 := b.NewValue0(v.Line, OpARMADDshiftLL, x.Type) + v1.AddArg(x) + v1.AddArg(x) + v1.AuxInt = 3 + v0.AddArg(v1) + v.AddArg(v0) + v.AddArg(a) + return true + } // match: (MULA (MOVWconst [c]) (MOVWconst [d]) a) // cond: // result: (ADDconst [int64(int32(c*d))] a) @@ -5474,6 +10088,213 @@ func rewriteValueARM_OpARMMVN(v *Value, config *Config) bool { v.AuxInt = ^c return true } + // match: (MVN (SLLconst [c] x)) + // cond: + // result: (MVNshiftLL x [c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSLLconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v.reset(OpARMMVNshiftLL) + v.AddArg(x) + v.AuxInt = c + return true + } + // match: (MVN (SRLconst [c] x)) + // cond: + // result: (MVNshiftRL x [c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRLconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v.reset(OpARMMVNshiftRL) + v.AddArg(x) + v.AuxInt = c + return true + } + // match: (MVN (SRAconst [c] x)) + // cond: + // result: (MVNshiftRA x [c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRAconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v.reset(OpARMMVNshiftRA) + v.AddArg(x) + v.AuxInt = c + return true + } + // match: (MVN (SLL x y)) + // cond: + // result: (MVNshiftLLreg x y) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSLL { + break + } + x := v_0.Args[0] + y := v_0.Args[1] + v.reset(OpARMMVNshiftLLreg) + v.AddArg(x) + v.AddArg(y) + return true + } + // match: (MVN (SRL x y)) + // cond: + // result: (MVNshiftRLreg x y) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRL { + break + } + x := v_0.Args[0] + y := v_0.Args[1] + v.reset(OpARMMVNshiftRLreg) + v.AddArg(x) + v.AddArg(y) + return true + } + // match: (MVN (SRA x y)) + // cond: + // result: (MVNshiftRAreg x y) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRA { + break + } + x := v_0.Args[0] + y := v_0.Args[1] + v.reset(OpARMMVNshiftRAreg) + v.AddArg(x) + v.AddArg(y) + return true + } + return false +} +func rewriteValueARM_OpARMMVNshiftLL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (MVNshiftLL (MOVWconst [c]) [d]) + // cond: + // result: (MOVWconst [^int64(uint32(c)<>uint64(d))]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + d := v.AuxInt + v.reset(OpARMMOVWconst) + v.AuxInt = ^int64(int32(c) >> uint64(d)) + return true + } + return false +} +func rewriteValueARM_OpARMMVNshiftRAreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (MVNshiftRAreg x (MOVWconst [c])) + // cond: + // result: (MVNshiftRA x [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + v.reset(OpARMMVNshiftRA) + v.AddArg(x) + v.AuxInt = c + return true + } + return false +} +func rewriteValueARM_OpARMMVNshiftRL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (MVNshiftRL (MOVWconst [c]) [d]) + // cond: + // result: (MOVWconst [^int64(uint32(c)>>uint64(d))]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + d := v.AuxInt + v.reset(OpARMMOVWconst) + v.AuxInt = ^int64(uint32(c) >> uint64(d)) + return true + } + return false +} +func rewriteValueARM_OpARMMVNshiftRLreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (MVNshiftRLreg x (MOVWconst [c])) + // cond: + // result: (MVNshiftRL x [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + v.reset(OpARMMVNshiftRL) + v.AddArg(x) + v.AuxInt = c + return true + } return false } func rewriteValueARM_OpMod16(v *Value, config *Config) bool { @@ -6293,6 +11114,210 @@ func rewriteValueARM_OpARMOR(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (OR x (SLLconst [c] y)) + // cond: + // result: (ORshiftLL x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSLLconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + v.reset(OpARMORshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (OR (SLLconst [c] y) x) + // cond: + // result: (ORshiftLL x y [c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSLLconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + v.reset(OpARMORshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (OR x (SRLconst [c] y)) + // cond: + // result: (ORshiftRL x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRLconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + v.reset(OpARMORshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (OR (SRLconst [c] y) x) + // cond: + // result: (ORshiftRL x y [c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRLconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + v.reset(OpARMORshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (OR x (SRAconst [c] y)) + // cond: + // result: (ORshiftRA x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRAconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + v.reset(OpARMORshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (OR (SRAconst [c] y) x) + // cond: + // result: (ORshiftRA x y [c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRAconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + v.reset(OpARMORshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (OR x (SLL y z)) + // cond: + // result: (ORshiftLLreg x y z) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSLL { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + v.reset(OpARMORshiftLLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (OR (SLL y z) x) + // cond: + // result: (ORshiftLLreg x y z) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSLL { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + v.reset(OpARMORshiftLLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (OR x (SRL y z)) + // cond: + // result: (ORshiftRLreg x y z) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRL { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + v.reset(OpARMORshiftRLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (OR (SRL y z) x) + // cond: + // result: (ORshiftRLreg x y z) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRL { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + v.reset(OpARMORshiftRLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (OR x (SRA y z)) + // cond: + // result: (ORshiftRAreg x y z) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRA { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + v.reset(OpARMORshiftRAreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (OR (SRA y z) x) + // cond: + // result: (ORshiftRAreg x y z) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRA { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + v.reset(OpARMORshiftRAreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } // match: (OR x x) // cond: // result: x @@ -6368,6 +11393,315 @@ func rewriteValueARM_OpARMORconst(v *Value, config *Config) bool { } return false } +func rewriteValueARM_OpARMORshiftLL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (ORshiftLL (MOVWconst [c]) x [d]) + // cond: + // result: (ORconst [c] (SLLconst x [d])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + v.reset(OpARMORconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSLLconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + return true + } + // match: (ORshiftLL x (MOVWconst [c]) [d]) + // cond: + // result: (ORconst x [int64(uint32(c)< x y)) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + v.reset(OpARMORconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSLL, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + return true + } + // match: (ORshiftLLreg x y (MOVWconst [c])) + // cond: + // result: (ORshiftLL x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMORshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + return false +} +func rewriteValueARM_OpARMORshiftRA(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (ORshiftRA (MOVWconst [c]) x [d]) + // cond: + // result: (ORconst [c] (SRAconst x [d])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + v.reset(OpARMORconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRAconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + return true + } + // match: (ORshiftRA x (MOVWconst [c]) [d]) + // cond: + // result: (ORconst x [int64(int32(c)>>uint64(d))]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + v.reset(OpARMORconst) + v.AddArg(x) + v.AuxInt = int64(int32(c) >> uint64(d)) + return true + } + // match: (ORshiftRA x y:(SRAconst x [c]) [d]) + // cond: c==d + // result: y + for { + x := v.Args[0] + y := v.Args[1] + if y.Op != OpARMSRAconst { + break + } + if x != y.Args[0] { + break + } + c := y.AuxInt + d := v.AuxInt + if !(c == d) { + break + } + v.reset(OpCopy) + v.Type = y.Type + v.AddArg(y) + return true + } + return false +} +func rewriteValueARM_OpARMORshiftRAreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (ORshiftRAreg (MOVWconst [c]) x y) + // cond: + // result: (ORconst [c] (SRA x y)) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + v.reset(OpARMORconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRA, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + return true + } + // match: (ORshiftRAreg x y (MOVWconst [c])) + // cond: + // result: (ORshiftRA x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMORshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + return false +} +func rewriteValueARM_OpARMORshiftRL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (ORshiftRL (MOVWconst [c]) x [d]) + // cond: + // result: (ORconst [c] (SRLconst x [d])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + v.reset(OpARMORconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRLconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + return true + } + // match: (ORshiftRL x (MOVWconst [c]) [d]) + // cond: + // result: (ORconst x [int64(uint32(c)>>uint64(d))]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + v.reset(OpARMORconst) + v.AddArg(x) + v.AuxInt = int64(uint32(c) >> uint64(d)) + return true + } + // match: (ORshiftRL x y:(SRLconst x [c]) [d]) + // cond: c==d + // result: y + for { + x := v.Args[0] + y := v.Args[1] + if y.Op != OpARMSRLconst { + break + } + if x != y.Args[0] { + break + } + c := y.AuxInt + d := v.AuxInt + if !(c == d) { + break + } + v.reset(OpCopy) + v.Type = y.Type + v.AddArg(y) + return true + } + return false +} +func rewriteValueARM_OpARMORshiftRLreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (ORshiftRLreg (MOVWconst [c]) x y) + // cond: + // result: (ORconst [c] (SRL x y)) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + v.reset(OpARMORconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRL, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + return true + } + // match: (ORshiftRLreg x y (MOVWconst [c])) + // cond: + // result: (ORshiftRL x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMORshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + return false +} func rewriteValueARM_OpOffPtr(v *Value, config *Config) bool { b := v.Block _ = b @@ -6490,6 +11824,465 @@ func rewriteValueARM_OpARMRSB(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (RSB x (SLLconst [c] y)) + // cond: + // result: (RSBshiftLL x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSLLconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + v.reset(OpARMRSBshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (RSB (SLLconst [c] y) x) + // cond: + // result: (SUBshiftLL x y [c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSLLconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + v.reset(OpARMSUBshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (RSB x (SRLconst [c] y)) + // cond: + // result: (RSBshiftRL x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRLconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + v.reset(OpARMRSBshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (RSB (SRLconst [c] y) x) + // cond: + // result: (SUBshiftRL x y [c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRLconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + v.reset(OpARMSUBshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (RSB x (SRAconst [c] y)) + // cond: + // result: (RSBshiftRA x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRAconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + v.reset(OpARMRSBshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (RSB (SRAconst [c] y) x) + // cond: + // result: (SUBshiftRA x y [c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRAconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + v.reset(OpARMSUBshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (RSB x (SLL y z)) + // cond: + // result: (RSBshiftLLreg x y z) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSLL { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + v.reset(OpARMRSBshiftLLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (RSB (SLL y z) x) + // cond: + // result: (SUBshiftLLreg x y z) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSLL { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + v.reset(OpARMSUBshiftLLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (RSB x (SRL y z)) + // cond: + // result: (RSBshiftRLreg x y z) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRL { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + v.reset(OpARMRSBshiftRLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (RSB (SRL y z) x) + // cond: + // result: (SUBshiftRLreg x y z) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRL { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + v.reset(OpARMSUBshiftRLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (RSB x (SRA y z)) + // cond: + // result: (RSBshiftRAreg x y z) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRA { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + v.reset(OpARMRSBshiftRAreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (RSB (SRA y z) x) + // cond: + // result: (SUBshiftRAreg x y z) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRA { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + v.reset(OpARMSUBshiftRAreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (RSB x x) + // cond: + // result: (MOVWconst [0]) + for { + x := v.Args[0] + if x != v.Args[1] { + break + } + v.reset(OpARMMOVWconst) + v.AuxInt = 0 + return true + } + return false +} +func rewriteValueARM_OpARMRSBSshiftLL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (RSBSshiftLL (MOVWconst [c]) x [d]) + // cond: + // result: (SUBSconst [c] (SLLconst x [d])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + v.reset(OpARMSUBSconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSLLconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + return true + } + // match: (RSBSshiftLL x (MOVWconst [c]) [d]) + // cond: + // result: (RSBSconst x [int64(uint32(c)< x y)) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + v.reset(OpARMSUBSconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSLL, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + return true + } + // match: (RSBSshiftLLreg x y (MOVWconst [c])) + // cond: + // result: (RSBSshiftLL x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMRSBSshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + return false +} +func rewriteValueARM_OpARMRSBSshiftRA(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (RSBSshiftRA (MOVWconst [c]) x [d]) + // cond: + // result: (SUBSconst [c] (SRAconst x [d])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + v.reset(OpARMSUBSconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRAconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + return true + } + // match: (RSBSshiftRA x (MOVWconst [c]) [d]) + // cond: + // result: (RSBSconst x [int64(int32(c)>>uint64(d))]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + v.reset(OpARMRSBSconst) + v.AddArg(x) + v.AuxInt = int64(int32(c) >> uint64(d)) + return true + } + return false +} +func rewriteValueARM_OpARMRSBSshiftRAreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (RSBSshiftRAreg (MOVWconst [c]) x y) + // cond: + // result: (SUBSconst [c] (SRA x y)) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + v.reset(OpARMSUBSconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRA, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + return true + } + // match: (RSBSshiftRAreg x y (MOVWconst [c])) + // cond: + // result: (RSBSshiftRA x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMRSBSshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + return false +} +func rewriteValueARM_OpARMRSBSshiftRL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (RSBSshiftRL (MOVWconst [c]) x [d]) + // cond: + // result: (SUBSconst [c] (SRLconst x [d])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + v.reset(OpARMSUBSconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRLconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + return true + } + // match: (RSBSshiftRL x (MOVWconst [c]) [d]) + // cond: + // result: (RSBSconst x [int64(uint32(c)>>uint64(d))]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + v.reset(OpARMRSBSconst) + v.AddArg(x) + v.AuxInt = int64(uint32(c) >> uint64(d)) + return true + } + return false +} +func rewriteValueARM_OpARMRSBSshiftRLreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (RSBSshiftRLreg (MOVWconst [c]) x y) + // cond: + // result: (SUBSconst [c] (SRL x y)) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + v.reset(OpARMSUBSconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRL, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + return true + } + // match: (RSBSshiftRLreg x y (MOVWconst [c])) + // cond: + // result: (RSBSshiftRL x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMRSBSshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } return false } func rewriteValueARM_OpARMRSBconst(v *Value, config *Config) bool { @@ -6559,6 +12352,312 @@ func rewriteValueARM_OpARMRSBconst(v *Value, config *Config) bool { } return false } +func rewriteValueARM_OpARMRSBshiftLL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (RSBshiftLL (MOVWconst [c]) x [d]) + // cond: + // result: (SUBconst [c] (SLLconst x [d])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + v.reset(OpARMSUBconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSLLconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + return true + } + // match: (RSBshiftLL x (MOVWconst [c]) [d]) + // cond: + // result: (RSBconst x [int64(uint32(c)< x y)) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + v.reset(OpARMSUBconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSLL, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + return true + } + // match: (RSBshiftLLreg x y (MOVWconst [c])) + // cond: + // result: (RSBshiftLL x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMRSBshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + return false +} +func rewriteValueARM_OpARMRSBshiftRA(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (RSBshiftRA (MOVWconst [c]) x [d]) + // cond: + // result: (SUBconst [c] (SRAconst x [d])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + v.reset(OpARMSUBconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRAconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + return true + } + // match: (RSBshiftRA x (MOVWconst [c]) [d]) + // cond: + // result: (RSBconst x [int64(int32(c)>>uint64(d))]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + v.reset(OpARMRSBconst) + v.AddArg(x) + v.AuxInt = int64(int32(c) >> uint64(d)) + return true + } + // match: (RSBshiftRA x (SRAconst x [c]) [d]) + // cond: c==d + // result: (MOVWconst [0]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRAconst { + break + } + if x != v_1.Args[0] { + break + } + c := v_1.AuxInt + d := v.AuxInt + if !(c == d) { + break + } + v.reset(OpARMMOVWconst) + v.AuxInt = 0 + return true + } + return false +} +func rewriteValueARM_OpARMRSBshiftRAreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (RSBshiftRAreg (MOVWconst [c]) x y) + // cond: + // result: (SUBconst [c] (SRA x y)) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + v.reset(OpARMSUBconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRA, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + return true + } + // match: (RSBshiftRAreg x y (MOVWconst [c])) + // cond: + // result: (RSBshiftRA x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMRSBshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + return false +} +func rewriteValueARM_OpARMRSBshiftRL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (RSBshiftRL (MOVWconst [c]) x [d]) + // cond: + // result: (SUBconst [c] (SRLconst x [d])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + v.reset(OpARMSUBconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRLconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + return true + } + // match: (RSBshiftRL x (MOVWconst [c]) [d]) + // cond: + // result: (RSBconst x [int64(uint32(c)>>uint64(d))]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + v.reset(OpARMRSBconst) + v.AddArg(x) + v.AuxInt = int64(uint32(c) >> uint64(d)) + return true + } + // match: (RSBshiftRL x (SRLconst x [c]) [d]) + // cond: c==d + // result: (MOVWconst [0]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRLconst { + break + } + if x != v_1.Args[0] { + break + } + c := v_1.AuxInt + d := v.AuxInt + if !(c == d) { + break + } + v.reset(OpARMMOVWconst) + v.AuxInt = 0 + return true + } + return false +} +func rewriteValueARM_OpARMRSBshiftRLreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (RSBshiftRLreg (MOVWconst [c]) x y) + // cond: + // result: (SUBconst [c] (SRL x y)) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + v.reset(OpARMSUBconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRL, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + return true + } + // match: (RSBshiftRLreg x y (MOVWconst [c])) + // cond: + // result: (RSBshiftRL x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMRSBshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + return false +} func rewriteValueARM_OpARMRSCconst(v *Value, config *Config) bool { b := v.Block _ = b @@ -6600,22 +12699,298 @@ func rewriteValueARM_OpARMRSCconst(v *Value, config *Config) bool { } return false } +func rewriteValueARM_OpARMRSCshiftLL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (RSCshiftLL (MOVWconst [c]) x [d] flags) + // cond: + // result: (SBCconst [c] (SLLconst x [d]) flags) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + flags := v.Args[2] + v.reset(OpARMSBCconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSLLconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + v.AddArg(flags) + return true + } + // match: (RSCshiftLL x (MOVWconst [c]) [d] flags) + // cond: + // result: (RSCconst x [int64(uint32(c)< x y) flags) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + flags := v.Args[3] + v.reset(OpARMSBCconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSLL, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + v.AddArg(flags) + return true + } + // match: (RSCshiftLLreg x y (MOVWconst [c]) flags) + // cond: + // result: (RSCshiftLL x y [c] flags) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + flags := v.Args[3] + v.reset(OpARMRSCshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + v.AddArg(flags) + return true + } + return false +} +func rewriteValueARM_OpARMRSCshiftRA(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (RSCshiftRA (MOVWconst [c]) x [d] flags) + // cond: + // result: (SBCconst [c] (SRAconst x [d]) flags) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + flags := v.Args[2] + v.reset(OpARMSBCconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRAconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + v.AddArg(flags) + return true + } + // match: (RSCshiftRA x (MOVWconst [c]) [d] flags) + // cond: + // result: (RSCconst x [int64(int32(c)>>uint64(d))] flags) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + flags := v.Args[2] + v.reset(OpARMRSCconst) + v.AddArg(x) + v.AuxInt = int64(int32(c) >> uint64(d)) + v.AddArg(flags) + return true + } + return false +} +func rewriteValueARM_OpARMRSCshiftRAreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (RSCshiftRAreg (MOVWconst [c]) x y flags) + // cond: + // result: (SBCconst [c] (SRA x y) flags) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + flags := v.Args[3] + v.reset(OpARMSBCconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRA, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + v.AddArg(flags) + return true + } + // match: (RSCshiftRAreg x y (MOVWconst [c]) flags) + // cond: + // result: (RSCshiftRA x y [c] flags) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + flags := v.Args[3] + v.reset(OpARMRSCshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + v.AddArg(flags) + return true + } + return false +} +func rewriteValueARM_OpARMRSCshiftRL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (RSCshiftRL (MOVWconst [c]) x [d] flags) + // cond: + // result: (SBCconst [c] (SRLconst x [d]) flags) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + flags := v.Args[2] + v.reset(OpARMSBCconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRLconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + v.AddArg(flags) + return true + } + // match: (RSCshiftRL x (MOVWconst [c]) [d] flags) + // cond: + // result: (RSCconst x [int64(uint32(c)>>uint64(d))] flags) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + flags := v.Args[2] + v.reset(OpARMRSCconst) + v.AddArg(x) + v.AuxInt = int64(uint32(c) >> uint64(d)) + v.AddArg(flags) + return true + } + return false +} +func rewriteValueARM_OpARMRSCshiftRLreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (RSCshiftRLreg (MOVWconst [c]) x y flags) + // cond: + // result: (SBCconst [c] (SRL x y) flags) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + flags := v.Args[3] + v.reset(OpARMSBCconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRL, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + v.AddArg(flags) + return true + } + // match: (RSCshiftRLreg x y (MOVWconst [c]) flags) + // cond: + // result: (RSCshiftRL x y [c] flags) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + flags := v.Args[3] + v.reset(OpARMRSCshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + v.AddArg(flags) + return true + } + return false +} func rewriteValueARM_OpRsh16Ux16(v *Value, config *Config) bool { b := v.Block _ = b // match: (Rsh16Ux16 x y) // cond: - // result: (SRL (ZeroExt16to32 x) (ZeroExt16to32 y)) + // result: (CMOVWHSconst (SRL (ZeroExt16to32 x) (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0]) for { x := v.Args[0] y := v.Args[1] - v.reset(OpARMSRL) - v0 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32()) - v0.AddArg(x) - v.AddArg(v0) + v.reset(OpARMCMOVWHSconst) + v0 := b.NewValue0(v.Line, OpARMSRL, x.Type) v1 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32()) - v1.AddArg(y) - v.AddArg(v1) + v1.AddArg(x) + v0.AddArg(v1) + v2 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32()) + v2.AddArg(y) + v0.AddArg(v2) + v.AddArg(v0) + v3 := b.NewValue0(v.Line, OpARMCMPconst, TypeFlags) + v3.AuxInt = 256 + v4 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32()) + v4.AddArg(y) + v3.AddArg(v4) + v.AddArg(v3) + v.AuxInt = 0 return true } } @@ -6624,15 +12999,22 @@ func rewriteValueARM_OpRsh16Ux32(v *Value, config *Config) bool { _ = b // match: (Rsh16Ux32 x y) // cond: - // result: (SRL (ZeroExt16to32 x) y) + // result: (CMOVWHSconst (SRL (ZeroExt16to32 x) y) (CMPconst [256] y) [0]) for { x := v.Args[0] y := v.Args[1] - v.reset(OpARMSRL) - v0 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32()) - v0.AddArg(x) + v.reset(OpARMCMOVWHSconst) + v0 := b.NewValue0(v.Line, OpARMSRL, x.Type) + v1 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32()) + v1.AddArg(x) + v0.AddArg(v1) + v0.AddArg(y) v.AddArg(v0) - v.AddArg(y) + v2 := b.NewValue0(v.Line, OpARMCMPconst, TypeFlags) + v2.AuxInt = 256 + v2.AddArg(y) + v.AddArg(v2) + v.AuxInt = 0 return true } } @@ -6702,17 +13084,23 @@ func rewriteValueARM_OpRsh16x16(v *Value, config *Config) bool { _ = b // match: (Rsh16x16 x y) // cond: - // result: (SRA (SignExt16to32 x) (ZeroExt16to32 y)) + // result: (SRAcond (SignExt16to32 x) (ZeroExt16to32 y) (CMPconst [256] (ZeroExt16to32 y))) for { x := v.Args[0] y := v.Args[1] - v.reset(OpARMSRA) + v.reset(OpARMSRAcond) v0 := b.NewValue0(v.Line, OpSignExt16to32, config.fe.TypeInt32()) v0.AddArg(x) v.AddArg(v0) v1 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32()) v1.AddArg(y) v.AddArg(v1) + v2 := b.NewValue0(v.Line, OpARMCMPconst, TypeFlags) + v2.AuxInt = 256 + v3 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32()) + v3.AddArg(y) + v2.AddArg(v3) + v.AddArg(v2) return true } } @@ -6721,15 +13109,19 @@ func rewriteValueARM_OpRsh16x32(v *Value, config *Config) bool { _ = b // match: (Rsh16x32 x y) // cond: - // result: (SRA (SignExt16to32 x) y) + // result: (SRAcond (SignExt16to32 x) y (CMPconst [256] y)) for { x := v.Args[0] y := v.Args[1] - v.reset(OpARMSRA) + v.reset(OpARMSRAcond) v0 := b.NewValue0(v.Line, OpSignExt16to32, config.fe.TypeInt32()) v0.AddArg(x) v.AddArg(v0) v.AddArg(y) + v1 := b.NewValue0(v.Line, OpARMCMPconst, TypeFlags) + v1.AuxInt = 256 + v1.AddArg(y) + v.AddArg(v1) return true } } @@ -6804,15 +13196,24 @@ func rewriteValueARM_OpRsh32Ux16(v *Value, config *Config) bool { _ = b // match: (Rsh32Ux16 x y) // cond: - // result: (SRL x (ZeroExt16to32 y)) + // result: (CMOVWHSconst (SRL x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0]) for { x := v.Args[0] y := v.Args[1] - v.reset(OpARMSRL) - v.AddArg(x) - v0 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32()) - v0.AddArg(y) + v.reset(OpARMCMOVWHSconst) + v0 := b.NewValue0(v.Line, OpARMSRL, x.Type) + v0.AddArg(x) + v1 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32()) + v1.AddArg(y) + v0.AddArg(v1) v.AddArg(v0) + v2 := b.NewValue0(v.Line, OpARMCMPconst, TypeFlags) + v2.AuxInt = 256 + v3 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32()) + v3.AddArg(y) + v2.AddArg(v3) + v.AddArg(v2) + v.AuxInt = 0 return true } } @@ -6821,13 +13222,20 @@ func rewriteValueARM_OpRsh32Ux32(v *Value, config *Config) bool { _ = b // match: (Rsh32Ux32 x y) // cond: - // result: (SRL x y) + // result: (CMOVWHSconst (SRL x y) (CMPconst [256] y) [0]) for { x := v.Args[0] y := v.Args[1] - v.reset(OpARMSRL) - v.AddArg(x) - v.AddArg(y) + v.reset(OpARMCMOVWHSconst) + v0 := b.NewValue0(v.Line, OpARMSRL, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + v1 := b.NewValue0(v.Line, OpARMCMPconst, TypeFlags) + v1.AuxInt = 256 + v1.AddArg(y) + v.AddArg(v1) + v.AuxInt = 0 return true } } @@ -6892,15 +13300,21 @@ func rewriteValueARM_OpRsh32x16(v *Value, config *Config) bool { _ = b // match: (Rsh32x16 x y) // cond: - // result: (SRA x (ZeroExt16to32 y)) + // result: (SRAcond x (ZeroExt16to32 y) (CMPconst [256] (ZeroExt16to32 y))) for { x := v.Args[0] y := v.Args[1] - v.reset(OpARMSRA) + v.reset(OpARMSRAcond) v.AddArg(x) v0 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32()) v0.AddArg(y) v.AddArg(v0) + v1 := b.NewValue0(v.Line, OpARMCMPconst, TypeFlags) + v1.AuxInt = 256 + v2 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32()) + v2.AddArg(y) + v1.AddArg(v2) + v.AddArg(v1) return true } } @@ -6909,13 +13323,17 @@ func rewriteValueARM_OpRsh32x32(v *Value, config *Config) bool { _ = b // match: (Rsh32x32 x y) // cond: - // result: (SRA x y) + // result: (SRAcond x y (CMPconst [256] y)) for { x := v.Args[0] y := v.Args[1] - v.reset(OpARMSRA) + v.reset(OpARMSRAcond) v.AddArg(x) v.AddArg(y) + v0 := b.NewValue0(v.Line, OpARMCMPconst, TypeFlags) + v0.AuxInt = 256 + v0.AddArg(y) + v.AddArg(v0) return true } } @@ -6982,17 +13400,26 @@ func rewriteValueARM_OpRsh8Ux16(v *Value, config *Config) bool { _ = b // match: (Rsh8Ux16 x y) // cond: - // result: (SRL (ZeroExt8to32 x) (ZeroExt16to32 y)) + // result: (CMOVWHSconst (SRL (ZeroExt8to32 x) (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0]) for { x := v.Args[0] y := v.Args[1] - v.reset(OpARMSRL) - v0 := b.NewValue0(v.Line, OpZeroExt8to32, config.fe.TypeUInt32()) - v0.AddArg(x) + v.reset(OpARMCMOVWHSconst) + v0 := b.NewValue0(v.Line, OpARMSRL, x.Type) + v1 := b.NewValue0(v.Line, OpZeroExt8to32, config.fe.TypeUInt32()) + v1.AddArg(x) + v0.AddArg(v1) + v2 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32()) + v2.AddArg(y) + v0.AddArg(v2) v.AddArg(v0) - v1 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32()) - v1.AddArg(y) - v.AddArg(v1) + v3 := b.NewValue0(v.Line, OpARMCMPconst, TypeFlags) + v3.AuxInt = 256 + v4 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32()) + v4.AddArg(y) + v3.AddArg(v4) + v.AddArg(v3) + v.AuxInt = 0 return true } } @@ -7001,15 +13428,22 @@ func rewriteValueARM_OpRsh8Ux32(v *Value, config *Config) bool { _ = b // match: (Rsh8Ux32 x y) // cond: - // result: (SRL (ZeroExt8to32 x) y) + // result: (CMOVWHSconst (SRL (ZeroExt8to32 x) y) (CMPconst [256] y) [0]) for { x := v.Args[0] y := v.Args[1] - v.reset(OpARMSRL) - v0 := b.NewValue0(v.Line, OpZeroExt8to32, config.fe.TypeUInt32()) - v0.AddArg(x) + v.reset(OpARMCMOVWHSconst) + v0 := b.NewValue0(v.Line, OpARMSRL, x.Type) + v1 := b.NewValue0(v.Line, OpZeroExt8to32, config.fe.TypeUInt32()) + v1.AddArg(x) + v0.AddArg(v1) + v0.AddArg(y) v.AddArg(v0) - v.AddArg(y) + v2 := b.NewValue0(v.Line, OpARMCMPconst, TypeFlags) + v2.AuxInt = 256 + v2.AddArg(y) + v.AddArg(v2) + v.AuxInt = 0 return true } } @@ -7079,17 +13513,23 @@ func rewriteValueARM_OpRsh8x16(v *Value, config *Config) bool { _ = b // match: (Rsh8x16 x y) // cond: - // result: (SRA (SignExt8to32 x) (ZeroExt16to32 y)) + // result: (SRAcond (SignExt8to32 x) (ZeroExt16to32 y) (CMPconst [256] (ZeroExt16to32 y))) for { x := v.Args[0] y := v.Args[1] - v.reset(OpARMSRA) + v.reset(OpARMSRAcond) v0 := b.NewValue0(v.Line, OpSignExt8to32, config.fe.TypeInt32()) v0.AddArg(x) v.AddArg(v0) v1 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32()) v1.AddArg(y) v.AddArg(v1) + v2 := b.NewValue0(v.Line, OpARMCMPconst, TypeFlags) + v2.AuxInt = 256 + v3 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32()) + v3.AddArg(y) + v2.AddArg(v3) + v.AddArg(v2) return true } } @@ -7098,15 +13538,19 @@ func rewriteValueARM_OpRsh8x32(v *Value, config *Config) bool { _ = b // match: (Rsh8x32 x y) // cond: - // result: (SRA (SignExt8to32 x) y) + // result: (SRAcond (SignExt8to32 x) y (CMPconst [256] y)) for { x := v.Args[0] y := v.Args[1] - v.reset(OpARMSRA) + v.reset(OpARMSRAcond) v0 := b.NewValue0(v.Line, OpSignExt8to32, config.fe.TypeInt32()) v0.AddArg(x) v.AddArg(v0) v.AddArg(y) + v1 := b.NewValue0(v.Line, OpARMCMPconst, TypeFlags) + v1.AuxInt = 256 + v1.AddArg(y) + v.AddArg(v1) return true } } @@ -7213,6 +13657,234 @@ func rewriteValueARM_OpARMSBC(v *Value, config *Config) bool { v.AddArg(flags) return true } + // match: (SBC x (SLLconst [c] y) flags) + // cond: + // result: (SBCshiftLL x y [c] flags) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSLLconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + flags := v.Args[2] + v.reset(OpARMSBCshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + v.AddArg(flags) + return true + } + // match: (SBC (SLLconst [c] y) x flags) + // cond: + // result: (RSCshiftLL x y [c] flags) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSLLconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + flags := v.Args[2] + v.reset(OpARMRSCshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + v.AddArg(flags) + return true + } + // match: (SBC x (SRLconst [c] y) flags) + // cond: + // result: (SBCshiftRL x y [c] flags) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRLconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + flags := v.Args[2] + v.reset(OpARMSBCshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + v.AddArg(flags) + return true + } + // match: (SBC (SRLconst [c] y) x flags) + // cond: + // result: (RSCshiftRL x y [c] flags) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRLconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + flags := v.Args[2] + v.reset(OpARMRSCshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + v.AddArg(flags) + return true + } + // match: (SBC x (SRAconst [c] y) flags) + // cond: + // result: (SBCshiftRA x y [c] flags) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRAconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + flags := v.Args[2] + v.reset(OpARMSBCshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + v.AddArg(flags) + return true + } + // match: (SBC (SRAconst [c] y) x flags) + // cond: + // result: (RSCshiftRA x y [c] flags) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRAconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + flags := v.Args[2] + v.reset(OpARMRSCshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + v.AddArg(flags) + return true + } + // match: (SBC x (SLL y z) flags) + // cond: + // result: (SBCshiftLLreg x y z flags) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSLL { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + flags := v.Args[2] + v.reset(OpARMSBCshiftLLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + v.AddArg(flags) + return true + } + // match: (SBC (SLL y z) x flags) + // cond: + // result: (RSCshiftLLreg x y z flags) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSLL { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + flags := v.Args[2] + v.reset(OpARMRSCshiftLLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + v.AddArg(flags) + return true + } + // match: (SBC x (SRL y z) flags) + // cond: + // result: (SBCshiftRLreg x y z flags) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRL { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + flags := v.Args[2] + v.reset(OpARMSBCshiftRLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + v.AddArg(flags) + return true + } + // match: (SBC (SRL y z) x flags) + // cond: + // result: (RSCshiftRLreg x y z flags) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRL { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + flags := v.Args[2] + v.reset(OpARMRSCshiftRLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + v.AddArg(flags) + return true + } + // match: (SBC x (SRA y z) flags) + // cond: + // result: (SBCshiftRAreg x y z flags) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRA { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + flags := v.Args[2] + v.reset(OpARMSBCshiftRAreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + v.AddArg(flags) + return true + } + // match: (SBC (SRA y z) x flags) + // cond: + // result: (RSCshiftRAreg x y z flags) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRA { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + flags := v.Args[2] + v.reset(OpARMRSCshiftRAreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + v.AddArg(flags) + return true + } return false } func rewriteValueARM_OpARMSBCconst(v *Value, config *Config) bool { @@ -7256,6 +13928,273 @@ func rewriteValueARM_OpARMSBCconst(v *Value, config *Config) bool { } return false } +func rewriteValueARM_OpARMSBCshiftLL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (SBCshiftLL (MOVWconst [c]) x [d] flags) + // cond: + // result: (RSCconst [c] (SLLconst x [d]) flags) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + flags := v.Args[2] + v.reset(OpARMRSCconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSLLconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + v.AddArg(flags) + return true + } + // match: (SBCshiftLL x (MOVWconst [c]) [d] flags) + // cond: + // result: (SBCconst x [int64(uint32(c)< x y) flags) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + flags := v.Args[3] + v.reset(OpARMRSCconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSLL, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + v.AddArg(flags) + return true + } + // match: (SBCshiftLLreg x y (MOVWconst [c]) flags) + // cond: + // result: (SBCshiftLL x y [c] flags) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + flags := v.Args[3] + v.reset(OpARMSBCshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + v.AddArg(flags) + return true + } + return false +} +func rewriteValueARM_OpARMSBCshiftRA(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (SBCshiftRA (MOVWconst [c]) x [d] flags) + // cond: + // result: (RSCconst [c] (SRAconst x [d]) flags) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + flags := v.Args[2] + v.reset(OpARMRSCconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRAconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + v.AddArg(flags) + return true + } + // match: (SBCshiftRA x (MOVWconst [c]) [d] flags) + // cond: + // result: (SBCconst x [int64(int32(c)>>uint64(d))] flags) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + flags := v.Args[2] + v.reset(OpARMSBCconst) + v.AddArg(x) + v.AuxInt = int64(int32(c) >> uint64(d)) + v.AddArg(flags) + return true + } + return false +} +func rewriteValueARM_OpARMSBCshiftRAreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (SBCshiftRAreg (MOVWconst [c]) x y flags) + // cond: + // result: (RSCconst [c] (SRA x y) flags) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + flags := v.Args[3] + v.reset(OpARMRSCconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRA, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + v.AddArg(flags) + return true + } + // match: (SBCshiftRAreg x y (MOVWconst [c]) flags) + // cond: + // result: (SBCshiftRA x y [c] flags) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + flags := v.Args[3] + v.reset(OpARMSBCshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + v.AddArg(flags) + return true + } + return false +} +func rewriteValueARM_OpARMSBCshiftRL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (SBCshiftRL (MOVWconst [c]) x [d] flags) + // cond: + // result: (RSCconst [c] (SRLconst x [d]) flags) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + flags := v.Args[2] + v.reset(OpARMRSCconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRLconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + v.AddArg(flags) + return true + } + // match: (SBCshiftRL x (MOVWconst [c]) [d] flags) + // cond: + // result: (SBCconst x [int64(uint32(c)>>uint64(d))] flags) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + flags := v.Args[2] + v.reset(OpARMSBCconst) + v.AddArg(x) + v.AuxInt = int64(uint32(c) >> uint64(d)) + v.AddArg(flags) + return true + } + return false +} +func rewriteValueARM_OpARMSBCshiftRLreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (SBCshiftRLreg (MOVWconst [c]) x y flags) + // cond: + // result: (RSCconst [c] (SRL x y) flags) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + flags := v.Args[3] + v.reset(OpARMRSCconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRL, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + v.AddArg(flags) + return true + } + // match: (SBCshiftRLreg x y (MOVWconst [c]) flags) + // cond: + // result: (SBCshiftRL x y [c] flags) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + flags := v.Args[3] + v.reset(OpARMSBCshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + v.AddArg(flags) + return true + } + return false +} func rewriteValueARM_OpARMSLL(v *Value, config *Config) bool { b := v.Block _ = b @@ -7315,6 +14254,83 @@ func rewriteValueARM_OpARMSRA(v *Value, config *Config) bool { } return false } +func rewriteValueARM_OpARMSRAcond(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (SRAcond x _ (FlagEQ)) + // cond: + // result: (SRAconst x [31]) + for { + x := v.Args[0] + v_2 := v.Args[2] + if v_2.Op != OpARMFlagEQ { + break + } + v.reset(OpARMSRAconst) + v.AddArg(x) + v.AuxInt = 31 + return true + } + // match: (SRAcond x y (FlagLT_ULT)) + // cond: + // result: (SRA x y) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMFlagLT_ULT { + break + } + v.reset(OpARMSRA) + v.AddArg(x) + v.AddArg(y) + return true + } + // match: (SRAcond x _ (FlagLT_UGT)) + // cond: + // result: (SRAconst x [31]) + for { + x := v.Args[0] + v_2 := v.Args[2] + if v_2.Op != OpARMFlagLT_UGT { + break + } + v.reset(OpARMSRAconst) + v.AddArg(x) + v.AuxInt = 31 + return true + } + // match: (SRAcond x y (FlagGT_ULT)) + // cond: + // result: (SRA x y) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMFlagGT_ULT { + break + } + v.reset(OpARMSRA) + v.AddArg(x) + v.AddArg(y) + return true + } + // match: (SRAcond x _ (FlagGT_UGT)) + // cond: + // result: (SRAconst x [31]) + for { + x := v.Args[0] + v_2 := v.Args[2] + if v_2.Op != OpARMFlagGT_UGT { + break + } + v.reset(OpARMSRAconst) + v.AddArg(x) + v.AuxInt = 31 + return true + } + return false +} func rewriteValueARM_OpARMSRAconst(v *Value, config *Config) bool { b := v.Block _ = b @@ -7406,6 +14422,210 @@ func rewriteValueARM_OpARMSUB(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (SUB x (SLLconst [c] y)) + // cond: + // result: (SUBshiftLL x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSLLconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + v.reset(OpARMSUBshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (SUB (SLLconst [c] y) x) + // cond: + // result: (RSBshiftLL x y [c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSLLconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + v.reset(OpARMRSBshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (SUB x (SRLconst [c] y)) + // cond: + // result: (SUBshiftRL x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRLconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + v.reset(OpARMSUBshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (SUB (SRLconst [c] y) x) + // cond: + // result: (RSBshiftRL x y [c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRLconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + v.reset(OpARMRSBshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (SUB x (SRAconst [c] y)) + // cond: + // result: (SUBshiftRA x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRAconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + v.reset(OpARMSUBshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (SUB (SRAconst [c] y) x) + // cond: + // result: (RSBshiftRA x y [c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRAconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + v.reset(OpARMRSBshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (SUB x (SLL y z)) + // cond: + // result: (SUBshiftLLreg x y z) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSLL { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + v.reset(OpARMSUBshiftLLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (SUB (SLL y z) x) + // cond: + // result: (RSBshiftLLreg x y z) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSLL { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + v.reset(OpARMRSBshiftLLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (SUB x (SRL y z)) + // cond: + // result: (SUBshiftRLreg x y z) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRL { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + v.reset(OpARMSUBshiftRLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (SUB (SRL y z) x) + // cond: + // result: (RSBshiftRLreg x y z) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRL { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + v.reset(OpARMRSBshiftRLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (SUB x (SRA y z)) + // cond: + // result: (SUBshiftRAreg x y z) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRA { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + v.reset(OpARMSUBshiftRAreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (SUB (SRA y z) x) + // cond: + // result: (RSBshiftRAreg x y z) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRA { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + v.reset(OpARMRSBshiftRAreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } // match: (SUB x x) // cond: // result: (MOVWconst [0]) @@ -7453,6 +14673,453 @@ func rewriteValueARM_OpARMSUBS(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (SUBS x (SLLconst [c] y)) + // cond: + // result: (SUBSshiftLL x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSLLconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + v.reset(OpARMSUBSshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (SUBS (SLLconst [c] y) x) + // cond: + // result: (RSBSshiftLL x y [c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSLLconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + v.reset(OpARMRSBSshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (SUBS x (SRLconst [c] y)) + // cond: + // result: (SUBSshiftRL x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRLconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + v.reset(OpARMSUBSshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (SUBS (SRLconst [c] y) x) + // cond: + // result: (RSBSshiftRL x y [c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRLconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + v.reset(OpARMRSBSshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (SUBS x (SRAconst [c] y)) + // cond: + // result: (SUBSshiftRA x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRAconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + v.reset(OpARMSUBSshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (SUBS (SRAconst [c] y) x) + // cond: + // result: (RSBSshiftRA x y [c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRAconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + v.reset(OpARMRSBSshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (SUBS x (SLL y z)) + // cond: + // result: (SUBSshiftLLreg x y z) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSLL { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + v.reset(OpARMSUBSshiftLLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (SUBS (SLL y z) x) + // cond: + // result: (RSBSshiftLLreg x y z) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSLL { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + v.reset(OpARMRSBSshiftLLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (SUBS x (SRL y z)) + // cond: + // result: (SUBSshiftRLreg x y z) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRL { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + v.reset(OpARMSUBSshiftRLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (SUBS (SRL y z) x) + // cond: + // result: (RSBSshiftRLreg x y z) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRL { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + v.reset(OpARMRSBSshiftRLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (SUBS x (SRA y z)) + // cond: + // result: (SUBSshiftRAreg x y z) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRA { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + v.reset(OpARMSUBSshiftRAreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (SUBS (SRA y z) x) + // cond: + // result: (RSBSshiftRAreg x y z) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRA { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + v.reset(OpARMRSBSshiftRAreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + return false +} +func rewriteValueARM_OpARMSUBSshiftLL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (SUBSshiftLL (MOVWconst [c]) x [d]) + // cond: + // result: (RSBSconst [c] (SLLconst x [d])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + v.reset(OpARMRSBSconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSLLconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + return true + } + // match: (SUBSshiftLL x (MOVWconst [c]) [d]) + // cond: + // result: (SUBSconst x [int64(uint32(c)< x y)) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + v.reset(OpARMRSBSconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSLL, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + return true + } + // match: (SUBSshiftLLreg x y (MOVWconst [c])) + // cond: + // result: (SUBSshiftLL x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMSUBSshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + return false +} +func rewriteValueARM_OpARMSUBSshiftRA(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (SUBSshiftRA (MOVWconst [c]) x [d]) + // cond: + // result: (RSBSconst [c] (SRAconst x [d])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + v.reset(OpARMRSBSconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRAconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + return true + } + // match: (SUBSshiftRA x (MOVWconst [c]) [d]) + // cond: + // result: (SUBSconst x [int64(int32(c)>>uint64(d))]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + v.reset(OpARMSUBSconst) + v.AddArg(x) + v.AuxInt = int64(int32(c) >> uint64(d)) + return true + } + return false +} +func rewriteValueARM_OpARMSUBSshiftRAreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (SUBSshiftRAreg (MOVWconst [c]) x y) + // cond: + // result: (RSBSconst [c] (SRA x y)) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + v.reset(OpARMRSBSconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRA, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + return true + } + // match: (SUBSshiftRAreg x y (MOVWconst [c])) + // cond: + // result: (SUBSshiftRA x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMSUBSshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + return false +} +func rewriteValueARM_OpARMSUBSshiftRL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (SUBSshiftRL (MOVWconst [c]) x [d]) + // cond: + // result: (RSBSconst [c] (SRLconst x [d])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + v.reset(OpARMRSBSconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRLconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + return true + } + // match: (SUBSshiftRL x (MOVWconst [c]) [d]) + // cond: + // result: (SUBSconst x [int64(uint32(c)>>uint64(d))]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + v.reset(OpARMSUBSconst) + v.AddArg(x) + v.AuxInt = int64(uint32(c) >> uint64(d)) + return true + } + return false +} +func rewriteValueARM_OpARMSUBSshiftRLreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (SUBSshiftRLreg (MOVWconst [c]) x y) + // cond: + // result: (RSBSconst [c] (SRL x y)) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + v.reset(OpARMRSBSconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRL, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + return true + } + // match: (SUBSshiftRLreg x y (MOVWconst [c])) + // cond: + // result: (SUBSshiftRL x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMSUBSshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } return false } func rewriteValueARM_OpARMSUBconst(v *Value, config *Config) bool { @@ -7535,6 +15202,312 @@ func rewriteValueARM_OpARMSUBconst(v *Value, config *Config) bool { } return false } +func rewriteValueARM_OpARMSUBshiftLL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (SUBshiftLL (MOVWconst [c]) x [d]) + // cond: + // result: (RSBconst [c] (SLLconst x [d])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + v.reset(OpARMRSBconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSLLconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + return true + } + // match: (SUBshiftLL x (MOVWconst [c]) [d]) + // cond: + // result: (SUBconst x [int64(uint32(c)< x y)) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + v.reset(OpARMRSBconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSLL, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + return true + } + // match: (SUBshiftLLreg x y (MOVWconst [c])) + // cond: + // result: (SUBshiftLL x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMSUBshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + return false +} +func rewriteValueARM_OpARMSUBshiftRA(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (SUBshiftRA (MOVWconst [c]) x [d]) + // cond: + // result: (RSBconst [c] (SRAconst x [d])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + v.reset(OpARMRSBconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRAconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + return true + } + // match: (SUBshiftRA x (MOVWconst [c]) [d]) + // cond: + // result: (SUBconst x [int64(int32(c)>>uint64(d))]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + v.reset(OpARMSUBconst) + v.AddArg(x) + v.AuxInt = int64(int32(c) >> uint64(d)) + return true + } + // match: (SUBshiftRA x (SRAconst x [c]) [d]) + // cond: c==d + // result: (MOVWconst [0]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRAconst { + break + } + if x != v_1.Args[0] { + break + } + c := v_1.AuxInt + d := v.AuxInt + if !(c == d) { + break + } + v.reset(OpARMMOVWconst) + v.AuxInt = 0 + return true + } + return false +} +func rewriteValueARM_OpARMSUBshiftRAreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (SUBshiftRAreg (MOVWconst [c]) x y) + // cond: + // result: (RSBconst [c] (SRA x y)) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + v.reset(OpARMRSBconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRA, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + return true + } + // match: (SUBshiftRAreg x y (MOVWconst [c])) + // cond: + // result: (SUBshiftRA x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMSUBshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + return false +} +func rewriteValueARM_OpARMSUBshiftRL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (SUBshiftRL (MOVWconst [c]) x [d]) + // cond: + // result: (RSBconst [c] (SRLconst x [d])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + v.reset(OpARMRSBconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRLconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + return true + } + // match: (SUBshiftRL x (MOVWconst [c]) [d]) + // cond: + // result: (SUBconst x [int64(uint32(c)>>uint64(d))]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + v.reset(OpARMSUBconst) + v.AddArg(x) + v.AuxInt = int64(uint32(c) >> uint64(d)) + return true + } + // match: (SUBshiftRL x (SRLconst x [c]) [d]) + // cond: c==d + // result: (MOVWconst [0]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRLconst { + break + } + if x != v_1.Args[0] { + break + } + c := v_1.AuxInt + d := v.AuxInt + if !(c == d) { + break + } + v.reset(OpARMMOVWconst) + v.AuxInt = 0 + return true + } + return false +} +func rewriteValueARM_OpARMSUBshiftRLreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (SUBshiftRLreg (MOVWconst [c]) x y) + // cond: + // result: (RSBconst [c] (SRL x y)) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + v.reset(OpARMRSBconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRL, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + return true + } + // match: (SUBshiftRLreg x y (MOVWconst [c])) + // cond: + // result: (SUBshiftRL x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMSUBshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + return false +} func rewriteValueARM_OpSelect0(v *Value, config *Config) bool { b := v.Block _ = b @@ -7953,6 +15926,210 @@ func rewriteValueARM_OpARMXOR(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (XOR x (SLLconst [c] y)) + // cond: + // result: (XORshiftLL x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSLLconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + v.reset(OpARMXORshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (XOR (SLLconst [c] y) x) + // cond: + // result: (XORshiftLL x y [c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSLLconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + v.reset(OpARMXORshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (XOR x (SRLconst [c] y)) + // cond: + // result: (XORshiftRL x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRLconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + v.reset(OpARMXORshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (XOR (SRLconst [c] y) x) + // cond: + // result: (XORshiftRL x y [c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRLconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + v.reset(OpARMXORshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (XOR x (SRAconst [c] y)) + // cond: + // result: (XORshiftRA x y [c]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRAconst { + break + } + c := v_1.AuxInt + y := v_1.Args[0] + v.reset(OpARMXORshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (XOR (SRAconst [c] y) x) + // cond: + // result: (XORshiftRA x y [c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRAconst { + break + } + c := v_0.AuxInt + y := v_0.Args[0] + x := v.Args[1] + v.reset(OpARMXORshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + // match: (XOR x (SLL y z)) + // cond: + // result: (XORshiftLLreg x y z) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSLL { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + v.reset(OpARMXORshiftLLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (XOR (SLL y z) x) + // cond: + // result: (XORshiftLLreg x y z) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSLL { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + v.reset(OpARMXORshiftLLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (XOR x (SRL y z)) + // cond: + // result: (XORshiftRLreg x y z) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRL { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + v.reset(OpARMXORshiftRLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (XOR (SRL y z) x) + // cond: + // result: (XORshiftRLreg x y z) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRL { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + v.reset(OpARMXORshiftRLreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (XOR x (SRA y z)) + // cond: + // result: (XORshiftRAreg x y z) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRA { + break + } + y := v_1.Args[0] + z := v_1.Args[1] + v.reset(OpARMXORshiftRAreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } + // match: (XOR (SRA y z) x) + // cond: + // result: (XORshiftRAreg x y z) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMSRA { + break + } + y := v_0.Args[0] + z := v_0.Args[1] + x := v.Args[1] + v.reset(OpARMXORshiftRAreg) + v.AddArg(x) + v.AddArg(y) + v.AddArg(z) + return true + } // match: (XOR x x) // cond: // result: (MOVWconst [0]) @@ -8015,6 +16192,312 @@ func rewriteValueARM_OpARMXORconst(v *Value, config *Config) bool { } return false } +func rewriteValueARM_OpARMXORshiftLL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (XORshiftLL (MOVWconst [c]) x [d]) + // cond: + // result: (XORconst [c] (SLLconst x [d])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + v.reset(OpARMXORconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSLLconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + return true + } + // match: (XORshiftLL x (MOVWconst [c]) [d]) + // cond: + // result: (XORconst x [int64(uint32(c)< x y)) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + v.reset(OpARMXORconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSLL, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + return true + } + // match: (XORshiftLLreg x y (MOVWconst [c])) + // cond: + // result: (XORshiftLL x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMXORshiftLL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + return false +} +func rewriteValueARM_OpARMXORshiftRA(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (XORshiftRA (MOVWconst [c]) x [d]) + // cond: + // result: (XORconst [c] (SRAconst x [d])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + v.reset(OpARMXORconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRAconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + return true + } + // match: (XORshiftRA x (MOVWconst [c]) [d]) + // cond: + // result: (XORconst x [int64(int32(c)>>uint64(d))]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + v.reset(OpARMXORconst) + v.AddArg(x) + v.AuxInt = int64(int32(c) >> uint64(d)) + return true + } + // match: (XORshiftRA x (SRAconst x [c]) [d]) + // cond: c==d + // result: (MOVWconst [0]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRAconst { + break + } + if x != v_1.Args[0] { + break + } + c := v_1.AuxInt + d := v.AuxInt + if !(c == d) { + break + } + v.reset(OpARMMOVWconst) + v.AuxInt = 0 + return true + } + return false +} +func rewriteValueARM_OpARMXORshiftRAreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (XORshiftRAreg (MOVWconst [c]) x y) + // cond: + // result: (XORconst [c] (SRA x y)) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + v.reset(OpARMXORconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRA, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + return true + } + // match: (XORshiftRAreg x y (MOVWconst [c])) + // cond: + // result: (XORshiftRA x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMXORshiftRA) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + return false +} +func rewriteValueARM_OpARMXORshiftRL(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (XORshiftRL (MOVWconst [c]) x [d]) + // cond: + // result: (XORconst [c] (SRLconst x [d])) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + d := v.AuxInt + v.reset(OpARMXORconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRLconst, x.Type) + v0.AddArg(x) + v0.AuxInt = d + v.AddArg(v0) + return true + } + // match: (XORshiftRL x (MOVWconst [c]) [d]) + // cond: + // result: (XORconst x [int64(uint32(c)>>uint64(d))]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMMOVWconst { + break + } + c := v_1.AuxInt + d := v.AuxInt + v.reset(OpARMXORconst) + v.AddArg(x) + v.AuxInt = int64(uint32(c) >> uint64(d)) + return true + } + // match: (XORshiftRL x (SRLconst x [c]) [d]) + // cond: c==d + // result: (MOVWconst [0]) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARMSRLconst { + break + } + if x != v_1.Args[0] { + break + } + c := v_1.AuxInt + d := v.AuxInt + if !(c == d) { + break + } + v.reset(OpARMMOVWconst) + v.AuxInt = 0 + return true + } + return false +} +func rewriteValueARM_OpARMXORshiftRLreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (XORshiftRLreg (MOVWconst [c]) x y) + // cond: + // result: (XORconst [c] (SRL x y)) + for { + v_0 := v.Args[0] + if v_0.Op != OpARMMOVWconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + y := v.Args[2] + v.reset(OpARMXORconst) + v.AuxInt = c + v0 := b.NewValue0(v.Line, OpARMSRL, x.Type) + v0.AddArg(x) + v0.AddArg(y) + v.AddArg(v0) + return true + } + // match: (XORshiftRLreg x y (MOVWconst [c])) + // cond: + // result: (XORshiftRL x y [c]) + for { + x := v.Args[0] + y := v.Args[1] + v_2 := v.Args[2] + if v_2.Op != OpARMMOVWconst { + break + } + c := v_2.AuxInt + v.reset(OpARMXORshiftRL) + v.AddArg(x) + v.AddArg(y) + v.AuxInt = c + return true + } + return false +} func rewriteValueARM_OpXor16(v *Value, config *Config) bool { b := v.Block _ = b @@ -8365,11 +16848,16 @@ func rewriteValueARM_OpZeromask(v *Value, config *Config) bool { _ = b // match: (Zeromask x) // cond: - // result: (LoweredZeromask x) + // result: (SRAconst (RSBshiftRL x x [1]) [31]) for { x := v.Args[0] - v.reset(OpARMLoweredZeromask) - v.AddArg(x) + v.reset(OpARMSRAconst) + v0 := b.NewValue0(v.Line, OpARMRSBshiftRL, config.fe.TypeInt32()) + v0.AddArg(x) + v0.AddArg(x) + v0.AuxInt = 1 + v.AddArg(v0) + v.AuxInt = 31 return true } }