Eric Fang has uploaded this change for review.
runtime: use stp/ldp to save and restore all registers on arm64
Async preemption needs to save and restore almost all of the registers,
currently this is done by ldr and str on arm64. We can do it with ldp
and stp as they are more efficient.
Change-Id: Ida5a6f0a8d825a56af607ba2c2cd91fdc2e8f67f
---
M src/runtime/mkpreempt.go
M src/runtime/preempt_arm64.s
2 files changed, 103 insertions(+), 154 deletions(-)
diff --git a/src/runtime/mkpreempt.go b/src/runtime/mkpreempt.go
index 17c9b75..10079ac 100644
--- a/src/runtime/mkpreempt.go
+++ b/src/runtime/mkpreempt.go
@@ -122,7 +122,7 @@
fmt.Fprintf(out, "// Code generated by mkpreempt.go; DO NOT EDIT.\n\n")
if beLe[arch] {
base := arch[:len(arch)-1]
- fmt.Fprintf(out, "//go:build %s || %sle\n", base, base)
+ fmt.Fprintf(out, "//go:build %s || %sle\n\n", base, base)
}
fmt.Fprintf(out, "#include \"go_asm.h\"\n")
fmt.Fprintf(out, "#include \"textflag.h\"\n\n")
@@ -147,8 +147,9 @@
type regPos struct {
pos int
- op string
- reg string
+ saveOp string
+ restoreOp string
+ reg string
// If this register requires special save and restore, these
// give those operations with a %d placeholder for the stack
@@ -156,8 +157,8 @@
save, restore string
}
-func (l *layout) add(op, reg string, size int) {
- l.regs = append(l.regs, regPos{op: op, reg: reg, pos: l.stack})
+func (l *layout) add(sop, rop, reg string, size int) {
+ l.regs = append(l.regs, regPos{saveOp: sop, restoreOp: rop, reg: reg, pos: l.stack})
l.stack += size
}
@@ -171,7 +172,7 @@
if reg.save != "" {
p(reg.save, reg.pos)
} else {
- p("%s %s, %d(%s)", reg.op, reg.reg, reg.pos, l.sp)
+ p("%s %s, %d(%s)", reg.saveOp, reg.reg, reg.pos, l.sp)
}
}
}
@@ -182,7 +183,7 @@
if reg.restore != "" {
p(reg.restore, reg.pos)
} else {
- p("%s %d(%s), %s", reg.op, reg.pos, l.sp, reg.reg)
+ p("%s %d(%s), %s", reg.restoreOp, reg.pos, l.sp, reg.reg)
}
}
}
@@ -195,7 +196,7 @@
if reg == "SP" || strings.HasPrefix(reg, "X") {
continue
}
- l.add("MOVL", reg, 4)
+ l.add("MOVL", "MOVL", reg, 4)
}
softfloat := "GO386_softfloat"
@@ -203,7 +204,7 @@
// Save SSE state only if supported.
lSSE := layout{stack: l.stack, sp: "SP"}
for i := 0; i < 8; i++ {
- lSSE.add("MOVUPS", fmt.Sprintf("X%d", i), 16)
+ lSSE.add("MOVUPS", "MOVUPS", fmt.Sprintf("X%d", i), 16)
}
p("ADJSP $%d", lSSE.stack)
@@ -231,13 +232,13 @@
continue
}
if !strings.HasPrefix(reg, "X") {
- l.add("MOVQ", reg, 8)
+ l.add("MOVQ", "MOVQ", reg, 8)
}
}
lSSE := layout{stack: l.stack, sp: "SP"}
for _, reg := range regNamesAMD64 {
if strings.HasPrefix(reg, "X") {
- lSSE.add("MOVUPS", reg, 16)
+ lSSE.add("MOVUPS", "MOVUPS", reg, 16)
}
}
@@ -284,7 +285,7 @@
if i == 10 {
continue // R10 is g register, no need to save/restore
}
- l.add("MOVW", reg, 4)
+ l.add("MOVW", "MOVW", reg, 4)
}
// Add flag register.
l.addSpecial(
@@ -300,7 +301,7 @@
4)
for i := 0; i <= 15; i++ {
reg := fmt.Sprintf("F%d", i)
- lfp.add("MOVD", reg, 8)
+ lfp.add("MOVD", "MOVD", reg, 8)
}
p("MOVW.W R14, -%d(R13)", lfp.stack) // allocate frame, save LR
@@ -324,12 +325,13 @@
// R27 (REGTMP), R28 (g), R29 (FP), R30 (LR), R31 (SP) are special
// and not saved here.
var l = layout{sp: "RSP", stack: 8} // add slot to save PC of interrupted instruction
- for i := 0; i <= 26; i++ {
+ for i := 0; i < 26; i += 2 {
if i == 18 {
+ i--
continue // R18 is not used, skip
}
- reg := fmt.Sprintf("R%d", i)
- l.add("MOVD", reg, 8)
+ reg := fmt.Sprintf("(R%d, R%d)", i, i+1)
+ l.add("STP", "LDP", reg, 16)
}
// Add flag registers.
l.addSpecial(
@@ -342,9 +344,9 @@
8)
// TODO: FPCR? I don't think we'll change it, so no need to save.
// Add floating point registers F0-F31.
- for i := 0; i <= 31; i++ {
- reg := fmt.Sprintf("F%d", i)
- l.add("FMOVD", reg, 8)
+ for i := 0; i < 31; i += 2 {
+ reg := fmt.Sprintf("(F%d, F%d)", i, i+1)
+ l.add("FSTPD", "FLDPD", reg, 16)
}
if l.stack%16 != 0 {
l.stack += 8 // SP needs 16-byte alignment
@@ -353,10 +355,8 @@
// allocate frame, save PC of interrupted instruction (in LR)
p("MOVD R30, %d(RSP)", -l.stack)
p("SUB $%d, RSP", l.stack)
- p("#ifdef GOOS_linux")
p("MOVD R29, -8(RSP)") // save frame pointer (only used on Linux)
p("SUB $8, RSP, R29") // set up new frame pointer
- p("#endif")
// On iOS, save the LR again after decrementing SP. We run the
// signal handler on the G stack (as it doesn't support sigaltstack),
// so any writes below SP may be clobbered.
@@ -369,11 +369,9 @@
l.restore()
p("MOVD %d(RSP), R30", l.stack) // sigctxt.pushCall has pushed LR (at interrupt) on stack, restore it
- p("#ifdef GOOS_linux")
- p("MOVD -8(RSP), R29") // restore frame pointer
- p("#endif")
- p("MOVD (RSP), R27") // load PC to REGTMP
- p("ADD $%d, RSP", l.stack+16) // pop frame (including the space pushed by sigctxt.pushCall)
+ p("MOVD -8(RSP), R29") // restore frame pointer
+ p("MOVD (RSP), R27") // load PC to REGTMP
+ p("ADD $%d, RSP", l.stack+16) // pop frame (including the space pushed by sigctxt.pushCall)
p("JMP (R27)")
}
@@ -404,9 +402,9 @@
continue // R23 is REGTMP
}
reg := fmt.Sprintf("R%d", i)
- l.add(mov, reg, regsize)
+ l.add(mov, mov, reg, regsize)
}
- l.add(mov, r28, regsize)
+ l.add(mov, mov, r28, regsize)
l.addSpecial(
mov+" HI, R1\n"+mov+" R1, %d(R29)",
mov+" %d(R29), R1\n"+mov+" R1, HI",
@@ -425,7 +423,7 @@
// Add floating point registers F0-F31.
for i := 0; i <= 31; i++ {
reg := fmt.Sprintf("F%d", i)
- lfp.add(movf, reg, regsize)
+ lfp.add(movf, movf, reg, regsize)
}
// allocate frame, save PC of interrupted instruction (in LR)
@@ -463,7 +461,7 @@
continue
}
reg := fmt.Sprintf("R%d", i)
- l.add("MOVD", reg, 8)
+ l.add("MOVD", "MOVD", reg, 8)
}
l.addSpecial(
"MOVW CR, R31\nMOVW R31, %d(R1)",
@@ -476,7 +474,7 @@
// Add floating point registers F0-F31.
for i := 0; i <= 31; i++ {
reg := fmt.Sprintf("F%d", i)
- l.add("FMOVD", reg, 8)
+ l.add("FMOVD", "FMOVD", reg, 8)
}
// Add floating point control/status register FPSCR.
l.addSpecial(
@@ -513,13 +511,13 @@
continue
}
reg := fmt.Sprintf("X%d", i)
- l.add("MOV", reg, 8)
+ l.add("MOV", "MOV", reg, 8)
}
// Add floating point registers (F0-F31).
for i := 0; i <= 31; i++ {
reg := fmt.Sprintf("F%d", i)
- l.add("MOVD", reg, 8)
+ l.add("MOVD", "MOVD", reg, 8)
}
p("MOV X1, -%d(X2)", l.stack)
@@ -545,7 +543,7 @@
// Add floating point registers F0-F31.
for i := 0; i <= 15; i++ {
reg := fmt.Sprintf("F%d", i)
- l.add("FMOVD", reg, 8)
+ l.add("FMOVD", "FMOVD", reg, 8)
}
// allocate frame, save PC of interrupted instruction (in LR) and flags (condition code)
diff --git a/src/runtime/preempt_arm64.s b/src/runtime/preempt_arm64.s
index 36ee132..c27d475 100644
--- a/src/runtime/preempt_arm64.s
+++ b/src/runtime/preempt_arm64.s
@@ -6,142 +6,80 @@
TEXT ·asyncPreempt(SB),NOSPLIT|NOFRAME,$0-0
MOVD R30, -496(RSP)
SUB $496, RSP
- #ifdef GOOS_linux
MOVD R29, -8(RSP)
SUB $8, RSP, R29
- #endif
#ifdef GOOS_ios
MOVD R30, (RSP)
#endif
- MOVD R0, 8(RSP)
- MOVD R1, 16(RSP)
- MOVD R2, 24(RSP)
- MOVD R3, 32(RSP)
- MOVD R4, 40(RSP)
- MOVD R5, 48(RSP)
- MOVD R6, 56(RSP)
- MOVD R7, 64(RSP)
- MOVD R8, 72(RSP)
- MOVD R9, 80(RSP)
- MOVD R10, 88(RSP)
- MOVD R11, 96(RSP)
- MOVD R12, 104(RSP)
- MOVD R13, 112(RSP)
- MOVD R14, 120(RSP)
- MOVD R15, 128(RSP)
- MOVD R16, 136(RSP)
- MOVD R17, 144(RSP)
- MOVD R19, 152(RSP)
- MOVD R20, 160(RSP)
- MOVD R21, 168(RSP)
- MOVD R22, 176(RSP)
- MOVD R23, 184(RSP)
- MOVD R24, 192(RSP)
- MOVD R25, 200(RSP)
- MOVD R26, 208(RSP)
+ STP (R0, R1), 8(RSP)
+ STP (R2, R3), 24(RSP)
+ STP (R4, R5), 40(RSP)
+ STP (R6, R7), 56(RSP)
+ STP (R8, R9), 72(RSP)
+ STP (R10, R11), 88(RSP)
+ STP (R12, R13), 104(RSP)
+ STP (R14, R15), 120(RSP)
+ STP (R16, R17), 136(RSP)
+ STP (R19, R20), 152(RSP)
+ STP (R21, R22), 168(RSP)
+ STP (R23, R24), 184(RSP)
+ STP (R25, R26), 200(RSP)
MOVD NZCV, R0
MOVD R0, 216(RSP)
MOVD FPSR, R0
MOVD R0, 224(RSP)
- FMOVD F0, 232(RSP)
- FMOVD F1, 240(RSP)
- FMOVD F2, 248(RSP)
- FMOVD F3, 256(RSP)
- FMOVD F4, 264(RSP)
- FMOVD F5, 272(RSP)
- FMOVD F6, 280(RSP)
- FMOVD F7, 288(RSP)
- FMOVD F8, 296(RSP)
- FMOVD F9, 304(RSP)
- FMOVD F10, 312(RSP)
- FMOVD F11, 320(RSP)
- FMOVD F12, 328(RSP)
- FMOVD F13, 336(RSP)
- FMOVD F14, 344(RSP)
- FMOVD F15, 352(RSP)
- FMOVD F16, 360(RSP)
- FMOVD F17, 368(RSP)
- FMOVD F18, 376(RSP)
- FMOVD F19, 384(RSP)
- FMOVD F20, 392(RSP)
- FMOVD F21, 400(RSP)
- FMOVD F22, 408(RSP)
- FMOVD F23, 416(RSP)
- FMOVD F24, 424(RSP)
- FMOVD F25, 432(RSP)
- FMOVD F26, 440(RSP)
- FMOVD F27, 448(RSP)
- FMOVD F28, 456(RSP)
- FMOVD F29, 464(RSP)
- FMOVD F30, 472(RSP)
- FMOVD F31, 480(RSP)
+ FSTPD (F0, F1), 232(RSP)
+ FSTPD (F2, F3), 248(RSP)
+ FSTPD (F4, F5), 264(RSP)
+ FSTPD (F6, F7), 280(RSP)
+ FSTPD (F8, F9), 296(RSP)
+ FSTPD (F10, F11), 312(RSP)
+ FSTPD (F12, F13), 328(RSP)
+ FSTPD (F14, F15), 344(RSP)
+ FSTPD (F16, F17), 360(RSP)
+ FSTPD (F18, F19), 376(RSP)
+ FSTPD (F20, F21), 392(RSP)
+ FSTPD (F22, F23), 408(RSP)
+ FSTPD (F24, F25), 424(RSP)
+ FSTPD (F26, F27), 440(RSP)
+ FSTPD (F28, F29), 456(RSP)
+ FSTPD (F30, F31), 472(RSP)
CALL ·asyncPreempt2(SB)
- FMOVD 480(RSP), F31
- FMOVD 472(RSP), F30
- FMOVD 464(RSP), F29
- FMOVD 456(RSP), F28
- FMOVD 448(RSP), F27
- FMOVD 440(RSP), F26
- FMOVD 432(RSP), F25
- FMOVD 424(RSP), F24
- FMOVD 416(RSP), F23
- FMOVD 408(RSP), F22
- FMOVD 400(RSP), F21
- FMOVD 392(RSP), F20
- FMOVD 384(RSP), F19
- FMOVD 376(RSP), F18
- FMOVD 368(RSP), F17
- FMOVD 360(RSP), F16
- FMOVD 352(RSP), F15
- FMOVD 344(RSP), F14
- FMOVD 336(RSP), F13
- FMOVD 328(RSP), F12
- FMOVD 320(RSP), F11
- FMOVD 312(RSP), F10
- FMOVD 304(RSP), F9
- FMOVD 296(RSP), F8
- FMOVD 288(RSP), F7
- FMOVD 280(RSP), F6
- FMOVD 272(RSP), F5
- FMOVD 264(RSP), F4
- FMOVD 256(RSP), F3
- FMOVD 248(RSP), F2
- FMOVD 240(RSP), F1
- FMOVD 232(RSP), F0
+ FLDPD 472(RSP), (F30, F31)
+ FLDPD 456(RSP), (F28, F29)
+ FLDPD 440(RSP), (F26, F27)
+ FLDPD 424(RSP), (F24, F25)
+ FLDPD 408(RSP), (F22, F23)
+ FLDPD 392(RSP), (F20, F21)
+ FLDPD 376(RSP), (F18, F19)
+ FLDPD 360(RSP), (F16, F17)
+ FLDPD 344(RSP), (F14, F15)
+ FLDPD 328(RSP), (F12, F13)
+ FLDPD 312(RSP), (F10, F11)
+ FLDPD 296(RSP), (F8, F9)
+ FLDPD 280(RSP), (F6, F7)
+ FLDPD 264(RSP), (F4, F5)
+ FLDPD 248(RSP), (F2, F3)
+ FLDPD 232(RSP), (F0, F1)
MOVD 224(RSP), R0
MOVD R0, FPSR
MOVD 216(RSP), R0
MOVD R0, NZCV
- MOVD 208(RSP), R26
- MOVD 200(RSP), R25
- MOVD 192(RSP), R24
- MOVD 184(RSP), R23
- MOVD 176(RSP), R22
- MOVD 168(RSP), R21
- MOVD 160(RSP), R20
- MOVD 152(RSP), R19
- MOVD 144(RSP), R17
- MOVD 136(RSP), R16
- MOVD 128(RSP), R15
- MOVD 120(RSP), R14
- MOVD 112(RSP), R13
- MOVD 104(RSP), R12
- MOVD 96(RSP), R11
- MOVD 88(RSP), R10
- MOVD 80(RSP), R9
- MOVD 72(RSP), R8
- MOVD 64(RSP), R7
- MOVD 56(RSP), R6
- MOVD 48(RSP), R5
- MOVD 40(RSP), R4
- MOVD 32(RSP), R3
- MOVD 24(RSP), R2
- MOVD 16(RSP), R1
- MOVD 8(RSP), R0
+ LDP 200(RSP), (R25, R26)
+ LDP 184(RSP), (R23, R24)
+ LDP 168(RSP), (R21, R22)
+ LDP 152(RSP), (R19, R20)
+ LDP 136(RSP), (R16, R17)
+ LDP 120(RSP), (R14, R15)
+ LDP 104(RSP), (R12, R13)
+ LDP 88(RSP), (R10, R11)
+ LDP 72(RSP), (R8, R9)
+ LDP 56(RSP), (R6, R7)
+ LDP 40(RSP), (R4, R5)
+ LDP 24(RSP), (R2, R3)
+ LDP 8(RSP), (R0, R1)
MOVD 496(RSP), R30
- #ifdef GOOS_linux
MOVD -8(RSP), R29
- #endif
MOVD (RSP), R27
ADD $512, RSP
JMP (R27)
To view, visit change 379715. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Cherry Mui.
Patch set 1:Run-TryBot +1Code-Review +1Trust +1
Attention is currently required from: Eric Fang.
3 comments:
Patchset:
I don't think it actually matters. (But doesn't hurt.)
File src/runtime/mkpreempt.go:
Patch Set #1, Line 125: fmt.Fprintf(out, "//go:build %s || %sle\n\n", base, base)
Is this change related? Does it affect all other generated files?
Patch Set #1, Line 160: func (l *layout) add(sop, rop, reg string, size int) {
The change to all callers of add looks undesired. Maybe introduce an add2 method and undo those.
To view, visit change 379715. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Eric Fang.
Eric Fang uploaded patch set #2 to this change.
runtime: use stp/ldp to save and restore all registers on arm64
Async preemption needs to save and restore almost all of the registers,
currently this is done by ldr and str on arm64. We can do it with ldp
and stp as they are more efficient.
Change-Id: Ida5a6f0a8d825a56af607ba2c2cd91fdc2e8f67f
---
M src/runtime/mkpreempt.go
M src/runtime/preempt_arm64.s
2 files changed, 93 insertions(+), 139 deletions(-)
To view, visit change 379715. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Cherry Mui.
Patch set 2:Run-TryBot +1Code-Review +1Trust +1
3 comments:
Patchset:
I don't think it actually matters. (But doesn't hurt. […]
In the process of building go, function asyncPreempt was called a lot, we also need to stop the world via async preemption when gc starts. This function may not be a performance critical part, but the change is worthwhile.
File src/runtime/mkpreempt.go:
Patch Set #1, Line 125: fmt.Fprintf(out, "//go:build %s || %sle\n\n", base, base)
Is this change related? Does it affect all other generated files?
Without this change, other generated files will be affected. As we can see from preempt_mips64x.s, there's a blank before and after '//go:build mips64 || mips64le', without this additional '\n', there will not be a blank line after '//go:build mips64 || mips64le'.
Patch Set #1, Line 160: func (l *layout) add(sop, rop, reg string, size int) {
The change to all callers of add looks undesired. Maybe introduce an add2 method and undo those.
Done
To view, visit change 379715. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Cherry Mui.
1 comment:
File src/runtime/mkpreempt.go:
Patch Set #1, Line 125: fmt.Fprintf(out, "//go:build %s || %sle\n\n", base, base)
Without this change, other generated files will be affected. As we can see from preempt_mips64x. […]
Done
To view, visit change 379715. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Eric Fang.
2 comments:
Patchset:
In the process of building go, function asyncPreempt was called a lot, we also need to stop the worl […]
It is only called when receiving an OS signal. Compared to an OS signal (kernel/user mode switches, a bunch of functions called etc.) a few extra instructions are ignorable.
Patchset:
LGTM.
R=go1.19
To view, visit change 379715. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Eric Fang.
Patch set 2:Code-Review +2
Patch set 3:Run-TryBot +1Code-Review +2Trust +1
Patch set 4:Run-TryBot +1Code-Review +2Trust +1
Patch set 4:-Code-Review
Eric Fang submitted this change.
3 is the latest approved patch-set.
No files were changed between the latest approved patch-set and the submitted one.
runtime: use stp/ldp to save and restore all registers on arm64
Async preemption needs to save and restore almost all of the registers,
currently this is done by ldr and str on arm64. We can do it with ldp
and stp as they are more efficient.
Change-Id: Ida5a6f0a8d825a56af607ba2c2cd91fdc2e8f67f
Reviewed-on: https://go-review.googlesource.com/c/go/+/379715
Reviewed-by: Cherry Mui <cher...@google.com>
Trust: Eric Fang <eric...@arm.com>
Run-TryBot: Eric Fang <eric...@arm.com>
TryBot-Result: Gopher Robot <go...@golang.org>
---
M src/runtime/mkpreempt.go
M src/runtime/preempt_arm64.s
2 files changed, 98 insertions(+), 139 deletions(-)
diff --git a/src/runtime/mkpreempt.go b/src/runtime/mkpreempt.go
index 17c9b75..37a8cf8 100644
--- a/src/runtime/mkpreempt.go
+++ b/src/runtime/mkpreempt.go
@@ -122,7 +122,7 @@
fmt.Fprintf(out, "// Code generated by mkpreempt.go; DO NOT EDIT.\n\n")
if beLe[arch] {
base := arch[:len(arch)-1]
- fmt.Fprintf(out, "//go:build %s || %sle\n", base, base)
+ fmt.Fprintf(out, "//go:build %s || %sle\n\n", base, base)
}
fmt.Fprintf(out, "#include \"go_asm.h\"\n")
fmt.Fprintf(out, "#include \"textflag.h\"\n\n")
@@ -147,8 +147,9 @@
type regPos struct {
pos int
- op string
- reg string
+ saveOp string
+ restoreOp string
+ reg string
// If this register requires special save and restore, these
// give those operations with a %d placeholder for the stack
@@ -157,7 +158,12 @@
}
func (l *layout) add(op, reg string, size int) {
- l.regs = append(l.regs, regPos{op: op, reg: reg, pos: l.stack})
+ l.regs = append(l.regs, regPos{saveOp: op, restoreOp: op, reg: reg, pos: l.stack})
+ l.stack += size
+}
+
+func (l *layout) add2(sop, rop, reg string, size int) {
+ l.regs = append(l.regs, regPos{saveOp: sop, restoreOp: rop, reg: reg, pos: l.stack})
l.stack += size
}
@@ -171,7 +177,7 @@
if reg.save != "" {
p(reg.save, reg.pos)
} else {
- p("%s %s, %d(%s)", reg.op, reg.reg, reg.pos, l.sp)
+ p("%s %s, %d(%s)", reg.saveOp, reg.reg, reg.pos, l.sp)
}
}
}
@@ -182,7 +188,7 @@
if reg.restore != "" {
p(reg.restore, reg.pos)
} else {
- p("%s %d(%s), %s", reg.op, reg.pos, l.sp, reg.reg)
+ p("%s %d(%s), %s", reg.restoreOp, reg.pos, l.sp, reg.reg)
}
}
}
@@ -324,12 +330,13 @@
// R27 (REGTMP), R28 (g), R29 (FP), R30 (LR), R31 (SP) are special
// and not saved here.
var l = layout{sp: "RSP", stack: 8} // add slot to save PC of interrupted instruction
- for i := 0; i <= 26; i++ {
+ for i := 0; i < 26; i += 2 {
if i == 18 {
+ i--
continue // R18 is not used, skip
}
- reg := fmt.Sprintf("R%d", i)
- l.add("MOVD", reg, 8)
+ reg := fmt.Sprintf("(R%d, R%d)", i, i+1)
+ l.add2("STP", "LDP", reg, 16)
}
// Add flag registers.
l.addSpecial(
@@ -342,9 +349,9 @@
8)
// TODO: FPCR? I don't think we'll change it, so no need to save.
// Add floating point registers F0-F31.
- for i := 0; i <= 31; i++ {
- reg := fmt.Sprintf("F%d", i)
- l.add("FMOVD", reg, 8)
+ for i := 0; i < 31; i += 2 {
+ reg := fmt.Sprintf("(F%d, F%d)", i, i+1)
+ l.add2("FSTPD", "FLDPD", reg, 16)
}
if l.stack%16 != 0 {
l.stack += 8 // SP needs 16-byte alignment
@@ -353,10 +360,8 @@
// allocate frame, save PC of interrupted instruction (in LR)
p("MOVD R30, %d(RSP)", -l.stack)
p("SUB $%d, RSP", l.stack)
- p("#ifdef GOOS_linux")
p("MOVD R29, -8(RSP)") // save frame pointer (only used on Linux)
p("SUB $8, RSP, R29") // set up new frame pointer
- p("#endif")
// On iOS, save the LR again after decrementing SP. We run the
// signal handler on the G stack (as it doesn't support sigaltstack),
// so any writes below SP may be clobbered.
@@ -369,11 +374,9 @@
l.restore()
p("MOVD %d(RSP), R30", l.stack) // sigctxt.pushCall has pushed LR (at interrupt) on stack, restore it
- p("#ifdef GOOS_linux")
- p("MOVD -8(RSP), R29") // restore frame pointer
- p("#endif")
- p("MOVD (RSP), R27") // load PC to REGTMP
- p("ADD $%d, RSP", l.stack+16) // pop frame (including the space pushed by sigctxt.pushCall)
+ p("MOVD -8(RSP), R29") // restore frame pointer
+ p("MOVD (RSP), R27") // load PC to REGTMP
+ p("ADD $%d, RSP", l.stack+16) // pop frame (including the space pushed by sigctxt.pushCall)
p("JMP (R27)")
}
To view, visit change 379715. To unsubscribe, or for help writing mail filters, visit settings.