From 695f12c21a217e0116a80c2c1a518d382cfea22e Mon Sep 17 00:00:00 2001 From: Lynn Boger Date: Fri, 3 Feb 2017 08:40:18 -0500 Subject: [PATCH] cmd/compile: rules change to use ANDN more effectively on ppc64x Currently there are cases where an XOR with -1 followed by an AND is generanted when it could be done with just an ANDN instruction. Changes to PPC64.rules and required files allows this change in generated code. Examples of this occur in sha3 among others. Fixes: #18918 Change-Id: I647cb9b4a4aaeebb27db85f8bf75487d78f720c9 Reviewed-on: https://go-review.googlesource.com/36218 TryBot-Result: Gobot Gobot Reviewed-by: David Chase Reviewed-by: Carlos Eduardo Seo --- src/cmd/compile/internal/ppc64/prog.go | 1 + src/cmd/compile/internal/ppc64/ssa.go | 2 +- src/cmd/compile/internal/ssa/gen/PPC64.rules | 10 +++--- src/cmd/compile/internal/ssa/gen/PPC64Ops.go | 1 + src/cmd/compile/internal/ssa/opGen.go | 15 +++++++++ src/cmd/compile/internal/ssa/rewritePPC64.go | 34 ++++++++++---------- 6 files changed, 40 insertions(+), 23 deletions(-) diff --git a/src/cmd/compile/internal/ppc64/prog.go b/src/cmd/compile/internal/ppc64/prog.go index ff5fde36e6..dbcf68f256 100644 --- a/src/cmd/compile/internal/ppc64/prog.go +++ b/src/cmd/compile/internal/ppc64/prog.go @@ -49,6 +49,7 @@ var progtable = [ppc64.ALAST & obj.AMask]gc.ProgInfo{ ppc64.AOR & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, ppc64.AORN & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, ppc64.AXOR & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, + ppc64.ANOR & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, ppc64.AEQV & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, ppc64.AMULLD & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, ppc64.AMULLW & obj.AMask: {Flags: gc.SizeL | gc.LeftRead | gc.RegRead | gc.RightWrite}, diff --git a/src/cmd/compile/internal/ppc64/ssa.go b/src/cmd/compile/internal/ppc64/ssa.go index 6548df51ae..2c0cbad06f 100644 --- a/src/cmd/compile/internal/ppc64/ssa.go +++ b/src/cmd/compile/internal/ppc64/ssa.go @@ -300,7 +300,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { ssa.OpPPC64SRAD, ssa.OpPPC64SRAW, ssa.OpPPC64SRD, ssa.OpPPC64SRW, ssa.OpPPC64SLD, ssa.OpPPC64SLW, ssa.OpPPC64MULHD, ssa.OpPPC64MULHW, ssa.OpPPC64MULHDU, ssa.OpPPC64MULHWU, ssa.OpPPC64FMUL, ssa.OpPPC64FMULS, ssa.OpPPC64FDIV, ssa.OpPPC64FDIVS, - ssa.OpPPC64AND, ssa.OpPPC64OR, ssa.OpPPC64ANDN, ssa.OpPPC64ORN, ssa.OpPPC64XOR, ssa.OpPPC64EQV: + ssa.OpPPC64AND, ssa.OpPPC64OR, ssa.OpPPC64ANDN, ssa.OpPPC64ORN, ssa.OpPPC64NOR, ssa.OpPPC64XOR, ssa.OpPPC64EQV: r := v.Reg() r1 := v.Args[0].Reg() r2 := v.Args[1].Reg() diff --git a/src/cmd/compile/internal/ssa/gen/PPC64.rules b/src/cmd/compile/internal/ssa/gen/PPC64.rules index 8cca320589..23ddead3c4 100644 --- a/src/cmd/compile/internal/ssa/gen/PPC64.rules +++ b/src/cmd/compile/internal/ssa/gen/PPC64.rules @@ -257,10 +257,10 @@ (Neg16 x) -> (NEG x) (Neg8 x) -> (NEG x) -(Com64 x) -> (XORconst [-1] x) -(Com32 x) -> (XORconst [-1] x) -(Com16 x) -> (XORconst [-1] x) -(Com8 x) -> (XORconst [-1] x) +(Com64 x) -> (NOR x x) +(Com32 x) -> (NOR x x) +(Com16 x) -> (NOR x x) +(Com8 x) -> (NOR x x) // Lowering boolean ops (AndB x y) -> (AND x y) @@ -268,7 +268,7 @@ (Not x) -> (XORconst [1] x) // Use ANDN for AND x NOT y -(AND x (XORconst [-1] y)) -> (ANDN x y) +(AND x (NOR y y)) -> (ANDN x y) // Lowering comparisons (EqB x y) -> (ANDconst [1] (EQV x y)) diff --git a/src/cmd/compile/internal/ssa/gen/PPC64Ops.go b/src/cmd/compile/internal/ssa/gen/PPC64Ops.go index 003479774a..0402a57086 100644 --- a/src/cmd/compile/internal/ssa/gen/PPC64Ops.go +++ b/src/cmd/compile/internal/ssa/gen/PPC64Ops.go @@ -216,6 +216,7 @@ func init() { {name: "ANDN", argLength: 2, reg: gp21, asm: "ANDN"}, // arg0&^arg1 {name: "OR", argLength: 2, reg: gp21, asm: "OR", commutative: true}, // arg0|arg1 {name: "ORN", argLength: 2, reg: gp21, asm: "ORN"}, // arg0|^arg1 + {name: "NOR", argLength: 2, reg: gp21, asm: "NOR"}, // ^(arg0|arg1) {name: "XOR", argLength: 2, reg: gp21, asm: "XOR", typ: "Int64", commutative: true}, // arg0^arg1 {name: "EQV", argLength: 2, reg: gp21, asm: "EQV", typ: "Int64", commutative: true}, // arg0^^arg1 {name: "NEG", argLength: 1, reg: gp11, asm: "NEG"}, // -arg0 (integer) diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go index d8407df09c..e30a08d361 100644 --- a/src/cmd/compile/internal/ssa/opGen.go +++ b/src/cmd/compile/internal/ssa/opGen.go @@ -1290,6 +1290,7 @@ const ( OpPPC64ANDN OpPPC64OR OpPPC64ORN + OpPPC64NOR OpPPC64XOR OpPPC64EQV OpPPC64NEG @@ -16090,6 +16091,20 @@ var opcodeTable = [...]opInfo{ }, }, }, + { + name: "NOR", + argLen: 2, + asm: ppc64.ANOR, + reg: regInfo{ + inputs: []inputInfo{ + {0, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 + {1, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 + }, + outputs: []outputInfo{ + {0, 1073733624}, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 + }, + }, + }, { name: "XOR", argLen: 2, diff --git a/src/cmd/compile/internal/ssa/rewritePPC64.go b/src/cmd/compile/internal/ssa/rewritePPC64.go index 95608e1058..1c0ae0ab68 100644 --- a/src/cmd/compile/internal/ssa/rewritePPC64.go +++ b/src/cmd/compile/internal/ssa/rewritePPC64.go @@ -825,11 +825,11 @@ func rewriteValuePPC64_OpCom16(v *Value, config *Config) bool { _ = b // match: (Com16 x) // cond: - // result: (XORconst [-1] x) + // result: (NOR x x) for { x := v.Args[0] - v.reset(OpPPC64XORconst) - v.AuxInt = -1 + v.reset(OpPPC64NOR) + v.AddArg(x) v.AddArg(x) return true } @@ -839,11 +839,11 @@ func rewriteValuePPC64_OpCom32(v *Value, config *Config) bool { _ = b // match: (Com32 x) // cond: - // result: (XORconst [-1] x) + // result: (NOR x x) for { x := v.Args[0] - v.reset(OpPPC64XORconst) - v.AuxInt = -1 + v.reset(OpPPC64NOR) + v.AddArg(x) v.AddArg(x) return true } @@ -853,11 +853,11 @@ func rewriteValuePPC64_OpCom64(v *Value, config *Config) bool { _ = b // match: (Com64 x) // cond: - // result: (XORconst [-1] x) + // result: (NOR x x) for { x := v.Args[0] - v.reset(OpPPC64XORconst) - v.AuxInt = -1 + v.reset(OpPPC64NOR) + v.AddArg(x) v.AddArg(x) return true } @@ -867,11 +867,11 @@ func rewriteValuePPC64_OpCom8(v *Value, config *Config) bool { _ = b // match: (Com8 x) // cond: - // result: (XORconst [-1] x) + // result: (NOR x x) for { x := v.Args[0] - v.reset(OpPPC64XORconst) - v.AuxInt = -1 + v.reset(OpPPC64NOR) + v.AddArg(x) v.AddArg(x) return true } @@ -4473,19 +4473,19 @@ func rewriteValuePPC64_OpPPC64ADDconst(v *Value, config *Config) bool { func rewriteValuePPC64_OpPPC64AND(v *Value, config *Config) bool { b := v.Block _ = b - // match: (AND x (XORconst [-1] y)) + // match: (AND x (NOR y y)) // cond: // result: (ANDN x y) for { x := v.Args[0] v_1 := v.Args[1] - if v_1.Op != OpPPC64XORconst { - break - } - if v_1.AuxInt != -1 { + if v_1.Op != OpPPC64NOR { break } y := v_1.Args[0] + if y != v_1.Args[1] { + break + } v.reset(OpPPC64ANDN) v.AddArg(x) v.AddArg(y)