mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 22:04:21 +00:00
Some syscalls such as fadvise require an extra argument to comply with the register pair alignment imposed by the ABI. Wacky, isn't it?
203 lines
5.2 KiB
Zig
203 lines
5.2 KiB
Zig
// SPDX-License-Identifier: MIT
|
|
// Copyright (c) 2015-2021 Zig Contributors
|
|
// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
|
|
// The MIT license requires this copyright notice to be included in all copies
|
|
// and substantial portions of the software.
|
|
usingnamespace @import("../bits.zig");
|
|
|
|
pub fn syscall0(number: SYS) usize {
|
|
return asm volatile (
|
|
\\ syscall
|
|
\\ blez $7, 1f
|
|
\\ subu $2, $0, $2
|
|
\\ 1:
|
|
: [ret] "={$2}" (-> usize)
|
|
: [number] "{$2}" (@enumToInt(number))
|
|
: "memory", "cc", "$7"
|
|
);
|
|
}
|
|
|
|
pub fn syscall_pipe(fd: *[2]i32) usize {
|
|
return asm volatile (
|
|
\\ .set noat
|
|
\\ .set noreorder
|
|
\\ syscall
|
|
\\ blez $7, 1f
|
|
\\ nop
|
|
\\ b 2f
|
|
\\ subu $2, $0, $2
|
|
\\ 1:
|
|
\\ sw $2, 0($4)
|
|
\\ sw $3, 4($4)
|
|
\\ 2:
|
|
: [ret] "={$2}" (-> usize)
|
|
: [number] "{$2}" (@enumToInt(SYS.pipe))
|
|
: "memory", "cc", "$7"
|
|
);
|
|
}
|
|
|
|
pub fn syscall1(number: SYS, arg1: usize) usize {
|
|
return asm volatile (
|
|
\\ syscall
|
|
\\ blez $7, 1f
|
|
\\ subu $2, $0, $2
|
|
\\ 1:
|
|
: [ret] "={$2}" (-> usize)
|
|
: [number] "{$2}" (@enumToInt(number)),
|
|
[arg1] "{$4}" (arg1)
|
|
: "memory", "cc", "$7"
|
|
);
|
|
}
|
|
|
|
pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {
|
|
return asm volatile (
|
|
\\ syscall
|
|
\\ blez $7, 1f
|
|
\\ subu $2, $0, $2
|
|
\\ 1:
|
|
: [ret] "={$2}" (-> usize)
|
|
: [number] "{$2}" (@enumToInt(number)),
|
|
[arg1] "{$4}" (arg1),
|
|
[arg2] "{$5}" (arg2)
|
|
: "memory", "cc", "$7"
|
|
);
|
|
}
|
|
|
|
pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {
|
|
return asm volatile (
|
|
\\ syscall
|
|
\\ blez $7, 1f
|
|
\\ subu $2, $0, $2
|
|
\\ 1:
|
|
: [ret] "={$2}" (-> usize)
|
|
: [number] "{$2}" (@enumToInt(number)),
|
|
[arg1] "{$4}" (arg1),
|
|
[arg2] "{$5}" (arg2),
|
|
[arg3] "{$6}" (arg3)
|
|
: "memory", "cc", "$7"
|
|
);
|
|
}
|
|
|
|
pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
|
|
return asm volatile (
|
|
\\ syscall
|
|
\\ blez $7, 1f
|
|
\\ subu $2, $0, $2
|
|
\\ 1:
|
|
: [ret] "={$2}" (-> usize)
|
|
: [number] "{$2}" (@enumToInt(number)),
|
|
[arg1] "{$4}" (arg1),
|
|
[arg2] "{$5}" (arg2),
|
|
[arg3] "{$6}" (arg3),
|
|
[arg4] "{$7}" (arg4)
|
|
: "memory", "cc", "$7"
|
|
);
|
|
}
|
|
|
|
pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize {
|
|
return asm volatile (
|
|
\\ .set noat
|
|
\\ subu $sp, $sp, 24
|
|
\\ sw %[arg5], 16($sp)
|
|
\\ syscall
|
|
\\ addu $sp, $sp, 24
|
|
\\ blez $7, 1f
|
|
\\ subu $2, $0, $2
|
|
\\ 1:
|
|
: [ret] "={$2}" (-> usize)
|
|
: [number] "{$2}" (@enumToInt(number)),
|
|
[arg1] "{$4}" (arg1),
|
|
[arg2] "{$5}" (arg2),
|
|
[arg3] "{$6}" (arg3),
|
|
[arg4] "{$7}" (arg4),
|
|
[arg5] "r" (arg5)
|
|
: "memory", "cc", "$7"
|
|
);
|
|
}
|
|
|
|
// NOTE: The o32 calling convention requires the callee to reserve 16 bytes for
|
|
// the first four arguments even though they're passed in $a0-$a3.
|
|
|
|
pub fn syscall6(
|
|
number: SYS,
|
|
arg1: usize,
|
|
arg2: usize,
|
|
arg3: usize,
|
|
arg4: usize,
|
|
arg5: usize,
|
|
arg6: usize,
|
|
) usize {
|
|
return asm volatile (
|
|
\\ .set noat
|
|
\\ subu $sp, $sp, 24
|
|
\\ sw %[arg5], 16($sp)
|
|
\\ sw %[arg6], 20($sp)
|
|
\\ syscall
|
|
\\ addu $sp, $sp, 24
|
|
\\ blez $7, 1f
|
|
\\ subu $2, $0, $2
|
|
\\ 1:
|
|
: [ret] "={$2}" (-> usize)
|
|
: [number] "{$2}" (@enumToInt(number)),
|
|
[arg1] "{$4}" (arg1),
|
|
[arg2] "{$5}" (arg2),
|
|
[arg3] "{$6}" (arg3),
|
|
[arg4] "{$7}" (arg4),
|
|
[arg5] "r" (arg5),
|
|
[arg6] "r" (arg6)
|
|
: "memory", "cc", "$7"
|
|
);
|
|
}
|
|
|
|
pub fn syscall7(
|
|
number: SYS,
|
|
arg1: usize,
|
|
arg2: usize,
|
|
arg3: usize,
|
|
arg4: usize,
|
|
arg5: usize,
|
|
arg6: usize,
|
|
arg7: usize,
|
|
) usize {
|
|
return asm volatile (
|
|
\\ .set noat
|
|
\\ subu $sp, $sp, 32
|
|
\\ sw %[arg5], 16($sp)
|
|
\\ sw %[arg6], 20($sp)
|
|
\\ sw %[arg7], 24($sp)
|
|
\\ syscall
|
|
\\ addu $sp, $sp, 32
|
|
\\ blez $7, 1f
|
|
\\ subu $2, $0, $2
|
|
\\ 1:
|
|
: [ret] "={$2}" (-> usize)
|
|
: [number] "{$2}" (@enumToInt(number)),
|
|
[arg1] "{$4}" (arg1),
|
|
[arg2] "{$5}" (arg2),
|
|
[arg3] "{$6}" (arg3),
|
|
[arg4] "{$7}" (arg4),
|
|
[arg5] "r" (arg5),
|
|
[arg6] "r" (arg6),
|
|
[arg7] "r" (arg7)
|
|
: "memory", "cc", "$7"
|
|
);
|
|
}
|
|
|
|
/// This matches the libc clone function.
|
|
pub extern fn clone(func: fn (arg: usize) callconv(.C) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
|
|
|
|
pub fn restore() callconv(.Naked) void {
|
|
return asm volatile ("syscall"
|
|
:
|
|
: [number] "{$2}" (@enumToInt(SYS.sigreturn))
|
|
: "memory", "cc", "$7"
|
|
);
|
|
}
|
|
|
|
pub fn restore_rt() callconv(.Naked) void {
|
|
return asm volatile ("syscall"
|
|
:
|
|
: [number] "{$2}" (@enumToInt(SYS.rt_sigreturn))
|
|
: "memory", "cc", "$7"
|
|
);
|
|
}
|