Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
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.