]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: add runtime changes for register ABI on s390x
authorSrinivas Pokala <Pokala.Srinivas@ibm.com>
Tue, 11 Nov 2025 03:53:03 +0000 (04:53 +0100)
committerKeith Randall <khr@golang.org>
Mon, 24 Nov 2025 18:21:49 +0000 (10:21 -0800)
This adds the changes for the register ABI in the runtime
functions for s390x platform:
- Add spill/unspill functions used by runtime
- Add ABIInternal to functions

Updates #40724

Change-Id: I6aaeec1d7293b6fec2aa489df90414937b80199e
Reviewed-on: https://go-review.googlesource.com/c/go/+/719465
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Vishwanatha HD <vishwanatha.hd@ibm.com>
src/runtime/asm_s390x.s
src/runtime/stubs_s390x.go
src/runtime/tls_s390x.s

index bb29845f5839c02e034b21eb6e767e43c9ace9f0..791ea80bc2987cf1af934cce9953d9d04405c939 100644 (file)
@@ -160,7 +160,7 @@ nocgo:
        MOVD    $0, 1(R0)
        RET
 
-DATA   runtime·mainPC+0(SB)/8,$runtime·main(SB)
+DATA   runtime·mainPC+0(SB)/8,$runtime·main<ABIInternal>(SB)
 GLOBL  runtime·mainPC(SB),RODATA,$8
 
 TEXT runtime·breakpoint(SB),NOSPLIT|NOFRAME,$0-0
@@ -205,25 +205,29 @@ TEXT gogo<>(SB), NOSPLIT|NOFRAME, $0
 // Switch to m->g0's stack, call fn(g).
 // Fn must never return.  It should gogo(&g->sched)
 // to keep running g.
-TEXT runtime·mcall(SB), NOSPLIT, $-8-8
+TEXT runtime·mcall<ABIInternal>(SB), NOSPLIT, $-8-8
+#ifdef GOEXPERIMENT_regabiargs
+       MOVD    R2, R12                         // context
+#else
+       MOVD    fn+0(FP), R12                   // context
+#endif
        // Save caller state in g->sched
        MOVD    R15, (g_sched+gobuf_sp)(g)
        MOVD    LR, (g_sched+gobuf_pc)(g)
        MOVD    $0, (g_sched+gobuf_lr)(g)
 
        // Switch to m->g0 & its stack, call fn.
-       MOVD    g, R3
-       MOVD    g_m(g), R8
-       MOVD    m_g0(R8), g
+       MOVD    g, R2
+       MOVD    g_m(g), R4
+       MOVD    m_g0(R4), g
        BL      runtime·save_g(SB)
-       CMP     g, R3
+       CMP     g, R2
        BNE     2(PC)
        BR      runtime·badmcall(SB)
-       MOVD    fn+0(FP), R12                   // context
        MOVD    0(R12), R4                      // code pointer
        MOVD    (g_sched+gobuf_sp)(g), R15      // sp = m->g0->sched.sp
        SUB     $16, R15
-       MOVD    R3, 8(R15)
+       MOVD    R2, 8(R15)
        MOVD    $0, 0(R15)
        BL      (R4)
        BR      runtime·badmcall2(SB)
@@ -292,18 +296,18 @@ noswitch:
 
 // func switchToCrashStack0(fn func())
 TEXT runtime·switchToCrashStack0<ABIInternal>(SB), NOSPLIT, $0-8
-       MOVD    fn+0(FP), R12   // context
-       MOVD    g_m(g), R4      // curm
+       MOVD    R2, R12         // context
+       MOVD    g_m(g), R2      // curm
 
        // set g to gcrash
        MOVD    $runtime·gcrash(SB), g // g = &gcrash
        BL      runtime·save_g(SB)
-       MOVD    R4, g_m(g)      // g.m = curm
-       MOVD    g, m_g0(R4)     // curm.g0 = g
+       MOVD    R2, g_m(g)      // g.m = curm
+       MOVD    g, m_g0(R2)     // curm.g0 = g
 
        // switch to crashstack
