| // Copyright 2020 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| //go:build zos && s390x && gc |
| // +build zos |
| // +build s390x |
| // +build gc |
| |
| #include "textflag.h" |
| |
| #define PSALAA 1208(R0) |
| #define GTAB64(x) 80(x) |
| #define LCA64(x) 88(x) |
| #define CAA(x) 8(x) |
| #define EDCHPXV(x) 1016(x) // in the CAA |
| #define SAVSTACK_ASYNC(x) 336(x) // in the LCA |
| |
| // SS_*, where x=SAVSTACK_ASYNC |
| #define SS_LE(x) 0(x) |
| #define SS_GO(x) 8(x) |
| #define SS_ERRNO(x) 16(x) |
| #define SS_ERRNOJR(x) 20(x) |
| |
| #define LE_CALL BYTE $0x0D; BYTE $0x76; // BL R7, R6 |
| |
| TEXT ·clearErrno(SB),NOSPLIT,$0-0 |
| BL addrerrno<>(SB) |
| MOVD $0, 0(R3) |
| RET |
| |
| // Returns the address of errno in R3. |
| TEXT addrerrno<>(SB),NOSPLIT|NOFRAME,$0-0 |
| // Get library control area (LCA). |
| MOVW PSALAA, R8 |
| MOVD LCA64(R8), R8 |
| |
| // Get __errno FuncDesc. |
| MOVD CAA(R8), R9 |
| MOVD EDCHPXV(R9), R9 |
| ADD $(0x156*16), R9 |
| LMG 0(R9), R5, R6 |
| |
| // Switch to saved LE stack. |
| MOVD SAVSTACK_ASYNC(R8), R9 |
| MOVD 0(R9), R4 |
| MOVD $0, 0(R9) |
| |
| // Call __errno function. |
| LE_CALL |
| NOPH |
| |
| // Switch back to Go stack. |
| XOR R0, R0 // Restore R0 to $0. |
| MOVD R4, 0(R9) // Save stack pointer. |
| RET |
| |
| TEXT ·syscall_syscall(SB),NOSPLIT,$0-56 |
| BL runtime·entersyscall(SB) |
| MOVD a1+8(FP), R1 |
| MOVD a2+16(FP), R2 |
| MOVD a3+24(FP), R3 |
| |
| // Get library control area (LCA). |
| MOVW PSALAA, R8 |
| MOVD LCA64(R8), R8 |
| |
| // Get function. |
| MOVD CAA(R8), R9 |
| MOVD EDCHPXV(R9), R9 |
| MOVD trap+0(FP), R5 |
| SLD $4, R5 |
| ADD R5, R9 |
| LMG 0(R9), R5, R6 |
| |
| // Restore LE stack. |
| MOVD SAVSTACK_ASYNC(R8), R9 |
| MOVD 0(R9), R4 |
| MOVD $0, 0(R9) |
| |
| // Call function. |
| LE_CALL |
| NOPH |
| XOR R0, R0 // Restore R0 to $0. |
| MOVD R4, 0(R9) // Save stack pointer. |
| |
| MOVD R3, r1+32(FP) |
| MOVD R0, r2+40(FP) |
| MOVD R0, err+48(FP) |
| MOVW R3, R4 |
| CMP R4, $-1 |
| BNE done |
| BL addrerrno<>(SB) |
| MOVWZ 0(R3), R3 |
| MOVD R3, err+48(FP) |
| done: |
| BL runtime·exitsyscall(SB) |
| RET |
| |
| TEXT ·syscall_rawsyscall(SB),NOSPLIT,$0-56 |
| MOVD a1+8(FP), R1 |
| MOVD a2+16(FP), R2 |
| MOVD a3+24(FP), R3 |
| |
| // Get library control area (LCA). |
| MOVW PSALAA, R8 |
| MOVD LCA64(R8), R8 |
| |
| // Get function. |
| MOVD CAA(R8), R9 |
| MOVD EDCHPXV(R9), R9 |
| MOVD trap+0(FP), R5 |
| SLD $4, R5 |
| ADD R5, R9 |
| LMG 0(R9), R5, R6 |
| |
| // Restore LE stack. |
| MOVD SAVSTACK_ASYNC(R8), R9 |
| MOVD 0(R9), R4 |
| MOVD $0, 0(R9) |
| |
| // Call function. |
| LE_CALL |
| NOPH |
| XOR R0, R0 // Restore R0 to $0. |
| MOVD R4, 0(R9) // Save stack pointer. |
| |
| MOVD R3, r1+32(FP) |
| MOVD R0, r2+40(FP) |
| MOVD R0, err+48(FP) |
| MOVW R3, R4 |
| CMP R4, $-1 |
| BNE done |
| BL addrerrno<>(SB) |
| MOVWZ 0(R3), R3 |
| MOVD R3, err+48(FP) |
| done: |
| RET |
| |
| TEXT ·syscall_syscall6(SB),NOSPLIT,$0-80 |
| BL runtime·entersyscall(SB) |
| MOVD a1+8(FP), R1 |
| MOVD a2+16(FP), R2 |
| MOVD a3+24(FP), R3 |
| |
| // Get library control area (LCA). |
| MOVW PSALAA, R8 |
| MOVD LCA64(R8), R8 |
| |
| // Get function. |
| MOVD CAA(R8), R9 |
| MOVD EDCHPXV(R9), R9 |
| MOVD trap+0(FP), R5 |
| SLD $4, R5 |
| ADD R5, R9 |
| LMG 0(R9), R5, R6 |
| |
| // Restore LE stack. |
| MOVD SAVSTACK_ASYNC(R8), R9 |
| MOVD 0(R9), R4 |
| MOVD $0, 0(R9) |
| |
| // Fill in parameter list. |
| MOVD a4+32(FP), R12 |
| MOVD R12, (2176+24)(R4) |
| MOVD a5+40(FP), R12 |
| MOVD R12, (2176+32)(R4) |
| MOVD a6+48(FP), R12 |
| MOVD R12, (2176+40)(R4) |
| |
| // Call function. |
| LE_CALL |
| NOPH |
| XOR R0, R0 // Restore R0 to $0. |
| MOVD R4, 0(R9) // Save stack pointer. |
| |
| MOVD R3, r1+56(FP) |
| MOVD R0, r2+64(FP) |
| MOVD R0, err+72(FP) |
| MOVW R3, R4 |
| CMP R4, $-1 |
| BNE done |
| BL addrerrno<>(SB) |
| MOVWZ 0(R3), R3 |
| MOVD R3, err+72(FP) |
| done: |
| BL runtime·exitsyscall(SB) |
| RET |
| |
| TEXT ·syscall_rawsyscall6(SB),NOSPLIT,$0-80 |
| MOVD a1+8(FP), R1 |
| MOVD a2+16(FP), R2 |
| MOVD a3+24(FP), R3 |
| |
| // Get library control area (LCA). |
| MOVW PSALAA, R8 |
| MOVD LCA64(R8), R8 |
| |
| // Get function. |
| MOVD CAA(R8), R9 |
| MOVD EDCHPXV(R9), R9 |
| MOVD trap+0(FP), R5 |
| SLD $4, R5 |
| ADD R5, R9 |
| LMG 0(R9), R5, R6 |
| |
| // Restore LE stack. |
| MOVD SAVSTACK_ASYNC(R8), R9 |
| MOVD 0(R9), R4 |
| MOVD $0, 0(R9) |
| |
| // Fill in parameter list. |
| MOVD a4+32(FP), R12 |
| MOVD R12, (2176+24)(R4) |
| MOVD a5+40(FP), R12 |
| MOVD R12, (2176+32)(R4) |
| MOVD a6+48(FP), R12 |
| MOVD R12, (2176+40)(R4) |
| |
| // Call function. |
| LE_CALL |
| NOPH |
| XOR R0, R0 // Restore R0 to $0. |
| MOVD R4, 0(R9) // Save stack pointer. |
| |
| MOVD R3, r1+56(FP) |
| MOVD R0, r2+64(FP) |
| MOVD R0, err+72(FP) |
| MOVW R3, R4 |
| CMP R4, $-1 |
| BNE done |
| BL ·rrno<>(SB) |
| MOVWZ 0(R3), R3 |
| MOVD R3, err+72(FP) |
| done: |
| RET |
| |
| TEXT ·syscall_syscall9(SB),NOSPLIT,$0 |
| BL runtime·entersyscall(SB) |
| MOVD a1+8(FP), R1 |
| MOVD a2+16(FP), R2 |
| MOVD a3+24(FP), R3 |
| |
| // Get library control area (LCA). |
| MOVW PSALAA, R8 |
| MOVD LCA64(R8), R8 |
| |
| // Get function. |
| MOVD CAA(R8), R9 |
| MOVD EDCHPXV(R9), R9 |
| MOVD trap+0(FP), R5 |
| SLD $4, R5 |
| ADD R5, R9 |
| LMG 0(R9), R5, R6 |
| |
| // Restore LE stack. |
| MOVD SAVSTACK_ASYNC(R8), R9 |
| MOVD 0(R9), R4 |
| MOVD $0, 0(R9) |
| |
| // Fill in parameter list. |
| MOVD a4+32(FP), R12 |
| MOVD R12, (2176+24)(R4) |
| MOVD a5+40(FP), R12 |
| MOVD R12, (2176+32)(R4) |
| MOVD a6+48(FP), R12 |
| MOVD R12, (2176+40)(R4) |
| MOVD a7+56(FP), R12 |
| MOVD R12, (2176+48)(R4) |
| MOVD a8+64(FP), R12 |
| MOVD R12, (2176+56)(R4) |
| MOVD a9+72(FP), R12 |
| MOVD R12, (2176+64)(R4) |
| |
| // Call function. |
| LE_CALL |
| NOPH |
| XOR R0, R0 // Restore R0 to $0. |
| MOVD R4, 0(R9) // Save stack pointer. |
| |
| MOVD R3, r1+80(FP) |
| MOVD R0, r2+88(FP) |
| MOVD R0, err+96(FP) |
| MOVW R3, R4 |
| CMP R4, $-1 |
| BNE done |
| BL addrerrno<>(SB) |
| MOVWZ 0(R3), R3 |
| MOVD R3, err+96(FP) |
| done: |
| BL runtime·exitsyscall(SB) |
| RET |
| |
| TEXT ·syscall_rawsyscall9(SB),NOSPLIT,$0 |
| MOVD a1+8(FP), R1 |
| MOVD a2+16(FP), R2 |
| MOVD a3+24(FP), R3 |
| |
| // Get library control area (LCA). |
| MOVW PSALAA, R8 |
| MOVD LCA64(R8), R8 |
| |
| // Get function. |
| MOVD CAA(R8), R9 |
| MOVD EDCHPXV(R9), R9 |
| MOVD trap+0(FP), R5 |
| SLD $4, R5 |
| ADD R5, R9 |
| LMG 0(R9), R5, R6 |
| |
| // Restore LE stack. |
| MOVD SAVSTACK_ASYNC(R8), R9 |
| MOVD 0(R9), R4 |
| MOVD $0, 0(R9) |
| |
| // Fill in parameter list. |
| MOVD a4+32(FP), R12 |
| MOVD R12, (2176+24)(R4) |
| MOVD a5+40(FP), R12 |
| MOVD R12, (2176+32)(R4) |
| MOVD a6+48(FP), R12 |
| MOVD R12, (2176+40)(R4) |
| MOVD a7+56(FP), R12 |
| MOVD R12, (2176+48)(R4) |
| MOVD a8+64(FP), R12 |
| MOVD R12, (2176+56)(R4) |
| MOVD a9+72(FP), R12 |
| MOVD R12, (2176+64)(R4) |
| |
| // Call function. |
| LE_CALL |
| NOPH |
| XOR R0, R0 // Restore R0 to $0. |
| MOVD R4, 0(R9) // Save stack pointer. |
| |
| MOVD R3, r1+80(FP) |
| MOVD R0, r2+88(FP) |
| MOVD R0, err+96(FP) |
| MOVW R3, R4 |
| CMP R4, $-1 |
| BNE done |
| BL addrerrno<>(SB) |
| MOVWZ 0(R3), R3 |
| MOVD R3, err+96(FP) |
| done: |
| RET |
| |
| // func svcCall(fnptr unsafe.Pointer, argv *unsafe.Pointer, dsa *uint64) |
| TEXT ·svcCall(SB),NOSPLIT,$0 |
| BL runtime·save_g(SB) // Save g and stack pointer |
| MOVW PSALAA, R8 |
| MOVD LCA64(R8), R8 |
| MOVD SAVSTACK_ASYNC(R8), R9 |
| MOVD R15, 0(R9) |
| |
| MOVD argv+8(FP), R1 // Move function arguments into registers |
| MOVD dsa+16(FP), g |
| MOVD fnptr+0(FP), R15 |
| |
| BYTE $0x0D // Branch to function |
| BYTE $0xEF |
| |
| BL runtime·load_g(SB) // Restore g and stack pointer |
| MOVW PSALAA, R8 |
| MOVD LCA64(R8), R8 |
| MOVD SAVSTACK_ASYNC(R8), R9 |
| MOVD 0(R9), R15 |
| |
| RET |
| |
| // func svcLoad(name *byte) unsafe.Pointer |
| TEXT ·svcLoad(SB),NOSPLIT,$0 |
| MOVD R15, R2 // Save go stack pointer |
| MOVD name+0(FP), R0 // Move SVC args into registers |
| MOVD $0x80000000, R1 |
| MOVD $0, R15 |
| BYTE $0x0A // SVC 08 LOAD |
| BYTE $0x08 |
| MOVW R15, R3 // Save return code from SVC |
| MOVD R2, R15 // Restore go stack pointer |
| CMP R3, $0 // Check SVC return code |
| BNE error |
| |
| MOVD $-2, R3 // Reset last bit of entry point to zero |
| AND R0, R3 |
| MOVD R3, addr+8(FP) // Return entry point returned by SVC |
| CMP R0, R3 // Check if last bit of entry point was set |
| BNE done |
| |
| MOVD R15, R2 // Save go stack pointer |
| MOVD $0, R15 // Move SVC args into registers (entry point still in r0 from SVC 08) |
| BYTE $0x0A // SVC 09 DELETE |
| BYTE $0x09 |
| MOVD R2, R15 // Restore go stack pointer |
| |
| error: |
| MOVD $0, addr+8(FP) // Return 0 on failure |
| done: |
| XOR R0, R0 // Reset r0 to 0 |
| RET |
| |
| // func svcUnload(name *byte, fnptr unsafe.Pointer) int64 |
| TEXT ·svcUnload(SB),NOSPLIT,$0 |
| MOVD R15, R2 // Save go stack pointer |
| MOVD name+0(FP), R0 // Move SVC args into registers |
| MOVD addr+8(FP), R15 |
| BYTE $0x0A // SVC 09 |
| BYTE $0x09 |
| XOR R0, R0 // Reset r0 to 0 |
| MOVD R15, R1 // Save SVC return code |
| MOVD R2, R15 // Restore go stack pointer |
| MOVD R1, rc+0(FP) // Return SVC return code |
| RET |
| |
| // func gettid() uint64 |
| TEXT ·gettid(SB), NOSPLIT, $0 |
| // Get library control area (LCA). |
| MOVW PSALAA, R8 |
| MOVD LCA64(R8), R8 |
| |
| // Get CEECAATHDID |
| MOVD CAA(R8), R9 |
| MOVD 0x3D0(R9), R9 |
| MOVD R9, ret+0(FP) |
| |
| RET |