mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-05-30 21:07:34 +03:00
7534ac7367
This adds support to std, primarily for linux, to support the Alpha architecture. closes #30940 closes #30926
359 lines
9.0 KiB
Zig
359 lines
9.0 KiB
Zig
const builtin = @import("builtin");
|
|
const std = @import("../../std.zig");
|
|
const SYS = std.os.linux.SYS;
|
|
|
|
pub fn syscall0(number: SYS) u64 {
|
|
return asm volatile (
|
|
\\ callsys
|
|
\\ beq $19, 1f
|
|
\\ negq $0, $0
|
|
\\1:
|
|
: [ret] "={$0}" (-> u64),
|
|
: [number] "{$0}" (number),
|
|
: .{
|
|
.r1 = true,
|
|
.r2 = true,
|
|
.r3 = true,
|
|
.r4 = true,
|
|
.r5 = true,
|
|
.r6 = true,
|
|
.r7 = true,
|
|
.r8 = true,
|
|
.r22 = true,
|
|
.r23 = true,
|
|
.r24 = true,
|
|
.r25 = true,
|
|
.r27 = true,
|
|
.r28 = true,
|
|
.memory = true,
|
|
.r16 = true,
|
|
.r17 = true,
|
|
.r18 = true,
|
|
.r20 = true,
|
|
.r21 = true,
|
|
});
|
|
}
|
|
|
|
pub fn syscall1(number: SYS, arg1: u64) u64 {
|
|
// These registers are both inputs and clobbers.
|
|
var r16_out: u64 = undefined;
|
|
return asm volatile (
|
|
\\ callsys
|
|
\\ beq $19, 1f
|
|
\\ negq $0, $0
|
|
\\1:
|
|
: [ret] "={$0}" (-> u64),
|
|
[r16_out] "={$16}" (r16_out),
|
|
: [number] "{$0}" (number),
|
|
[arg1] "{$16}" (arg1),
|
|
: .{
|
|
.r1 = true,
|
|
.r2 = true,
|
|
.r3 = true,
|
|
.r4 = true,
|
|
.r5 = true,
|
|
.r6 = true,
|
|
.r7 = true,
|
|
.r8 = true,
|
|
.r22 = true,
|
|
.r23 = true,
|
|
.r24 = true,
|
|
.r25 = true,
|
|
.r27 = true,
|
|
.r28 = true,
|
|
.memory = true,
|
|
.r17 = true,
|
|
.r18 = true,
|
|
.r20 = true,
|
|
.r21 = true,
|
|
});
|
|
}
|
|
|
|
pub fn syscall2(number: SYS, arg1: u64, arg2: u64) u64 {
|
|
// These registers are both inputs and clobbers.
|
|
var r16_out: u64 = undefined;
|
|
var r17_out: u64 = undefined;
|
|
return asm volatile (
|
|
\\ callsys
|
|
\\ beq $19, 1f
|
|
\\ negq $0, $0
|
|
\\1:
|
|
: [ret] "={$0}" (-> u64),
|
|
[r16_out] "={$16}" (r16_out),
|
|
[r17_out] "={$17}" (r17_out),
|
|
: [number] "{$0}" (number),
|
|
[arg1] "{$16}" (arg1),
|
|
[arg2] "{$17}" (arg2),
|
|
: .{
|
|
.r1 = true,
|
|
.r2 = true,
|
|
.r3 = true,
|
|
.r4 = true,
|
|
.r5 = true,
|
|
.r6 = true,
|
|
.r7 = true,
|
|
.r8 = true,
|
|
.r22 = true,
|
|
.r23 = true,
|
|
.r24 = true,
|
|
.r25 = true,
|
|
.r27 = true,
|
|
.r28 = true,
|
|
.memory = true,
|
|
.r18 = true,
|
|
.r20 = true,
|
|
.r21 = true,
|
|
});
|
|
}
|
|
|
|
pub fn syscall3(number: SYS, arg1: u64, arg2: u64, arg3: u64) u64 {
|
|
// These registers are both inputs and clobbers.
|
|
var r16_out: u64 = undefined;
|
|
var r17_out: u64 = undefined;
|
|
var r18_out: u64 = undefined;
|
|
return asm volatile (
|
|
\\ callsys
|
|
\\ beq $19, 1f
|
|
\\ negq $0, $0
|
|
\\1:
|
|
: [ret] "={$0}" (-> u64),
|
|
[r16_out] "={$16}" (r16_out),
|
|
[r17_out] "={$17}" (r17_out),
|
|
[r18_out] "={$18}" (r18_out),
|
|
: [number] "{$0}" (number),
|
|
[arg1] "{$16}" (arg1),
|
|
[arg2] "{$17}" (arg2),
|
|
[arg3] "{$18}" (arg3),
|
|
: .{
|
|
.r1 = true,
|
|
.r2 = true,
|
|
.r3 = true,
|
|
.r4 = true,
|
|
.r5 = true,
|
|
.r6 = true,
|
|
.r7 = true,
|
|
.r8 = true,
|
|
.r22 = true,
|
|
.r23 = true,
|
|
.r24 = true,
|
|
.r25 = true,
|
|
.r27 = true,
|
|
.r28 = true,
|
|
.memory = true,
|
|
.r20 = true,
|
|
.r21 = true,
|
|
});
|
|
}
|
|
|
|
pub fn syscall4(number: SYS, arg1: u64, arg2: u64, arg3: u64, arg4: u64) u64 {
|
|
// These registers are both inputs and clobbers.
|
|
var r16_out: u64 = undefined;
|
|
var r17_out: u64 = undefined;
|
|
var r18_out: u64 = undefined;
|
|
var r19_out: u64 = undefined;
|
|
return asm volatile (
|
|
\\ callsys
|
|
\\ beq $19, 1f
|
|
\\ negq $0, $0
|
|
\\1:
|
|
: [ret] "={$0}" (-> u64),
|
|
[r16_out] "={$16}" (r16_out),
|
|
[r17_out] "={$17}" (r17_out),
|
|
[r18_out] "={$18}" (r18_out),
|
|
[r19_out] "={$19}" (r19_out),
|
|
: [number] "{$0}" (number),
|
|
[arg1] "{$16}" (arg1),
|
|
[arg2] "{$17}" (arg2),
|
|
[arg3] "{$18}" (arg3),
|
|
[arg4] "{$19}" (arg4),
|
|
: .{
|
|
.r1 = true,
|
|
.r2 = true,
|
|
.r3 = true,
|
|
.r4 = true,
|
|
.r5 = true,
|
|
.r6 = true,
|
|
.r7 = true,
|
|
.r8 = true,
|
|
.r22 = true,
|
|
.r23 = true,
|
|
.r24 = true,
|
|
.r25 = true,
|
|
.r27 = true,
|
|
.r28 = true,
|
|
.memory = true,
|
|
.r20 = true,
|
|
.r21 = true,
|
|
});
|
|
}
|
|
|
|
pub fn syscall5(number: SYS, arg1: u64, arg2: u64, arg3: u64, arg4: u64, arg5: u64) u64 {
|
|
// These registers are both inputs and clobbers.
|
|
var r16_out: u64 = undefined;
|
|
var r17_out: u64 = undefined;
|
|
var r18_out: u64 = undefined;
|
|
var r19_out: u64 = undefined;
|
|
var r20_out: u64 = undefined;
|
|
return asm volatile (
|
|
\\ callsys
|
|
\\ beq $19, 1f
|
|
\\ negq $0, $0
|
|
\\1:
|
|
: [ret] "={$0}" (-> u64),
|
|
[r16_out] "={$16}" (r16_out),
|
|
[r17_out] "={$17}" (r17_out),
|
|
[r18_out] "={$18}" (r18_out),
|
|
[r19_out] "={$19}" (r19_out),
|
|
[r20_out] "={$20}" (r20_out),
|
|
: [number] "{$0}" (number),
|
|
[arg1] "{$16}" (arg1),
|
|
[arg2] "{$17}" (arg2),
|
|
[arg3] "{$18}" (arg3),
|
|
[arg4] "{$19}" (arg4),
|
|
[arg5] "{$20}" (arg5),
|
|
: .{
|
|
.r1 = true,
|
|
.r2 = true,
|
|
.r3 = true,
|
|
.r4 = true,
|
|
.r5 = true,
|
|
.r6 = true,
|
|
.r7 = true,
|
|
.r8 = true,
|
|
.r22 = true,
|
|
.r23 = true,
|
|
.r24 = true,
|
|
.r25 = true,
|
|
.r27 = true,
|
|
.r28 = true,
|
|
.memory = true,
|
|
.r21 = true,
|
|
});
|
|
}
|
|
|
|
pub fn syscall6(
|
|
number: SYS,
|
|
arg1: u64,
|
|
arg2: u64,
|
|
arg3: u64,
|
|
arg4: u64,
|
|
arg5: u64,
|
|
arg6: u64,
|
|
) u64 {
|
|
// These registers are both inputs and clobbers.
|
|
var r16_out: u64 = undefined;
|
|
var r17_out: u64 = undefined;
|
|
var r18_out: u64 = undefined;
|
|
var r19_out: u64 = undefined;
|
|
var r20_out: u64 = undefined;
|
|
var r21_out: u64 = undefined;
|
|
return asm volatile (
|
|
\\ callsys
|
|
\\ beq $19, 1f
|
|
\\ negq $0, $0
|
|
\\1:
|
|
: [ret] "={$0}" (-> u64),
|
|
[r16_out] "={$16}" (r16_out),
|
|
[r17_out] "={$17}" (r17_out),
|
|
[r18_out] "={$18}" (r18_out),
|
|
[r19_out] "={$19}" (r19_out),
|
|
[r20_out] "={$20}" (r20_out),
|
|
[r21_out] "={$21}" (r21_out),
|
|
: [number] "{$0}" (number),
|
|
[arg1] "{$16}" (arg1),
|
|
[arg2] "{$17}" (arg2),
|
|
[arg3] "{$18}" (arg3),
|
|
[arg4] "{$19}" (arg4),
|
|
[arg5] "{$20}" (arg5),
|
|
[arg6] "{$21}" (arg6),
|
|
: .{
|
|
.r1 = true,
|
|
.r2 = true,
|
|
.r3 = true,
|
|
.r4 = true,
|
|
.r5 = true,
|
|
.r6 = true,
|
|
.r7 = true,
|
|
.r8 = true,
|
|
.r22 = true,
|
|
.r23 = true,
|
|
.r24 = true,
|
|
.r25 = true,
|
|
.r27 = true,
|
|
.r28 = true,
|
|
.memory = true,
|
|
});
|
|
}
|
|
|
|
pub fn clone() callconv(.naked) u64 {
|
|
// __clone(func, stack, flags, arg, ptid, tls, ctid)
|
|
// a0, a1, a2, a3, a4, a5, +0
|
|
//
|
|
// syscall(SYS_clone, flags, stack, ptid, ctid, tls)
|
|
// v0 a0, a1, a2, a3, a4
|
|
asm volatile (
|
|
// a0 = $16, a1 = $17, a2 = $18, a3 = $19,
|
|
// a4 = $20, a5 = $21, sp = $30, v0 = $0
|
|
\\ # Save function pointer and argument pointer on new thread stack
|
|
\\ ldi $1, -8
|
|
\\ and $17, $17, $1
|
|
\\ lda $17, -16($17)
|
|
\\ stq $16, 0($17)
|
|
\\ stq $19, 8($17)
|
|
\\
|
|
\\ # Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,ctid,tls)
|
|
\\ mov $18, $16
|
|
\\ mov $20, $18
|
|
\\ ldq $19, 0($30)
|
|
\\ mov $21, $20
|
|
\\
|
|
\\ # Actual syscall
|
|
\\ ldi $0, 312 # SYS_clone
|
|
\\ callsys
|
|
\\ beq $19, 1f
|
|
\\ negq $0, $0
|
|
\\ ret
|
|
\\1:
|
|
\\ beq $0, 2f
|
|
\\ ret
|
|
\\2:
|
|
);
|
|
if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
|
|
// ra = $26
|
|
\\ .cfi_undefined $26
|
|
);
|
|
asm volatile (
|
|
// v0 = $0, t9 = $23, a0 = $16, ra = $26, sp = $30, fp = $15
|
|
\\ mov 0, $15
|
|
\\
|
|
\\ ldq $23, 0($30)
|
|
\\ ldq $16, 8($30)
|
|
\\ lda $30, 16($30)
|
|
\\ jsr $26, ($23)
|
|
\\
|
|
\\ mov $0, $16
|
|
\\ ldi $0, 1 # SYS_EXIT
|
|
\\ callsys
|
|
);
|
|
}
|
|
|
|
pub fn restore() noreturn {
|
|
asm volatile (
|
|
// v0 = $0, a0 = $16, sp = $30
|
|
\\ mov $30, $16
|
|
\\ ldi $0, 103 # SIGRETURN
|
|
\\ callsys
|
|
);
|
|
}
|
|
|
|
pub fn restore_rt() noreturn {
|
|
asm volatile (
|
|
// v0 = $0, a0 = $16, sp = $30
|
|
\\ mov $30, $16
|
|
\\ ldi $0, 351 # RT_SIGRETURN
|
|
\\ callsys
|
|
);
|
|
}
|
|
|
|
pub const VDSO = void;
|