-       MOVD    (g_stack+stack_hi)(g), R4
-       ADD     $(-4*8), R4, R15
+       MOVD    (g_stack+stack_hi)(g), R2
+       ADD     $(-4*8), R2, R15
 
        // call target function
        MOVD    0(R12), R3      // code pointer
@@ -446,10 +450,14 @@ tailArgs: /* copy remaining bytes */              \
        EXRL    $callfnMVC<>(SB), R5;           \
 callFunction:                                  \
        MOVD    f+8(FP), R12;                   \
-       MOVD    (R12), R8;                      \
+       MOVD    regArgs+40(FP), R10;            \
+       BL      ·unspillArgs(SB);              \
+       MOVD    (R12), R10;                     \
        PCDATA  $PCDATA_StackMapIndex, $0;      \
-       BL      (R8);                           \
+       BL      (R10);                          \
        /* copy return values back */           \
+       MOVD    regArgs+40(FP), R10;            \
+       BL      ·spillArgs(SB);                \
        MOVD    stackArgsType+0(FP), R7;                \
        MOVD    stackArgs+16(FP), R6;                   \
        MOVWZ   stackArgsSize+24(FP), R5;                       \
@@ -466,11 +474,12 @@ callFunction:                                     \
 // to reflectcallmove. It does not follow the Go ABI; it expects its
 // arguments in registers.
 TEXT callRet<>(SB), NOSPLIT, $40-0
+       NO_LOCAL_POINTERS;
        MOVD    R7, 8(R15)
        MOVD    R6, 16(R15)
        MOVD    R4, 24(R15)
        MOVD    R5, 32(R15)
-       MOVD    $0, 40(R15)
+       MOVD    R10, 40(R15)
        BL      runtime·reflectcallmove(SB)
        RET
 
@@ -754,15 +763,80 @@ TEXT runtime·cputicks(SB),NOSPLIT,$0-8
        MOVD    R3, ret+0(FP)
        RET
 
+#ifdef GOEXPERIMENT_regabiargs
+// spillArgs stores return values from registers to a *internal/abi.RegArgs in R10.
+TEXT runtime·spillArgs(SB),NOSPLIT,$0-0
+       MOVD    R2, 0(R10)
+       MOVD    R3, 8(R10)
+       MOVD    R4, 16(R10)
+       MOVD    R5, 24(R10)
+       MOVD    R6, 32(R10)
+       MOVD    R7, 40(R10)
+       MOVD    R8, 48(R10)
+       MOVD    R9, 56(R10)
+       FMOVD   F0, 64(R10)
+       FMOVD   F1, 72(R10)
+       FMOVD   F2, 80(R10)
+       FMOVD   F3, 88(R10)
+       FMOVD   F4, 96(R10)
+       FMOVD   F5, 104(R10)
+       FMOVD   F6, 112(R10)
+       FMOVD   F7, 120(R10)
+       FMOVD   F8, 128(R10)
+       FMOVD   F9, 136(R10)
+       FMOVD   F10, 144(R10)
+       FMOVD   F11, 152(R10)
+       FMOVD   F12, 160(R10)
+       FMOVD   F13, 168(R10)
+       FMOVD   F14, 176(R10)
+       FMOVD   F15, 184(R10)
+       RET
+
+// unspillArgs loads args into registers from a *internal/abi.RegArgs in R10.
+TEXT runtime·unspillArgs(SB),NOSPLIT,$0-0
+       MOVD    0(R10), R2
+       MOVD    8(R10), R3
+       MOVD    16(R10), R4
+       MOVD    24(R10), R5
+       MOVD    32(R10), R6
+       MOVD    40(R10), R7
+       MOVD    48(R10), R8
+       MOVD    56(R10), R9
+       FMOVD   64(R10), F0
+       FMOVD   72(R10), F1
+       FMOVD   80(R10), F2
+       FMOVD   88(R10), F3
+       FMOVD   96(R10), F4
+       FMOVD   104(R10), F5
+       FMOVD   112(R10), F6
+       FMOVD   120(R10), F7
+       FMOVD   128(R10), F8
+       FMOVD   136(R10), F9
+       FMOVD   144(R10), F10
+       FMOVD   152(R10), F11
+       FMOVD   160(R10), F12
+       FMOVD   168(R10), F13
+       FMOVD   176(R10), F14
+       FMOVD   184(R10), F15
+       RET
+#else
+
+TEXT runtime·spillArgs(SB),NOSPLIT,$0-0
+        RET
+
+TEXT runtime·unspillArgs(SB),NOSPLIT,$0-0
+        RET
+#endif
+
 // AES hashing not implemented for s390x
