diff options
Diffstat (limited to 'src/runtime/sys_openbsd_amd64.s')
| -rw-r--r-- | src/runtime/sys_openbsd_amd64.s | 341 |
1 files changed, 341 insertions, 0 deletions
diff --git a/src/runtime/sys_openbsd_amd64.s b/src/runtime/sys_openbsd_amd64.s index 4680a7f7aa..b3a76b57a3 100644 --- a/src/runtime/sys_openbsd_amd64.s +++ b/src/runtime/sys_openbsd_amd64.s @@ -445,3 +445,344 @@ TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0 MOVL $0xf1, 0xf1 // crash POPQ BP RET + +// syscall calls a function in libc on behalf of the syscall package. +// syscall takes a pointer to a struct like: +// struct { +// fn uintptr +// a1 uintptr +// a2 uintptr +// a3 uintptr +// r1 uintptr +// r2 uintptr +// err uintptr +// } +// syscall must be called on the g0 stack with the +// C calling convention (use libcCall). +// +// syscall expects a 32-bit result and tests for 32-bit -1 +// to decide there was an error. +TEXT runtime·syscall(SB),NOSPLIT,$0 + PUSHQ BP + MOVQ SP, BP + SUBQ $16, SP + MOVQ (0*8)(DI), CX // fn + MOVQ (2*8)(DI), SI // a2 + MOVQ (3*8)(DI), DX // a3 + MOVQ DI, (SP) + MOVQ (1*8)(DI), DI // a1 + XORL AX, AX // vararg: say "no float args" + + CALL CX + + MOVQ (SP), DI + MOVQ AX, (4*8)(DI) // r1 + MOVQ DX, (5*8)(DI) // r2 + + // Standard libc functions return -1 on error + // and set errno. + CMPL AX, $-1 // Note: high 32 bits are junk + JNE ok + + // Get error code from libc. + CALL libc_errno(SB) + MOVLQSX (AX), AX + MOVQ (SP), DI + MOVQ AX, (6*8)(DI) // err + +ok: + XORL AX, AX // no error (it's ignored anyway) + MOVQ BP, SP + POPQ BP + RET + +// syscallX calls a function in libc on behalf of the syscall package. +// syscallX takes a pointer to a struct like: +// struct { +// fn uintptr +// a1 uintptr +// a2 uintptr +// a3 uintptr +// r1 uintptr +// r2 uintptr +// err uintptr +// } +// syscallX must be called on the g0 stack with the +// C calling convention (use libcCall). +// +// syscallX is like syscall but expects a 64-bit result +// and tests for 64-bit -1 to decide there was an error. +TEXT runtime·syscallX(SB),NOSPLIT,$0 + PUSHQ BP + MOVQ SP, BP + SUBQ $16, SP + MOVQ (0*8)(DI), CX // fn + MOVQ (2*8)(DI), SI // a2 + MOVQ (3*8)(DI), DX // a3 + MOVQ DI, (SP) + MOVQ (1*8)(DI), DI // a1 + XORL AX, AX // vararg: say "no float args" + + CALL CX + + MOVQ (SP), DI + MOVQ AX, (4*8)(DI) // r1 + MOVQ DX, (5*8)(DI) // r2 + + // Standard libc functions return -1 on error + // and set errno. + CMPQ AX, $-1 + JNE ok + + // Get error code from libc. + CALL libc_errno(SB) + MOVLQSX (AX), AX + MOVQ (SP), DI + MOVQ AX, (6*8)(DI) // err + +ok: + XORL AX, AX // no error (it's ignored anyway) + MOVQ BP, SP + POPQ BP + RET + +// syscall6 calls a function in libc on behalf of the syscall package. +// syscall6 takes a pointer to a struct like: +// struct { +// fn uintptr +// a1 uintptr +// a2 uintptr +// a3 uintptr +// a4 uintptr +// a5 uintptr +// a6 uintptr +// r1 uintptr +// r2 uintptr +// err uintptr +// } +// syscall6 must be called on the g0 stack with the +// C calling convention (use libcCall). +// +// syscall6 expects a 32-bit result and tests for 32-bit -1 +// to decide there was an error. +TEXT runtime·syscall6(SB),NOSPLIT,$0 + PUSHQ BP + MOVQ SP, BP + SUBQ $16, SP + MOVQ (0*8)(DI), R11// fn + MOVQ (2*8)(DI), SI // a2 + MOVQ (3*8)(DI), DX // a3 + MOVQ (4*8)(DI), CX // a4 + MOVQ (5*8)(DI), R8 // a5 + MOVQ (6*8)(DI), R9 // a6 + MOVQ DI, (SP) + MOVQ (1*8)(DI), DI // a1 + XORL AX, AX // vararg: say "no float args" + + CALL R11 + + MOVQ (SP), DI + MOVQ AX, (7*8)(DI) // r1 + MOVQ DX, (8*8)(DI) // r2 + + CMPL AX, $-1 + JNE ok + + CALL libc_errno(SB) + MOVLQSX (AX), AX + MOVQ (SP), DI + MOVQ AX, (9*8)(DI) // err + +ok: + XORL AX, AX // no error (it's ignored anyway) + MOVQ BP, SP + POPQ BP + RET + +// syscall6X calls a function in libc on behalf of the syscall package. +// syscall6X takes a pointer to a struct like: +// struct { +// fn uintptr +// a1 uintptr +// a2 uintptr +// a3 uintptr +// a4 uintptr +// a5 uintptr +// a6 uintptr +// r1 uintptr +// r2 uintptr +// err uintptr +// } +// syscall6X must be called on the g0 stack with the +// C calling convention (use libcCall). +// +// syscall6X is like syscall6 but expects a 64-bit result +// and tests for 64-bit -1 to decide there was an error. +TEXT runtime·syscall6X(SB),NOSPLIT,$0 + PUSHQ BP + MOVQ SP, BP + SUBQ $16, SP + MOVQ (0*8)(DI), R11// fn + MOVQ (2*8)(DI), SI // a2 + MOVQ (3*8)(DI), DX // a3 + MOVQ (4*8)(DI), CX // a4 + MOVQ (5*8)(DI), R8 // a5 + MOVQ (6*8)(DI), R9 // a6 + MOVQ DI, (SP) + MOVQ (1*8)(DI), DI // a1 + XORL AX, AX // vararg: say "no float args" + + CALL R11 + + MOVQ (SP), DI + MOVQ AX, (7*8)(DI) // r1 + MOVQ DX, (8*8)(DI) // r2 + + CMPQ AX, $-1 + JNE ok + + CALL libc_errno(SB) + MOVLQSX (AX), AX + MOVQ (SP), DI + MOVQ AX, (9*8)(DI) // err + +ok: + XORL AX, AX // no error (it's ignored anyway) + MOVQ BP, SP + POPQ BP + RET + +// syscall10 calls a function in libc on behalf of the syscall package. +// syscall10 takes a pointer to a struct like: +// struct { +// fn uintptr +// a1 uintptr +// a2 uintptr +// a3 uintptr +// a4 uintptr +// a5 uintptr +// a6 uintptr +// a7 uintptr +// a8 uintptr +// a9 uintptr +// a10 uintptr +// r1 uintptr +// r2 uintptr +// err uintptr +// } +// syscall10 must be called on the g0 stack with the +// C calling convention (use libcCall). +TEXT runtime·syscall10(SB),NOSPLIT,$0 + PUSHQ BP + MOVQ SP, BP + SUBQ $48, SP + + // Arguments a1 to a6 get passed in registers, with a7 onwards being + // passed via the stack per the x86-64 System V ABI + // (https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf). + MOVQ (7*8)(DI), R10 // a7 + MOVQ (8*8)(DI), R11 // a8 + MOVQ (9*8)(DI), R12 // a9 + MOVQ (10*8)(DI), R13 // a10 + MOVQ R10, (0*8)(SP) // a7 + MOVQ R11, (1*8)(SP) // a8 + MOVQ R12, (2*8)(SP) // a9 + MOVQ R13, (3*8)(SP) // a10 + MOVQ (0*8)(DI), R11 // fn + MOVQ (2*8)(DI), SI // a2 + MOVQ (3*8)(DI), DX // a3 + MOVQ (4*8)(DI), CX // a4 + MOVQ (5*8)(DI), R8 // a5 + MOVQ (6*8)(DI), R9 // a6 + MOVQ DI, (4*8)(SP) + MOVQ (1*8)(DI), DI // a1 + XORL AX, AX // vararg: say "no float args" + + CALL R11 + + MOVQ (4*8)(SP), DI + MOVQ AX, (11*8)(DI) // r1 + MOVQ DX, (12*8)(DI) // r2 + + CMPL AX, $-1 + JNE ok + + CALL libc_errno(SB) + MOVLQSX (AX), AX + MOVQ (4*8)(SP), DI + MOVQ AX, (13*8)(DI) // err + +ok: + XORL AX, AX // no error (it's ignored anyway) + MOVQ BP, SP + POPQ BP + RET + +// syscall10X calls a function in libc on behalf of the syscall package. +// syscall10X takes a pointer to a struct like: +// struct { +// fn uintptr +// a1 uintptr +// a2 uintptr +// a3 uintptr +// a4 uintptr +// a5 uintptr +// a6 uintptr +// a7 uintptr +// a8 uintptr +// a9 uintptr +// a10 uintptr +// r1 uintptr +// r2 uintptr +// err uintptr +// } +// syscall10X must be called on the g0 stack with the +// C calling convention (use libcCall). +// +// syscall10X is like syscall10 but expects a 64-bit result +// and tests for 64-bit -1 to decide there was an error. +TEXT runtime·syscall10X(SB),NOSPLIT,$0 + PUSHQ BP + MOVQ SP, BP + SUBQ $48, SP + + // Arguments a1 to a6 get passed in registers, with a7 onwards being + // passed via the stack per the x86-64 System V ABI + // (https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf). + MOVQ (7*8)(DI), R10 // a7 + MOVQ (8*8)(DI), R11 // a8 + MOVQ (9*8)(DI), R12 // a9 + MOVQ (10*8)(DI), R13 // a10 + MOVQ R10, (0*8)(SP) // a7 + MOVQ R11, (1*8)(SP) // a8 + MOVQ R12, (2*8)(SP) // a9 + MOVQ R13, (3*8)(SP) // a10 + MOVQ (0*8)(DI), R11 // fn + MOVQ (2*8)(DI), SI // a2 + MOVQ (3*8)(DI), DX // a3 + MOVQ (4*8)(DI), CX // a4 + MOVQ (5*8)(DI), R8 // a5 + MOVQ (6*8)(DI), R9 // a6 + MOVQ DI, (4*8)(SP) + MOVQ (1*8)(DI), DI // a1 + XORL AX, AX // vararg: say "no float args" + + CALL R11 + + MOVQ (4*8)(SP), DI + MOVQ AX, (11*8)(DI) // r1 + MOVQ DX, (12*8)(DI) // r2 + + CMPQ AX, $-1 + JNE ok + + CALL libc_errno(SB) + MOVLQSX (AX), AX + MOVQ (4*8)(SP), DI + MOVQ AX, (13*8)(DI) // err + +ok: + XORL AX, AX // no error (it's ignored anyway) + MOVQ BP, SP + POPQ BP + RET |
