aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/mkpreempt.go
diff options
context:
space:
mode:
authorCherry Zhang <cherryyz@google.com>2020-03-04 11:14:53 -0500
committerCherry Zhang <cherryyz@google.com>2020-03-04 18:09:01 +0000
commit588ee7987d7f6be605166872ff8c478aa125bc58 (patch)
treecf707c3f9cc19d0888bebfcc0b79489d474f265c /src/runtime/mkpreempt.go
parent18a6fd44bb9de9399dba86a4c1ae1e56f967bcda (diff)
downloadgo-588ee7987d7f6be605166872ff8c478aa125bc58.tar.gz
go-588ee7987d7f6be605166872ff8c478aa125bc58.zip
runtime: don't save/restore FP registers in softfloat mode on MIPS(64)
Fixes #37653. Change-Id: I6188e44b4bc4aba7b56f29d9ce9de4618c70fd7b Reviewed-on: https://go-review.googlesource.com/c/go/+/222057 Run-TryBot: Cherry Zhang <cherryyz@google.com> Reviewed-by: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/runtime/mkpreempt.go')
-rw-r--r--src/runtime/mkpreempt.go24
1 files changed, 17 insertions, 7 deletions
diff --git a/src/runtime/mkpreempt.go b/src/runtime/mkpreempt.go
index c26406e55f..35ed42871f 100644
--- a/src/runtime/mkpreempt.go
+++ b/src/runtime/mkpreempt.go
@@ -382,6 +382,7 @@ func genMIPS(_64bit bool) {
sub := "SUB"
r28 := "R28"
regsize := 4
+ softfloat := "GOMIPS_softfloat"
if _64bit {
mov = "MOVV"
movf = "MOVD"
@@ -389,6 +390,7 @@ func genMIPS(_64bit bool) {
sub = "SUBV"
r28 = "RSB"
regsize = 8
+ softfloat = "GOMIPS64_softfloat"
}
// Add integer registers R1-R22, R24-R25, R28
@@ -411,28 +413,36 @@ func genMIPS(_64bit bool) {
mov+" LO, R1\n"+mov+" R1, %d(R29)",
mov+" %d(R29), R1\n"+mov+" R1, LO",
regsize)
+
// Add floating point control/status register FCR31 (FCR0-FCR30 are irrelevant)
- l.addSpecial(
+ var lfp = layout{sp: "R29", stack: l.stack}
+ lfp.addSpecial(
mov+" FCR31, R1\n"+mov+" R1, %d(R29)",
mov+" %d(R29), R1\n"+mov+" R1, FCR31",
regsize)
// Add floating point registers F0-F31.
for i := 0; i <= 31; i++ {
reg := fmt.Sprintf("F%d", i)
- l.add(movf, reg, regsize)
+ lfp.add(movf, reg, regsize)
}
// allocate frame, save PC of interrupted instruction (in LR)
- p(mov+" R31, -%d(R29)", l.stack)
- p(sub+" $%d, R29", l.stack)
+ p(mov+" R31, -%d(R29)", lfp.stack)
+ p(sub+" $%d, R29", lfp.stack)
l.save()
+ p("#ifndef %s", softfloat)
+ lfp.save()
+ p("#endif")
p("CALL ·asyncPreempt2(SB)")
+ p("#ifndef %s", softfloat)
+ lfp.restore()
+ p("#endif")
l.restore()
- p(mov+" %d(R29), R31", l.stack) // sigctxt.pushCall has pushed LR (at interrupt) on stack, restore it
- p(mov + " (R29), R23") // load PC to REGTMP
- p(add+" $%d, R29", l.stack+regsize) // pop frame (including the space pushed by sigctxt.pushCall)
+ p(mov+" %d(R29), R31", lfp.stack) // sigctxt.pushCall has pushed LR (at interrupt) on stack, restore it
+ p(mov + " (R29), R23") // load PC to REGTMP
+ p(add+" $%d, R29", lfp.stack+regsize) // pop frame (including the space pushed by sigctxt.pushCall)
p("JMP (R23)")
}