-TEXT runtime·memhash(SB),NOSPLIT|NOFRAME,$0-32
-       JMP     runtime·memhashFallback(SB)
-TEXT runtime·strhash(SB),NOSPLIT|NOFRAME,$0-24
-       JMP     runtime·strhashFallback(SB)
-TEXT runtime·memhash32(SB),NOSPLIT|NOFRAME,$0-24
-       JMP     runtime·memhash32Fallback(SB)
-TEXT runtime·memhash64(SB),NOSPLIT|NOFRAME,$0-24
-       JMP     runtime·memhash64Fallback(SB)
+TEXT runtime·memhash<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-32
+       JMP     runtime·memhashFallback<ABIInternal>(SB)
+TEXT runtime·strhash<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
+       JMP     runtime·strhashFallback<ABIInternal>(SB)
+TEXT runtime·memhash32<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
+       JMP     runtime·memhash32Fallback<ABIInternal>(SB)
+TEXT runtime·memhash64<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
+       JMP     runtime·memhash64Fallback<ABIInternal>(SB)
 
 // Called from cgo wrappers, this function returns g->m->curg.stack.hi.
 // Must obey the gcc calling convention.
@@ -902,8 +976,7 @@ TEXT runtime·panicBounds<ABIInternal>(SB),NOSPLIT,$144-0
        // skip R14 aka LR @ 136
        // skip R15 aka SP @ 144
 
-       MOVD    R14, 8(R15)     // PC immediately after call to panicBounds
-       ADD     $24, R15, R0    // pointer to save area
-       MOVD    R0, 16(R15)
+       MOVD    R14, R2         // PC immediately after call to panicBounds
+       ADD     $24, R15, R3    // pointer to save area
        CALL    runtime·panicBounds64<ABIInternal>(SB)
        RET
index a2b07ff8aa8e6bbc989201c254039f806a00082f..6d704e820037a53e76172e3cf7d1af595d5a1c2b 100644 (file)
@@ -8,6 +8,13 @@ package runtime
 func load_g()
 func save_g()
 
+// Used by reflectcall and the reflect package.
+//
+// Spills/loads arguments in registers to/from an internal/abi.RegArgs
+// respectively. Does not follow the Go ABI.
+func spillArgs()
+func unspillArgs()
+
 // getfp returns the frame pointer register of its caller or 0 if not implemented.
 // TODO: Make this a compiler intrinsic
 func getfp() uintptr { return 0 }
index cb6a21c1143848059741a9c12150b2b98e98776d..388e7b88bd94ec79eb035c1927c2301fdc3639bf 100644 (file)
@@ -19,7 +19,7 @@
 //
 // If !iscgo, this is a no-op.
 //
-// NOTE: setg_gcc<> assume this clobbers only R10 and R11.
+// NOTE: setg_gcc<> and mcall assume this clobbers only R10 and R11.
 TEXT runtime·save_g(SB),NOSPLIT|NOFRAME,$0-0
        MOVB    runtime·iscgo(SB),  R10
        CMPBEQ  R10, $0, nocgo