diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-11-01 22:14:56 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-11-01 22:14:56 -0500 |
| commit | 909aae8153e7ac71197bc9f864e4ceb2793317f2 (patch) | |
| tree | 5da829286b85ef6e79ab9a9536b96b7ab6b33e97 /lib/std/os | |
| parent | af60931a488ac84030900d14c2ae7d17e0c84891 (diff) | |
| parent | 891c6ddd5f4aa7a2de79bf5c155ffea71417bb15 (diff) | |
| download | zig-909aae8153e7ac71197bc9f864e4ceb2793317f2.tar.gz zig-909aae8153e7ac71197bc9f864e4ceb2793317f2.zip | |
Merge pull request #6792 from koachan/sparc64-linux
Initial sparc64-linux bringup
Diffstat (limited to 'lib/std/os')
| -rw-r--r-- | lib/std/os/bits/linux.zig | 33 | ||||
| -rw-r--r-- | lib/std/os/bits/linux/sparc64.zig | 679 | ||||
| -rw-r--r-- | lib/std/os/linux.zig | 9 | ||||
| -rw-r--r-- | lib/std/os/linux/sparc64.zig | 153 | ||||
| -rw-r--r-- | lib/std/os/linux/tls.zig | 9 |
5 files changed, 874 insertions, 9 deletions
diff --git a/lib/std/os/bits/linux.zig b/lib/std/os/bits/linux.zig index 8dbf21fcf2..ce9b4a90d1 100644 --- a/lib/std/os/bits/linux.zig +++ b/lib/std/os/bits/linux.zig @@ -19,6 +19,7 @@ pub usingnamespace switch (builtin.arch) { .aarch64 => @import("linux/arm64.zig"), .arm => @import("linux/arm-eabi.zig"), .riscv64 => @import("linux/riscv64.zig"), + .sparcv9 => @import("linux/sparc64.zig"), .mips, .mipsel => @import("linux/mips.zig"), .powerpc64, .powerpc64le => @import("linux/powerpc64.zig"), else => struct {}, @@ -30,6 +31,7 @@ pub usingnamespace @import("linux/securebits.zig"); const is_mips = builtin.arch.isMIPS(); const is_ppc64 = builtin.arch.isPPC64(); +const is_sparc = builtin.arch.isSPARC(); pub const pid_t = i32; pub const fd_t = i32; @@ -182,28 +184,47 @@ pub usingnamespace if (is_mips) pub const SA_NOCLDSTOP = 1; pub const SA_NOCLDWAIT = 0x10000; pub const SA_SIGINFO = 8; + pub const SA_RESTART = 0x10000000; + pub const SA_RESETHAND = 0x80000000; + pub const SA_ONSTACK = 0x08000000; + pub const SA_NODEFER = 0x40000000; + pub const SA_RESTORER = 0x04000000; pub const SIG_BLOCK = 1; pub const SIG_UNBLOCK = 2; pub const SIG_SETMASK = 3; } +else if (is_sparc) + struct { + pub const SA_NOCLDSTOP = 0x8; + pub const SA_NOCLDWAIT = 0x100; + pub const SA_SIGINFO = 0x200; + pub const SA_RESTART = 0x2; + pub const SA_RESETHAND = 0x4; + pub const SA_ONSTACK = 0x1; + pub const SA_NODEFER = 0x20; + pub const SA_RESTORER = 0x04000000; + + pub const SIG_BLOCK = 1; + pub const SIG_UNBLOCK = 2; + pub const SIG_SETMASK = 4; + } else struct { pub const SA_NOCLDSTOP = 1; pub const SA_NOCLDWAIT = 2; pub const SA_SIGINFO = 4; + pub const SA_RESTART = 0x10000000; + pub const SA_RESETHAND = 0x80000000; + pub const SA_ONSTACK = 0x08000000; + pub const SA_NODEFER = 0x40000000; + pub const SA_RESTORER = 0x04000000; pub const SIG_BLOCK = 0; pub const SIG_UNBLOCK = 1; pub const SIG_SETMASK = 2; }; -pub const SA_ONSTACK = 0x08000000; -pub const SA_RESTART = 0x10000000; -pub const SA_NODEFER = 0x40000000; -pub const SA_RESETHAND = 0x80000000; -pub const SA_RESTORER = 0x04000000; - pub const SIGHUP = 1; pub const SIGINT = 2; pub const SIGQUIT = 3; diff --git a/lib/std/os/bits/linux/sparc64.zig b/lib/std/os/bits/linux/sparc64.zig new file mode 100644 index 0000000000..0f2e5b5035 --- /dev/null +++ b/lib/std/os/bits/linux/sparc64.zig @@ -0,0 +1,679 @@ +// sparc64-specific declarations that are intended to be imported into the POSIX namespace. +const std = @import("../../../std.zig"); +const pid_t = linux.pid_t; +const uid_t = linux.uid_t; +const clock_t = linux.clock_t; +const stack_t = linux.stack_t; +const sigset_t = linux.sigset_t; + +const linux = std.os.linux; +const sockaddr = linux.sockaddr; +const socklen_t = linux.socklen_t; +const iovec = linux.iovec; +const iovec_const = linux.iovec_const; + +pub const SYS = extern enum(usize) { + restart_syscall = 0, + exit = 1, + fork = 2, + read = 3, + write = 4, + open = 5, + close = 6, + wait4 = 7, + creat = 8, + link = 9, + unlink = 10, + execv = 11, + chdir = 12, + chown = 13, + mknod = 14, + chmod = 15, + lchown = 16, + brk = 17, + perfctr = 18, + lseek = 19, + getpid = 20, + capget = 21, + capset = 22, + setuid = 23, + getuid = 24, + vmsplice = 25, + ptrace = 26, + alarm = 27, + sigaltstack = 28, + pause = 29, + utime = 30, + access = 33, + nice = 34, + sync = 36, + kill = 37, + stat = 38, + sendfile = 39, + lstat = 40, + dup = 41, + pipe = 42, + times = 43, + umount2 = 45, + setgid = 46, + getgid = 47, + signal = 48, + geteuid = 49, + getegid = 50, + acct = 51, + memory_ordering = 52, + ioctl = 54, + reboot = 55, + symlink = 57, + readlink = 58, + execve = 59, + umask = 60, + chroot = 61, + fstat = 62, + fstat64 = 63, + getpagesize = 64, + msync = 65, + vfork = 66, + pread64 = 67, + pwrite64 = 68, + mmap = 71, + munmap = 73, + mprotect = 74, + madvise = 75, + vhangup = 76, + mincore = 78, + getgroups = 79, + setgroups = 80, + getpgrp = 81, + setitimer = 83, + swapon = 85, + getitimer = 86, + sethostname = 88, + dup2 = 90, + fcntl = 92, + select = 93, + fsync = 95, + setpriority = 96, + socket = 97, + connect = 98, + accept = 99, + getpriority = 100, + rt_sigreturn = 101, + rt_sigaction = 102, + rt_sigprocmask = 103, + rt_sigpending = 104, + rt_sigtimedwait = 105, + rt_sigqueueinfo = 106, + rt_sigsuspend = 107, + setresuid = 108, + getresuid = 109, + setresgid = 110, + getresgid = 111, + recvmsg = 113, + sendmsg = 114, + gettimeofday = 116, + getrusage = 117, + getsockopt = 118, + getcwd = 119, + readv = 120, + writev = 121, + settimeofday = 122, + fchown = 123, + fchmod = 124, + recvfrom = 125, + setreuid = 126, + setregid = 127, + rename = 128, + truncate = 129, + ftruncate = 130, + flock = 131, + lstat64 = 132, + sendto = 133, + shutdown = 134, + socketpair = 135, + mkdir = 136, + rmdir = 137, + utimes = 138, + stat64 = 139, + sendfile64 = 140, + getpeername = 141, + futex = 142, + gettid = 143, + getrlimit = 144, + setrlimit = 145, + pivot_root = 146, + prctl = 147, + pciconfig_read = 148, + pciconfig_write = 149, + getsockname = 150, + inotify_init = 151, + inotify_add_watch = 152, + poll = 153, + getdents64 = 154, + inotify_rm_watch = 156, + statfs = 157, + fstatfs = 158, + umount = 159, + sched_set_affinity = 160, + sched_get_affinity = 161, + getdomainname = 162, + setdomainname = 163, + utrap_install = 164, + quotactl = 165, + set_tid_address = 166, + mount = 167, + ustat = 168, + setxattr = 169, + lsetxattr = 170, + fsetxattr = 171, + getxattr = 172, + lgetxattr = 173, + getdents = 174, + setsid = 175, + fchdir = 176, + fgetxattr = 177, + listxattr = 178, + llistxattr = 179, + flistxattr = 180, + removexattr = 181, + lremovexattr = 182, + sigpending = 183, + query_module = 184, + setpgid = 185, + fremovexattr = 186, + tkill = 187, + exit_group = 188, + uname = 189, + init_module = 190, + personality = 191, + remap_file_pages = 192, + epoll_create = 193, + epoll_ctl = 194, + epoll_wait = 195, + ioprio_set = 196, + getppid = 197, + sigaction = 198, + sgetmask = 199, + ssetmask = 200, + sigsuspend = 201, + oldlstat = 202, + uselib = 203, + readdir = 204, + readahead = 205, + socketcall = 206, + syslog = 207, + lookup_dcookie = 208, + fadvise64 = 209, + fadvise64_64 = 210, + tgkill = 211, + waitpid = 212, + swapoff = 213, + sysinfo = 214, + ipc = 215, + sigreturn = 216, + clone = 217, + ioprio_get = 218, + adjtimex = 219, + sigprocmask = 220, + create_module = 221, + delete_module = 222, + get_kernel_syms = 223, + getpgid = 224, + bdflush = 225, + sysfs = 226, + afs_syscall = 227, + setfsuid = 228, + setfsgid = 229, + _newselect = 230, + splice = 232, + stime = 233, + statfs64 = 234, + fstatfs64 = 235, + _llseek = 236, + mlock = 237, + munlock = 238, + mlockall = 239, + munlockall = 240, + sched_setparam = 241, + sched_getparam = 242, + sched_setscheduler = 243, + sched_getscheduler = 244, + sched_yield = 245, + sched_get_priority_max = 246, + sched_get_priority_min = 247, + sched_rr_get_interval = 248, + nanosleep = 249, + mremap = 250, + _sysctl = 251, + getsid = 252, + fdatasync = 253, + nfsservctl = 254, + sync_file_range = 255, + clock_settime = 256, + clock_gettime = 257, + clock_getres = 258, + clock_nanosleep = 259, + sched_getaffinity = 260, + sched_setaffinity = 261, + timer_settime = 262, + timer_gettime = 263, + timer_getoverrun = 264, + timer_delete = 265, + timer_create = 266, + vserver = 267, + io_setup = 268, + io_destroy = 269, + io_submit = 270, + io_cancel = 271, + io_getevents = 272, + mq_open = 273, + mq_unlink = 274, + mq_timedsend = 275, + mq_timedreceive = 276, + mq_notify = 277, + mq_getsetattr = 278, + waitid = 279, + tee = 280, + add_key = 281, + request_key = 282, + keyctl = 283, + openat = 284, + mkdirat = 285, + mknodat = 286, + fchownat = 287, + futimesat = 288, + fstatat64 = 289, + unlinkat = 290, + renameat = 291, + linkat = 292, + symlinkat = 293, + readlinkat = 294, + fchmodat = 295, + faccessat = 296, + pselect6 = 297, + ppoll = 298, + unshare = 299, + set_robust_list = 300, + get_robust_list = 301, + migrate_pages = 302, + mbind = 303, + get_mempolicy = 304, + set_mempolicy = 305, + kexec_load = 306, + move_pages = 307, + getcpu = 308, + epoll_pwait = 309, + utimensat = 310, + signalfd = 311, + timerfd_create = 312, + eventfd = 313, + fallocate = 314, + timerfd_settime = 315, + timerfd_gettime = 316, + signalfd4 = 317, + eventfd2 = 318, + epoll_create1 = 319, + dup3 = 320, + pipe2 = 321, + inotify_init1 = 322, + accept4 = 323, + preadv = 324, + pwritev = 325, + rt_tgsigqueueinfo = 326, + perf_event_open = 327, + recvmmsg = 328, + fanotify_init = 329, + fanotify_mark = 330, + prlimit64 = 331, + name_to_handle_at = 332, + open_by_handle_at = 333, + clock_adjtime = 334, + syncfs = 335, + sendmmsg = 336, + setns = 337, + process_vm_readv = 338, + process_vm_writev = 339, + kern_features = 340, + kcmp = 341, + finit_module = 342, + sched_setattr = 343, + sched_getattr = 344, + renameat2 = 345, + seccomp = 346, + getrandom = 347, + memfd_create = 348, + bpf = 349, + execveat = 350, + membarrier = 351, + userfaultfd = 352, + bind = 353, + listen = 354, + setsockopt = 355, + mlock2 = 356, + copy_file_range = 357, + preadv2 = 358, + pwritev2 = 359, + statx = 360, + io_pgetevents = 361, + pkey_mprotect = 362, + pkey_alloc = 363, + pkey_free = 364, + rseq = 365, + semtimedop = 392, + semget = 393, + semctl = 394, + shmget = 395, + shmctl = 396, + shmat = 397, + shmdt = 398, + msgget = 399, + msgsnd = 400, + msgrcv = 401, + msgctl = 402, + pidfd_send_signal = 424, + io_uring_setup = 425, + io_uring_enter = 426, + io_uring_register = 427, + open_tree = 428, + move_mount = 429, + fsopen = 430, + fsconfig = 431, + fsmount = 432, + fspick = 433, + pidfd_open = 434, + openat2 = 437, + pidfd_getfd = 438, + + _, +}; + +pub const O_CREAT = 0x200; +pub const O_EXCL = 0x800; +pub const O_NOCTTY = 0x8000; +pub const O_TRUNC = 0x400; +pub const O_APPEND = 0x8; +pub const O_NONBLOCK = 0x4000; +pub const O_SYNC = 0x802000; +pub const O_DSYNC = 0x2000; +pub const O_RSYNC = O_SYNC; +pub const O_DIRECTORY = 0x10000; +pub const O_NOFOLLOW = 0x20000; +pub const O_CLOEXEC = 0x400000; + +pub const O_ASYNC = 0x40; +pub const O_DIRECT = 0x100000; +pub const O_LARGEFILE = 0; +pub const O_NOATIME = 0x200000; +pub const O_PATH = 0x1000000; +pub const O_TMPFILE = 0x2010000; +pub const O_NDELAY = O_NONBLOCK | 0x4; + +pub const F_DUPFD = 0; +pub const F_GETFD = 1; +pub const F_SETFD = 2; +pub const F_GETFL = 3; +pub const F_SETFL = 4; + +pub const F_SETOWN = 5; +pub const F_GETOWN = 6; +pub const F_GETLK = 7; +pub const F_SETLK = 8; +pub const F_SETLKW = 9; + +pub const F_RDLCK = 1; +pub const F_WRLCK = 2; +pub const F_UNLCK = 3; + +pub const F_SETOWN_EX = 15; +pub const F_GETOWN_EX = 16; + +pub const F_GETOWNER_UIDS = 17; + +pub const LOCK_SH = 1; +pub const LOCK_EX = 2; +pub const LOCK_NB = 4; +pub const LOCK_UN = 8; + +/// stack-like segment +pub const MAP_GROWSDOWN = 0x0200; + +/// ETXTBSY +pub const MAP_DENYWRITE = 0x0800; + +/// mark it as an executable +pub const MAP_EXECUTABLE = 0x1000; + +/// pages are locked +pub const MAP_LOCKED = 0x0100; + +/// don't check for reservations +pub const MAP_NORESERVE = 0x0040; + +pub const VDSO_CGT_SYM = "__vdso_clock_gettime"; +pub const VDSO_CGT_VER = "LINUX_2.6"; + +pub const Flock = extern struct { + l_type: i16, + l_whence: i16, + l_start: off_t, + l_len: off_t, + l_pid: pid_t, +}; + +pub const msghdr = extern struct { + msg_name: ?*sockaddr, + msg_namelen: socklen_t, + msg_iov: [*]iovec, + msg_iovlen: u64, + msg_control: ?*c_void, + msg_controllen: u64, + msg_flags: i32, +}; + +pub const msghdr_const = extern struct { + msg_name: ?*const sockaddr, + msg_namelen: socklen_t, + msg_iov: [*]iovec_const, + msg_iovlen: u64, + msg_control: ?*c_void, + msg_controllen: u64, + msg_flags: i32, +}; + +pub const off_t = i64; +pub const ino_t = u64; +pub const mode_t = u32; + +/// atime, mtime, and ctime have functions to return `timespec`, +/// because although this is a POSIX API, the layout and names of +/// the structs are inconsistent across operating systems, and +/// in C, macros are used to hide the differences. Here we use +/// methods to accomplish this. +pub const libc_stat = extern struct { + dev: u64, + ino: ino_t, + mode: u32, + nlink: usize, + + uid: u32, + gid: u32, + rdev: u64, + __pad0: u32, + + size: off_t, + blksize: isize, + blocks: i64, + + atim: timespec, + mtim: timespec, + ctim: timespec, + __unused: [2]isize, + + pub fn atime(self: libc_stat) timespec { + return self.atim; + } + + pub fn mtime(self: libc_stat) timespec { + return self.mtim; + } + + pub fn ctime(self: libc_stat) timespec { + return self.ctim; + } +}; + +pub const kernel_stat = extern struct { + dev: u32, + ino: ino_t, + mode: mode_t, + nlink: i16, + + uid: u32, + gid: u32, + rdev: u32, + + size: off_t, + atim: isize, + mtim: isize, + ctim: isize, + + blksize: off_t, + blocks: off_t, + + __unused4: [2]isize, + + // Hack to make the stdlib not complain about atime + // and friends not being a method. + // TODO what should tv_nsec be filled with? + pub fn atime(self: kernel_stat) timespec { + return timespec{.tv_sec=self.atim, .tv_nsec=0}; + } + + pub fn mtime(self: kernel_stat) timespec { + return timespec{.tv_sec=self.mtim, .tv_nsec=0}; + } + + pub fn ctime(self: kernel_stat) timespec { + return timespec{.tv_sec=self.ctim, .tv_nsec=0}; + } +}; + +/// Renamed to Stat to not conflict with the stat function. +pub const Stat = if (std.builtin.link_libc) libc_stat else kernel_stat; + +pub const timespec = extern struct { + tv_sec: isize, + tv_nsec: isize, +}; + +pub const timeval = extern struct { + tv_sec: isize, + tv_usec: isize, +}; + +pub const timezone = extern struct { + tz_minuteswest: i32, + tz_dsttime: i32, +}; + +// TODO I'm not sure if the code below is correct, need someone with more +// knowledge about sparc64 linux internals to look into. + +pub const Elf_Symndx = u32; + +pub const fpstate = extern struct { + regs: [32]u64, + fsr: u64, + gsr: u64, + fprs: u64, +}; + +pub const __fpq = extern struct { + fpq_addr: *u32, + fpq_instr: u32, +}; + +pub const __fq = extern struct { + FQu: extern union { + whole: f64, + fpq: __fpq, + }, +}; + +pub const fpregset_t = extern struct { + fpu_fr: extern union { + fpu_regs: [32]u32, + fpu_dregs: [32]f64, + fpu_qregs: [16]c_longdouble, + }, + fpu_q: *__fq, + fpu_fsr: u64, + fpu_qcnt: u8, + fpu_q_entrysize: u8, + fpu_en: u8, +}; + +pub const siginfo_fpu_t = extern struct { + float_regs: [64]u32, + fsr: u64, + gsr: u64, + fprs: u64, +}; + +pub const sigcontext = extern struct { + info: [128]i8, + regs: extern struct { + u_regs: [16]u64, + tstate: u64, + tpc: u64, + tnpc: u64, + y: u64, + fprs: u64, + }, + fpu_save: *siginfo_fpu_t, + stack: extern struct { + sp: usize, + flags: i32, + size: u64, + }, + mask: u64, +}; + +pub const greg_t = u64; +pub const gregset_t = [19]greg_t; + +pub const fq = extern struct { + addr: *u64, + insn: u32, +}; + +pub const fpu_t = extern struct { + fregs: extern union { + sregs: [32]u32, + dregs: [32]u64, + qregs: [16]c_longdouble, + }, + fsr: u64, + fprs: u64, + gsr: u64, + fq: *fq, + qcnt: u8, + qentsz: u8, + enab: u8, +}; + +pub const mcontext_t = extern struct { + gregs: gregset_t, + fp: greg_t, + @"i7": greg_t, + fpregs: fpu_t, +}; + +pub const ucontext_t = extern struct { + link: *ucontext_t, + flags: u64, + sigmask: u64, + mcontext: mcontext_t, + stack: stack_t, + sigmask: sigset_t, +}; diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index a126231db1..96e8a5edf4 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -24,6 +24,7 @@ pub usingnamespace switch (builtin.arch) { .aarch64 => @import("linux/arm64.zig"), .arm => @import("linux/arm-eabi.zig"), .riscv64 => @import("linux/riscv64.zig"), + .sparcv9 => @import("linux/sparc64.zig"), .mips, .mipsel => @import("linux/mips.zig"), .powerpc64, .powerpc64le => @import("linux/powerpc64.zig"), else => struct {}, @@ -381,7 +382,7 @@ pub fn faccessat(dirfd: i32, path: [*:0]const u8, mode: u32, flags: u32) usize { } pub fn pipe(fd: *[2]i32) usize { - if (comptime builtin.arch.isMIPS()) { + if (comptime (builtin.arch.isMIPS() or builtin.arch.isSPARC())) { return syscall_pipe(fd); } else if (@hasField(SYS, "pipe")) { return syscall1(.pipe, @ptrToInt(fd)); @@ -818,7 +819,11 @@ pub fn sigaction(sig: u6, noalias act: *const Sigaction, noalias oact: ?*Sigacti var ksa_old: k_sigaction = undefined; const ksa_mask_size = @sizeOf(@TypeOf(ksa_old.mask)); @memcpy(@ptrCast([*]u8, &ksa.mask), @ptrCast([*]const u8, &act.mask), ksa_mask_size); - const result = syscall4(.rt_sigaction, sig, @ptrToInt(&ksa), @ptrToInt(&ksa_old), ksa_mask_size); + const result = switch (builtin.arch) { + // The sparc version of rt_sigaction needs the restorer function to be passed as an argument too. + .sparc, .sparcv9 => syscall5(.rt_sigaction, sig, @ptrToInt(&ksa), @ptrToInt(&ksa_old), @ptrToInt(ksa.restorer), ksa_mask_size), + else => syscall4(.rt_sigaction, sig, @ptrToInt(&ksa), @ptrToInt(&ksa_old), ksa_mask_size), + }; const err = getErrno(result); if (err != 0) { return result; diff --git a/lib/std/os/linux/sparc64.zig b/lib/std/os/linux/sparc64.zig new file mode 100644 index 0000000000..c3c95424a0 --- /dev/null +++ b/lib/std/os/linux/sparc64.zig @@ -0,0 +1,153 @@ +usingnamespace @import("../bits.zig"); + +pub fn syscall_pipe(fd: *[2]i32) usize { + return asm volatile ( + \\ mov %%o0, %%o2 + \\ t 0x6d + \\ bcc,pt %%xcc, 1f + \\ nop + \\ ba 2f + \\ neg %%o0 + \\ 1: + \\ st %%o0, [%%o2] + \\ st %%o1, [%%o2 + 4] + \\ clr %%o0 + \\ 2: + : [ret] "={o0}" (-> usize) + : [number] "{$2}" (@enumToInt(SYS.pipe)) + : "memory", "xcc", "o1", "o2", "o3", "o4", "o5", "o7" + ); +} + +pub fn syscall0(number: SYS) usize { + return asm volatile ( + \\ t 0x6d + \\ bcc,pt %%xcc, 1f + \\ nop + \\ neg %%o0 + \\ 1: + : [ret] "={o0}" (-> usize) + : [number] "{g1}" (@enumToInt(number)) + : "memory", "xcc", "o1", "o2", "o3", "o4", "o5", "o7" + ); +} + +pub fn syscall1(number: SYS, arg1: usize) usize { + return asm volatile ( + \\ t 0x6d + \\ bcc,pt %%xcc, 1f + \\ nop + \\ neg %%o0 + \\ 1: + : [ret] "={o0}" (-> usize) + : [number] "{g1}" (@enumToInt(number)), + [arg1] "{o0}" (arg1) + : "memory", "xcc", "o1", "o2", "o3", "o4", "o5", "o7" + ); +} + +pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize { + return asm volatile ( + \\ t 0x6d + \\ bcc,pt %%xcc, 1f + \\ nop + \\ neg %%o0 + \\ 1: + : [ret] "={o0}" (-> usize) + : [number] "{g1}" (@enumToInt(number)), + [arg1] "{o0}" (arg1), + [arg2] "{o1}" (arg2) + : "memory", "xcc", "o1", "o2", "o3", "o4", "o5", "o7" + ); +} + +pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize { + return asm volatile ( + \\ t 0x6d + \\ bcc,pt %%xcc, 1f + \\ nop + \\ neg %%o0 + \\ 1: + : [ret] "={o0}" (-> usize) + : [number] "{g1}" (@enumToInt(number)), + [arg1] "{o0}" (arg1), + [arg2] "{o1}" (arg2), + [arg3] "{o2}" (arg3) + : "memory", "xcc", "o1", "o2", "o3", "o4", "o5", "o7" + ); +} + +pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize { + return asm volatile ( + \\ t 0x6d + \\ bcc,pt %%xcc, 1f + \\ nop + \\ neg %%o0 + \\ 1: + : [ret] "={o0}" (-> usize) + : [number] "{g1}" (@enumToInt(number)), + [arg1] "{o0}" (arg1), + [arg2] "{o1}" (arg2), + [arg3] "{o2}" (arg3), + [arg4] "{o3}" (arg4) + : "memory", "xcc", "o1", "o2", "o3", "o4", "o5", "o7" + ); +} + +pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize { + return asm volatile ( + \\ t 0x6d + \\ bcc,pt %%xcc, 1f + \\ nop + \\ neg %%o0 + \\ 1: + : [ret] "={o0}" (-> usize) + : [number] "{g1}" (@enumToInt(number)), + [arg1] "{o0}" (arg1), + [arg2] "{o1}" (arg2), + [arg3] "{o2}" (arg3), + [arg4] "{o3}" (arg4), + [arg5] "{o4}" (arg5), + : "memory", "xcc", "o1", "o2", "o3", "o4", "o5", "o7" + ); +} + +pub fn syscall6( + number: SYS, + arg1: usize, + arg2: usize, + arg3: usize, + arg4: usize, + arg5: usize, + arg6: usize, +) usize { + return asm volatile ( + \\ t 0x6d + \\ bcc,pt %%xcc, 1f + \\ nop + \\ neg %%o0 + \\ 1: + : [ret] "={o0}" (-> usize) + : [number] "{g1}" (@enumToInt(number)), + [arg1] "{o0}" (arg1), + [arg2] "{o1}" (arg2), + [arg3] "{o2}" (arg3), + [arg4] "{o3}" (arg4), + [arg5] "{o4}" (arg5), + [arg6] "{o5}" (arg6), + : "memory", "xcc", "o1", "o2", "o3", "o4", "o5", "o7" + ); +} + +/// This matches the libc clone function. +pub extern fn clone(func: fn (arg: usize) callconv(.C) u8, stack: usize, flags: usize, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize; + +pub const restore = restore_rt; + +pub fn restore_rt() callconv(.Naked) void { + return asm volatile ("t 0x6d" + : + : [number] "{g1}" (@enumToInt(SYS.rt_sigreturn)) + : "memory", "xcc", "o0", "o1", "o2", "o3", "o4", "o5", "o7" + ); +} diff --git a/lib/std/os/linux/tls.zig b/lib/std/os/linux/tls.zig index 69e7816f13..f6c339bc2c 100644 --- a/lib/std/os/linux/tls.zig +++ b/lib/std/os/linux/tls.zig @@ -54,7 +54,7 @@ const TLSVariant = enum { const tls_variant = switch (builtin.arch) { .arm, .armeb, .aarch64, .aarch64_be, .riscv32, .riscv64, .mips, .mipsel, .powerpc, .powerpc64, .powerpc64le => TLSVariant.VariantI, - .x86_64, .i386 => TLSVariant.VariantII, + .x86_64, .i386, .sparcv9 => TLSVariant.VariantII, else => @compileError("undefined tls_variant for this architecture"), }; @@ -172,6 +172,13 @@ pub fn setThreadPointer(addr: usize) void { : [addr] "r" (addr) ); }, + .sparcv9 => { + asm volatile ( + \\ mov %[addr], %%g7 + : + : [addr] "r" (addr) + ); + }, else => @compileError("Unsupported architecture"), } } |
