Skip to content

Commit b291538

Browse files
committed
runtime: rework asmcgocall on ppc64x
On some platforms asmcgocall can be called with a nil g. Additionally, it can be called when already on a the system (g0) stack or on a signal stack. In these cases we do not need to switch (and/or cannot switch) to the system stack and as a result, do not need to save the g. Rework asmcgocall on ppc64x to follow the pattern used on other architectures, such as amd64 and arm64, where a separate nosave path is called in the above cases. The nil g case will be needed to support openbsd/ppc64. Updates #56001 Change-Id: I431d4200bcbc4aaddeb617aefe18590165ff2927 Reviewed-on: https://go-review.googlesource.com/c/go/+/478775 Reviewed-by: Lynn Boger <[email protected]> Reviewed-by: Paul Murphy <[email protected]> Run-TryBot: Joel Sing <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]> Reviewed-by: Bryan Mills <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent 26d4ce7 commit b291538

File tree

1 file changed

+46
-8
lines changed

1 file changed

+46
-8
lines changed

src/runtime/asm_ppc64x.s

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,8 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-20
554554
MOVD arg+8(FP), R4
555555

556556
MOVD R1, R7 // save original stack pointer
557+
CMP $0, g
558+
BEQ nosave
557559
MOVD g, R5
558560

559561
// Figure out if we need to switch to m->g0 stack.
@@ -563,29 +565,29 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-20
563565
MOVD g_m(g), R8
564566
MOVD m_gsignal(R8), R6
565567
CMP R6, g
566-
BEQ g0
568+
BEQ nosave
567569
MOVD m_g0(R8), R6
568570
CMP R6, g
569-
BEQ g0
571+
BEQ nosave
572+
570573
BL gosave_systemstack_switch<>(SB)
571574
MOVD R6, g
572575
BL runtime·save_g(SB)
573576
MOVD (g_sched+gobuf_sp)(g), R1
574577

575578
// Now on a scheduling stack (a pthread-created stack).
576-
g0:
577579
#ifdef GOOS_aix
578580
// Create a fake LR to improve backtrace.
579581
MOVD $runtime·asmcgocall(SB), R6
580582
MOVD R6, 16(R1)
581-
// AIX also save one argument on the stack.
582-
SUB $8, R1
583+
// AIX also saves one argument on the stack.
584+
SUB $8, R1
583585
#endif
584586
// Save room for two of our pointers, plus the callee
585587
// save area that lives on the caller stack.
586588
SUB $(asmcgocallSaveOffset+16), R1
587589
RLDCR $0, R1, $~15, R1 // 16-byte alignment for gcc ABI
588-
MOVD R5, (asmcgocallSaveOffset+8)(R1)// save old g on stack
590+
MOVD R5, (asmcgocallSaveOffset+8)(R1) // save old g on stack
589591
MOVD (g_stack+stack_hi)(R5), R5
590592
SUB R7, R5
591593
MOVD R5, asmcgocallSaveOffset(R1) // save depth in old g stack (can't just save SP, as stack might be copied during a callback)
@@ -605,9 +607,10 @@ g0:
605607
MOVD R12, CTR
606608
MOVD R4, R3 // arg in r3
607609
BL (CTR)
608-
// C code can clobber R0, so set it back to 0. F27-F31 are
609-
// callee save, so we don't need to recover those.
610+
611+
// Reinitialise zero value register.
610612
XOR R0, R0
613+
611614
// Restore g, stack pointer, toc pointer.
612615
// R3 is errno, so don't touch it
613616
MOVD (asmcgocallSaveOffset+8)(R1), g
@@ -623,6 +626,41 @@ g0:
623626
MOVW R3, ret+16(FP)
624627
RET
625628

629+
nosave:
630+
// Running on a system stack, perhaps even without a g.
631+
// Having no g can happen during thread creation or thread teardown.
632+
// This code is like the above sequence but without saving/restoring g
633+
// and without worrying about the stack moving out from under us
634+
// (because we're on a system stack, not a goroutine stack).
635+
// The above code could be used directly if already on a system stack,
636+
// but then the only path through this code would be a rare case.
637+
// Using this code for all "already on system stack" calls exercises it more,
638+
// which should help keep it correct.
639+
640+
SUB $(asmcgocallSaveOffset+8), R1
641+
RLDCR $0, R1, $~15, R1 // 16-byte alignment for gcc ABI
642+
MOVD R7, asmcgocallSaveOffset(R1) // Save original stack pointer.
643+
644+
MOVD R3, R12 // fn
645+
#ifdef GO_PPC64X_HAS_FUNCDESC
646+
// Load the real entry address from the first slot of the function descriptor.
647+
MOVD 8(R12), R2
648+
MOVD (R12), R12
649+
#endif
650+
MOVD R12, CTR
651+
MOVD R4, R3 // arg
652+
BL (CTR)
653+
654+
// Reinitialise zero value register.
655+
XOR R0, R0
656+
657+
MOVD asmcgocallSaveOffset(R1), R1 // Restore stack pointer.
658+
#ifndef GOOS_aix
659+
MOVD 24(R1), R2
660+
#endif
661+
MOVW R3, ret+16(FP)
662+
RET
663+
626664
// func cgocallback(fn, frame unsafe.Pointer, ctxt uintptr)
627665
// See cgocall.go for more details.
628666
TEXT ·cgocallback(SB),NOSPLIT,$24-24

0 commit comments

Comments
 (0)