mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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: Cherry Zhang <cherryyz@google.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
6e97c71cb7
commit
01b1a34aac
9 changed files with 27 additions and 38 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -35,11 +35,11 @@
|
|||
|
||||
(Div32 x y) ->
|
||||
(SUB (XOR <types.UInt32> // negate the result if one operand is negative
|
||||
(Select0 <types.UInt32> (CALLudiv {config.ctxt.Lookup("udiv", 0)}
|
||||
(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))
|
||||
|
|
@ -49,11 +49,11 @@
|
|||
|
||||
(Mod32 x y) ->
|
||||
(SUB (XOR <types.UInt32> // negate the result if x is negative
|
||||
(Select1 <types.UInt32> (CALLudiv {config.ctxt.Lookup("udiv", 0)}
|
||||
(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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue