Skip to content

Commit ac571a3

Browse files
committed
runtime: cleanup PPC64/linux runtime.sigtramp
Add new helper macros to further simplify the transition from the host's ABI to Go. Fortunately the same one should work for all PPC64 targets. Update the other site which uses these wrappers to further consolidate. Also, update the call to runtime.sigtrampgo to call the ABIInternal version directly. Also, update the SAVE/RESTORE_VR macros to accept R0. Change-Id: I0046176029e1e1b25838688e4b7bf57805b01bd4 Reviewed-on: https://go-review.googlesource.com/c/go/+/476297 Reviewed-by: Archana Ravindar <[email protected]> Run-TryBot: Paul Murphy <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]> Reviewed-by: Lynn Boger <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent 4ac638f commit ac571a3

File tree

2 files changed

+102
-226
lines changed

2 files changed

+102
-226
lines changed

src/runtime/cgo/abi_ppc64x.h

Lines changed: 82 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -104,58 +104,92 @@
104104
// Save and restore VR20-31 (aka VSR56-63). These
105105
// macros must point to a 16B aligned offset.
106106
#define SAVE_VR_SIZE (12*16)
107-
#define SAVE_VR(offset, rtmp) \
108-
MOVD $(offset), rtmp \
109-
STVX V20, (rtmp)(R1) \
110-
ADD $16, rtmp \
111-
STVX V21, (rtmp)(R1) \
112-
ADD $16, rtmp \
113-
STVX V22, (rtmp)(R1) \
114-
ADD $16, rtmp \
115-
STVX V23, (rtmp)(R1) \
116-
ADD $16, rtmp \
117-
STVX V24, (rtmp)(R1) \
118-
ADD $16, rtmp \
119-
STVX V25, (rtmp)(R1) \
120-
ADD $16, rtmp \
121-
STVX V26, (rtmp)(R1) \
122-
ADD $16, rtmp \
123-
STVX V27, (rtmp)(R1) \
124-
ADD $16, rtmp \
125-
STVX V28, (rtmp)(R1) \
126-
ADD $16, rtmp \
127-
STVX V29, (rtmp)(R1) \
128-
ADD $16, rtmp \
129-
STVX V30, (rtmp)(R1) \
130-
ADD $16, rtmp \
107+
#define SAVE_VR(offset, rtmp) \
108+
MOVD $(offset+16*0), rtmp \
109+
STVX V20, (rtmp)(R1) \
110+
MOVD $(offset+16*1), rtmp \
111+
STVX V21, (rtmp)(R1) \
112+
MOVD $(offset+16*2), rtmp \
113+
STVX V22, (rtmp)(R1) \
114+
MOVD $(offset+16*3), rtmp \
115+
STVX V23, (rtmp)(R1) \
116+
MOVD $(offset+16*4), rtmp \
117+
STVX V24, (rtmp)(R1) \
118+
MOVD $(offset+16*5), rtmp \
119+
STVX V25, (rtmp)(R1) \
120+
MOVD $(offset+16*6), rtmp \
121+
STVX V26, (rtmp)(R1) \
122+
MOVD $(offset+16*7), rtmp \
123+
STVX V27, (rtmp)(R1) \
124+
MOVD $(offset+16*8), rtmp \
125+
STVX V28, (rtmp)(R1) \
126+
MOVD $(offset+16*9), rtmp \
127+
STVX V29, (rtmp)(R1) \
128+
MOVD $(offset+16*10), rtmp \
129+
STVX V30, (rtmp)(R1) \
130+
MOVD $(offset+16*11), rtmp \
131131
STVX V31, (rtmp)(R1)
132132

