Commit 01b1a34a authored by Josh Bleecher Snyder's avatar Josh Bleecher Snyder

cmd/compile: rework handling of udiv on ARM

Instead of populating the aux symbol
of CALLudiv during rewrite rules,
populate it during genssa.

This simplifies the rewrite rules.
It also removes all remaining calls
to ctxt.Lookup from any rewrite rules.
This is a first step towards removing
ctxt from ssa.Cache entirely,
and also a first step towards converting
the obj.LSym.Version field into a boolean.
It should also speed up compilation.

Also, move func udiv into package runtime.
That's where it is anyway,
and it lets udiv look and act like the rest of
the runtime support functions.

Change-Id: I41462a632c14fdc41f61b08049ec13cd80a87bfe
Reviewed-on: https://go-review.googlesource.com/41191
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarCherry Zhang <cherryyz@google.com>
Reviewed-by: default avatarMatthew Dempsky <mdempsky@google.com>
parent 6e97c71c
......@@ -622,7 +622,10 @@ 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, ssa.OpARMCALLudiv:
case ssa.OpARMCALLstatic, ssa.OpARMCALLclosure, ssa.OpARMCALLinter:
s.Call(v)
case ssa.OpARMCALLudiv:
v.Aux = gc.Udiv
s.Call(v)
case ssa.OpARMDUFFZERO:
p := s.Prog(obj.ADUFFZERO)
......
......@@ -270,5 +270,6 @@ var (
writeBarrier,
writebarrierptr,
typedmemmove,
typedmemclr *obj.LSym
typedmemclr,
Udiv *obj.LSym
)
......@@ -91,6 +91,7 @@ func initssaconfig() {
writebarrierptr = Sysfunc("writebarrierptr")
typedmemmove = Sysfunc("typedmemmove")
typedmemclr = Sysfunc("typedmemclr")
Udiv = Sysfunc("udiv")
}
// buildssa builds an SSA function.
......
......@@ -34,12 +34,12 @@
(Mul32uhilo x y) -> (MULLU x y)
(Div32 x y) ->
(SUB (XOR <types.UInt32> // negate the result if one operand is negative
(Select0 <types.UInt32> (CALLudiv {config.ctxt.Lookup("udiv", 0)}
(SUB (XOR <types.UInt32> // negate the result if one operand is negative
(Select0 <types.UInt32> (CALLudiv
(SUB <types.UInt32> (XOR x <types.UInt32> (Signmask x)) (Signmask x)) // negate x if negative
(SUB <types.UInt32> (XOR y <types.UInt32> (Signmask y)) (Signmask y)))) // negate y if negative
(Signmask (XOR <types.UInt32> x y))) (Signmask (XOR <types.UInt32> x y)))
(Div32u x y) -> (Select0 <types.UInt32> (CALLudiv {config.ctxt.Lookup("udiv", 0)} x y))
(Div32u x y) -> (Select0 <types.UInt32> (CALLudiv 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))
......@@ -48,12 +48,12 @@
(Div64F x y) -> (DIVD x y)
(Mod32 x y) ->
(SUB (XOR <types.UInt32> // negate the result if x is negative
(Select1 <types.UInt32> (CALLudiv {config.ctxt.Lookup("udiv", 0)}
(SUB (XOR <types.UInt32> // negate the result if x is negative
(Select1 <types.UInt32> (CALLudiv
(SUB <types.UInt32> (XOR <types.UInt32> x (Signmask x)) (Signmask x)) // negate x if negative
(SUB <types.UInt32> (XOR <types.UInt32> y (Signmask y)) (Signmask y)))) // negate y if negative
(Signmask x)) (Signmask x))
(Mod32u x y) -> (Select1 <types.UInt32> (CALLudiv {config.ctxt.Lookup("udiv", 0)} x y))
(Mod32u x y) -> (Select1 <types.UInt32> (CALLudiv 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))
......
......@@ -152,10 +152,7 @@ func init() {
},
clobberFlags: true,
typ: "(UInt32,UInt32)",
aux: "SymOff",
// TODO(mdempsky): Should this be true?
call: false,
symEffect: "None",
call: false, // TODO(mdempsky): Should this be true?
},
{name: "ADDS", argLength: 2, reg: gp21carry, asm: "ADD", commutative: true}, // arg0 + arg1, set carry flag
......
......@@ -8151,10 +8151,8 @@ var opcodeTable = [...]opInfo{
},
{
name: "CALLudiv",
auxType: auxSymOff,
argLen: 2,
clobberFlags: true,
symEffect: SymNone,
reg: regInfo{
inputs: []inputInfo{
{0, 2}, // R1
......
......@@ -13582,13 +13582,11 @@ func rewriteValueARM_OpDiv16u(v *Value) bool {
func rewriteValueARM_OpDiv32(v *Value) bool {
b := v.Block
_ = b
config := b.Func.Config
_ = config
types := &b.Func.Config.Types
_ = types
// match: (Div32 x y)
// cond:
// result: (SUB (XOR <types.UInt32> (Select0 <types.UInt32> (CALLudiv {config.ctxt.Lookup("udiv", 0)} (SUB <types.UInt32> (XOR x <types.UInt32> (Signmask x)) (Signmask x)) (SUB <types.UInt32> (XOR y <types.UInt32> (Signmask y)) (Signmask y)))) (Signmask (XOR <types.UInt32> x y))) (Signmask (XOR <types.UInt32> x y)))
// result: (SUB (XOR <types.UInt32> (Select0 <types.UInt32> (CALLudiv (SUB <types.UInt32> (XOR x <types.UInt32> (Signmask x)) (Signmask x)) (SUB <types.UInt32> (XOR y <types.UInt32> (Signmask y)) (Signmask y)))) (Signmask (XOR <types.UInt32> x y))) (Signmask (XOR <types.UInt32> x y)))
for {
x := v.Args[0]
y := v.Args[1]
......@@ -13596,7 +13594,6 @@ func rewriteValueARM_OpDiv32(v *Value) bool {
v0 := b.NewValue0(v.Pos, OpARMXOR, types.UInt32)
v1 := b.NewValue0(v.Pos, OpSelect0, types.UInt32)
v2 := b.NewValue0(v.Pos, OpARMCALLudiv, MakeTuple(types.UInt32, types.UInt32))
v2.Aux = config.ctxt.Lookup("udiv", 0)
v3 := b.NewValue0(v.Pos, OpARMSUB, types.UInt32)
v4 := b.NewValue0(v.Pos, OpARMXOR, types.UInt32)
v4.AddArg(x)
......@@ -13653,20 +13650,17 @@ func rewriteValueARM_OpDiv32F(v *Value) bool {
func rewriteValueARM_OpDiv32u(v *Value) bool {
b := v.Block
_ = b
config := b.Func.Config
_ = config
types := &b.Func.Config.Types
_ = types
// match: (Div32u x y)
// cond:
// result: (Select0 <types.UInt32> (CALLudiv {config.ctxt.Lookup("udiv", 0)} x y))
// result: (Select0 <types.UInt32> (CALLudiv x y))
for {
x := v.Args[0]
y := v.Args[1]
v.reset(OpSelect0)
v.Type = types.UInt32
v0 := b.NewValue0(v.Pos, OpARMCALLudiv, MakeTuple(types.UInt32, types.UInt32))
v0.Aux = config.ctxt.Lookup("udiv", 0)
v0.AddArg(x)
v0.AddArg(y)
v.AddArg(v0)
......@@ -15088,13 +15082,11 @@ func rewriteValueARM_OpMod16u(v *Value) bool {
func rewriteValueARM_OpMod32(v *Value) bool {
b := v.Block
_ = b
config := b.Func.Config
_ = config
types := &b.Func.Config.Types
_ = types
// match: (Mod32 x y)
// cond:
// result: (SUB (XOR <types.UInt32> (Select1 <types.UInt32> (CALLudiv {config.ctxt.Lookup("udiv", 0)} (SUB <types.UInt32> (XOR <types.UInt32> x (Signmask x)) (Signmask x)) (SUB <types.UInt32> (XOR <types.UInt32> y (Signmask y)) (Signmask y)))) (Signmask x)) (Signmask x))
// result: (SUB (XOR <types.UInt32> (Select1 <types.UInt32> (CALLudiv (SUB <types.UInt32> (XOR <types.UInt32> x (Signmask x)) (Signmask x)) (SUB <types.UInt32> (XOR <types.UInt32> y (Signmask y)) (Signmask y)))) (Signmask x)) (Signmask x))
for {
x := v.Args[0]
y := v.Args[1]
......@@ -15102,7 +15094,6 @@ func rewriteValueARM_OpMod32(v *Value) bool {
v0 := b.NewValue0(v.Pos, OpARMXOR, types.UInt32)
v1 := b.NewValue0(v.Pos, OpSelect1, types.UInt32)
v2 := b.NewValue0(v.Pos, OpARMCALLudiv, MakeTuple(types.UInt32, types.UInt32))
v2.Aux = config.ctxt.Lookup("udiv", 0)
v3 := b.NewValue0(v.Pos, OpARMSUB, types.UInt32)
v4 := b.NewValue0(v.Pos, OpARMXOR, types.UInt32)
v4.AddArg(x)
......@@ -15140,20 +15131,17 @@ func rewriteValueARM_OpMod32(v *Value) bool {
func rewriteValueARM_OpMod32u(v *Value) bool {
b := v.Block
_ = b
config := b.Func.Config
_ = config
types := &b.Func.Config.Types
_ = types
// match: (Mod32u x y)
// cond:
// result: (Select1 <types.UInt32> (CALLudiv {config.ctxt.Lookup("udiv", 0)} x y))
// result: (Select1 <types.UInt32> (CALLudiv x y))
for {
x := v.Args[0]
y := v.Args[1]
v.reset(OpSelect1)
v.Type = types.UInt32
v0 := b.NewValue0(v.Pos, OpARMCALLudiv, MakeTuple(types.UInt32, types.UInt32))
v0.Aux = config.ctxt.Lookup("udiv", 0)
v0.AddArg(x)
v0.AddArg(y)
v.AddArg(v0)
......
......@@ -19,6 +19,7 @@ runtime/duff_arm.s: [arm] duffcopy: function duffcopy missing Go declaration
runtime/tls_arm.s: [arm] save_g: function save_g missing Go declaration
runtime/tls_arm.s: [arm] load_g: function load_g missing Go declaration
runtime/tls_arm.s: [arm] _initcgo: function _initcgo missing Go declaration
runtime/vlop_arm.s: [arm] udiv: function udiv missing Go declaration
// Clearer using FP than SP, but that requires named offsets.
runtime/asm_arm.s: [arm] rt0_go: use of 4(R13) points beyond argument frame
......
......@@ -106,7 +106,7 @@ TEXT runtime·_sfloatpanic(SB),NOSPLIT,$-4
MOVW g_sigpc(g), LR
B runtime·sigpanic(SB)
// func udiv(n, d uint32) (q, r uint32)
// func runtime·udiv(n, d uint32) (q, r uint32)
// compiler knowns the register usage of this function
// Reference:
// Sloss, Andrew et. al; ARM System Developer's Guide: Designing and Optimizing System Software
......@@ -118,7 +118,7 @@ TEXT runtime·_sfloatpanic(SB),NOSPLIT,$-4
#define Ra R11
// Be careful: Ra == R11 will be used by the linker for synthesized instructions.
TEXT udiv(SB),NOSPLIT,$-4
TEXT runtime·udiv(SB),NOSPLIT,$-4
MOVBU runtime·hardDiv(SB), Ra
CMP $0, Ra
BNE udiv_hardware
......@@ -241,7 +241,7 @@ TEXT _divu(SB), NOSPLIT, $16-0
MOVW Rn, Rr /* numerator */
MOVW g_m(g), Rq
MOVW m_divmod(Rq), Rq /* denominator */
BL udiv(SB)
BL runtime·udiv(SB)
MOVW Rq, RTMP
MOVW 4(R13), Rq
MOVW 8(R13), Rr
......@@ -259,7 +259,7 @@ TEXT _modu(SB), NOSPLIT, $16-0
MOVW Rn, Rr /* numerator */
MOVW g_m(g), Rq
MOVW m_divmod(Rq), Rq /* denominator */
BL udiv(SB)
BL runtime·udiv(SB)
MOVW Rr, RTMP
MOVW 4(R13), Rq
MOVW 8(R13), Rr
......@@ -283,7 +283,7 @@ TEXT _div(SB),NOSPLIT,$16-0
BGE d2
RSB $0, Rq, Rq
d0:
BL udiv(SB) /* none/both neg */
BL runtime·udiv(SB) /* none/both neg */
MOVW Rq, RTMP
B out1
d1:
......@@ -291,7 +291,7 @@ d1:
BGE d0
RSB $0, Rq, Rq
d2:
BL udiv(SB) /* one neg */
BL runtime·udiv(SB) /* one neg */
RSB $0, Rq, RTMP
out1:
MOVW 4(R13), Rq
......@@ -314,11 +314,11 @@ TEXT _mod(SB),NOSPLIT,$16-0
CMP $0, Rr
BGE m1
RSB $0, Rr, Rr
BL udiv(SB) /* neg numerator */
BL runtime·udiv(SB) /* neg numerator */
RSB $0, Rr, RTMP
B out
m1:
BL udiv(SB) /* pos numerator */
BL runtime·udiv(SB) /* pos numerator */
MOVW Rr, RTMP
out:
MOVW 4(R13), Rq
......
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