diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/cmd/compile/internal/ssa/_gen/386.rules | 4 | ||||
| -rw-r--r-- | src/cmd/compile/internal/ssa/_gen/386Ops.go | 1 | ||||
| -rw-r--r-- | src/cmd/compile/internal/ssa/opGen.go | 15 | ||||
| -rw-r--r-- | src/cmd/compile/internal/ssa/rewrite386.go | 27 | ||||
| -rw-r--r-- | src/cmd/compile/internal/ssagen/ssa.go | 6 | ||||
| -rw-r--r-- | src/cmd/compile/internal/x86/ssa.go | 23 |
6 files changed, 73 insertions, 3 deletions
diff --git a/src/cmd/compile/internal/ssa/_gen/386.rules b/src/cmd/compile/internal/ssa/_gen/386.rules index db16ab0961..03413b289e 100644 --- a/src/cmd/compile/internal/ssa/_gen/386.rules +++ b/src/cmd/compile/internal/ssa/_gen/386.rules @@ -56,8 +56,12 @@ (Sqrt ...) => (SQRTSD ...) (Sqrt32 ...) => (SQRTSS ...) +(Ctz8 x) => (BSFL (ORLconst <typ.UInt32> [0x100] x)) +(Ctz8NonZero ...) => (BSFL ...) (Ctz16 x) => (BSFL (ORLconst <typ.UInt32> [0x10000] x)) (Ctz16NonZero ...) => (BSFL ...) +(Ctz32 ...) => (LoweredCtz32 ...) +(Ctz32NonZero ...) => (BSFL ...) // Lowering extension (SignExt8to16 ...) => (MOVBLSX ...) diff --git a/src/cmd/compile/internal/ssa/_gen/386Ops.go b/src/cmd/compile/internal/ssa/_gen/386Ops.go index 6f19ea6427..7401ac871c 100644 --- a/src/cmd/compile/internal/ssa/_gen/386Ops.go +++ b/src/cmd/compile/internal/ssa/_gen/386Ops.go @@ -302,6 +302,7 @@ func init() { {name: "BSFL", argLength: 1, reg: gp11, asm: "BSFL", clobberFlags: true}, // arg0 # of low-order zeroes ; undef if zero {name: "BSFW", argLength: 1, reg: gp11, asm: "BSFW", clobberFlags: true}, // arg0 # of low-order zeroes ; undef if zero + {name: "LoweredCtz32", argLength: 1, reg: gp11, clobberFlags: true}, // arg0 # of low-order zeroes {name: "BSRL", argLength: 1, reg: gp11, asm: "BSRL", clobberFlags: true}, // arg0 # of high-order zeroes ; undef if zero {name: "BSRW", argLength: 1, reg: gp11, asm: "BSRW", clobberFlags: true}, // arg0 # of high-order zeroes ; undef if zero diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go index 4a24012b1d..b5ca35953c 100644 --- a/src/cmd/compile/internal/ssa/opGen.go +++ b/src/cmd/compile/internal/ssa/opGen.go @@ -456,6 +456,7 @@ const ( Op386NOTL Op386BSFL Op386BSFW + Op386LoweredCtz32 Op386BSRL Op386BSRW Op386BSWAPL @@ -5035,6 +5036,20 @@ var opcodeTable = [...]opInfo{ }, }, { + name: "LoweredCtz32", + argLen: 1, + clobberFlags: true, + asm: x86.ABSFL, + reg: regInfo{ + inputs: []inputInfo{ + {0, 239}, // AX CX DX BX BP SI DI + }, + outputs: []outputInfo{ + {0, 239}, // AX CX DX BX BP SI DI + }, + }, + }, + { name: "BSRL", argLen: 1, clobberFlags: true, diff --git a/src/cmd/compile/internal/ssa/rewrite386.go b/src/cmd/compile/internal/ssa/rewrite386.go index f658d9380a..fe5bbe56a3 100644 --- a/src/cmd/compile/internal/ssa/rewrite386.go +++ b/src/cmd/compile/internal/ssa/rewrite386.go @@ -315,6 +315,17 @@ func rewriteValue386(v *Value) bool { case OpCtz16NonZero: v.Op = Op386BSFL return true + case OpCtz32: + v.Op = Op386LoweredCtz32 + return true + case OpCtz32NonZero: + v.Op = Op386BSFL + return true + case OpCtz8: + return rewriteValue386_OpCtz8(v) + case OpCtz8NonZero: + v.Op = Op386BSFL + return true case OpCvt32Fto32: v.Op = Op386CVTTSS2SL return true @@ -8527,6 +8538,22 @@ func rewriteValue386_OpCtz16(v *Value) bool { return true } } +func rewriteValue386_OpCtz8(v *Value) bool { + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types + // match: (Ctz8 x) + // result: (BSFL (ORLconst <typ.UInt32> [0x100] x)) + for { + x := v_0 + v.reset(Op386BSFL) + v0 := b.NewValue0(v.Pos, Op386ORLconst, typ.UInt32) + v0.AuxInt = int32ToAuxInt(0x100) + v0.AddArg(x) + v.AddArg(v0) + return true + } +} func rewriteValue386_OpDiv8(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] diff --git a/src/cmd/compile/internal/ssagen/ssa.go b/src/cmd/compile/internal/ssagen/ssa.go index b4a55c00af..e49ba5ee71 100644 --- a/src/cmd/compile/internal/ssagen/ssa.go +++ b/src/cmd/compile/internal/ssagen/ssa.go @@ -4492,12 +4492,12 @@ func InitTables() { func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return s.newValue1(ssa.OpCtz64, types.Types[types.TINT], args[0]) }, - sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm) + sys.AMD64, sys.I386, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm) addF("math/bits", "TrailingZeros32", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return s.newValue1(ssa.OpCtz32, types.Types[types.TINT], args[0]) }, - sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm) + sys.AMD64, sys.I386, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm) addF("math/bits", "TrailingZeros16", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { x := s.newValue1(ssa.OpZeroExt16to32, types.Types[types.TUINT32], args[0]) @@ -4531,7 +4531,7 @@ func InitTables() { func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return s.newValue1(ssa.OpCtz8, types.Types[types.TINT], args[0]) }, - sys.AMD64, sys.ARM, sys.ARM64, sys.Wasm) + sys.AMD64, sys.I386, sys.ARM, sys.ARM64, sys.Wasm) addF("math/bits", "TrailingZeros8", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { x := s.newValue1(ssa.OpZeroExt8to64, types.Types[types.TUINT64], args[0]) diff --git a/src/cmd/compile/internal/x86/ssa.go b/src/cmd/compile/internal/x86/ssa.go index 6c92ca1f56..811a34cc0b 100644 --- a/src/cmd/compile/internal/x86/ssa.go +++ b/src/cmd/compile/internal/x86/ssa.go @@ -831,6 +831,29 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { if base.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers base.WarnfAt(v.Pos, "generated nil check") } + case ssa.Op386LoweredCtz32: + // BSFL in, out + p := s.Prog(x86.ABSFL) + p.From.Type = obj.TYPE_REG + p.From.Reg = v.Args[0].Reg() + p.To.Type = obj.TYPE_REG + p.To.Reg = v.Reg() + + // JNZ 2(PC) + p1 := s.Prog(x86.AJNE) + p1.To.Type = obj.TYPE_BRANCH + + // MOVL $32, out + p2 := s.Prog(x86.AMOVL) + p2.From.Type = obj.TYPE_CONST + p2.From.Offset = 32 + p2.To.Type = obj.TYPE_REG + p2.To.Reg = v.Reg() + + // NOP (so the JNZ has somewhere to land) + nop := s.Prog(obj.ANOP) + p1.To.SetTarget(nop) + case ssa.OpClobber: p := s.Prog(x86.AMOVL) p.From.Type = obj.TYPE_CONST |
