| // 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 |