|
|
Message-ID: <20261102170202.24963-2-kaloz@kernel.org>
Date: Mon, 2 Nov 2026 18:02:01 +0100
From: Imre Kaloz <kaloz@...nel.org>
To: musl@...ts.openwall.com
Subject: [PATCH 1/2] add 32-bit sparc (V8) port
The objects are V8 except casa, which is emitted as a word, with its
ASI chosen from AT_HWCAP at startup. PAGESIZE is not defined, since
pages are 4K on V8 hardware and 8K under a 64-bit kernel. The sparc64
hooks are used, except ipc and suseconds_t.
---
arch/sparc/atomic_arch.h | 44 +++
arch/sparc/bits/alltypes.h.in | 18 ++
arch/sparc/bits/errno.h | 134 ++++++++
arch/sparc/bits/fcntl.h | 40 +++
arch/sparc/bits/fenv.h | 17 ++
arch/sparc/bits/float.h | 20 ++
arch/sparc/bits/ioctl.h | 99 ++++++
arch/sparc/bits/ipc.h | 12 +
arch/sparc/bits/ipcstat.h | 1 +
arch/sparc/bits/mman.h | 12 +
arch/sparc/bits/msg.h | 18 ++
arch/sparc/bits/poll.h | 5 +
arch/sparc/bits/resource.h | 5 +
arch/sparc/bits/sem.h | 12 +
arch/sparc/bits/setjmp.h | 1 +
arch/sparc/bits/shm.h | 30 ++
arch/sparc/bits/signal.h | 96 ++++++
arch/sparc/bits/socket.h | 80 +++++
arch/sparc/bits/syscall.h.in | 440 +++++++++++++++++++++++++++
arch/sparc/bits/termios.h | 151 +++++++++
arch/sparc/bits/user.h | 27 ++
arch/sparc/crt_arch.h | 19 ++
arch/sparc/ksigaction.h | 10 +
arch/sparc/kstat.h | 22 ++
arch/sparc/pthread_arch.h | 9 +
arch/sparc/reloc.h | 46 +++
arch/sparc/syscall_arch.h | 132 ++++++++
configure | 7 +
src/fenv/sparc/fenv.c | 58 ++++
src/ldso/sparc/dlsym.s | 8 +
src/math/sparc/q.c | 137 +++++++++
src/setjmp/sparc/longjmp.s | 20 ++
src/setjmp/sparc/setjmp.s | 21 ++
src/signal/sparc/restore.s | 21 ++
src/signal/sparc/sigsetjmp.s | 25 ++
src/thread/sparc/__set_thread_area.c | 19 ++
src/thread/sparc/__unmapself.c | 26 ++
src/thread/sparc/atomics.s | 24 ++
src/thread/sparc/clone.S | 45 +++
src/thread/sparc/syscall_cp.s | 39 +++
src/unistd/sparc/pipe.s | 18 ++
41 files changed, 1968 insertions(+)
create mode 100644 arch/sparc/atomic_arch.h
create mode 100644 arch/sparc/bits/alltypes.h.in
create mode 100644 arch/sparc/bits/errno.h
create mode 100644 arch/sparc/bits/fcntl.h
create mode 100644 arch/sparc/bits/fenv.h
create mode 100644 arch/sparc/bits/float.h
create mode 100644 arch/sparc/bits/ioctl.h
create mode 100644 arch/sparc/bits/ipc.h
create mode 100644 arch/sparc/bits/ipcstat.h
create mode 100644 arch/sparc/bits/mman.h
create mode 100644 arch/sparc/bits/msg.h
create mode 100644 arch/sparc/bits/poll.h
create mode 100644 arch/sparc/bits/resource.h
create mode 100644 arch/sparc/bits/sem.h
create mode 100644 arch/sparc/bits/setjmp.h
create mode 100644 arch/sparc/bits/shm.h
create mode 100644 arch/sparc/bits/signal.h
create mode 100644 arch/sparc/bits/socket.h
create mode 100644 arch/sparc/bits/syscall.h.in
create mode 100644 arch/sparc/bits/termios.h
create mode 100644 arch/sparc/bits/user.h
create mode 100644 arch/sparc/crt_arch.h
create mode 100644 arch/sparc/ksigaction.h
create mode 100644 arch/sparc/kstat.h
create mode 100644 arch/sparc/pthread_arch.h
create mode 100644 arch/sparc/reloc.h
create mode 100644 arch/sparc/syscall_arch.h
create mode 100644 src/fenv/sparc/fenv.c
create mode 100644 src/ldso/sparc/dlsym.s
create mode 100644 src/math/sparc/q.c
create mode 100644 src/setjmp/sparc/longjmp.s
create mode 100644 src/setjmp/sparc/setjmp.s
create mode 100644 src/signal/sparc/restore.s
create mode 100644 src/signal/sparc/sigsetjmp.s
create mode 100644 src/thread/sparc/__set_thread_area.c
create mode 100644 src/thread/sparc/__unmapself.c
create mode 100644 src/thread/sparc/atomics.s
create mode 100644 src/thread/sparc/clone.S
create mode 100644 src/thread/sparc/syscall_cp.s
create mode 100644 src/unistd/sparc/pipe.s
diff --git a/arch/sparc/atomic_arch.h b/arch/sparc/atomic_arch.h
new file mode 100644
index 00000000..b91ac9a3
--- /dev/null
+++ b/arch/sparc/atomic_arch.h
@@ -0,0 +1,44 @@
+extern hidden uintptr_t __a_cas_ptr;
+
+#define a_cas a_cas
+static inline int a_cas(volatile int *p, int t, int s)
+{
+ register volatile int *rp __asm__("o0") = p;
+ register int rt __asm__("o1") = t;
+ register int rs __asm__("o2") = s;
+ __asm__ __volatile__ (
+ "jmpl %3, %%o7\n\t nop"
+ : "+r"(rs)
+ : "r"(rp), "r"(rt), "r"(__a_cas_ptr)
+ : "o7", "memory");
+ return rs;
+}
+
+/* On SMP sun4m a kernel that emulates casa makes it atomic only against
+ * other casa traps and its futex operations, so a native swap, ldstub or
+ * plain store to a shared word can lose an update there. Loop on a_cas
+ * instead of the generic barrier+store+barrier. */
+#define a_store a_store
+static inline void a_store(volatile int *p, int v)
+{
+ int old;
+ do old = *p;
+ while (a_cas(p, old, v) != old);
+}
+
+/* ldstub is a V8 instruction, so it runs natively on every V8 CPU. On a
+ * private stack byte it has no cross-thread contention, and under TSO an
+ * atomic load-store drains the store buffer and orders with its
+ * surroundings, giving a full barrier on both sun4m and LEON. */
+#define a_barrier a_barrier
+static inline void a_barrier()
+{
+ unsigned char x, t;
+ __asm__ __volatile__ ("ldstub [%1], %0" : "=r"(t) : "r"(&x) : "memory");
+}
+
+#define a_crash a_crash
+static inline void a_crash()
+{
+ __asm__ __volatile__ ("unimp 0");
+}
diff --git a/arch/sparc/bits/alltypes.h.in b/arch/sparc/bits/alltypes.h.in
new file mode 100644
index 00000000..c47b7184
--- /dev/null
+++ b/arch/sparc/bits/alltypes.h.in
@@ -0,0 +1,18 @@
+#define _Addr int
+#define _Int64 long long
+#define _Reg int
+
+#define __BYTE_ORDER 4321
+#define __LONG_MAX 0x7fffffffL
+
+#ifndef __cplusplus
+TYPEDEF int wchar_t;
+#endif
+
+TYPEDEF int blksize_t;
+TYPEDEF unsigned int nlink_t;
+
+TYPEDEF float float_t;
+TYPEDEF double double_t;
+
+TYPEDEF struct { long long __ll; long double __ld; } max_align_t;
diff --git a/arch/sparc/bits/errno.h b/arch/sparc/bits/errno.h
new file mode 100644
index 00000000..98dbdd7c
--- /dev/null
+++ b/arch/sparc/bits/errno.h
@@ -0,0 +1,134 @@
+#define EPERM 1
+#define ENOENT 2
+#define ESRCH 3
+#define EINTR 4
+#define EIO 5
+#define ENXIO 6
+#define E2BIG 7
+#define ENOEXEC 8
+#define EBADF 9
+#define ECHILD 10
+#define EAGAIN 11
+#define ENOMEM 12
+#define EACCES 13
+#define EFAULT 14
+#define ENOTBLK 15
+#define EBUSY 16
+#define EEXIST 17
+#define EXDEV 18
+#define ENODEV 19
+#define ENOTDIR 20
+#define EISDIR 21
+#define EINVAL 22
+#define ENFILE 23
+#define EMFILE 24
+#define ENOTTY 25
+#define ETXTBSY 26
+#define EFBIG 27
+#define ENOSPC 28
+#define ESPIPE 29
+#define EROFS 30
+#define EMLINK 31
+#define EPIPE 32
+#define EDOM 33
+#define ERANGE 34
+#define EDEADLK 78
+#define ENAMETOOLONG 63
+#define ENOLCK 79
+#define ENOSYS 90
+#define ENOTEMPTY 66
+#define ELOOP 62
+#define EWOULDBLOCK EAGAIN
+#define ENOMSG 75
+#define EIDRM 77
+#define ECHRNG 94
+#define EL2NSYNC 95
+#define EL3HLT 96
+#define EL3RST 97
+#define ELNRNG 98
+#define EUNATCH 99
+#define ENOCSI 100
+#define EL2HLT 101
+#define EBADE 102
+#define EBADR 103
+#define EXFULL 104
+#define ENOANO 105
+#define EBADRQC 106
+#define EBADSLT 107
+#define EDEADLOCK 108
+#define EBFONT 109
+#define ENOSTR 72
+#define ENODATA 111
+#define ETIME 73
+#define ENOSR 74
+#define ENONET 80
+#define ENOPKG 113
+#define EREMOTE 71
+#define ENOLINK 82
+#define EADV 83
+#define ESRMNT 84
+#define ECOMM 85
+#define EPROTO 86
+#define EMULTIHOP 87
+#define EDOTDOT 88
+#define EBADMSG 76
+#define EOVERFLOW 92
+#define ENOTUNIQ 115
+#define EBADFD 93
+#define EREMCHG 89
+#define ELIBACC 114
+#define ELIBBAD 112
+#define ELIBSCN 124
+#define ELIBMAX 123
+#define ELIBEXEC 110
+#define EILSEQ 122
+#define ERESTART 116
+#define ESTRPIPE 91
+#define EUSERS 68
+#define ENOTSOCK 38
+#define EDESTADDRREQ 39
+#define EMSGSIZE 40
+#define EPROTOTYPE 41
+#define ENOPROTOOPT 42
+#define EPROTONOSUPPORT 43
+#define ESOCKTNOSUPPORT 44
+#define EOPNOTSUPP 45
+#define ENOTSUP EOPNOTSUPP
+#define EPFNOSUPPORT 46
+#define EAFNOSUPPORT 47
+#define EADDRINUSE 48
+#define EADDRNOTAVAIL 49
+#define ENETDOWN 50
+#define ENETUNREACH 51
+#define ENETRESET 52
+#define ECONNABORTED 53
+#define ECONNRESET 54
+#define ENOBUFS 55
+#define EISCONN 56
+#define ENOTCONN 57
+#define ESHUTDOWN 58
+#define ETOOMANYREFS 59
+#define ETIMEDOUT 60
+#define ECONNREFUSED 61
+#define EHOSTDOWN 64
+#define EHOSTUNREACH 65
+#define EALREADY 37
+#define EINPROGRESS 36
+#define ESTALE 70
+#define EUCLEAN 117
+#define ENOTNAM 118
+#define ENAVAIL 119
+#define EISNAM 120
+#define EREMOTEIO 121
+#define EDQUOT 69
+#define ENOMEDIUM 125
+#define EMEDIUMTYPE 126
+#define ECANCELED 127
+#define ENOKEY 128
+#define EKEYEXPIRED 129
+#define EKEYREVOKED 130
+#define EKEYREJECTED 131
+#define EOWNERDEAD 132
+#define ENOTRECOVERABLE 133
+#define ERFKILL 134
+#define EHWPOISON 135
diff --git a/arch/sparc/bits/fcntl.h b/arch/sparc/bits/fcntl.h
new file mode 100644
index 00000000..004e6004
--- /dev/null
+++ b/arch/sparc/bits/fcntl.h
@@ -0,0 +1,40 @@
+#define O_CREAT 01000
+#define O_EXCL 04000
+#define O_NOCTTY 0100000
+#define O_TRUNC 02000
+#define O_APPEND 010
+#define O_NONBLOCK 040000
+#define O_DSYNC 020000
+#define O_SYNC 040020000
+#define O_RSYNC 040020000
+#define O_DIRECTORY 0200000
+#define O_NOFOLLOW 0400000
+#define O_CLOEXEC 020000000
+#define O_ASYNC 0100
+#define O_DIRECT 04000000
+#define O_LARGEFILE 01000000
+#define O_NOATIME 010000000
+#define O_PATH 0100000000
+#define O_TMPFILE 0200200000
+#define F_DUPFD 0
+#define F_GETFD 1
+#define F_SETFD 2
+#define F_GETFL 3
+#define F_SETFL 4
+#define F_SETOWN 6
+#define F_GETOWN 5
+#define F_SETSIG 10
+#define F_GETSIG 11
+
+#define F_GETLK 12
+#define F_SETLK 13
+#define F_SETLKW 14
+#define F_SETOWN_EX 15
+#define F_GETOWN_EX 16
+#define F_GETOWNER_UIDS 17
+
+#define O_NDELAY O_NONBLOCK
+
+#define F_RDLCK 1
+#define F_WRLCK 2
+#define F_UNLCK 3
diff --git a/arch/sparc/bits/fenv.h b/arch/sparc/bits/fenv.h
new file mode 100644
index 00000000..5f411b97
--- /dev/null
+++ b/arch/sparc/bits/fenv.h
@@ -0,0 +1,17 @@
+#define FE_INEXACT 0x020
+#define FE_DIVBYZERO 0x040
+#define FE_UNDERFLOW 0x080
+#define FE_OVERFLOW 0x100
+#define FE_INVALID 0x200
+
+#define FE_ALL_EXCEPT 0x3e0
+
+#define FE_TONEAREST 0
+#define FE_TOWARDZERO 1
+#define FE_UPWARD 2
+#define FE_DOWNWARD 3
+
+typedef unsigned long fexcept_t;
+typedef unsigned long fenv_t;
+
+#define FE_DFL_ENV ((const fenv_t *)-1)
diff --git a/arch/sparc/bits/float.h b/arch/sparc/bits/float.h
new file mode 100644
index 00000000..e188cb61
--- /dev/null
+++ b/arch/sparc/bits/float.h
@@ -0,0 +1,20 @@
+#ifdef __FLT_EVAL_METHOD__
+#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__
+#else
+#define FLT_EVAL_METHOD 0
+#endif
+
+#define LDBL_TRUE_MIN 6.47517511943802511092443895822764655e-4966L
+#define LDBL_MIN 3.36210314311209350626267781732175260e-4932L
+#define LDBL_MAX 1.18973149535723176508575932662800702e+4932L
+#define LDBL_EPSILON 1.92592994438723585305597794258492732e-34L
+
+#define LDBL_MANT_DIG 113
+#define LDBL_MIN_EXP (-16381)
+#define LDBL_MAX_EXP 16384
+
+#define LDBL_DIG 33
+#define LDBL_MIN_10_EXP (-4931)
+#define LDBL_MAX_10_EXP 4932
+
+#define DECIMAL_DIG 36
diff --git a/arch/sparc/bits/ioctl.h b/arch/sparc/bits/ioctl.h
new file mode 100644
index 00000000..bf29ff6e
--- /dev/null
+++ b/arch/sparc/bits/ioctl.h
@@ -0,0 +1,99 @@
+#define _IOC(a,b,c,d) ( ((a)<<29) | ((b)<<8) | (c) | ((d)<<16) )
+#define _IOC_NONE 1U
+#define _IOC_READ 2U
+#define _IOC_WRITE 4U
+
+#define _IO(a,b) _IOC(_IOC_NONE,(a),(b),0)
+#define _IOW(a,b,c) _IOC(_IOC_WRITE,(a),(b),sizeof(c))
+#define _IOR(a,b,c) _IOC(_IOC_READ,(a),(b),sizeof(c))
+#define _IOWR(a,b,c) _IOC(_IOC_READ|_IOC_WRITE,(a),(b),sizeof(c))
+#define TCGETS 0x40245408
+#define TCSETS 0x80245409
+#define TCSETSW 0x8024540a
+#define TCSETSF 0x8024540b
+#define TCGETA 0x40125401
+#define TCSETA 0x80125402
+#define TCSETAW 0x80125403
+#define TCSETAF 0x80125404
+#define TCSBRK 0x20005405
+#define TCXONC 0x20005406
+#define TCFLSH 0x20005407
+#define TIOCEXCL 0x2000740d
+#define TIOCNXCL 0x2000740e
+#define TIOCSCTTY 0x20007484
+#define TIOCGPGRP 0x40047483
+#define TIOCSPGRP 0x80047482
+#define TIOCOUTQ 0x40047473
+#define TIOCSTI 0x80017472
+#define TIOCGWINSZ 0x40087468
+#define TIOCSWINSZ 0x80087467
+#define TIOCMGET 0x4004746a
+#define TIOCMBIS 0x8004746c
+#define TIOCMBIC 0x8004746b
+#define TIOCMSET 0x8004746d
+#define TIOCGSOFTCAR 0x40047464
+#define TIOCSSOFTCAR 0x80047465
+#define FIONREAD 0x4004667f
+#define TIOCLINUX 0x541c
+#define TIOCCONS 0x20007424
+#define TIOCGSERIAL 0x541e
+#define TIOCSSERIAL 0x541f
+#define TIOCPKT 0x80047470
+#define FIONBIO 0x8004667e
+#define TIOCNOTTY 0x20007471
+#define TIOCSETD 0x80047401
+#define TIOCGETD 0x40047400
+#define TCSBRKP 0x5425
+#define TIOCSBRK 0x2000747b
+#define TIOCCBRK 0x2000747a
+#define TIOCGSID 0x40047485
+#define TIOCGRS485 0x40205441
+#define TIOCSRS485 0xc0205442
+#define TIOCGPTN 0x40047486
+#define TIOCSPTLCK 0x80047487
+#define TIOCGDEV 0x40045432
+#define TIOCSIG 0x80047488
+#define TIOCVHANGUP 0x20005437
+#define TIOCGPKT 0x40045438
+#define TIOCGPTLCK 0x40045439
+#define TIOCGEXCL 0x40045440
+#define TIOCGPTPEER 0x20007489
+#define TIOCGISO7816 0x40285443
+#define TIOCSISO7816 0xc0285444
+#define FIONCLEX 0x20006602
+#define FIOCLEX 0x20006601
+#define FIOASYNC 0x8004667d
+#define TIOCSERCONFIG 0x5453
+#define TIOCSERGWILD 0x5454
+#define TIOCSERSWILD 0x5455
+#define TIOCGLCKTRMIOS 0x5456
+#define TIOCSLCKTRMIOS 0x5457
+#define TIOCSERGSTRUCT 0x5458
+#define TIOCSERGETLSR 0x5459
+#define TIOCSERGETMULTI 0x545a
+#define TIOCSERSETMULTI 0x545b
+#define TIOCMIWAIT 0x545c
+#define TIOCGICOUNT 0x545d
+#define FIOQSIZE 0x40086680
+#define TIOCM_LE 0x1
+#define TIOCM_DTR 0x2
+#define TIOCM_RTS 0x4
+#define TIOCM_ST 0x8
+#define TIOCM_SR 0x10
+#define TIOCM_CTS 0x20
+#define TIOCM_CAR 0x40
+#define TIOCM_RNG 0x80
+#define TIOCM_DSR 0x100
+#define TIOCM_OUT1 0x2000
+#define TIOCM_OUT2 0x4000
+#define TIOCM_LOOP 0x8000
+#define FIOSETOWN 0x8901
+#define SIOCSPGRP 0x8902
+#define FIOGETOWN 0x8903
+#define SIOCGPGRP 0x8904
+#define SIOCATMARK 0x8905
+#define SIOCGSTAMP _IOR(0x89, 6, char[16])
+#define SIOCGSTAMPNS _IOR(0x89, 7, char[16])
+#define TIOCINQ FIONREAD
+#define TIOCM_CD TIOCM_CAR
+#define TIOCM_RI TIOCM_RNG
diff --git a/arch/sparc/bits/ipc.h b/arch/sparc/bits/ipc.h
new file mode 100644
index 00000000..a388d56b
--- /dev/null
+++ b/arch/sparc/bits/ipc.h
@@ -0,0 +1,12 @@
+struct ipc_perm {
+ key_t __ipc_perm_key;
+ uid_t uid;
+ gid_t gid;
+ uid_t cuid;
+ gid_t cgid;
+ mode_t mode;
+ int __ipc_perm_seq;
+ int __pad1;
+ long long __pad2;
+ long long __pad3;
+};
diff --git a/arch/sparc/bits/ipcstat.h b/arch/sparc/bits/ipcstat.h
new file mode 100644
index 00000000..4f4fcb0c
--- /dev/null
+++ b/arch/sparc/bits/ipcstat.h
@@ -0,0 +1 @@
+#define IPC_STAT 0x102
diff --git a/arch/sparc/bits/mman.h b/arch/sparc/bits/mman.h
new file mode 100644
index 00000000..588d041b
--- /dev/null
+++ b/arch/sparc/bits/mman.h
@@ -0,0 +1,12 @@
+#undef MAP_GROWSDOWN
+#define MAP_GROWSDOWN 0x200
+#undef MAP_LOCKED
+#define MAP_LOCKED 0x100
+#undef MAP_NORESERVE
+#define MAP_NORESERVE 0x40
+#undef MCL_CURRENT
+#define MCL_CURRENT 0x2000
+#undef MCL_FUTURE
+#define MCL_FUTURE 0x4000
+#undef MCL_ONFAULT
+#define MCL_ONFAULT 0x8000
diff --git a/arch/sparc/bits/msg.h b/arch/sparc/bits/msg.h
new file mode 100644
index 00000000..9fb15dcc
--- /dev/null
+++ b/arch/sparc/bits/msg.h
@@ -0,0 +1,18 @@
+struct msqid_ds {
+ struct ipc_perm msg_perm;
+ unsigned long __msg_stime_hi;
+ unsigned long __msg_stime_lo;
+ unsigned long __msg_rtime_hi;
+ unsigned long __msg_rtime_lo;
+ unsigned long __msg_ctime_hi;
+ unsigned long __msg_ctime_lo;
+ unsigned long msg_cbytes;
+ msgqnum_t msg_qnum;
+ msglen_t msg_qbytes;
+ pid_t msg_lspid;
+ pid_t msg_lrpid;
+ unsigned long __unused[2];
+ time_t msg_stime;
+ time_t msg_rtime;
+ time_t msg_ctime;
+};
diff --git a/arch/sparc/bits/poll.h b/arch/sparc/bits/poll.h
new file mode 100644
index 00000000..d9952334
--- /dev/null
+++ b/arch/sparc/bits/poll.h
@@ -0,0 +1,5 @@
+#define POLLWRNORM 4
+#define POLLWRBAND 256
+
+#define POLLMSG 512
+#define POLLRDHUP 2048
diff --git a/arch/sparc/bits/resource.h b/arch/sparc/bits/resource.h
new file mode 100644
index 00000000..6623b5e6
--- /dev/null
+++ b/arch/sparc/bits/resource.h
@@ -0,0 +1,5 @@
+#define RLIMIT_RSS 5
+#define RLIMIT_NPROC 7
+#define RLIMIT_NOFILE 6
+#define RLIMIT_MEMLOCK 8
+#define RLIMIT_AS 9
diff --git a/arch/sparc/bits/sem.h b/arch/sparc/bits/sem.h
new file mode 100644
index 00000000..28be4845
--- /dev/null
+++ b/arch/sparc/bits/sem.h
@@ -0,0 +1,12 @@
+struct semid_ds {
+ struct ipc_perm sem_perm;
+ unsigned long __sem_otime_hi;
+ unsigned long __sem_otime_lo;
+ unsigned long __sem_ctime_hi;
+ unsigned long __sem_ctime_lo;
+ unsigned short __sem_nsems_pad, sem_nsems;
+ long __unused3;
+ long __unused4;
+ time_t sem_otime;
+ time_t sem_ctime;
+};
diff --git a/arch/sparc/bits/setjmp.h b/arch/sparc/bits/setjmp.h
new file mode 100644
index 00000000..dae9bc16
--- /dev/null
+++ b/arch/sparc/bits/setjmp.h
@@ -0,0 +1 @@
+typedef unsigned long __jmp_buf[3];
diff --git a/arch/sparc/bits/shm.h b/arch/sparc/bits/shm.h
new file mode 100644
index 00000000..4ce8b6dc
--- /dev/null
+++ b/arch/sparc/bits/shm.h
@@ -0,0 +1,30 @@
+#define SHMLBA 262144
+
+struct shmid_ds {
+ struct ipc_perm shm_perm;
+ unsigned long __shm_atime_hi;
+ unsigned long __shm_atime_lo;
+ unsigned long __shm_dtime_hi;
+ unsigned long __shm_dtime_lo;
+ unsigned long __shm_ctime_hi;
+ unsigned long __shm_ctime_lo;
+ size_t shm_segsz;
+ pid_t shm_cpid;
+ pid_t shm_lpid;
+ unsigned long shm_nattch;
+ unsigned long __pad1;
+ unsigned long __pad2;
+ time_t shm_atime;
+ time_t shm_dtime;
+ time_t shm_ctime;
+};
+
+struct shminfo {
+ unsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];
+};
+
+struct shm_info {
+ int __used_ids;
+ unsigned long shm_tot, shm_rss, shm_swp;
+ unsigned long __swap_attempts, __swap_successes;
+};
diff --git a/arch/sparc/bits/signal.h b/arch/sparc/bits/signal.h
new file mode 100644
index 00000000..6bca9c3b
--- /dev/null
+++ b/arch/sparc/bits/signal.h
@@ -0,0 +1,96 @@
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define MINSIGSTKSZ 4096
+#define SIGSTKSZ 16384
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+typedef struct {
+ unsigned long mc_psr;
+ unsigned long mc_pc;
+ unsigned long mc_npc;
+ unsigned long mc_y;
+ unsigned long mc_gregs[16];
+} mcontext_t;
+#else
+
+typedef struct {
+ unsigned long __regs[20];
+} mcontext_t;
+#endif
+
+struct sigaltstack {
+ void *ss_sp;
+ int ss_flags;
+ size_t ss_size;
+};
+
+/* an SA_SIGINFO handler's ucontext is &rt_signal_frame.regs, so mcontext_t
+ * overlays struct pt_regs and uc_sigmask is the frame's mask at offset 80.
+ * Only its first 8 bytes are in the frame, so a handler changes it with
+ * sigaddset or sigdelset, never by assignment. The members after
+ * uc_sigmask are not filled in by signal delivery. */
+typedef struct __ucontext {
+ mcontext_t uc_mcontext;
+ sigset_t uc_sigmask;
+ unsigned long uc_flags;
+ struct __ucontext *uc_link;
+ stack_t uc_stack;
+} ucontext_t;
+
+#define SA_NOCLDSTOP 0x8U
+#define SA_NOCLDWAIT 0x100U
+#define SA_SIGINFO 0x200U
+#define SA_ONSTACK 0x1U
+#define SA_RESTART 0x2U
+#define SA_NODEFER 0x20U
+#define SA_RESETHAND 0x4U
+
+#endif
+
+#undef SIG_BLOCK
+#define SIG_BLOCK 1
+#undef SIG_UNBLOCK
+#define SIG_UNBLOCK 2
+#undef SIG_SETMASK
+#define SIG_SETMASK 4
+
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGEMT 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGBUS 10
+#define SIGSEGV 11
+#define SIGSYS 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGURG 16
+#define SIGSTOP 17
+#define SIGTSTP 18
+#define SIGCONT 19
+#define SIGCHLD 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGIO 23
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGLOST 29
+#define SIGUSR1 30
+#define SIGUSR2 31
+#define SIGIOT SIGABRT
+#define SIGPOLL SIGIO
+#define SIGPWR SIGLOST
+
+#define _NSIG 65
diff --git a/arch/sparc/bits/socket.h b/arch/sparc/bits/socket.h
new file mode 100644
index 00000000..6143b9ce
--- /dev/null
+++ b/arch/sparc/bits/socket.h
@@ -0,0 +1,80 @@
+#define SOCK_CLOEXEC 4194304
+#define SOCK_NONBLOCK 16384
+
+#define SO_DEBUG 1
+#define SO_REUSEADDR 4
+#define SO_TYPE 4104
+#define SO_ERROR 4103
+#define SO_DONTROUTE 16
+#define SO_BROADCAST 32
+#define SO_SNDBUF 4097
+#define SO_RCVBUF 4098
+#define SO_KEEPALIVE 8
+#define SO_OOBINLINE 256
+#define SO_NO_CHECK 11
+#define SO_PRIORITY 12
+#define SO_LINGER 128
+#define SO_BSDCOMPAT 1024
+#define SO_REUSEPORT 512
+#define SO_PASSCRED 2
+#define SO_PEERCRED 64
+#define SO_RCVLOWAT 2048
+#define SO_SNDLOWAT 4096
+#define SO_ACCEPTCONN 32768
+#define SO_PEERSEC 30
+#define SO_SNDBUFFORCE 4106
+#define SO_RCVBUFFORCE 4107
+#define SO_PROTOCOL 4136
+#define SO_DOMAIN 4137
+
+#define SO_RCVTIMEO 68
+#define SO_SNDTIMEO 69
+
+#define SO_TIMESTAMP 70
+#define SO_TIMESTAMPNS 66
+#define SO_TIMESTAMPING 67
+
+#define SO_SECURITY_AUTHENTICATION 20481
+#define SO_SECURITY_ENCRYPTION_TRANSPORT 20482
+#define SO_SECURITY_ENCRYPTION_NETWORK 20484
+#define SO_BINDTODEVICE 13
+#define SO_ATTACH_FILTER 26
+#define SO_DETACH_FILTER 27
+#define SO_GET_FILTER SO_ATTACH_FILTER
+#define SO_PEERNAME 28
+#define SCM_TIMESTAMP SO_TIMESTAMP
+#define SO_PASSSEC 31
+#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+#define SO_MARK 34
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+#define SO_RXQ_OVFL 36
+#define SO_WIFI_STATUS 37
+#define SCM_WIFI_STATUS SO_WIFI_STATUS
+#define SO_PEEK_OFF 38
+#define SO_NOFCS 39
+#define SO_LOCK_FILTER 40
+#define SO_SELECT_ERR_QUEUE 41
+#define SO_BUSY_POLL 48
+#define SO_MAX_PACING_RATE 49
+#define SO_BPF_EXTENSIONS 50
+#define SO_INCOMING_CPU 51
+#define SO_ATTACH_BPF 52
+#define SO_DETACH_BPF SO_DETACH_FILTER
+#define SO_ATTACH_REUSEPORT_CBPF 53
+#define SO_ATTACH_REUSEPORT_EBPF 54
+#define SO_CNX_ADVICE 55
+#define SCM_TIMESTAMPING_OPT_STATS 56
+#define SO_MEMINFO 57
+#define SO_INCOMING_NAPI_ID 58
+#define SO_COOKIE 59
+#define SCM_TIMESTAMPING_PKTINFO 60
+#define SO_PEERGROUPS 61
+#define SO_ZEROCOPY 62
+#define SO_TXTIME 63
+#define SCM_TXTIME SO_TXTIME
+#define SO_BINDTOIFINDEX 65
+#define SO_DETACH_REUSEPORT_BPF 71
+#define SO_PREFER_BUSY_POLL 72
+#define SO_BUSY_POLL_BUDGET 73
+
+#define SOL_SOCKET 65535
diff --git a/arch/sparc/bits/syscall.h.in b/arch/sparc/bits/syscall.h.in
new file mode 100644
index 00000000..16852437
--- /dev/null
+++ b/arch/sparc/bits/syscall.h.in
@@ -0,0 +1,440 @@
+#define __NR_restart_syscall 0
+#define __NR_exit 1
+#define __NR_fork 2
+#define __NR_read 3
+#define __NR_write 4
+#define __NR_open 5
+#define __NR_close 6
+#define __NR_wait4 7
+#define __NR_creat 8
+#define __NR_link 9
+#define __NR_unlink 10
+#define __NR_execv 11
+#define __NR_chdir 12
+#define __NR_chown 13
+#define __NR_mknod 14
+#define __NR_chmod 15
+#define __NR_lchown 16
+#define __NR_brk 17
+#define __NR_perfctr 18
+#define __NR_lseek 19
+#define __NR_getpid 20
+#define __NR_capget 21
+#define __NR_capset 22
+#define __NR_setuid 23
+#define __NR_getuid 24
+#define __NR_vmsplice 25
+#define __NR_ptrace 26
+#define __NR_alarm 27
+#define __NR_sigaltstack 28
+#define __NR_pause 29
+#define __NR_utime 30
+#define __NR_lchown32 31
+#define __NR_fchown32 32
+#define __NR_access 33
+#define __NR_nice 34
+#define __NR_chown32 35
+#define __NR_sync 36
+#define __NR_kill 37
+#define __NR_stat 38
+#define __NR_sendfile 39
+#define __NR_lstat 40
+#define __NR_dup 41
+#define __NR_pipe 42
+#define __NR_times 43
+#define __NR_getuid32 44
+#define __NR_umount2 45
+#define __NR_setgid 46
+#define __NR_getgid 47
+#define __NR_signal 48
+#define __NR_geteuid 49
+#define __NR_getegid 50
+#define __NR_acct 51
+#define __NR_getgid32 53
+#define __NR_ioctl 54
+#define __NR_reboot 55
+#define __NR_mmap2 56
+#define __NR_symlink 57
+#define __NR_readlink 58
+#define __NR_execve 59
+#define __NR_umask 60
+#define __NR_chroot 61
+#define __NR_fstat 62
+#define __NR_fstat64 63
+#define __NR_getpagesize 64
+#define __NR_msync 65
+#define __NR_vfork 66
+#define __NR_pread64 67
+#define __NR_pwrite64 68
+#define __NR_geteuid32 69
+#define __NR_getegid32 70
+#define __NR_mmap 71
+#define __NR_setreuid32 72
+#define __NR_munmap 73
+#define __NR_mprotect 74
+#define __NR_madvise 75
+#define __NR_vhangup 76
+#define __NR_truncate64 77
+#define __NR_mincore 78
+#define __NR_getgroups 79
+#define __NR_setgroups 80
+#define __NR_getpgrp 81
+#define __NR_setgroups32 82
+#define __NR_setitimer 83
+#define __NR_ftruncate64 84
+#define __NR_swapon 85
+#define __NR_getitimer 86
+#define __NR_setuid32 87
+#define __NR_sethostname 88
+#define __NR_setgid32 89
+#define __NR_dup2 90
+#define __NR_setfsuid32 91
+#define __NR_fcntl 92
+#define __NR_select 93
+#define __NR_setfsgid32 94
+#define __NR_fsync 95
+#define __NR_setpriority 96
+#define __NR_socket 97
+#define __NR_connect 98
+#define __NR_accept 99
+#define __NR_getpriority 100
+#define __NR_rt_sigreturn 101
+#define __NR_rt_sigaction 102
+#define __NR_rt_sigprocmask 103
+#define __NR_rt_sigpending 104
+#define __NR_rt_sigtimedwait 105
+#define __NR_rt_sigqueueinfo 106
+#define __NR_rt_sigsuspend 107
+#define __NR_setresuid32 108
+#define __NR_getresuid32 109
+#define __NR_setresgid32 110
+#define __NR_getresgid32 111
+#define __NR_setregid32 112
+#define __NR_recvmsg 113
+#define __NR_sendmsg 114
+#define __NR_getgroups32 115
+#define __NR_gettimeofday 116
+#define __NR_getrusage 117
+#define __NR_getsockopt 118
+#define __NR_getcwd 119
+#define __NR_readv 120
+#define __NR_writev 121
+#define __NR_settimeofday 122
+#define __NR_fchown 123
+#define __NR_fchmod 124
+#define __NR_recvfrom 125
+#define __NR_setreuid 126
+#define __NR_setregid 127
+#define __NR_rename 128
+#define __NR_truncate 129
+#define __NR_ftruncate 130
+#define __NR_flock 131
+#define __NR_lstat64 132
+#define __NR_sendto 133
+#define __NR_shutdown 134
+#define __NR_socketpair 135
+#define __NR_mkdir 136
+#define __NR_rmdir 137
+#define __NR_utimes 138
+#define __NR_stat64 139
+#define __NR_sendfile64 140
+#define __NR_getpeername 141
+#define __NR_futex 142
+#define __NR_gettid 143
+#define __NR_getrlimit 144
+#define __NR_setrlimit 145
+#define __NR_pivot_root 146
+#define __NR_prctl 147
+#define __NR_pciconfig_read 148
+#define __NR_pciconfig_write 149
+#define __NR_getsockname 150
+#define __NR_inotify_init 151
+#define __NR_inotify_add_watch 152
+#define __NR_poll 153
+#define __NR_getdents64 154
+#define __NR_fcntl64 155
+#define __NR_inotify_rm_watch 156
+#define __NR_statfs 157
+#define __NR_fstatfs 158
+#define __NR_umount 159
+#define __NR_sched_set_affinity 160
+#define __NR_sched_get_affinity 161
+#define __NR_getdomainname 162
+#define __NR_setdomainname 163
+#define __NR_quotactl 165
+#define __NR_set_tid_address 166
+#define __NR_mount 167
+#define __NR_ustat 168
+#define __NR_setxattr 169
+#define __NR_lsetxattr 170
+#define __NR_fsetxattr 171
+#define __NR_getxattr 172
+#define __NR_lgetxattr 173
+#define __NR_getdents 174
+#define __NR_setsid 175
+#define __NR_fchdir 176
+#define __NR_fgetxattr 177
+#define __NR_listxattr 178
+#define __NR_llistxattr 179
+#define __NR_flistxattr 180
+#define __NR_removexattr 181
+#define __NR_lremovexattr 182
+#define __NR_sigpending 183
+#define __NR_query_module 184
+#define __NR_setpgid 185
+#define __NR_fremovexattr 186
+#define __NR_tkill 187
+#define __NR_exit_group 188
+#define __NR_uname 189
+#define __NR_init_module 190
+#define __NR_personality 191
+#define __NR_remap_file_pages 192
+#define __NR_epoll_create 193
+#define __NR_epoll_ctl 194
+#define __NR_epoll_wait 195
+#define __NR_ioprio_set 196
+#define __NR_getppid 197
+#define __NR_sigaction 198
+#define __NR_sgetmask 199
+#define __NR_ssetmask 200
+#define __NR_sigsuspend 201
+#define __NR_oldlstat 202
+#define __NR_uselib 203
+#define __NR_readdir 204
+#define __NR_readahead 205
+#define __NR_socketcall 206
+#define __NR_syslog 207
+#define __NR_lookup_dcookie 208
+#define __NR_fadvise64 209
+#define __NR_fadvise64_64 210
+#define __NR_tgkill 211
+#define __NR_waitpid 212
+#define __NR_swapoff 213
+#define __NR_sysinfo 214
+#define __NR_ipc 215
+#define __NR_sigreturn 216
+#define __NR_clone 217
+#define __NR_ioprio_get 218
+#define __NR_adjtimex 219
+#define __NR_sigprocmask 220
+#define __NR_create_module 221
+#define __NR_delete_module 222
+#define __NR_get_kernel_syms 223
+#define __NR_getpgid 224
+#define __NR_bdflush 225
+#define __NR_sysfs 226
+#define __NR_afs_syscall 227
+#define __NR_setfsuid 228
+#define __NR_setfsgid 229
+#define __NR__newselect 230
+#define __NR_time 231
+#define __NR_splice 232
+#define __NR_stime 233
+#define __NR_statfs64 234
+#define __NR_fstatfs64 235
+#define __NR__llseek 236
+#define __NR_mlock 237
+#define __NR_munlock 238
+#define __NR_mlockall 239
+#define __NR_munlockall 240
+#define __NR_sched_setparam 241
+#define __NR_sched_getparam 242
+#define __NR_sched_setscheduler 243
+#define __NR_sched_getscheduler 244
+#define __NR_sched_yield 245
+#define __NR_sched_get_priority_max 246
+#define __NR_sched_get_priority_min 247
+#define __NR_sched_rr_get_interval 248
+#define __NR_nanosleep 249
+#define __NR_mremap 250
+#define __NR__sysctl 251
+#define __NR_getsid 252
+#define __NR_fdatasync 253
+#define __NR_nfsservctl 254
+#define __NR_sync_file_range 255
+#define __NR_clock_settime 256
+#define __NR_clock_gettime 257
+#define __NR_clock_getres 258
+#define __NR_clock_nanosleep 259
+#define __NR_sched_getaffinity 260
+#define __NR_sched_setaffinity 261
+#define __NR_timer_settime 262
+#define __NR_timer_gettime 263
+#define __NR_timer_getoverrun 264
+#define __NR_timer_delete 265
+#define __NR_timer_create 266
+#define __NR_vserver 267
+#define __NR_io_setup 268
+#define __NR_io_destroy 269
+#define __NR_io_submit 270
+#define __NR_io_cancel 271
+#define __NR_io_getevents 272
+#define __NR_mq_open 273
+#define __NR_mq_unlink 274
+#define __NR_mq_timedsend 275
+#define __NR_mq_timedreceive 276
+#define __NR_mq_notify 277
+#define __NR_mq_getsetattr 278
+#define __NR_waitid 279
+#define __NR_tee 280
+#define __NR_add_key 281
+#define __NR_request_key 282
+#define __NR_keyctl 283
+#define __NR_openat 284
+#define __NR_mkdirat 285
+#define __NR_mknodat 286
+#define __NR_fchownat 287
+#define __NR_futimesat 288
+#define __NR_fstatat64 289
+#define __NR_unlinkat 290
+#define __NR_renameat 291
+#define __NR_linkat 292
+#define __NR_symlinkat 293
+#define __NR_readlinkat 294
+#define __NR_fchmodat 295
+#define __NR_faccessat 296
+#define __NR_pselect6 297
+#define __NR_ppoll 298
+#define __NR_unshare 299
+#define __NR_set_robust_list 300
+#define __NR_get_robust_list 301
+#define __NR_migrate_pages 302
+#define __NR_mbind 303
+#define __NR_get_mempolicy 304
+#define __NR_set_mempolicy 305
+#define __NR_kexec_load 306
+#define __NR_move_pages 307
+#define __NR_getcpu 308
+#define __NR_epoll_pwait 309
+#define __NR_utimensat 310
+#define __NR_signalfd 311
+#define __NR_timerfd_create 312
+#define __NR_eventfd 313
+#define __NR_fallocate 314
+#define __NR_timerfd_settime 315
+#define __NR_timerfd_gettime 316
+#define __NR_signalfd4 317
+#define __NR_eventfd2 318
+#define __NR_epoll_create1 319
+#define __NR_dup3 320
+#define __NR_pipe2 321
+#define __NR_inotify_init1 322
+#define __NR_accept4 323
+#define __NR_preadv 324
+#define __NR_pwritev 325
+#define __NR_rt_tgsigqueueinfo 326
+#define __NR_perf_event_open 327
+#define __NR_recvmmsg 328
+#define __NR_fanotify_init 329
+#define __NR_fanotify_mark 330
+#define __NR_prlimit64 331
+#define __NR_name_to_handle_at 332
+#define __NR_open_by_handle_at 333
+#define __NR_clock_adjtime 334
+#define __NR_syncfs 335
+#define __NR_sendmmsg 336
+#define __NR_setns 337
+#define __NR_process_vm_readv 338
+#define __NR_process_vm_writev 339
+#define __NR_kern_features 340
+#define __NR_kcmp 341
+#define __NR_finit_module 342
+#define __NR_sched_setattr 343
+#define __NR_sched_getattr 344
+#define __NR_renameat2 345
+#define __NR_seccomp 346
+#define __NR_getrandom 347
+#define __NR_memfd_create 348
+#define __NR_bpf 349
+#define __NR_execveat 350
+#define __NR_membarrier 351
+#define __NR_userfaultfd 352
+#define __NR_bind 353
+#define __NR_listen 354
+#define __NR_setsockopt 355
+#define __NR_mlock2 356
+#define __NR_copy_file_range 357
+#define __NR_preadv2 358
+#define __NR_pwritev2 359
+#define __NR_statx 360
+#define __NR_io_pgetevents 361
+#define __NR_pkey_mprotect 362
+#define __NR_pkey_alloc 363
+#define __NR_pkey_free 364
+#define __NR_rseq 365
+#define __NR_semget 393
+#define __NR_semctl 394
+#define __NR_shmget 395
+#define __NR_shmctl 396
+#define __NR_shmat 397
+#define __NR_shmdt 398
+#define __NR_msgget 399
+#define __NR_msgsnd 400
+#define __NR_msgrcv 401
+#define __NR_msgctl 402
+#define __NR_clock_gettime64 403
+#define __NR_clock_settime64 404
+#define __NR_clock_adjtime64 405
+#define __NR_clock_getres_time64 406
+#define __NR_clock_nanosleep_time64 407
+#define __NR_timer_gettime64 408
+#define __NR_timer_settime64 409
+#define __NR_timerfd_gettime64 410
+#define __NR_timerfd_settime64 411
+#define __NR_utimensat_time64 412
+#define __NR_pselect6_time64 413
+#define __NR_ppoll_time64 414
+#define __NR_io_pgetevents_time64 416
+#define __NR_recvmmsg_time64 417
+#define __NR_mq_timedsend_time64 418
+#define __NR_mq_timedreceive_time64 419
+#define __NR_semtimedop_time64 420
+#define __NR_rt_sigtimedwait_time64 421
+#define __NR_futex_time64 422
+#define __NR_sched_rr_get_interval_time64 423
+#define __NR_pidfd_send_signal 424
+#define __NR_io_uring_setup 425
+#define __NR_io_uring_enter 426
+#define __NR_io_uring_register 427
+#define __NR_open_tree 428
+#define __NR_move_mount 429
+#define __NR_fsopen 430
+#define __NR_fsconfig 431
+#define __NR_fsmount 432
+#define __NR_fspick 433
+#define __NR_pidfd_open 434
+#define __NR_clone3 435
+#define __NR_close_range 436
+#define __NR_openat2 437
+#define __NR_pidfd_getfd 438
+#define __NR_faccessat2 439
+#define __NR_process_madvise 440
+#define __NR_epoll_pwait2 441
+#define __NR_mount_setattr 442
+#define __NR_quotactl_fd 443
+#define __NR_landlock_create_ruleset 444
+#define __NR_landlock_add_rule 445
+#define __NR_landlock_restrict_self 446
+#define __NR_process_mrelease 448
+#define __NR_futex_waitv 449
+#define __NR_set_mempolicy_home_node 450
+#define __NR_cachestat 451
+#define __NR_fchmodat2 452
+#define __NR_map_shadow_stack 453
+#define __NR_futex_wake 454
+#define __NR_futex_wait 455
+#define __NR_futex_requeue 456
+#define __NR_statmount 457
+#define __NR_listmount 458
+#define __NR_lsm_get_self_attr 459
+#define __NR_lsm_set_self_attr 460
+#define __NR_lsm_list_modules 461
+#define __NR_mseal 462
+#define __NR_setxattrat 463
+#define __NR_getxattrat 464
+#define __NR_listxattrat 465
+#define __NR_removexattrat 466
+#define __NR_open_tree_attr 467
+#define __NR_file_getattr 468
+#define __NR_file_setattr 469
+#define __NR_listns 470
diff --git a/arch/sparc/bits/termios.h b/arch/sparc/bits/termios.h
new file mode 100644
index 00000000..6bdad4a2
--- /dev/null
+++ b/arch/sparc/bits/termios.h
@@ -0,0 +1,151 @@
+#undef NCCS
+#define NCCS 17
+struct termios {
+ tcflag_t c_iflag;
+ tcflag_t c_oflag;
+ tcflag_t c_cflag;
+ tcflag_t c_lflag;
+ cc_t c_line;
+ cc_t c_cc[NCCS];
+ speed_t __c_ispeed;
+ speed_t __c_ospeed;
+};
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 4
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VDSUSP 11
+#define VEOL 5
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 6
+#define IGNBRK 1
+#define BRKINT 2
+#define IGNPAR 4
+#define PARMRK 8
+#define INPCK 16
+#define ISTRIP 32
+#define INLCR 64
+#define IGNCR 128
+#define ICRNL 256
+#define IUCLC 512
+#define IXON 1024
+#define IXANY 2048
+#define IXOFF 4096
+#define IMAXBEL 8192
+#define IUTF8 16384
+#define OPOST 1
+#define OLCUC 2
+#define ONLCR 4
+#define OCRNL 8
+#define ONOCR 16
+#define ONLRET 32
+#define OFILL 64
+#define OFDEL 128
+#define NLDLY 256
+#define NL0 0
+#define NL1 256
+#define CRDLY 1536
+#define CR0 0
+#define CR1 512
+#define CR2 1024
+#define CR3 1536
+#define TABDLY 6144
+#define TAB0 0
+#define TAB1 2048
+#define TAB2 4096
+#define TAB3 6144
+#define BSDLY 8192
+#define BS0 0
+#define BS1 8192
+#define FFDLY 32768
+#define FF0 0
+#define FF1 32768
+#define VTDLY 16384
+#define VT0 0
+#define VT1 16384
+#define B0 0
+#define B50 1
+#define B75 2
+#define B110 3
+#define B134 4
+#define B150 5
+#define B200 6
+#define B300 7
+#define B600 8
+#define B1200 9
+#define B1800 10
+#define B2400 11
+#define B4800 12
+#define B9600 13
+#define B19200 14
+#define B38400 15
+#define B57600 4097
+#define B76800 4101
+#define B115200 4098
+#define B153600 4102
+#define B230400 4099
+#define B307200 4103
+#define B460800 4100
+#define B500000 4106
+#define B576000 4107
+#define B614400 4104
+#define B921600 4105
+#define B1000000 4108
+#define B1152000 4109
+#define B1500000 4110
+#define B2000000 4111
+#define CSIZE 48
+#define CS5 0
+#define CS6 16
+#define CS7 32
+#define CS8 48
+#define CSTOPB 64
+#define CREAD 128
+#define PARENB 256
+#define PARODD 512
+#define HUPCL 1024
+#define CLOCAL 2048
+#define ISIG 1
+#define ICANON 2
+#define ECHO 8
+#define ECHOE 16
+#define ECHOK 32
+#define ECHONL 64
+#define NOFLSH 128
+#define TOSTOP 256
+#define IEXTEN 32768
+#define TCOOFF 0
+#define TCOON 1
+#define TCIOFF 2
+#define TCION 3
+#define TCIFLUSH 0
+#define TCOFLUSH 1
+#define TCIOFLUSH 2
+#define TCSANOW 0
+#define TCSADRAIN 1
+#define TCSAFLUSH 2
+#define EXTA 14
+#define EXTB 15
+#define CBAUD 4111
+#define CBAUDEX 4096
+#define CIBAUD 269418496
+#define CMSPAR 1073741824
+#define CRTSCTS 2147483648
+#define XCASE 4
+#define ECHOCTL 512
+#define ECHOPRT 1024
+#define ECHOKE 2048
+#define FLUSHO 8192
+#define PENDIN 16384
+#define EXTPROC 65536
+#define XTABS 6144
diff --git a/arch/sparc/bits/user.h b/arch/sparc/bits/user.h
new file mode 100644
index 00000000..14877ea1
--- /dev/null
+++ b/arch/sparc/bits/user.h
@@ -0,0 +1,27 @@
+struct user {
+ struct {
+ unsigned long psr, pc, npc, y;
+ unsigned long u_regs[16];
+ } regs;
+ unsigned long u_tsize, u_dsize, u_ssize;
+ unsigned long start_code, start_data, start_stack;
+ long signal;
+ void *u_ar0;
+ unsigned long magic;
+ char u_comm[32];
+};
+
+#define ELF_NGREG 38
+typedef unsigned long elf_greg_t, elf_gregset_t[ELF_NGREG];
+typedef struct {
+ union {
+ unsigned long pr_regs[32];
+ double pr_dregs[16];
+ } pr_fr;
+ unsigned long __unused;
+ unsigned long pr_fsr;
+ unsigned char pr_qcnt;
+ unsigned char pr_q_entrysize;
+ unsigned char pr_en;
+ unsigned int pr_q[64];
+} elf_fpregset_t;
diff --git a/arch/sparc/crt_arch.h b/arch/sparc/crt_arch.h
new file mode 100644
index 00000000..5867e94d
--- /dev/null
+++ b/arch/sparc/crt_arch.h
@@ -0,0 +1,19 @@
+__asm__(
+".text\n"
+".global " START "\n"
+".type " START ",#function\n"
+START ":\n"
+" mov %g0, %fp\n"
+" call 1f\n"
+" nop\n"
+"1: add %o7, 8, %g1\n"
+" ld [%g1 + (2f - 1b)], %o1\n"
+" add %g1, %o1, %o1\n"
+" call " START "_c\n"
+" add %sp, 64, %o0\n"
+" unimp\n"
+" .align 4\n"
+".weak _DYNAMIC\n"
+".hidden _DYNAMIC\n"
+"2: .word _DYNAMIC - 1b\n"
+);
diff --git a/arch/sparc/ksigaction.h b/arch/sparc/ksigaction.h
new file mode 100644
index 00000000..ba21964c
--- /dev/null
+++ b/arch/sparc/ksigaction.h
@@ -0,0 +1,10 @@
+#include <features.h>
+
+struct k_sigaction {
+ void (*handler)(int);
+ unsigned long flags;
+ void (*restorer)(void);
+ unsigned mask[2];
+};
+
+hidden void __restore(), __restore_rt();
diff --git a/arch/sparc/kstat.h b/arch/sparc/kstat.h
new file mode 100644
index 00000000..00cad3e8
--- /dev/null
+++ b/arch/sparc/kstat.h
@@ -0,0 +1,22 @@
+struct kstat {
+ unsigned long long st_dev;
+ unsigned long long st_ino;
+ unsigned st_mode;
+ unsigned st_nlink;
+ unsigned st_uid;
+ unsigned st_gid;
+ unsigned long long st_rdev;
+ unsigned char __pad3[8];
+ long long st_size;
+ unsigned st_blksize;
+ unsigned char __pad4[8];
+ unsigned st_blocks;
+ unsigned st_atime_sec;
+ unsigned st_atime_nsec;
+ unsigned st_mtime_sec;
+ unsigned st_mtime_nsec;
+ unsigned st_ctime_sec;
+ unsigned st_ctime_nsec;
+ unsigned __unused4;
+ unsigned __unused5;
+};
diff --git a/arch/sparc/pthread_arch.h b/arch/sparc/pthread_arch.h
new file mode 100644
index 00000000..a07fe66e
--- /dev/null
+++ b/arch/sparc/pthread_arch.h
@@ -0,0 +1,9 @@
+static inline uintptr_t __get_tp()
+{
+ uintptr_t tp;
+ __asm__ __volatile__ ("mov %%g7, %0" : "=r"(tp));
+ return tp;
+}
+
+#define MC_PC mc_pc
+#define MC_NPC mc_npc
diff --git a/arch/sparc/reloc.h b/arch/sparc/reloc.h
new file mode 100644
index 00000000..a9030556
--- /dev/null
+++ b/arch/sparc/reloc.h
@@ -0,0 +1,46 @@
+#include <elf.h>
+
+#define LDSO_ARCH "sparc"
+
+#define REL_SYMBOLIC R_SPARC_32
+#define REL_USYMBOLIC R_SPARC_UA32
+#define REL_GOT R_SPARC_GLOB_DAT
+#define REL_PLT R_SPARC_JMP_SLOT
+#define REL_RELATIVE R_SPARC_RELATIVE
+#define REL_COPY R_SPARC_COPY
+#define REL_DTPMOD R_SPARC_TLS_DTPMOD32
+#define REL_DTPOFF R_SPARC_TLS_DTPOFF32
+#define REL_TPOFF R_SPARC_TLS_TPOFF32
+
+#define CRTJMP(pc,sp) __asm__ __volatile__( \
+ "sub %1,64,%%sp ; jmpl %0,%%g0 ; nop" : : "r"(pc), "r"(sp) : "memory" )
+
+#define _SP_SETHI(rd, imm22) (0x01000000u | ((unsigned)(rd) << 25) \
+ | ((unsigned)(imm22) & 0x3fffffu))
+#define _SP_JMPL(rs1, imm13, rd) (0x81c02000u | ((unsigned)(rd) << 25) \
+ | ((unsigned)(rs1) << 14) \
+ | ((unsigned)(imm13) & 0x1fffu))
+#define _SP_NOP 0x01000000u
+
+#define _SP_G0 0
+#define _SP_G1 1
+
+#define ARCH_LOCAL_SYM_IS_BASE 1
+#define ARCH_PLT_WRITE 1
+
+static inline void arch_plt_write(volatile void *p, size_t val,
+ size_t addend, unsigned char *base)
+{
+ volatile unsigned *insn = p;
+
+ unsigned hi = (unsigned)(val >> 10);
+ unsigned lo = (unsigned)(val & 0x3ff);
+
+ insn[0] = _SP_SETHI(_SP_G1, hi);
+ insn[1] = _SP_JMPL(_SP_G1, lo, _SP_G0);
+ insn[2] = _SP_NOP;
+
+ __asm__ __volatile__ ("flush %0" :: "r"((char *)p + 0) : "memory");
+ __asm__ __volatile__ ("flush %0" :: "r"((char *)p + 4) : "memory");
+ __asm__ __volatile__ ("flush %0" :: "r"((char *)p + 8) : "memory");
+}
diff --git a/arch/sparc/syscall_arch.h b/arch/sparc/syscall_arch.h
new file mode 100644
index 00000000..98c1660a
--- /dev/null
+++ b/arch/sparc/syscall_arch.h
@@ -0,0 +1,132 @@
+#define __SYSCALL_LL_E(x) \
+((union { long long ll; long l[2]; }){ .ll = x }).l[0], \
+((union { long long ll; long l[2]; }){ .ll = x }).l[1]
+#define __SYSCALL_LL_O(x) __SYSCALL_LL_E((x))
+
+/* ta 0x10 traps to the kernel; the syscall number goes in %g1, and an
+ * error is the carry flag set with a positive errno in %o0, negated below.
+ * Other registers survive the trap except %o1, a second return value
+ * for fork, vfork, clone and pipe. */
+static __inline long __syscall0(long n)
+{
+ register long g1 __asm__("g1") = n;
+ register long o0 __asm__("o0");
+ long err;
+ __asm__ __volatile__ ("ta 0x10 ; addx %%g0, %%g0, %1"
+ : "=r"(o0), "=&r"(err)
+ : "r"(g1)
+ : "memory", "cc", "o1");
+ return err ? -o0 : o0;
+}
+
+static __inline long __syscall1(long n, long a)
+{
+ register long g1 __asm__("g1") = n;
+ register long o0 __asm__("o0") = a;
+ long err;
+ __asm__ __volatile__ ("ta 0x10 ; addx %%g0, %%g0, %1"
+ : "+r"(o0), "=&r"(err)
+ : "r"(g1)
+ : "memory", "cc", "o1");
+ return err ? -o0 : o0;
+}
+
+static __inline long __syscall2(long n, long a, long b)
+{
+ register long g1 __asm__("g1") = n;
+ register long o0 __asm__("o0") = a;
+ register long o1 __asm__("o1") = b;
+ long err;
+ __asm__ __volatile__ ("ta 0x10 ; addx %%g0, %%g0, %2"
+ : "+r"(o0), "+r"(o1), "=&r"(err)
+ : "r"(g1)
+ : "memory", "cc");
+ return err ? -o0 : o0;
+}
+
+static __inline long __syscall3(long n, long a, long b, long c)
+{
+ register long g1 __asm__("g1") = n;
+ register long o0 __asm__("o0") = a;
+ register long o1 __asm__("o1") = b;
+ register long o2 __asm__("o2") = c;
+ long err;
+ __asm__ __volatile__ ("ta 0x10 ; addx %%g0, %%g0, %2"
+ : "+r"(o0), "+r"(o1), "=&r"(err)
+ : "r"(g1), "r"(o2)
+ : "memory", "cc");
+ return err ? -o0 : o0;
+}
+
+static __inline long __syscall4(long n, long a, long b, long c, long d)
+{
+ register long g1 __asm__("g1") = n;
+ register long o0 __asm__("o0") = a;
+ register long o1 __asm__("o1") = b;
+ register long o2 __asm__("o2") = c;
+ register long o3 __asm__("o3") = d;
+ long err;
+ __asm__ __volatile__ ("ta 0x10 ; addx %%g0, %%g0, %2"
+ : "+r"(o0), "+r"(o1), "=&r"(err)
+ : "r"(g1), "r"(o2), "r"(o3)
+ : "memory", "cc");
+ return err ? -o0 : o0;
+}
+
+static __inline long __syscall5(long n, long a, long b, long c, long d, long e)
+{
+ register long g1 __asm__("g1") = n;
+ register long o0 __asm__("o0") = a;
+ register long o1 __asm__("o1") = b;
+ register long o2 __asm__("o2") = c;
+ register long o3 __asm__("o3") = d;
+ register long o4 __asm__("o4") = e;
+ long err;
+ __asm__ __volatile__ ("ta 0x10 ; addx %%g0, %%g0, %2"
+ : "+r"(o0), "+r"(o1), "=&r"(err)
+ : "r"(g1), "r"(o2), "r"(o3), "r"(o4)
+ : "memory", "cc");
+ return err ? -o0 : o0;
+}
+
+static __inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)
+{
+ register long g1 __asm__("g1") = n;
+ register long o0 __asm__("o0") = a;
+ register long o1 __asm__("o1") = b;
+ register long o2 __asm__("o2") = c;
+ register long o3 __asm__("o3") = d;
+ register long o4 __asm__("o4") = e;
+ register long o5 __asm__("o5") = f;
+ long err;
+ __asm__ __volatile__ ("ta 0x10 ; addx %%g0, %%g0, %2"
+ : "+r"(o0), "+r"(o1), "=&r"(err)
+ : "r"(g1), "r"(o2), "r"(o3), "r"(o4), "r"(o5)
+ : "memory", "cc");
+ return err ? -o0 : o0;
+}
+
+#define SYSCALL_CLONE_SUNOS 1
+#define SYSCALL_RT_SIGACTION_RESTORER 1
+
+static __inline long __syscall_clone_sunos(long flags, long stack)
+{
+ register long g1 __asm__("g1") = SYS_clone;
+ register long o0 __asm__("o0") = flags;
+ register long o1 __asm__("o1") = stack;
+ long err;
+ __asm__ __volatile__ ("ta 0x10 ; addx %%g0, %%g0, %2"
+ : "+r"(o0), "+r"(o1), "=&r"(err)
+ : "r"(g1)
+ : "memory", "cc");
+ /* copy_thread() gives the child %o1 = 1 and the parent's pid in %o0 */
+ if (err) return -o0;
+ if (o1) return 0;
+ return o0;
+}
+
+#define SO_RCVTIMEO_OLD 8192
+#define SO_SNDTIMEO_OLD 16384
+#define SO_TIMESTAMP_OLD 29
+#define SO_TIMESTAMPNS_OLD 33
+#define SO_TIMESTAMPING_OLD 35
diff --git a/configure b/configure
index 9d7ee892..23929656 100755
--- a/configure
+++ b/configure
@@ -341,6 +341,7 @@ riscv32*) ARCH=riscv32 ;;
sh[1-9bel-]*|sh|superh*) ARCH=sh ;;
s390x*) ARCH=s390x ;;
sparc64*) ARCH=sparc64 ;;
+sparc*) ARCH=sparc ;;
unknown) fail "$0: unable to detect target arch; try $0 --target=..." ;;
*) fail "$0: unknown or unsupported target \"$target\"" ;;
esac
@@ -758,6 +759,12 @@ fi
fi
if test "$ARCH" = "sparc64" ; then
+trycppif __arch64__ "$t" || ARCH=sparc
+elif test "$ARCH" = "sparc" ; then
+trycppif __arch64__ "$t" && ARCH=sparc64
+fi
+
+if test "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ; then
trycppif _SOFT_FLOAT "$t" && fail "$0: error: soft-float not supported on $ARCH"
fi
diff --git a/src/fenv/sparc/fenv.c b/src/fenv/sparc/fenv.c
new file mode 100644
index 00000000..5a266eba
--- /dev/null
+++ b/src/fenv/sparc/fenv.c
@@ -0,0 +1,58 @@
+#include <fenv.h>
+
+#define _FE_RD_SHIFT 30
+#define _FE_RD_MASK (3UL << _FE_RD_SHIFT)
+
+static inline unsigned long get_fsr(void)
+{
+ unsigned long fsr;
+ __asm__ __volatile__ ("st %%fsr, %0" : "=m"(fsr));
+ return fsr;
+}
+
+static inline void set_fsr(unsigned long fsr)
+{
+ __asm__ __volatile__ ("ld %0, %%fsr" : : "m"(fsr));
+}
+
+int feclearexcept(int mask)
+{
+ mask &= FE_ALL_EXCEPT;
+ set_fsr(get_fsr() & ~(unsigned long)mask);
+ return 0;
+}
+
+int feraiseexcept(int mask)
+{
+ mask &= FE_ALL_EXCEPT;
+ set_fsr(get_fsr() | (unsigned long)mask);
+ return 0;
+}
+
+int fetestexcept(int mask)
+{
+ return get_fsr() & mask & FE_ALL_EXCEPT;
+}
+
+int fegetround(void)
+{
+ return (get_fsr() >> _FE_RD_SHIFT) & 3;
+}
+
+int __fesetround(int r)
+{
+ set_fsr((get_fsr() & ~_FE_RD_MASK) | ((unsigned long)r << _FE_RD_SHIFT));
+ return 0;
+}
+
+int fegetenv(fenv_t *envp)
+{
+ *envp = get_fsr();
+ return 0;
+}
+
+int fesetenv(const fenv_t *envp)
+{
+ set_fsr(envp == FE_DFL_ENV ? 0 : *envp);
+ return 0;
+}
diff --git a/src/ldso/sparc/dlsym.s b/src/ldso/sparc/dlsym.s
new file mode 100644
index 00000000..e6ba5a06
--- /dev/null
+++ b/src/ldso/sparc/dlsym.s
@@ -0,0 +1,8 @@
+ .text
+ .global dlsym
+ .hidden __dlsym
+ .type dlsym,#function
+dlsym:
+ ba __dlsym
+ mov %o7, %o2
+ .size dlsym, .-dlsym
diff --git a/src/math/sparc/q.c b/src/math/sparc/q.c
new file mode 100644
index 00000000..616cb931
--- /dev/null
+++ b/src/math/sparc/q.c
@@ -0,0 +1,137 @@
+/* gcc lowers 32-bit sparc long double arithmetic and conversions to
+ * these _Q_* calls; libgcc references them but does not define them.
+ * Those returning long double rely on gcc calling them with the same
+ * struct return it uses for a C function returning long double. */
+
+static inline unsigned long get_fsr(void)
+{
+ unsigned long x;
+ __asm__ __volatile__ ("st %%fsr, %0" : "=m"(x));
+ return x;
+}
+
+static inline void set_fsr(unsigned long x)
+{
+ __asm__ __volatile__ ("ld %0, %%fsr" : : "m"(x));
+}
+
+#include "../sparc64/quad.h"
+
+long double _Q_add(const long double *a, const long double *b)
+{
+ return qf(qop(qadd, a, b));
+}
+
+long double _Q_sub(const long double *a, const long double *b)
+{
+ return qf(qop(qsub, a, b));
+}
+
+long double _Q_mul(const long double *a, const long double *b)
+{
+ return qf(qop(qmul, a, b));
+}
+
+long double _Q_div(const long double *a, const long double *b)
+{
+ return qf(qop(qdiv, a, b));
+}
+
+int _Q_feq(const long double *a, const long double *b)
+{
+ return cmp(a, b, 0) == 0;
+}
+
+int _Q_fne(const long double *a, const long double *b)
+{
+ return cmp(a, b, 0) != 0;
+}
+
+int _Q_flt(const long double *a, const long double *b)
+{
+ return cmp(a, b, 1) == 1;
+}
+
+int _Q_fle(const long double *a, const long double *b)
+{
+ return cmp(a, b, 1) < 2;
+}
+
+int _Q_fgt(const long double *a, const long double *b)
+{
+ return cmp(a, b, 1) == 2;
+}
+
+int _Q_fge(const long double *a, const long double *b)
+{
+ return (cmp(a, b, 1) & 1) == 0;
+}
+
+int _Q_cmp(const long double *a, const long double *b)
+{
+ return cmp(a, b, 0);
+}
+
+long double _Q_itoq(int a)
+{
+ return qf(qfromint(a < 0, a < 0 ? -(uint64_t)a : a));
+}
+
+long double _Q_utoq(unsigned a)
+{
+ return qf(qfromint(0, a));
+}
+
+long double _Q_lltoq(long long a)
+{
+ return qf(qfromint(a < 0, a < 0 ? -(uint64_t)a : a));
+}
+
+long double _Q_ulltoq(unsigned long long a)
+{
+ return qf(qfromint(0, a));
+}
+
+long double _Q_stoq(float a)
+{
+ union { float f; uint32_t i; } u = {a};
+ return qf(fromflt(u.i, 24, 8));
+}
+
+long double _Q_dtoq(double a)
+{
+ union { double f; uint64_t i; } u = {a};
+ return qf(fromflt(u.i, 53, 11));
+}
+
+int _Q_qtoi(const long double *a)
+{
+ return toint(a, 32, 1);
+}
+
+unsigned _Q_qtou(const long double *a)
+{
+ return toint(a, 32, 0);
+}
+
+long long _Q_qtoll(const long double *a)
+{
+ return toint(a, 64, 1);
+}
+
+unsigned long long _Q_qtoull(const long double *a)
+{
+ return toint(a, 64, 0);
+}
+
+float _Q_qtos(const long double *a)
+{
+ union { uint32_t i; float f; } u = {toflt(a, 24, 8)};
+ return u.f;
+}
+
+double _Q_qtod(const long double *a)
+{
+ union { uint64_t i; double f; } u = {toflt(a, 53, 11)};
+ return u.f;
+}
diff --git a/src/setjmp/sparc/longjmp.s b/src/setjmp/sparc/longjmp.s
new file mode 100644
index 00000000..35eac6c1
--- /dev/null
+++ b/src/setjmp/sparc/longjmp.s
@@ -0,0 +1,20 @@
+ .text
+ .global _longjmp
+ .global longjmp
+ .type _longjmp,#function
+ .type longjmp,#function
+_longjmp:
+longjmp:
+ save %sp, -96, %sp
+ ta 3
+ ld [%i0 + 0], %fp
+ ld [%i0 + 4], %i7
+ mov 1, %g2
+ tst %i1
+ be 1f
+ nop
+ mov %i1, %g2
+1:
+ mov %i0, %g1
+ ret
+ restore %g2, 0, %o0
diff --git a/src/setjmp/sparc/setjmp.s b/src/setjmp/sparc/setjmp.s
new file mode 100644
index 00000000..6a6b722d
--- /dev/null
+++ b/src/setjmp/sparc/setjmp.s
@@ -0,0 +1,21 @@
+ .text
+ .global ___setjmp
+ .hidden ___setjmp
+ .global __setjmp
+ .global _setjmp
+ .global setjmp
+ .type ___setjmp,#function
+ .type __setjmp,#function
+ .type _setjmp,#function
+ .type setjmp,#function
+___setjmp:
+__setjmp:
+_setjmp:
+setjmp:
+ save %sp, -96, %sp
+ ta 3
+ st %fp, [%i0 + 0]
+ st %i7, [%i0 + 4]
+ mov %i0, %g1
+ ret
+ restore %g0, 0, %o0
diff --git a/src/signal/sparc/restore.s b/src/signal/sparc/restore.s
new file mode 100644
index 00000000..2dddf686
--- /dev/null
+++ b/src/signal/sparc/restore.s
@@ -0,0 +1,21 @@
+/* the kernel sets the handler's %o7 to the restorer, so it is entered 8 bytes in */
+ .text
+ .global __restore_rt
+ .hidden __restore_rt
+ .type __restore_rt,#function
+__restore_rt:
+ nop
+ nop
+ mov 101, %g1
+ ta 0x10
+ unimp
+
+ .global __restore
+ .hidden __restore
+ .type __restore,#function
+__restore:
+ nop
+ nop
+ mov 216, %g1
+ ta 0x10
+ unimp
diff --git a/src/signal/sparc/sigsetjmp.s b/src/signal/sparc/sigsetjmp.s
new file mode 100644
index 00000000..05223d39
--- /dev/null
+++ b/src/signal/sparc/sigsetjmp.s
@@ -0,0 +1,25 @@
+ .text
+ .global sigsetjmp
+ .global __sigsetjmp
+ .type sigsetjmp,#function
+ .type __sigsetjmp,#function
+ .hidden ___setjmp
+ .hidden __sigsetjmp_tail
+sigsetjmp:
+__sigsetjmp:
+ tst %o1
+ be ___setjmp
+ nop
+
+ st %o7, [%o0 + 8]
+ call ___setjmp
+ nop
+
+ /* ___setjmp and longjmp both return with jb in %g1 */
+ mov %o0, %o1
+ mov %g1, %o0
+ ld [%o0 + 8], %o7
+
+ ba __sigsetjmp_tail
+ nop
+ .size sigsetjmp, .-sigsetjmp
diff --git a/src/thread/sparc/__set_thread_area.c b/src/thread/sparc/__set_thread_area.c
new file mode 100644
index 00000000..9c0df3b1
--- /dev/null
+++ b/src/thread/sparc/__set_thread_area.c
@@ -0,0 +1,19 @@
+#include <stdint.h>
+#include "pthread_impl.h"
+#include "libc.h"
+
+#define HWCAP_SPARC_V9 16
+
+extern hidden const unsigned char __a_cas_v8[], __a_cas_v9[];
+extern hidden uintptr_t __a_cas_ptr;
+
+int __set_thread_area(void *p)
+{
+ /* V9 CPUs refuse ASIs below 0x80 in user mode. Otherwise use 0x0a,
+ * which LEON accepts in user mode and which a kernel that emulates
+ * casa handles on CPUs without it. */
+ __a_cas_ptr = __hwcap & HWCAP_SPARC_V9 ? (uintptr_t)__a_cas_v9
+ : (uintptr_t)__a_cas_v8;
+ __asm__ __volatile__ ("mov %0, %%g7" : : "r"(p) : "memory");
+ return 0;
+}
diff --git a/src/thread/sparc/__unmapself.c b/src/thread/sparc/__unmapself.c
new file mode 100644
index 00000000..d3f3842c
--- /dev/null
+++ b/src/thread/sparc/__unmapself.c
@@ -0,0 +1,26 @@
+#include "pthread_impl.h"
+#include "syscall.h"
+
+/* Threads exiting at once share scratch: after the windows are flushed
+ * only a kernel window spill writes to it, and nothing reads it back. */
+static char scratch[256] __attribute__((aligned(16)));
+
+void __unmapself(void *base, size_t size)
+{
+ register long a0 __asm__("o0") = (long)base;
+ register long a1 __asm__("o1") = (long)size;
+ __asm__ __volatile__(
+ "ta 3\n\t"
+ "mov %2, %%sp\n\t"
+ "mov %3, %%g1\n\t"
+ "ta 0x10\n\t"
+ "mov 0, %%o0\n\t"
+ "mov %4, %%g1\n\t"
+ "ta 0x10\n\t"
+ :
+ : "r"(a0), "r"(a1),
+ "r"(scratch + sizeof scratch - 64),
+ "i"(SYS_munmap), "i"(SYS_exit)
+ : "g1", "memory");
+ __builtin_unreachable();
+}
diff --git a/src/thread/sparc/atomics.s b/src/thread/sparc/atomics.s
new file mode 100644
index 00000000..6702add5
--- /dev/null
+++ b/src/thread/sparc/atomics.s
@@ -0,0 +1,24 @@
+/* casa [%o0] asi, %o1, %o2, emitted as a word so the object stays EM_SPARC */
+ .text
+ .global __a_cas_v9
+ .hidden __a_cas_v9
+ .type __a_cas_v9,#function
+__a_cas_v9:
+ .word 0xd5e21009
+ retl
+ nop
+
+ .global __a_cas_v8
+ .hidden __a_cas_v8
+ .type __a_cas_v8,#function
+__a_cas_v8:
+ .word 0xd5e20149
+ retl
+ nop
+
+ .data
+ .align 4
+ .global __a_cas_ptr
+ .hidden __a_cas_ptr
+__a_cas_ptr:
+ .word __a_cas_v8
diff --git a/src/thread/sparc/clone.S b/src/thread/sparc/clone.S
new file mode 100644
index 00000000..fdd3a7d0
--- /dev/null
+++ b/src/thread/sparc/clone.S
@@ -0,0 +1,45 @@
+#define SYS_clone 217
+#define SYS_exit 1
+
+ .text
+ .global __clone
+ .hidden __clone
+ .type __clone,#function
+__clone:
+ /* clone_stackframe() copies the frame of whoever holds %sp, so take our own */
+ save %sp, -96, %sp
+ mov %i0, %g2
+ mov %i3, %g3
+ ld [%fp + 92], %o4
+
+ and %i1, -8, %o1
+ /* sparc_clone() takes tls in arg4 and child_tid in arg5 */
+ mov %i2, %o0
+ mov %i4, %o2
+ mov %i5, %o3
+
+ ta 3
+ mov SYS_clone, %g1
+ ta 0x10
+ bcs 2f
+ nop
+
+ tst %o1
+ bne 1f
+ nop
+
+ ret
+ restore %o0, %g0, %o0
+
+1:
+ mov %g3, %o0
+ call %g2
+ nop
+ mov SYS_exit, %g1
+ ta 0x10
+ unimp
+
+2: sub %g0, %o0, %o0
+ ret
+ restore %o0, %g0, %o0
+ .size __clone, .-__clone
diff --git a/src/thread/sparc/syscall_cp.s b/src/thread/sparc/syscall_cp.s
new file mode 100644
index 00000000..72c61e73
--- /dev/null
+++ b/src/thread/sparc/syscall_cp.s
@@ -0,0 +1,39 @@
+ .text
+ .global __cp_begin
+ .hidden __cp_begin
+ .global __cp_end
+ .hidden __cp_end
+ .global __cp_cancel
+ .hidden __cp_cancel
+ .hidden __cancel
+ .global __syscall_cp_asm
+ .hidden __syscall_cp_asm
+ .type __syscall_cp_asm,#function
+__syscall_cp_asm:
+__cp_begin:
+ ld [%o0], %g1
+ tst %g1
+ bne __cp_cancel
+ nop
+
+ mov %o1, %g1
+ mov %o2, %o0
+ mov %o3, %o1
+ mov %o4, %o2
+ mov %o5, %o3
+ ld [%sp + 92], %o4
+ ld [%sp + 96], %o5
+ ta 0x10
+__cp_end:
+ /* on error the carry is set and %o0 holds a positive errno */
+ bcs 1f
+ nop
+ retl
+ nop
+1: retl
+ sub %g0, %o0, %o0
+
+__cp_cancel:
+ ba __cancel
+ nop
+ .size __syscall_cp_asm, .-__syscall_cp_asm
diff --git a/src/unistd/sparc/pipe.s b/src/unistd/sparc/pipe.s
new file mode 100644
index 00000000..c6559eb2
--- /dev/null
+++ b/src/unistd/sparc/pipe.s
@@ -0,0 +1,18 @@
+ .text
+ .global pipe
+ .type pipe,#function
+ .hidden __syscall_ret
+pipe:
+ mov %o0, %o2
+ mov 42, %g1
+ ta 0x10
+ /* the kernel returns fd[0] in %o0 and fd[1] in %o1 */
+ bcs 1f
+ nop
+ st %o0, [%o2]
+ st %o1, [%o2 + 4]
+ retl
+ clr %o0
+1: ba __syscall_ret
+ neg %o0
+ .size pipe, .-pipe
--
2.47.3
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.