133-
#define RESTORE_VR(offset, rtmp) \
134-
MOVD $(offset), rtmp \
135-
LVX (rtmp)(R1), V20 \
136-
ADD $16, rtmp \
137-
LVX (rtmp)(R1), V21 \
138-
ADD $16, rtmp \
139-
LVX (rtmp)(R1), V22 \
140-
ADD $16, rtmp \
141-
LVX (rtmp)(R1), V23 \
142-
ADD $16, rtmp \
143-
LVX (rtmp)(R1), V24 \
144-
ADD $16, rtmp \
145-
LVX (rtmp)(R1), V25 \
146-
ADD $16, rtmp \
147-
LVX (rtmp)(R1), V26 \
148-
ADD $16, rtmp \
149-
LVX (rtmp)(R1), V27 \
150-
ADD $16, rtmp \
151-
LVX (rtmp)(R1), V28 \
152-
ADD $16, rtmp \
153-
LVX (rtmp)(R1), V29 \
154-
ADD $16, rtmp \
155-
LVX (rtmp)(R1), V30 \
156-
ADD $16, rtmp \
133+
#define RESTORE_VR(offset, rtmp) \
134+
MOVD $(offset+16*0), rtmp \
135+
LVX (rtmp)(R1), V20 \
136+
MOVD $(offset+16*1), rtmp \
137+
LVX (rtmp)(R1), V21 \
138+
MOVD $(offset+16*2), rtmp \
139+
LVX (rtmp)(R1), V22 \
140+
MOVD $(offset+16*3), rtmp \
141+
LVX (rtmp)(R1), V23 \
142+
MOVD $(offset+16*4), rtmp \
143+
LVX (rtmp)(R1), V24 \
144+
MOVD $(offset+16*5), rtmp \
145+
LVX (rtmp)(R1), V25 \
146+
MOVD $(offset+16*6), rtmp \
147+
LVX (rtmp)(R1), V26 \
148+
MOVD $(offset+16*7), rtmp \
149+
LVX (rtmp)(R1), V27 \
150+
MOVD $(offset+16*8), rtmp \
151+
LVX (rtmp)(R1), V28 \
152+
MOVD $(offset+16*9), rtmp \
153+
LVX (rtmp)(R1), V29 \
154+
MOVD $(offset+16*10), rtmp \
155+
LVX (rtmp)(R1), V30 \
156+
MOVD $(offset+16*11), rtmp \
157157
LVX (rtmp)(R1), V31
158158

159159
// LR and CR are saved in the caller's frame. The callee must
160160
// make space for all other callee-save registers.
161161
#define SAVE_ALL_REG_SIZE (SAVE_GPR_SIZE+SAVE_FPR_SIZE+SAVE_VR_SIZE)
162+
163+
// Stack a frame and save all callee-save registers following the
164+
// host OS's ABI. Fortunately, this is identical for AIX, ELFv1, and
165+
// ELFv2. All host ABIs require the stack pointer to maintain 16 byte
166+
// alignment, and save the callee-save registers in the same places.
167+
//
168+
// To restate, R1 is assumed to be aligned when this macro is used.
169+
// This assumes the caller's frame is compliant with the host ABI.
170+
// CR and LR are saved into the caller's frame per the host ABI.
171+
// R0 is initialized to $0 as expected by Go.
172+
#define STACK_AND_SAVE_HOST_TO_GO_ABI(extra) \
173+
MOVD LR, R0 \
174+
MOVD R0, 16(R1) \
175+
MOVW CR, R0 \
176+
MOVD R0, 8(R1) \
177+
MOVDU R1, -(extra)-FIXED_FRAME-SAVE_ALL_REG_SIZE(R1) \
178+
SAVE_GPR(extra+FIXED_FRAME) \
179+
SAVE_FPR(extra+FIXED_FRAME+SAVE_GPR_SIZE) \
180+
SAVE_VR(extra+FIXED_FRAME+SAVE_GPR_SIZE+SAVE_FPR_SIZE, R0) \
181+
MOVD $0, R0
182+
183+
// This unstacks the frame, restoring all callee-save registers
184+
// as saved by STACK_AND_SAVE_HOST_TO_GO_ABI.
185+
//
186+
// R0 is not guaranteed to contain $0 after this macro.
187+
#define UNSTACK_AND_RESTORE_GO_TO_HOST_ABI(extra) \
188+
RESTORE_GPR(extra+FIXED_FRAME) \
189+
RESTORE_FPR(extra+FIXED_FRAME+SAVE_GPR_SIZE) \
190+
RESTORE_VR(extra+FIXED_FRAME+SAVE_GPR_SIZE+SAVE_FPR_SIZE, R0) \
191+
ADD $(extra+FIXED_FRAME+SAVE_ALL_REG_SIZE), R1 \
192+
MOVD 16(R1), R0 \
193+
MOVD R0, LR \
194+
MOVD 8(R1), R0 \
195+
MOVW R0, CR

src/runtime/sys_linux_ppc64x.s

Lines changed: 20 additions & 178 deletions
Original file line numberDiff line numberDiff line change
@@ -456,90 +456,15 @@ TEXT sigtramp<>(SB),NOSPLIT|NOFRAME|TOPFRAME,$0
456456
// ppc64le doesn't need function descriptors
457457
// Save callee-save registers in the case of signal forwarding.
458458
// Same as on ARM64 https://golang.org/issue/31827 .
459+
//
460+
// Note, it is assumed this is always called indirectly (e.g via
461+
// a function pointer) as R2 may not be preserved when calling this
462+
// function. In those cases, the caller preserves their R2.
459463
TEXT runtime·sigtramp(SB),NOSPLIT|NOFRAME,$0
460464
#endif
461-
// Start with standard C stack frame layout and linkage.
462-
MOVD LR, R0
463-
MOVD R0, 16(R1) // Save LR in caller's frame.
464-
MOVW CR, R0 // Save CR in caller's frame
465-
MOVD R0, 8(R1)
466-
// The stack must be acquired here and not
467-
// in the automatic way based on stack size
468-
// since that sequence clobbers R31 before it
469-
// gets saved.
470-
// We are being ultra safe here in saving the
471-
// Vregs. The case where they might need to
472-
// be saved is very unlikely.
473-
MOVDU R1, -544(R1)
474-
MOVD R14, 64(R1)
475-
MOVD R15, 72(R1)
476-
MOVD R16, 80(R1)
477-
MOVD R17, 88(R1)
478-
MOVD R18, 96(R1)
479-
MOVD R19, 104(R1)
480-
MOVD R20, 112(R1)
481-
MOVD R21, 120(R1)
482-
MOVD R22, 128(R1)
483-
MOVD R23, 136(R1)
484-
MOVD R24, 144(R1)
485-
MOVD R25, 152(R1)
486-
MOVD R26, 160(R1)
487-
MOVD R27, 168(R1)
488-
MOVD R28, 176(R1)
489-
MOVD R29, 184(R1)
490-
MOVD g, 192(R1) // R30
491-
MOVD R31, 200(R1)
492-
FMOVD F14, 208(R1)
493-
FMOVD F15, 216(R1)
494-
FMOVD F16, 224(R1)
495-
FMOVD F17, 232(R1)
496-
FMOVD F18, 240(R1)
497-
FMOVD F19, 248(R1)
498-
FMOVD F20, 256(R1)
499-
FMOVD F21, 264(R1)
500-
FMOVD F22, 272(R1)
501-
FMOVD F23, 280(R1)
502-
FMOVD F24, 288(R1)
503-
FMOVD F25, 296(R1)
504-
FMOVD F26, 304(R1)
505-
FMOVD F27, 312(R1)
506-
FMOVD F28, 320(R1)
507-
FMOVD F29, 328(R1)
508-
FMOVD F30, 336(R1)
509-
FMOVD F31, 344(R1)
510-
// Save V regs
511-
// STXVD2X and LXVD2X used since
512-
// we aren't sure of alignment.
513-
// Endianness doesn't matter
514-
// if we are just loading and
515-
// storing values.
516-
MOVD $352, R7 // V20
517-
STXVD2X VS52, (R7)(R1)
518-
ADD $16, R7 // V21 368
519-
STXVD2X VS53, (R7)(R1)
520-
ADD $16, R7 // V22 384
521-
STXVD2X VS54, (R7)(R1)
522-
ADD $16, R7 // V23 400
523-
STXVD2X VS55, (R7)(R1)
524-
ADD $16, R7 // V24 416
525-
STXVD2X VS56, (R7)(R1)
526-
ADD $16, R7 // V25 432
527-
STXVD2X VS57, (R7)(R1)
528-
ADD $16, R7 // V26 448
529-
STXVD2X VS58, (R7)(R1)
530-
ADD $16, R7 // V27 464
531-
STXVD2X VS59, (R7)(R1)
532-
ADD $16, R7 // V28 480
533-
STXVD2X VS60, (R7)(R1)
534-
ADD $16, R7 // V29 496
535-
STXVD2X VS61, (R7)(R1)
536-
ADD $16, R7 // V30 512
537-
STXVD2X VS62, (R7)(R1)
538-
ADD $16, R7 // V31 528
539-
STXVD2X VS63, (R7)(R1)
540-
541-
// initialize essential registers (just in case)
542-
BL runtime·reginit(SB)
465+
// This is called with ELF calling conventions. Convert to Go.
466+
// Allocate space for argument storage to call runtime.sigtrampgo.
467+
STACK_AND_SAVE_HOST_TO_GO_ABI(32)
543468

544469
// this might be called in external code context,
545470
// where g is not set.
@@ -548,80 +473,19 @@ TEXT runtime·sigtramp(SB),NOSPLIT|NOFRAME,$0
548473
BEQ 2(PC)
549474
BL runtime·load_g(SB)
550475

551-
MOVW R3, FIXED_FRAME+0(R1)
552-
MOVD R4, FIXED_FRAME+8(R1)
553-
MOVD R5, FIXED_FRAME+16(R1)
554-
MOVD $runtime·sigtrampgo(SB), R12
476+
// R3,R4,R5 already hold the arguments. Forward them on.
477+
// TODO: Indirectly call runtime.sigtrampgo to avoid the linker's static NOSPLIT stack
478+
// overflow detection. It thinks this might be called on a small Go stack, but this is only
479+
// called from a larger pthread or sigaltstack stack. Can the checker be improved to not
480+
// flag a direct call here?
481+
MOVD $runtime·sigtrampgo<ABIInternal>(SB), R12
555482
MOVD R12, CTR
556483
BL (CTR)
557-
MOVD 24(R1), R2 // Should this be here? Where is it saved?
558-
// Starts at 64; FIXED_FRAME is 32
559-
MOVD 64(R1), R14
560-
MOVD 72(R1), R15
561-
MOVD 80(R1), R16
562-
MOVD 88(R1), R17
563-
MOVD 96(R1), R18
564-
MOVD 104(R1), R19
565-
MOVD 112(R1), R20
566-
MOVD 120(R1), R21
567-
MOVD 128(R1), R22
568-
MOVD 136(R1), R23
569-
MOVD 144(R1), R24
570-
MOVD 152(R1), R25
571-
MOVD 160(R1), R26
572-
MOVD 168(R1), R27
573-
MOVD 176(R1), R28
574-
MOVD 184(R1), R29
575-
MOVD 192(R1), g // R30
576-
MOVD 200(R1), R31
577-
FMOVD 208(R1), F14
578-
FMOVD 216(R1), F15
579-
FMOVD 224(R1), F16
580-
FMOVD 232(R1), F17
581-
FMOVD 240(R1), F18
582-
FMOVD 248(R1), F19
583-
FMOVD 256(R1), F20
584-
FMOVD 264(R1), F21
585-
FMOVD 272(R1), F22
586-
FMOVD 280(R1), F23
587-
FMOVD 288(R1), F24
588-
FMOVD 292(R1), F25
589-
FMOVD 300(R1), F26
590-
FMOVD 308(R1), F27
591-
FMOVD 316(R1), F28
592-
FMOVD 328(R1), F29
593-
FMOVD 336(R1), F30
594-
FMOVD 344(R1), F31
595-
MOVD $352, R7
596-
LXVD2X (R7)(R1), VS52
597-
ADD $16, R7 // 368 V21
598-
LXVD2X (R7)(R1), VS53
599-
ADD $16, R7 // 384 V22
600-
LXVD2X (R7)(R1), VS54
601-
ADD $16, R7 // 400 V23
602-
LXVD2X (R7)(R1), VS55
603-
ADD $16, R7 // 416 V24
604-
LXVD2X (R7)(R1), VS56
605-
ADD $16, R7 // 432 V25
606-
LXVD2X (R7)(R1), VS57
607-
ADD $16, R7 // 448 V26
608-
LXVD2X (R7)(R1), VS58
609-
ADD $16, R8 // 464 V27
610-
LXVD2X (R7)(R1), VS59
611-
ADD $16, R7 // 480 V28
612-
LXVD2X (R7)(R1), VS60
613-
ADD $16, R7 // 496 V29
614-
LXVD2X (R7)(R1), VS61
615-
ADD $16, R7 // 512 V30
616-
LXVD2X (R7)(R1), VS62
617-
ADD $16, R7 // 528 V31
618-
LXVD2X (R7)(R1), VS63
619-
ADD $544, R1
620-
MOVD 8(R1), R0
621-
MOVFL R0, $0xff
622-
MOVD 16(R1), R0
623-
MOVD R0, LR
484+
// Restore R2 (TOC pointer) in the event it might be used later in this function.
485+
// If this was not compiled as shared code, R2 is undefined, reloading it is harmless.
486+
MOVD 24(R1), R2
624487

488+
UNSTACK_AND_RESTORE_GO_TO_HOST_ABI(32)
625489
RET
626490

627491
#ifdef GOARCH_ppc64le
@@ -726,34 +590,12 @@ GLOBL runtime·tls_g+0(SB), TLSBSS+DUPOK, $8
726590

727591
TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT|NOFRAME,$0
728592
// This is called from C code. Callee save registers must be saved.
729-
// R3,R4,R5 hold arguments.
730-
// Save LR into R0 and stack a big frame.
731-
MOVD LR, R0
732-
MOVD R0, 16(R1)
733-
MOVW CR, R0
734-
MOVD R0, 8(R1)
735-
// Don't save a back chain pointer when calling into Go. It will be overwritten.
736-
// Go stores LR where ELF stores a back chain pointer. And, allocate 64B for
737-
// FIXED_FRAME and 24B argument space, rounded up to a 16 byte boundary.
738-
ADD $-(64+SAVE_ALL_REG_SIZE), R1
739-
740-
SAVE_GPR(64)
741-
SAVE_FPR(64+SAVE_GPR_SIZE)
742-
SAVE_VR(64+SAVE_GPR_SIZE+SAVE_FPR_SIZE, R6)
593+
// R3,R4,R5 hold arguments, and allocate argument space to call sigprofNonGo.
594+
STACK_AND_SAVE_HOST_TO_GO_ABI(32)
743595

744-
MOVD $0, R0
745596
CALL runtime·sigprofNonGo<ABIInternal>(SB)
746597

747-
RESTORE_GPR(64)
748-
RESTORE_FPR(64+SAVE_GPR_SIZE)
749-
RESTORE_VR(64+SAVE_GPR_SIZE+SAVE_FPR_SIZE, R6)
750-
751-
// Clear frame, restore LR, return
752-
ADD $(64+SAVE_ALL_REG_SIZE), R1
753-
MOVD 16(R1), R0
754-
MOVD R0, LR
755-
MOVD 8(R1), R0
756-
MOVW R0, CR
598+
UNSTACK_AND_RESTORE_GO_TO_HOST_ABI(32)
757599
RET
758600

759601
TEXT runtime·mmap(SB),NOSPLIT|NOFRAME,$0

0 commit comments

Comments
 (0)