From: Matthew Dempsky Date: Sat, 11 Mar 2017 06:09:43 +0000 (-0800) Subject: cmd/compile/internal/ssa: make ARM's udiv like other calls X-Git-Tag: go1.9beta1~1184 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=cc71aa9ac4f2f1dc62f395a6f13ada8709d58213;p=gostls13.git cmd/compile/internal/ssa: make ARM's udiv like other calls Passes toolstash-check -all. Change-Id: Id389f8158cf33a3c0fcef373615b5351e7c74b5b Reviewed-on: https://go-review.googlesource.com/38082 Run-TryBot: Matthew Dempsky TryBot-Result: Gobot Gobot Reviewed-by: Keith Randall --- diff --git a/src/cmd/compile/internal/arm/ssa.go b/src/cmd/compile/internal/arm/ssa.go index 932c35fc3c..768918a6ca 100644 --- a/src/cmd/compile/internal/arm/ssa.go +++ b/src/cmd/compile/internal/arm/ssa.go @@ -167,11 +167,6 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { p.From.Type = obj.TYPE_REG p.From.Reg = v.Args[0].Reg() gc.AddrAuto(&p.To, v) - case ssa.OpARMUDIVrtcall: - p := gc.Prog(obj.ACALL) - p.To.Type = obj.TYPE_MEM - p.To.Name = obj.NAME_EXTERN - p.To.Sym = obj.Linklookup(gc.Ctxt, "udiv", 0) case ssa.OpARMADD, ssa.OpARMADC, ssa.OpARMSUB, @@ -625,7 +620,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { p.From.Offset = v.AuxInt p.To.Type = obj.TYPE_REG p.To.Reg = v.Reg() - case ssa.OpARMCALLstatic, ssa.OpARMCALLclosure, ssa.OpARMCALLinter: + case ssa.OpARMCALLstatic, ssa.OpARMCALLclosure, ssa.OpARMCALLinter, ssa.OpARMCALLudiv: s.Call(v) case ssa.OpARMDUFFZERO: p := gc.Prog(obj.ADUFFZERO) diff --git a/src/cmd/compile/internal/ssa/config.go b/src/cmd/compile/internal/ssa/config.go index 6a8101a562..ea03ed7f10 100644 --- a/src/cmd/compile/internal/ssa/config.go +++ b/src/cmd/compile/internal/ssa/config.go @@ -286,7 +286,7 @@ func NewConfig(arch string, fe Frontend, ctxt *obj.Link, optimize bool) *Config c.noDuffDevice = true // Don't use Duff's device on NaCl // runtime call clobber R12 on nacl - opcodeTable[OpARMUDIVrtcall].reg.clobbers |= 1 << 12 // R12 + opcodeTable[OpARMCALLudiv].reg.clobbers |= 1 << 12 // R12 } // Assign IDs to preallocated values/blocks. diff --git a/src/cmd/compile/internal/ssa/gen/ARM.rules b/src/cmd/compile/internal/ssa/gen/ARM.rules index c9d2b550bb..a1e6b5a351 100644 --- a/src/cmd/compile/internal/ssa/gen/ARM.rules +++ b/src/cmd/compile/internal/ssa/gen/ARM.rules @@ -35,11 +35,11 @@ (Div32 x y) -> (SUB (XOR // negate the result if one operand is negative - (Select0 (UDIVrtcall + (Select0 (CALLudiv {config.ctxt.Lookup("udiv", 0)} (SUB (XOR x (Signmask x)) (Signmask x)) // negate x if negative (SUB (XOR y (Signmask y)) (Signmask y)))) // negate y if negative (Signmask (XOR x y))) (Signmask (XOR x y))) -(Div32u x y) -> (Select0 (UDIVrtcall x y)) +(Div32u x y) -> (Select0 (CALLudiv {config.ctxt.Lookup("udiv", 0)} x y)) (Div16 x y) -> (Div32 (SignExt16to32 x) (SignExt16to32 y)) (Div16u x y) -> (Div32u (ZeroExt16to32 x) (ZeroExt16to32 y)) (Div8 x y) -> (Div32 (SignExt8to32 x) (SignExt8to32 y)) @@ -49,11 +49,11 @@ (Mod32 x y) -> (SUB (XOR // negate the result if x is negative - (Select1 (UDIVrtcall + (Select1 (CALLudiv {config.ctxt.Lookup("udiv", 0)} (SUB (XOR x (Signmask x)) (Signmask x)) // negate x if negative (SUB (XOR y (Signmask y)) (Signmask y)))) // negate y if negative (Signmask x)) (Signmask x)) -(Mod32u x y) -> (Select1 (UDIVrtcall x y)) +(Mod32u x y) -> (Select1 (CALLudiv {config.ctxt.Lookup("udiv", 0)} x y)) (Mod16 x y) -> (Mod32 (SignExt16to32 x) (SignExt16to32 y)) (Mod16u x y) -> (Mod32u (ZeroExt16to32 x) (ZeroExt16to32 y)) (Mod8 x y) -> (Mod32 (SignExt8to32 x) (SignExt8to32 y)) @@ -593,10 +593,10 @@ (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 -(Select0 (UDIVrtcall x (MOVWconst [1]))) -> x -(Select1 (UDIVrtcall _ (MOVWconst [1]))) -> (MOVWconst [0]) -(Select0 (UDIVrtcall x (MOVWconst [c]))) && isPowerOfTwo(c) -> (SRLconst [log2(c)] x) -(Select1 (UDIVrtcall x (MOVWconst [c]))) && isPowerOfTwo(c) -> (ANDconst [c-1] x) +(Select0 (CALLudiv x (MOVWconst [1]))) -> x +(Select1 (CALLudiv _ (MOVWconst [1]))) -> (MOVWconst [0]) +(Select0 (CALLudiv x (MOVWconst [c]))) && isPowerOfTwo(c) -> (SRLconst [log2(c)] x) +(Select1 (CALLudiv x (MOVWconst [c]))) && isPowerOfTwo(c) -> (ANDconst [c-1] x) // constant comparisons (CMPconst (MOVWconst [x]) [y]) && int32(x)==int32(y) -> (FlagEQ) @@ -814,8 +814,8 @@ (SRAconst [c] (MOVWconst [d])) -> (MOVWconst [int64(int32(d)>>uint64(c))]) (MUL (MOVWconst [c]) (MOVWconst [d])) -> (MOVWconst [int64(int32(c*d))]) (MULA (MOVWconst [c]) (MOVWconst [d]) a) -> (ADDconst [int64(int32(c*d))] a) -(Select0 (UDIVrtcall (MOVWconst [c]) (MOVWconst [d]))) -> (MOVWconst [int64(uint32(c)/uint32(d))]) -(Select1 (UDIVrtcall (MOVWconst [c]) (MOVWconst [d]))) -> (MOVWconst [int64(uint32(c)%uint32(d))]) +(Select0 (CALLudiv (MOVWconst [c]) (MOVWconst [d]))) -> (MOVWconst [int64(uint32(c)/uint32(d))]) +(Select1 (CALLudiv (MOVWconst [c]) (MOVWconst [d]))) -> (MOVWconst [int64(uint32(c)%uint32(d))]) (ANDconst [c] (MOVWconst [d])) -> (MOVWconst [c&d]) (ANDconst [c] (ANDconst [d] x)) -> (ANDconst [c&d] x) (ORconst [c] (MOVWconst [d])) -> (MOVWconst [c|d]) diff --git a/src/cmd/compile/internal/ssa/gen/ARMOps.go b/src/cmd/compile/internal/ssa/gen/ARMOps.go index a29d6b5996..a6ca735c2b 100644 --- a/src/cmd/compile/internal/ssa/gen/ARMOps.go +++ b/src/cmd/compile/internal/ssa/gen/ARMOps.go @@ -143,7 +143,7 @@ func init() { // output0 = arg0/arg1, output1 = arg0%arg1 // see ../../../../../runtime/vlop_arm.s { - name: "UDIVrtcall", + name: "CALLudiv", argLength: 2, reg: regInfo{ inputs: []regMask{buildReg("R1"), buildReg("R0")}, @@ -152,6 +152,9 @@ func init() { }, clobberFlags: true, typ: "(UInt32,UInt32)", + aux: "SymOff", + // TODO(mdempsky): Should this be true? + call: false, }, {name: "ADDS", argLength: 2, reg: gp21carry, asm: "ADD", commutative: true}, // arg0 + arg1, set carry flag diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go index 6fbead35d3..90cb5869ef 100644 --- a/src/cmd/compile/internal/ssa/opGen.go +++ b/src/cmd/compile/internal/ssa/opGen.go @@ -660,7 +660,7 @@ const ( OpARMMUL OpARMHMUL OpARMHMULU - OpARMUDIVrtcall + OpARMCALLudiv OpARMADDS OpARMADDSconst OpARMADC @@ -7784,7 +7784,8 @@ var opcodeTable = [...]opInfo{ }, }, { - name: "UDIVrtcall", + name: "CALLudiv", + auxType: auxSymOff, argLen: 2, clobberFlags: true, reg: regInfo{ diff --git a/src/cmd/compile/internal/ssa/rewriteARM.go b/src/cmd/compile/internal/ssa/rewriteARM.go index 086d0577f7..4dd60d5983 100644 --- a/src/cmd/compile/internal/ssa/rewriteARM.go +++ b/src/cmd/compile/internal/ssa/rewriteARM.go @@ -13427,14 +13427,15 @@ func rewriteValueARM_OpDiv32(v *Value, config *Config) bool { _ = b // match: (Div32 x y) // cond: - // result: (SUB (XOR (Select0 (UDIVrtcall (SUB (XOR x (Signmask x)) (Signmask x)) (SUB (XOR y (Signmask y)) (Signmask y)))) (Signmask (XOR x y))) (Signmask (XOR x y))) + // result: (SUB (XOR (Select0 (CALLudiv {config.ctxt.Lookup("udiv", 0)} (SUB (XOR x (Signmask x)) (Signmask x)) (SUB (XOR y (Signmask y)) (Signmask y)))) (Signmask (XOR x y))) (Signmask (XOR x y))) for { x := v.Args[0] y := v.Args[1] v.reset(OpARMSUB) v0 := b.NewValue0(v.Pos, OpARMXOR, config.fe.TypeUInt32()) v1 := b.NewValue0(v.Pos, OpSelect0, config.fe.TypeUInt32()) - v2 := b.NewValue0(v.Pos, OpARMUDIVrtcall, MakeTuple(config.fe.TypeUInt32(), config.fe.TypeUInt32())) + v2 := b.NewValue0(v.Pos, OpARMCALLudiv, MakeTuple(config.fe.TypeUInt32(), config.fe.TypeUInt32())) + v2.Aux = config.ctxt.Lookup("udiv", 0) v3 := b.NewValue0(v.Pos, OpARMSUB, config.fe.TypeUInt32()) v4 := b.NewValue0(v.Pos, OpARMXOR, config.fe.TypeUInt32()) v4.AddArg(x) @@ -13495,13 +13496,14 @@ func rewriteValueARM_OpDiv32u(v *Value, config *Config) bool { _ = b // match: (Div32u x y) // cond: - // result: (Select0 (UDIVrtcall x y)) + // result: (Select0 (CALLudiv {config.ctxt.Lookup("udiv", 0)} x y)) for { x := v.Args[0] y := v.Args[1] v.reset(OpSelect0) v.Type = config.fe.TypeUInt32() - v0 := b.NewValue0(v.Pos, OpARMUDIVrtcall, MakeTuple(config.fe.TypeUInt32(), config.fe.TypeUInt32())) + v0 := b.NewValue0(v.Pos, OpARMCALLudiv, MakeTuple(config.fe.TypeUInt32(), config.fe.TypeUInt32())) + v0.Aux = config.ctxt.Lookup("udiv", 0) v0.AddArg(x) v0.AddArg(y) v.AddArg(v0) @@ -14885,14 +14887,15 @@ func rewriteValueARM_OpMod32(v *Value, config *Config) bool { _ = b // match: (Mod32 x y) // cond: - // result: (SUB (XOR (Select1 (UDIVrtcall (SUB (XOR x (Signmask x)) (Signmask x)) (SUB (XOR y (Signmask y)) (Signmask y)))) (Signmask x)) (Signmask x)) + // result: (SUB (XOR (Select1 (CALLudiv {config.ctxt.Lookup("udiv", 0)} (SUB (XOR x (Signmask x)) (Signmask x)) (SUB (XOR y (Signmask y)) (Signmask y)))) (Signmask x)) (Signmask x)) for { x := v.Args[0] y := v.Args[1] v.reset(OpARMSUB) v0 := b.NewValue0(v.Pos, OpARMXOR, config.fe.TypeUInt32()) v1 := b.NewValue0(v.Pos, OpSelect1, config.fe.TypeUInt32()) - v2 := b.NewValue0(v.Pos, OpARMUDIVrtcall, MakeTuple(config.fe.TypeUInt32(), config.fe.TypeUInt32())) + v2 := b.NewValue0(v.Pos, OpARMCALLudiv, MakeTuple(config.fe.TypeUInt32(), config.fe.TypeUInt32())) + v2.Aux = config.ctxt.Lookup("udiv", 0) v3 := b.NewValue0(v.Pos, OpARMSUB, config.fe.TypeUInt32()) v4 := b.NewValue0(v.Pos, OpARMXOR, config.fe.TypeUInt32()) v4.AddArg(x) @@ -14932,13 +14935,14 @@ func rewriteValueARM_OpMod32u(v *Value, config *Config) bool { _ = b // match: (Mod32u x y) // cond: - // result: (Select1 (UDIVrtcall x y)) + // result: (Select1 (CALLudiv {config.ctxt.Lookup("udiv", 0)} x y)) for { x := v.Args[0] y := v.Args[1] v.reset(OpSelect1) v.Type = config.fe.TypeUInt32() - v0 := b.NewValue0(v.Pos, OpARMUDIVrtcall, MakeTuple(config.fe.TypeUInt32(), config.fe.TypeUInt32())) + v0 := b.NewValue0(v.Pos, OpARMCALLudiv, MakeTuple(config.fe.TypeUInt32(), config.fe.TypeUInt32())) + v0.Aux = config.ctxt.Lookup("udiv", 0) v0.AddArg(x) v0.AddArg(y) v.AddArg(v0) @@ -16331,12 +16335,12 @@ func rewriteValueARM_OpRsh8x8(v *Value, config *Config) bool { func rewriteValueARM_OpSelect0(v *Value, config *Config) bool { b := v.Block _ = b - // match: (Select0 (UDIVrtcall x (MOVWconst [1]))) + // match: (Select0 (CALLudiv x (MOVWconst [1]))) // cond: // result: x for { v_0 := v.Args[0] - if v_0.Op != OpARMUDIVrtcall { + if v_0.Op != OpARMCALLudiv { break } x := v_0.Args[0] @@ -16352,12 +16356,12 @@ func rewriteValueARM_OpSelect0(v *Value, config *Config) bool { v.AddArg(x) return true } - // match: (Select0 (UDIVrtcall x (MOVWconst [c]))) + // match: (Select0 (CALLudiv x (MOVWconst [c]))) // cond: isPowerOfTwo(c) // result: (SRLconst [log2(c)] x) for { v_0 := v.Args[0] - if v_0.Op != OpARMUDIVrtcall { + if v_0.Op != OpARMCALLudiv { break } x := v_0.Args[0] @@ -16374,12 +16378,12 @@ func rewriteValueARM_OpSelect0(v *Value, config *Config) bool { v.AddArg(x) return true } - // match: (Select0 (UDIVrtcall (MOVWconst [c]) (MOVWconst [d]))) + // match: (Select0 (CALLudiv (MOVWconst [c]) (MOVWconst [d]))) // cond: // result: (MOVWconst [int64(uint32(c)/uint32(d))]) for { v_0 := v.Args[0] - if v_0.Op != OpARMUDIVrtcall { + if v_0.Op != OpARMCALLudiv { break } v_0_0 := v_0.Args[0] @@ -16401,12 +16405,12 @@ func rewriteValueARM_OpSelect0(v *Value, config *Config) bool { func rewriteValueARM_OpSelect1(v *Value, config *Config) bool { b := v.Block _ = b - // match: (Select1 (UDIVrtcall _ (MOVWconst [1]))) + // match: (Select1 (CALLudiv _ (MOVWconst [1]))) // cond: // result: (MOVWconst [0]) for { v_0 := v.Args[0] - if v_0.Op != OpARMUDIVrtcall { + if v_0.Op != OpARMCALLudiv { break } v_0_1 := v_0.Args[1] @@ -16420,12 +16424,12 @@ func rewriteValueARM_OpSelect1(v *Value, config *Config) bool { v.AuxInt = 0 return true } - // match: (Select1 (UDIVrtcall x (MOVWconst [c]))) + // match: (Select1 (CALLudiv x (MOVWconst [c]))) // cond: isPowerOfTwo(c) // result: (ANDconst [c-1] x) for { v_0 := v.Args[0] - if v_0.Op != OpARMUDIVrtcall { + if v_0.Op != OpARMCALLudiv { break } x := v_0.Args[0] @@ -16442,12 +16446,12 @@ func rewriteValueARM_OpSelect1(v *Value, config *Config) bool { v.AddArg(x) return true } - // match: (Select1 (UDIVrtcall (MOVWconst [c]) (MOVWconst [d]))) + // match: (Select1 (CALLudiv (MOVWconst [c]) (MOVWconst [d]))) // cond: // result: (MOVWconst [int64(uint32(c)%uint32(d))]) for { v_0 := v.Args[0] - if v_0.Op != OpARMUDIVrtcall { + if v_0.Op != OpARMCALLudiv { break } v_0_0 := v_0.Args[0] diff --git a/src/cmd/internal/obj/sym.go b/src/cmd/internal/obj/sym.go index 0527397749..8f6edb9af5 100644 --- a/src/cmd/internal/obj/sym.go +++ b/src/cmd/internal/obj/sym.go @@ -66,7 +66,7 @@ func Linknew(arch *LinkArch) *Link { return ctxt } -func Linklookup(ctxt *Link, name string, v int) *LSym { +func (ctxt *Link) Lookup(name string, v int) *LSym { s := ctxt.Hash[SymVer{name, v}] if s != nil { return s @@ -82,6 +82,10 @@ func Linklookup(ctxt *Link, name string, v int) *LSym { return s } +func Linklookup(ctxt *Link, name string, v int) *LSym { + return ctxt.Lookup(name, v) +} + func Linksymfmt(s *LSym) string { if s == nil { return ""