Commit 8bf4b7e6 authored by Josh Bleecher Snyder's avatar Josh Bleecher Snyder

cmd/compile: convert amd64 BSFL and BSRL from tuple to result only

Change-Id: I220a459f67ecb310b6e9a526a1ff55527d421e70
Reviewed-on: https://go-review.googlesource.com/109416
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarKeith Randall <khr@golang.org>
parent 5f5168e0
...@@ -946,12 +946,18 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { ...@@ -946,12 +946,18 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p := s.Prog(v.Op.Asm()) p := s.Prog(v.Op.Asm())
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = r p.To.Reg = r
case ssa.OpAMD64BSFQ, ssa.OpAMD64BSFL, ssa.OpAMD64BSRQ, ssa.OpAMD64BSRL: case ssa.OpAMD64BSFQ, ssa.OpAMD64BSRQ:
p := s.Prog(v.Op.Asm()) p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = v.Args[0].Reg() p.From.Reg = v.Args[0].Reg()
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg0() p.To.Reg = v.Reg0()
case ssa.OpAMD64BSFL, ssa.OpAMD64BSRL:
p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_REG
p.From.Reg = v.Args[0].Reg()
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg()
case ssa.OpAMD64SQRTSD: case ssa.OpAMD64SQRTSD:
p := s.Prog(v.Op.Asm()) p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
......
...@@ -57,13 +57,13 @@ ...@@ -57,13 +57,13 @@
// Lowering other arithmetic // Lowering other arithmetic
(Ctz64 <t> x) -> (CMOVQEQ (Select0 <t> (BSFQ x)) (MOVQconst <t> [64]) (Select1 <types.TypeFlags> (BSFQ x))) (Ctz64 <t> x) -> (CMOVQEQ (Select0 <t> (BSFQ x)) (MOVQconst <t> [64]) (Select1 <types.TypeFlags> (BSFQ x)))
(Ctz32 x) -> (Select0 (BSFQ (BTSQconst <typ.UInt64> [32] x))) (Ctz32 x) -> (Select0 (BSFQ (BTSQconst <typ.UInt64> [32] x)))
(Ctz16 x) -> (Select0 (BSFL (BTSLconst <typ.UInt32> [16] x))) (Ctz16 x) -> (BSFL (BTSLconst <typ.UInt32> [16] x))
(Ctz8 x) -> (Select0 (BSFL (BTSLconst <typ.UInt32> [ 8] x))) (Ctz8 x) -> (BSFL (BTSLconst <typ.UInt32> [ 8] x))
(Ctz64NonZero x) -> (Select0 (BSFQ x)) (Ctz64NonZero x) -> (Select0 (BSFQ x))
(Ctz32NonZero x) -> (Select0 (BSFL x)) (Ctz32NonZero x) -> (BSFL x)
(Ctz16NonZero x) -> (Select0 (BSFL x)) (Ctz16NonZero x) -> (BSFL x)
(Ctz8NonZero x) -> (Select0 (BSFL x)) (Ctz8NonZero x) -> (BSFL x)
// BitLen64 of a 64 bit value x requires checking whether x == 0, since BSRQ is undefined when x == 0. // BitLen64 of a 64 bit value x requires checking whether x == 0, since BSRQ is undefined when x == 0.
// However, for zero-extended values, we can cheat a bit, and calculate // However, for zero-extended values, we can cheat a bit, and calculate
...@@ -71,8 +71,8 @@ ...@@ -71,8 +71,8 @@
// places the index of the highest set bit where we want it. // places the index of the highest set bit where we want it.
(BitLen64 <t> x) -> (ADDQconst [1] (CMOVQEQ <t> (Select0 <t> (BSRQ x)) (MOVQconst <t> [-1]) (Select1 <types.TypeFlags> (BSRQ x)))) (BitLen64 <t> x) -> (ADDQconst [1] (CMOVQEQ <t> (Select0 <t> (BSRQ x)) (MOVQconst <t> [-1]) (Select1 <types.TypeFlags> (BSRQ x))))
(BitLen32 x) -> (Select0 (BSRQ (LEAQ1 <typ.UInt64> [1] (MOVLQZX <typ.UInt64> x) (MOVLQZX <typ.UInt64> x)))) (BitLen32 x) -> (Select0 (BSRQ (LEAQ1 <typ.UInt64> [1] (MOVLQZX <typ.UInt64> x) (MOVLQZX <typ.UInt64> x))))
(BitLen16 x) -> (Select0 (BSRL (LEAL1 <typ.UInt32> [1] (MOVWQZX <typ.UInt32> x) (MOVWQZX <typ.UInt32> x)))) (BitLen16 x) -> (BSRL (LEAL1 <typ.UInt32> [1] (MOVWQZX <typ.UInt32> x) (MOVWQZX <typ.UInt32> x)))
(BitLen8 x) -> (Select0 (BSRL (LEAL1 <typ.UInt32> [1] (MOVBQZX <typ.UInt32> x) (MOVBQZX <typ.UInt32> x)))) (BitLen8 x) -> (BSRL (LEAL1 <typ.UInt32> [1] (MOVBQZX <typ.UInt32> x) (MOVBQZX <typ.UInt32> x)))
(Bswap(64|32) x) -> (BSWAP(Q|L) x) (Bswap(64|32) x) -> (BSWAP(Q|L) x)
......
...@@ -345,13 +345,14 @@ func init() { ...@@ -345,13 +345,14 @@ func init() {
{name: "NOTQ", argLength: 1, reg: gp11, asm: "NOTQ", resultInArg0: true, clobberFlags: true}, // ^arg0 {name: "NOTQ", argLength: 1, reg: gp11, asm: "NOTQ", resultInArg0: true, clobberFlags: true}, // ^arg0
{name: "NOTL", argLength: 1, reg: gp11, asm: "NOTL", resultInArg0: true, clobberFlags: true}, // ^arg0 {name: "NOTL", argLength: 1, reg: gp11, asm: "NOTL", resultInArg0: true, clobberFlags: true}, // ^arg0
// BSF{L,Q} returns a tuple [result, flags] // BS{F,R}Q returns a tuple [result, flags]
// result is undefined if the input is zero. // result is undefined if the input is zero.
// flags are set to "equal" if the input is zero, "not equal" otherwise. // flags are set to "equal" if the input is zero, "not equal" otherwise.
// BS{F,R}L returns only the result.
{name: "BSFQ", argLength: 1, reg: gp11flags, asm: "BSFQ", typ: "(UInt64,Flags)"}, // # of low-order zeroes in 64-bit arg {name: "BSFQ", argLength: 1, reg: gp11flags, asm: "BSFQ", typ: "(UInt64,Flags)"}, // # of low-order zeroes in 64-bit arg
{name: "BSFL", argLength: 1, reg: gp11flags, asm: "BSFL", typ: "(UInt32,Flags)"}, // # of low-order zeroes in 32-bit arg {name: "BSFL", argLength: 1, reg: gp11, asm: "BSFL", typ: "UInt32"}, // # of low-order zeroes in 32-bit arg
{name: "BSRQ", argLength: 1, reg: gp11flags, asm: "BSRQ", typ: "(UInt64,Flags)"}, // # of high-order zeroes in 64-bit arg {name: "BSRQ", argLength: 1, reg: gp11flags, asm: "BSRQ", typ: "(UInt64,Flags)"}, // # of high-order zeroes in 64-bit arg
{name: "BSRL", argLength: 1, reg: gp11flags, asm: "BSRL", typ: "(UInt32,Flags)"}, // # of high-order zeroes in 32-bit arg {name: "BSRL", argLength: 1, reg: gp11, asm: "BSRL", typ: "UInt32"}, // # of high-order zeroes in 32-bit arg
// CMOV instructions: 64, 32 and 16-bit sizes. // CMOV instructions: 64, 32 and 16-bit sizes.
// if arg2 encodes a true result, return arg1, else arg0 // if arg2 encodes a true result, return arg1, else arg0
......
...@@ -7232,7 +7232,6 @@ var opcodeTable = [...]opInfo{ ...@@ -7232,7 +7232,6 @@ var opcodeTable = [...]opInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 {0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
}, },
outputs: []outputInfo{ outputs: []outputInfo{
{1, 0},
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 {0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
}, },
}, },
...@@ -7260,7 +7259,6 @@ var opcodeTable = [...]opInfo{ ...@@ -7260,7 +7259,6 @@ var opcodeTable = [...]opInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 {0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
}, },
outputs: []outputInfo{ outputs: []outputInfo{
{1, 0},
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15 {0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
}, },
}, },
......
...@@ -51924,20 +51924,18 @@ func rewriteValueAMD64_OpBitLen16_0(v *Value) bool { ...@@ -51924,20 +51924,18 @@ func rewriteValueAMD64_OpBitLen16_0(v *Value) bool {
_ = typ _ = typ
// match: (BitLen16 x) // match: (BitLen16 x)
// cond: // cond:
// result: (Select0 (BSRL (LEAL1 <typ.UInt32> [1] (MOVWQZX <typ.UInt32> x) (MOVWQZX <typ.UInt32> x)))) // result: (BSRL (LEAL1 <typ.UInt32> [1] (MOVWQZX <typ.UInt32> x) (MOVWQZX <typ.UInt32> x)))
for { for {
x := v.Args[0] x := v.Args[0]
v.reset(OpSelect0) v.reset(OpAMD64BSRL)
v0 := b.NewValue0(v.Pos, OpAMD64BSRL, types.NewTuple(typ.UInt32, types.TypeFlags)) v0 := b.NewValue0(v.Pos, OpAMD64LEAL1, typ.UInt32)
v1 := b.NewValue0(v.Pos, OpAMD64LEAL1, typ.UInt32) v0.AuxInt = 1
v1.AuxInt = 1 v1 := b.NewValue0(v.Pos, OpAMD64MOVWQZX, typ.UInt32)
v1.AddArg(x)
v0.AddArg(v1)
v2 := b.NewValue0(v.Pos, OpAMD64MOVWQZX, typ.UInt32) v2 := b.NewValue0(v.Pos, OpAMD64MOVWQZX, typ.UInt32)
v2.AddArg(x) v2.AddArg(x)
v1.AddArg(v2) v0.AddArg(v2)
v3 := b.NewValue0(v.Pos, OpAMD64MOVWQZX, typ.UInt32)
v3.AddArg(x)
v1.AddArg(v3)
v0.AddArg(v1)
v.AddArg(v0) v.AddArg(v0)
return true return true
} }
...@@ -52005,20 +52003,18 @@ func rewriteValueAMD64_OpBitLen8_0(v *Value) bool { ...@@ -52005,20 +52003,18 @@ func rewriteValueAMD64_OpBitLen8_0(v *Value) bool {
_ = typ _ = typ
// match: (BitLen8 x) // match: (BitLen8 x)
// cond: // cond:
// result: (Select0 (BSRL (LEAL1 <typ.UInt32> [1] (MOVBQZX <typ.UInt32> x) (MOVBQZX <typ.UInt32> x)))) // result: (BSRL (LEAL1 <typ.UInt32> [1] (MOVBQZX <typ.UInt32> x) (MOVBQZX <typ.UInt32> x)))
for { for {
x := v.Args[0] x := v.Args[0]
v.reset(OpSelect0) v.reset(OpAMD64BSRL)
v0 := b.NewValue0(v.Pos, OpAMD64BSRL, types.NewTuple(typ.UInt32, types.TypeFlags)) v0 := b.NewValue0(v.Pos, OpAMD64LEAL1, typ.UInt32)
v1 := b.NewValue0(v.Pos, OpAMD64LEAL1, typ.UInt32) v0.AuxInt = 1
v1.AuxInt = 1 v1 := b.NewValue0(v.Pos, OpAMD64MOVBQZX, typ.UInt32)
v1.AddArg(x)
v0.AddArg(v1)
v2 := b.NewValue0(v.Pos, OpAMD64MOVBQZX, typ.UInt32) v2 := b.NewValue0(v.Pos, OpAMD64MOVBQZX, typ.UInt32)
v2.AddArg(x) v2.AddArg(x)
v1.AddArg(v2) v0.AddArg(v2)
v3 := b.NewValue0(v.Pos, OpAMD64MOVBQZX, typ.UInt32)
v3.AddArg(x)
v1.AddArg(v3)
v0.AddArg(v1)
v.AddArg(v0) v.AddArg(v0)
return true return true
} }
...@@ -53301,33 +53297,25 @@ func rewriteValueAMD64_OpCtz16_0(v *Value) bool { ...@@ -53301,33 +53297,25 @@ func rewriteValueAMD64_OpCtz16_0(v *Value) bool {
_ = typ _ = typ
// match: (Ctz16 x) // match: (Ctz16 x)
// cond: // cond:
// result: (Select0 (BSFL (BTSLconst <typ.UInt32> [16] x))) // result: (BSFL (BTSLconst <typ.UInt32> [16] x))
for { for {
x := v.Args[0] x := v.Args[0]
v.reset(OpSelect0) v.reset(OpAMD64BSFL)
v0 := b.NewValue0(v.Pos, OpAMD64BSFL, types.NewTuple(typ.UInt32, types.TypeFlags)) v0 := b.NewValue0(v.Pos, OpAMD64BTSLconst, typ.UInt32)
v1 := b.NewValue0(v.Pos, OpAMD64BTSLconst, typ.UInt32) v0.AuxInt = 16
v1.AuxInt = 16 v0.AddArg(x)
v1.AddArg(x)
v0.AddArg(v1)
v.AddArg(v0) v.AddArg(v0)
return true return true
} }
} }
func rewriteValueAMD64_OpCtz16NonZero_0(v *Value) bool { func rewriteValueAMD64_OpCtz16NonZero_0(v *Value) bool {
b := v.Block
_ = b
typ := &b.Func.Config.Types
_ = typ
// match: (Ctz16NonZero x) // match: (Ctz16NonZero x)
// cond: // cond:
// result: (Select0 (BSFL x)) // result: (BSFL x)
for { for {
x := v.Args[0] x := v.Args[0]
v.reset(OpSelect0) v.reset(OpAMD64BSFL)
v0 := b.NewValue0(v.Pos, OpAMD64BSFL, types.NewTuple(typ.UInt32, types.TypeFlags)) v.AddArg(x)
v0.AddArg(x)
v.AddArg(v0)
return true return true
} }
} }
...@@ -53352,19 +53340,13 @@ func rewriteValueAMD64_OpCtz32_0(v *Value) bool { ...@@ -53352,19 +53340,13 @@ func rewriteValueAMD64_OpCtz32_0(v *Value) bool {
} }
} }
func rewriteValueAMD64_OpCtz32NonZero_0(v *Value) bool { func rewriteValueAMD64_OpCtz32NonZero_0(v *Value) bool {
b := v.Block
_ = b
typ := &b.Func.Config.Types
_ = typ
// match: (Ctz32NonZero x) // match: (Ctz32NonZero x)
// cond: // cond:
// result: (Select0 (BSFL x)) // result: (BSFL x)
for { for {
x := v.Args[0] x := v.Args[0]
v.reset(OpSelect0) v.reset(OpAMD64BSFL)
v0 := b.NewValue0(v.Pos, OpAMD64BSFL, types.NewTuple(typ.UInt32, types.TypeFlags)) v.AddArg(x)
v0.AddArg(x)
v.AddArg(v0)
return true return true
} }
} }
...@@ -53420,33 +53402,25 @@ func rewriteValueAMD64_OpCtz8_0(v *Value) bool { ...@@ -53420,33 +53402,25 @@ func rewriteValueAMD64_OpCtz8_0(v *Value) bool {
_ = typ _ = typ
// match: (Ctz8 x) // match: (Ctz8 x)
// cond: // cond:
// result: (Select0 (BSFL (BTSLconst <typ.UInt32> [ 8] x))) // result: (BSFL (BTSLconst <typ.UInt32> [ 8] x))
for { for {
x := v.Args[0] x := v.Args[0]
v.reset(OpSelect0) v.reset(OpAMD64BSFL)
v0 := b.NewValue0(v.Pos, OpAMD64BSFL, types.NewTuple(typ.UInt32, types.TypeFlags)) v0 := b.NewValue0(v.Pos, OpAMD64BTSLconst, typ.UInt32)
v1 := b.NewValue0(v.Pos, OpAMD64BTSLconst, typ.UInt32) v0.AuxInt = 8
v1.AuxInt = 8 v0.AddArg(x)
v1.AddArg(x)
v0.AddArg(v1)
v.AddArg(v0) v.AddArg(v0)
return true return true
} }
} }
func rewriteValueAMD64_OpCtz8NonZero_0(v *Value) bool { func rewriteValueAMD64_OpCtz8NonZero_0(v *Value) bool {
b := v.Block
_ = b
typ := &b.Func.Config.Types
_ = typ
// match: (Ctz8NonZero x) // match: (Ctz8NonZero x)
// cond: // cond:
// result: (Select0 (BSFL x)) // result: (BSFL x)
for { for {
x := v.Args[0] x := v.Args[0]
v.reset(OpSelect0) v.reset(OpAMD64BSFL)
v0 := b.NewValue0(v.Pos, OpAMD64BSFL, types.NewTuple(typ.UInt32, types.TypeFlags)) v.AddArg(x)
v0.AddArg(x)
v.AddArg(v0)
return true return true
} }
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment