]> Cypherpunks.ru repositories - gostls13.git/commitdiff
runtime/cgo: preserve VRs across crosscall_ppc64 on linux
authorPaul E. Murphy <murp@ibm.com>
Fri, 31 Mar 2023 18:33:25 +0000 (13:33 -0500)
committerGopher Robot <gobot@golang.org>
Thu, 4 May 2023 18:03:04 +0000 (18:03 +0000)
Rework this function to closely match the PPC64 crosscall2, but
written in gnu asm. Likewise, fix this to store TOC in the new
frame, not the caller's, as is required by the ELF ABIs.

Change-Id: I8902c74f2607e3436260882a7bea52e72a67b8f9
Reviewed-on: https://go-review.googlesource.com/c/go/+/486335
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Run-TryBot: Paul Murphy <murp@ibm.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com>
Reviewed-by: Carlos Amedee <carlos@golang.org>
Auto-Submit: Carlos Amedee <carlos@golang.org>

src/runtime/cgo/gcc_linux_ppc64x.S

index e67deaacf2533c6224aa311822a38447a1904bd4..745d232988c939dffc5bf3feb3f6d16b092acf83 100644 (file)
@@ -6,6 +6,37 @@
 
 .file "gcc_linux_ppc64x.S"
 
+// Define a frame which has no argument space, but is compatible with
+// a call into a Go ABI. We allocate 32B to match FIXED_FRAME with
+// similar semantics, except we store the backchain pointer, not the
+// LR at offset 0. R2 is stored in the Go TOC save slot (offset 24).
+.set GPR_OFFSET, 32
+.set FPR_OFFSET, GPR_OFFSET + 18*8
+.set VR_OFFSET, FPR_OFFSET + 18*8
+.set FRAME_SIZE, VR_OFFSET + 12*16
+
+.macro FOR_EACH_GPR opcode r=14
+.ifge 31 - \r
+       \opcode \r, GPR_OFFSET + 8*(\r-14)(1)
+       FOR_EACH_GPR \opcode "(\r+1)"
+.endif
+.endm
+
+.macro FOR_EACH_FPR opcode fr=14
+.ifge 31 - \fr
+       \opcode \fr, FPR_OFFSET + 8*(\fr-14)(1)
+       FOR_EACH_FPR \opcode "(\fr+1)"
+.endif
+.endm
+
+.macro FOR_EACH_VR opcode vr=20
+.ifge 31 - \vr
+       li 0, VR_OFFSET + 16*(\vr-20)
+       \opcode \vr, 1, 0
+       FOR_EACH_VR \opcode "(\vr+1)"
+.endif
+.endm
+
 /*
  * void crosscall_ppc64(void (*fn)(void), void *g)
  *
@@ -18,13 +49,17 @@ crosscall_ppc64:
        // Start with standard C stack frame layout and linkage
        mflr    %r0
        std     %r0, 16(%r1)    // Save LR in caller's frame
-       std     %r2, 24(%r1)    // Save TOC in caller's frame
-       bl      saveregs
-       stdu    %r1, -296(%r1)
+       mfcr    %r0
+       std     %r0, 8(%r1)     // Save CR in caller's frame
+       stdu    %r1, -FRAME_SIZE(%r1)
+       std     %r2, 24(%r1)
+
+       FOR_EACH_GPR std
+       FOR_EACH_FPR stfd
+       FOR_EACH_VR stvx
 
        // Set up Go ABI constant registers
-       bl      _cgo_reginit
-       nop
+       li      %r0, 0
 
        // Restore g pointer (r30 in Go ABI, which may have been clobbered by C)
        mr      %r30, %r4
@@ -34,97 +69,18 @@ crosscall_ppc64:
        mtctr   %r3
        bctrl
 
-       addi    %r1, %r1, 296
-       bl      restoreregs
+       FOR_EACH_GPR ld
+       FOR_EACH_FPR lfd
+       FOR_EACH_VR lvx
+
        ld      %r2, 24(%r1)
+       addi    %r1, %r1, FRAME_SIZE
        ld      %r0, 16(%r1)
        mtlr    %r0
+       ld      %r0, 8(%r1)
+       mtcr    %r0
        blr
 
-saveregs:
-       // Save callee-save registers
-       // O=-288; for R in %r{14..31}; do echo "\tstd\t$R, $O(%r1)"; ((O+=8)); done; for F in f{14..31}; do echo "\tstfd\t$F, $O(%r1)"; ((O+=8)); done
-       std     %r14, -288(%r1)
-       std     %r15, -280(%r1)
-       std     %r16, -272(%r1)
-       std     %r17, -264(%r1)
-       std     %r18, -256(%r1)
-       std     %r19, -248(%r1)
-       std     %r20, -240(%r1)
-       std     %r21, -232(%r1)
-       std     %r22, -224(%r1)
-       std     %r23, -216(%r1)
-       std     %r24, -208(%r1)
-       std     %r25, -200(%r1)
-       std     %r26, -192(%r1)
-       std     %r27, -184(%r1)
-       std     %r28, -176(%r1)
-       std     %r29, -168(%r1)
-       std     %r30, -160(%r1)
-       std     %r31, -152(%r1)
-       stfd    %f14, -144(%r1)
-       stfd    %f15, -136(%r1)
-       stfd    %f16, -128(%r1)
-       stfd    %f17, -120(%r1)
-       stfd    %f18, -112(%r1)
-       stfd    %f19, -104(%r1)
-       stfd    %f20, -96(%r1)
-       stfd    %f21, -88(%r1)
-       stfd    %f22, -80(%r1)
-       stfd    %f23, -72(%r1)
-       stfd    %f24, -64(%r1)
-       stfd    %f25, -56(%r1)
-       stfd    %f26, -48(%r1)
-       stfd    %f27, -40(%r1)
-       stfd    %f28, -32(%r1)
-       stfd    %f29, -24(%r1)
-       stfd    %f30, -16(%r1)
-       stfd    %f31, -8(%r1)
-
-       blr
-
-restoreregs:
-       // O=-288; for R in %r{14..31}; do echo "\tld\t$R, $O(%r1)"; ((O+=8)); done; for F in %f{14..31}; do echo "\tlfd\t$F, $O(%r1)"; ((O+=8)); done
-       ld      %r14, -288(%r1)
-       ld      %r15, -280(%r1)
-       ld      %r16, -272(%r1)
-       ld      %r17, -264(%r1)
-       ld      %r18, -256(%r1)
-       ld      %r19, -248(%r1)
-       ld      %r20, -240(%r1)
-       ld      %r21, -232(%r1)
-       ld      %r22, -224(%r1)
-       ld      %r23, -216(%r1)
-       ld      %r24, -208(%r1)
-       ld      %r25, -200(%r1)
-       ld      %r26, -192(%r1)
-       ld      %r27, -184(%r1)
-       ld      %r28, -176(%r1)
-       ld      %r29, -168(%r1)
-       ld      %r30, -160(%r1)
-       ld      %r31, -152(%r1)
-       lfd     %f14, -144(%r1)
-       lfd     %f15, -136(%r1)
-       lfd     %f16, -128(%r1)
-       lfd     %f17, -120(%r1)
-       lfd     %f18, -112(%r1)
-       lfd     %f19, -104(%r1)
-       lfd     %f20, -96(%r1)
-       lfd     %f21, -88(%r1)
-       lfd     %f22, -80(%r1)
-       lfd     %f23, -72(%r1)
-       lfd     %f24, -64(%r1)
-       lfd     %f25, -56(%r1)
-       lfd     %f26, -48(%r1)
-       lfd     %f27, -40(%r1)
-       lfd     %f28, -32(%r1)
-       lfd     %f29, -24(%r1)
-       lfd     %f30, -16(%r1)
-       lfd     %f31, -8(%r1)
-
-       blr
-
-
 #ifdef __ELF__
 .section .note.GNU-stack,"",%progbits
 #endif