]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: not use REGTMP in ZeroRange on ARM64
authorCherry Zhang <cherryyz@google.com>
Fri, 25 Oct 2019 04:50:00 +0000 (00:50 -0400)
committerCherry Zhang <cherryyz@google.com>
Tue, 5 Nov 2019 02:54:42 +0000 (02:54 +0000)
For async preemption, we will be using REGTMP as a temporary
register in injected call on ARM64, which will clobber it. So any
code that uses REGTMP is not safe for async preemption.

For ZeroRange, which is inserted at the function entry where
there is no register live, we could just use a different register
and avoid REGTMP.

Change-Id: I3db763828df6846908c9843a9912597efb9efcdf
Reviewed-on: https://go-review.googlesource.com/c/go/+/203458
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
src/cmd/compile/internal/arm64/ggen.go
src/cmd/compile/internal/gc/go.go

index dbe7495ccac9bf2adf589ae0526f38417e64a558..f698919e9b268ab7d922d2c6fe400997a71fda56 100644 (file)
@@ -44,12 +44,16 @@ func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
                p.To.Sym = gc.Duffzero
                p.To.Offset = 4 * (64 - cnt/(2*int64(gc.Widthptr)))
        } else {
-               p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_CONST, 0, 8+off-8, obj.TYPE_REG, arm64.REGTMP, 0)
+               // Not using REGTMP, so this is async preemptible (async preemption clobbers REGTMP).
+               // We are at the function entry, where no register is live, so it is okay to clobber
+               // other registers
+               const rtmp = arm64.REG_R20
+               p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_CONST, 0, 8+off-8, obj.TYPE_REG, rtmp, 0)
                p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGSP, 0, obj.TYPE_REG, arm64.REGRT1, 0)
-               p = pp.Appendpp(p, arm64.AADD, obj.TYPE_REG, arm64.REGTMP, 0, obj.TYPE_REG, arm64.REGRT1, 0)
+               p = pp.Appendpp(p, arm64.AADD, obj.TYPE_REG, rtmp, 0, obj.TYPE_REG, arm64.REGRT1, 0)
                p.Reg = arm64.REGRT1
-               p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, arm64.REGTMP, 0)
-               p = pp.Appendpp(p, arm64.AADD, obj.TYPE_REG, arm64.REGTMP, 0, obj.TYPE_REG, arm64.REGRT2, 0)
+               p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, rtmp, 0)
+               p = pp.Appendpp(p, arm64.AADD, obj.TYPE_REG, rtmp, 0, obj.TYPE_REG, arm64.REGRT2, 0)
                p.Reg = arm64.REGRT1
                p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGZERO, 0, obj.TYPE_MEM, arm64.REGRT1, int64(gc.Widthptr))
                p.Scond = arm64.C_XPRE
index c14fb4d3fab722ad7acdf2a1d01795d6f23676a5..025b276c20426066362358f4edbf8b166af359c6 100644 (file)
@@ -256,8 +256,12 @@ type Arch struct {
        Use387    bool // should 386 backend use 387 FP instructions instead of sse2.
        SoftFloat bool
 
-       PadFrame     func(int64) int64
-       ZeroRange    func(*Progs, *obj.Prog, int64, int64, *uint32) *obj.Prog
+       PadFrame func(int64) int64
+
+       // ZeroRange zeroes a range of memory on stack. It is only inserted
+       // at function entry, and it is ok to clobber registers.
+       ZeroRange func(*Progs, *obj.Prog, int64, int64, *uint32) *obj.Prog
+
        Ginsnop      func(*Progs) *obj.Prog
        Ginsnopdefer func(*Progs) *obj.Prog // special ginsnop for deferreturn