Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <a2d4433ef379b36a4c8609ab5701764234e11aeb.1693396649.git.quic_mathbern@quicinc.com>
Date: Wed, 30 Aug 2023 09:22:26 -0300
From: Matheus Tavares Bernardino <quic_mathbern@...cinc.com>
To: <musl@...ts.openwall.com>
CC: Brian Cain <bcain@...cinc.com>, Sid Manning <sidneym@...cinc.com>,
        "Rich
 Felker" <dalias@...c.org>, Fangrui Song <i@...kray.me>,
        Szabolcs Nagy
	<nsz@...t70.net>
Subject: [RFC PATCH 1/5] Add support to Hexagon arch

From: Sid Manning <sidneym@...cinc.com>

This ports musl to Qualcomm's Hexagon DSP architecture:
https://developer.qualcomm.com/software/hexagon-dsp-sdk/dsp-processor
---
 arch/hexagon/atomic_arch.h             | 191 +++++++++++++++
 arch/hexagon/bits/alltypes.h.in        |  18 ++
 arch/hexagon/bits/float.h              |  16 ++
 arch/hexagon/bits/ipcstat.h            |   1 +
 arch/hexagon/bits/msg.h                |  18 ++
 arch/hexagon/bits/posix.h              |   2 +
 arch/hexagon/bits/sem.h                |  13 +
 arch/hexagon/bits/setjmp.h             |   1 +
 arch/hexagon/bits/shm.h                |  31 +++
 arch/hexagon/bits/signal.h             | 103 ++++++++
 arch/hexagon/bits/stat.h               |  20 ++
 arch/hexagon/bits/stdint.h             |  20 ++
 arch/hexagon/bits/syscall.h.in         | 327 +++++++++++++++++++++++++
 arch/hexagon/crt_arch.h                |  22 ++
 arch/hexagon/kstat.h                   |  21 ++
 arch/hexagon/pthread_arch.h            |  13 +
 arch/hexagon/reloc.h                   |  16 ++
 arch/hexagon/syscall_arch.h            |  78 ++++++
 configure                              |   1 +
 include/elf.h                          | 101 ++++++++
 src/setjmp/hexagon/longjmp.s           |  25 ++
 src/setjmp/hexagon/setjmp.s            |  24 ++
 src/signal/hexagon/restore.s           |  11 +
 src/signal/hexagon/sigsetjmp.s         |  28 +++
 src/thread/hexagon/__set_thread_area.s |   7 +
 src/thread/hexagon/__unmapself.s       |  11 +
 src/thread/hexagon/clone.s             |  37 +++
 src/thread/hexagon/syscall_cp.s        |  35 +++
 28 files changed, 1191 insertions(+)
 create mode 100644 arch/hexagon/atomic_arch.h
 create mode 100644 arch/hexagon/bits/alltypes.h.in
 create mode 100644 arch/hexagon/bits/float.h
 create mode 100644 arch/hexagon/bits/ipcstat.h
 create mode 100644 arch/hexagon/bits/msg.h
 create mode 100644 arch/hexagon/bits/posix.h
 create mode 100644 arch/hexagon/bits/sem.h
 create mode 100644 arch/hexagon/bits/setjmp.h
 create mode 100644 arch/hexagon/bits/shm.h
 create mode 100644 arch/hexagon/bits/signal.h
 create mode 100644 arch/hexagon/bits/stat.h
 create mode 100644 arch/hexagon/bits/stdint.h
 create mode 100644 arch/hexagon/bits/syscall.h.in
 create mode 100644 arch/hexagon/crt_arch.h
 create mode 100644 arch/hexagon/kstat.h
 create mode 100644 arch/hexagon/pthread_arch.h
 create mode 100644 arch/hexagon/reloc.h
 create mode 100644 arch/hexagon/syscall_arch.h
 create mode 100644 src/setjmp/hexagon/longjmp.s
 create mode 100644 src/setjmp/hexagon/setjmp.s
 create mode 100644 src/signal/hexagon/restore.s
 create mode 100644 src/signal/hexagon/sigsetjmp.s
 create mode 100644 src/thread/hexagon/__set_thread_area.s
 create mode 100644 src/thread/hexagon/__unmapself.s
 create mode 100644 src/thread/hexagon/clone.s
 create mode 100644 src/thread/hexagon/syscall_cp.s

diff --git a/arch/hexagon/atomic_arch.h b/arch/hexagon/atomic_arch.h
new file mode 100644
index 00000000..b25af3d4
--- /dev/null
+++ b/arch/hexagon/atomic_arch.h
@@ -0,0 +1,191 @@
+#define a_ctz_32 a_ctz_32
+static inline int a_ctz_32(unsigned long x)
+{
+	__asm__(
+		"%0 = ct0(%0)\n\t"
+		: "+r"(x));
+	return x;
+}
+
+#define a_ctz_64 a_ctz_64
+static inline int a_ctz_64(uint64_t x)
+{
+	int count;
+	__asm__(
+		"%0 = ct0(%1)\n\t"
+		: "=r"(count) : "r"(x));
+	return count;
+}
+#define a_clz_64 a_clz_64
+static inline int a_clz_64(uint64_t x)
+{
+        __asm__(
+                "%0 = brev(%0)\n\t"
+		: "+r"(x));
+        return a_ctz_64(x);
+}
+
+#define a_cas a_cas
+static inline int a_cas(volatile int *p, int t, int s)
+{
+	int dummy;
+	__asm__ __volatile__(
+		"1:	%0 = memw_locked(%1)\n\t"
+		"	{ p0 = cmp.eq(%0, %2)\n\t"
+		"	  if (!p0.new) jump:nt 2f }\n\t"
+		"	memw_locked(%1, p0) = %3\n\t"
+		"	if (!p0) jump 1b\n\t"
+		"2:	\n\t"
+		: "=&r"(dummy)
+		: "r"(p), "r"(t), "r"(s)
+		: "p0", "memory" );
+        return dummy;
+}
+
+#define a_cas_p a_cas_p
+static inline void *a_cas_p(volatile void *p, void *t, void *s)
+{
+	return (void *)a_cas(p, (int)t, (int)s);
+}
+
+#define a_swap a_swap
+static inline int a_swap(volatile int *x, int v)
+{
+	int old, dummy;
+	__asm__ __volatile__(
+		"	%1 = %3\n\t"
+		"1:	%0 = memw_locked(%2)\n\t"
+		"	memw_locked(%2, p0) = %1\n\t"
+		"	if (!p0) jump 1b\n\t"
+		: "=&r"(old), "=&r"(dummy)
+		: "r"(x), "r"(v)
+		: "p0", "memory" );
+        return old;
+}
+
+#define a_fetch_add a_fetch_add
+static inline int a_fetch_add(volatile int *x, int v)
+{
+	int old, dummy;
+	__asm__ __volatile__(
+		"1:	%0 = memw_locked(%2)\n\t"
+		"	%1 = add(%0, %3)\n\t"
+		"	memw_locked(%2, p0) = %1\n\t"
+		"	if (!p0) jump 1b\n\t"
+		: "=&r"(old), "=&r"(dummy)
+		: "r"(x), "r"(v)
+		: "p0", "memory" );
+        return old;
+}
+
+#define a_inc a_inc
+static inline void a_inc(volatile int *x)
+{
+	a_fetch_add(x, 1);
+}
+
+#define a_dec a_dec
+static inline void a_dec(volatile int *x)
+{
+	int dummy;
+	__asm__ __volatile__(
+		"1:	%0 = memw_locked(%1)\n\t"
+		"	%0 = add(%0, #-1)\n\t"
+		"	memw_locked(%1, p0) = %0\n\t"
+		"	if (!p0) jump 1b\n\t"
+		: "=&r"(dummy)
+		: "r"(x)
+		: "p0", "memory" );
+}
+
+#define a_store a_store
+static inline void a_store(volatile int *p, int x)
+{
+	int dummy;
+	__asm__ __volatile__(
+		"1:	%0 = memw_locked(%1)\n\t"
+		"	memw_locked(%1, p0) = %2\n\t"
+		"	if (!p0) jump 1b\n\t"
+		: "=&r"(dummy)
+		: "r"(p), "r"(x)
+		: "p0", "memory" );
+}
+
+#define a_barrier a_barrier
+static inline void a_barrier()
+{
+	__asm__ __volatile__ ("barrier" ::: "memory");
+}
+#define a_spin a_spin
+static inline void a_spin()
+{
+	__asm__ __volatile__ ("pause(#255)" :::);
+}
+
+#define a_crash a_crash
+static inline void a_crash()
+{
+	*(volatile char *)0=0;
+}
+
+#define a_and a_and
+static inline void a_and(volatile int *p, int v)
+{
+	int dummy;
+	__asm__ __volatile__(
+		"1:	%0 = memw_locked(%1)\n\t"
+		"	%0 = and(%0, %2)\n\t"
+		"	memw_locked(%1, p0) = %0\n\t"
+		"	if (!p0) jump 1b\n\t"
+		: "=&r"(dummy)
+		: "r"(p), "r"(v)
+		: "p0", "memory" );
+}
+
+#define  a_or a_or
+static inline void a_or(volatile int *p, int v)
+{
+	int dummy;
+	__asm__ __volatile__(
+		"1:	%0 = memw_locked(%1)\n\t"
+		"	%0 = or(%0, %2)\n\t"
+		"	memw_locked(%1, p0) = %0\n\t"
+		"	if (!p0) jump 1b\n\t"
+		: "=&r"(dummy)
+		: "r"(p), "r"(v)
+		: "p0", "memory" );
+}
+
+#define a_or_l a_or_l
+static inline void a_or_l(volatile void *p, long v)
+{
+	a_or(p, v);
+}
+
+#define a_and_64 a_and_64
+static inline void a_and_64(volatile uint64_t *p, uint64_t v)
+{
+	uint64_t dummy;
+	__asm__ __volatile__(
+		"1:	%0 = memd_locked(%1)\n\t"
+		"	%0 = and(%0, %2)\n\t"
+		"	memd_locked(%1, p0) = %0\n\t"
+		"	if (!p0) jump 1b\n\t"
+		: "=&r"(dummy)
+		: "r"(p), "r"(v)
+		: "p0", "memory" );
+}
+
+#define  a_or_64 a_or_64
+static inline void a_or_64(volatile uint64_t *p, uint64_t v)
+{
+	uint64_t dummy;
+	__asm__ __volatile__(
+		"1:	%0 = memd_locked(%1)\n\t"
+		"	%0 = or(%0, %2)\n\t"
+		"	memd_locked(%1, p0) = %0\n\t"
+		"	if (!p0) jump 1b\n\t"
+		: "=&r"(dummy)
+		: "r"(p), "r"(v)
+		: "p0", "memory" );
+}
diff --git a/arch/hexagon/bits/alltypes.h.in b/arch/hexagon/bits/alltypes.h.in
new file mode 100644
index 00000000..e5d9d616
--- /dev/null
+++ b/arch/hexagon/bits/alltypes.h.in
@@ -0,0 +1,18 @@
+#define _Addr int
+#define _Int64 long long
+#define _Reg int
+
+#define __BYTE_ORDER 1234
+#define __LONG_MAX 0x7fffffffL
+
+#ifndef __cplusplus
+#ifdef __WCHAR_TYPE__
+TYPEDEF __WCHAR_TYPE__ wchar_t;
+#else
+TYPEDEF long wchar_t;
+#endif
+#endif
+
+TYPEDEF float float_t;
+TYPEDEF double double_t;
+TYPEDEF struct { long long __ll; long double __ld; } max_align_t;
diff --git a/arch/hexagon/bits/float.h b/arch/hexagon/bits/float.h
new file mode 100644
index 00000000..c4a655e7
--- /dev/null
+++ b/arch/hexagon/bits/float.h
@@ -0,0 +1,16 @@
+#define FLT_EVAL_METHOD 0
+
+#define LDBL_TRUE_MIN 4.94065645841246544177e-324L
+#define LDBL_MIN 2.22507385850720138309e-308L
+#define LDBL_MAX 1.79769313486231570815e+308L
+#define LDBL_EPSILON 2.22044604925031308085e-16L
+
+#define LDBL_MANT_DIG 53
+#define LDBL_MIN_EXP (-1021)
+#define LDBL_MAX_EXP 1024
+
+#define LDBL_DIG 15
+#define LDBL_MIN_10_EXP (-307)
+#define LDBL_MAX_10_EXP 308
+
+#define DECIMAL_DIG 17
diff --git a/arch/hexagon/bits/ipcstat.h b/arch/hexagon/bits/ipcstat.h
new file mode 100644
index 00000000..4f4fcb0c
--- /dev/null
+++ b/arch/hexagon/bits/ipcstat.h
@@ -0,0 +1 @@
+#define IPC_STAT 0x102
diff --git a/arch/hexagon/bits/msg.h b/arch/hexagon/bits/msg.h
new file mode 100644
index 00000000..7bbbb2bf
--- /dev/null
+++ b/arch/hexagon/bits/msg.h
@@ -0,0 +1,18 @@
+struct msqid_ds {
+	struct ipc_perm msg_perm;
+	unsigned long __msg_stime_lo;
+	unsigned long __msg_stime_hi;
+	unsigned long __msg_rtime_lo;
+	unsigned long __msg_rtime_hi;
+	unsigned long __msg_ctime_lo;
+	unsigned long __msg_ctime_hi;
+	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/hexagon/bits/posix.h b/arch/hexagon/bits/posix.h
new file mode 100644
index 00000000..30a38714
--- /dev/null
+++ b/arch/hexagon/bits/posix.h
@@ -0,0 +1,2 @@
+#define _POSIX_V6_ILP32_OFFBIG  1
+#define _POSIX_V7_ILP32_OFFBIG  1
diff --git a/arch/hexagon/bits/sem.h b/arch/hexagon/bits/sem.h
new file mode 100644
index 00000000..65661542
--- /dev/null
+++ b/arch/hexagon/bits/sem.h
@@ -0,0 +1,13 @@
+struct semid_ds {
+	struct ipc_perm sem_perm;
+	unsigned long __sem_otime_lo;
+	unsigned long __sem_otime_hi;
+	unsigned long __sem_ctime_lo;
+	unsigned long __sem_ctime_hi;
+	unsigned short sem_nsems;
+	char __sem_nsems_pad[sizeof(long)-sizeof(short)];
+	long __unused3;
+	long __unused4;
+	time_t sem_otime;
+	time_t sem_ctime;
+};
diff --git a/arch/hexagon/bits/setjmp.h b/arch/hexagon/bits/setjmp.h
new file mode 100644
index 00000000..2d75319a
--- /dev/null
+++ b/arch/hexagon/bits/setjmp.h
@@ -0,0 +1 @@
+typedef	long long  __jmp_buf[8];
diff --git a/arch/hexagon/bits/shm.h b/arch/hexagon/bits/shm.h
new file mode 100644
index 00000000..725fb469
--- /dev/null
+++ b/arch/hexagon/bits/shm.h
@@ -0,0 +1,31 @@
+#define SHMLBA 4096
+
+struct shmid_ds {
+	struct ipc_perm shm_perm;
+	size_t shm_segsz;
+	unsigned long __shm_atime_lo;
+	unsigned long __shm_atime_hi;
+	unsigned long __shm_dtime_lo;
+	unsigned long __shm_dtime_hi;
+	unsigned long __shm_ctime_lo;
+	unsigned long __shm_ctime_hi;
+	pid_t shm_cpid;
+	pid_t shm_lpid;
+	unsigned long shm_nattch;
+	unsigned long __pad1;
+	unsigned long __pad2;
+	unsigned long __pad3;
+	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/hexagon/bits/signal.h b/arch/hexagon/bits/signal.h
new file mode 100644
index 00000000..b119f163
--- /dev/null
+++ b/arch/hexagon/bits/signal.h
@@ -0,0 +1,103 @@
+#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 2048
+#define SIGSTKSZ 8192
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+typedef int greg_t, gregset_t[18];
+typedef struct sigcontext
+{
+	unsigned long  r0,  r1,  r2,  r3;
+	unsigned long  r4,  r5,  r6,  r7;
+	unsigned long  r8,  r9, r10, r11;
+	unsigned long r12, r13, r14, r15;
+	unsigned long r16, r17, r18, r19;
+	unsigned long r20, r21, r22, r23;
+	unsigned long r24, r25, r26, r27;
+	unsigned long r28, r29, r30, r31;
+	unsigned long sa0;
+	unsigned long lc0;
+	unsigned long sa1;
+	unsigned long lc1;
+	unsigned long m0;
+	unsigned long m1;
+	unsigned long usr;
+	unsigned long p3_0;
+	unsigned long gp;
+	unsigned long ugp;
+	unsigned long pc;
+	unsigned long cause;
+	unsigned long badva;
+	unsigned long pad1;
+	unsigned long long pad2;
+} mcontext_t;
+#else
+typedef struct {
+	unsigned long __regs[48];
+} __attribute__((__aligned__(8))) mcontext_t;
+#endif
+
+struct sigaltstack {
+	void *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+};
+
+typedef struct __ucontext {
+	unsigned long uc_flags;
+	struct __ucontext *uc_link;
+	stack_t uc_stack;
+	mcontext_t uc_mcontext;
+	sigset_t uc_sigmask;
+} ucontext_t;
+
+#define SA_NOCLDSTOP  1
+#define SA_NOCLDWAIT  2
+#define SA_SIGINFO    4
+#define SA_ONSTACK    0x08000000
+#define SA_RESTART    0x10000000
+#define SA_NODEFER    0x40000000
+#define SA_RESETHAND  0x80000000
+#define SA_RESTORER   0x04000000
+
+#endif
+
+#define SIGHUP    1
+#define SIGINT    2
+#define SIGQUIT   3
+#define SIGILL    4
+#define SIGTRAP   5
+#define SIGABRT   6
+#define SIGIOT    SIGABRT
+#define SIGBUS    7
+#define SIGFPE    8
+#define SIGKILL   9
+#define SIGUSR1   10
+#define SIGSEGV   11
+#define SIGUSR2   12
+#define SIGPIPE   13
+#define SIGALRM   14
+#define SIGTERM   15
+#define SIGSTKFLT 16
+#define SIGCHLD   17
+#define SIGCONT   18
+#define SIGSTOP   19
+#define SIGTSTP   20
+#define SIGTTIN   21
+#define SIGTTOU   22
+#define SIGURG    23
+#define SIGXCPU   24
+#define SIGXFSZ   25
+#define SIGVTALRM 26
+#define SIGPROF   27
+#define SIGWINCH  28
+#define SIGIO     29
+#define SIGPOLL   29
+#define SIGPWR    30
+#define SIGSYS    31
+#define SIGUNUSED SIGSYS
+
+#define _NSIG 65
diff --git a/arch/hexagon/bits/stat.h b/arch/hexagon/bits/stat.h
new file mode 100644
index 00000000..55e81fd9
--- /dev/null
+++ b/arch/hexagon/bits/stat.h
@@ -0,0 +1,20 @@
+/* copied from kernel definition, but with padding replaced
+ * by the corresponding correctly-sized userspace types. */
+struct stat {
+	dev_t st_dev;
+	ino_t st_ino;
+	mode_t st_mode;
+	nlink_t st_nlink;
+	uid_t st_uid;
+	gid_t st_gid;
+	dev_t st_rdev;
+	unsigned long __pad;
+	off_t st_size;
+	blksize_t st_blksize;
+	int __pad2;
+	blkcnt_t st_blocks;
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+	unsigned __unused[2];
+};
diff --git a/arch/hexagon/bits/stdint.h b/arch/hexagon/bits/stdint.h
new file mode 100644
index 00000000..d1b27121
--- /dev/null
+++ b/arch/hexagon/bits/stdint.h
@@ -0,0 +1,20 @@
+typedef int32_t int_fast16_t;
+typedef int32_t int_fast32_t;
+typedef uint32_t uint_fast16_t;
+typedef uint32_t uint_fast32_t;
+
+#define INT_FAST16_MIN  INT32_MIN
+#define INT_FAST32_MIN  INT32_MIN
+
+#define INT_FAST16_MAX  INT32_MAX
+#define INT_FAST32_MAX  INT32_MAX
+
+#define UINT_FAST16_MAX UINT32_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+
+#define INTPTR_MIN      INT32_MIN
+#define INTPTR_MAX      INT32_MAX
+#define UINTPTR_MAX     UINT32_MAX
+#define PTRDIFF_MIN     INT32_MIN
+#define PTRDIFF_MAX     INT32_MAX
+#define SIZE_MAX        UINT32_MAX
diff --git a/arch/hexagon/bits/syscall.h.in b/arch/hexagon/bits/syscall.h.in
new file mode 100644
index 00000000..5e7b96d0
--- /dev/null
+++ b/arch/hexagon/bits/syscall.h.in
@@ -0,0 +1,327 @@
+#define __NR_io_setup 0
+#define __NR_io_destroy 1
+#define __NR_io_submit 2
+#define __NR_io_cancel 3
+#define __NR_io_getevents 4
+#define __NR_setxattr 5
+#define __NR_lsetxattr 6
+#define __NR_fsetxattr 7
+#define __NR_getxattr 8
+#define __NR_lgetxattr 9
+#define __NR_fgetxattr 10
+#define __NR_listxattr 11
+#define __NR_llistxattr 12
+#define __NR_flistxattr 13
+#define __NR_removexattr 14
+#define __NR_lremovexattr 15
+#define __NR_fremovexattr 16
+#define __NR_getcwd 17
+#define __NR_lookup_dcookie 18
+#define __NR_eventfd2 19
+#define __NR_epoll_create1 20
+#define __NR_epoll_ctl 21
+#define __NR_epoll_pwait 22
+#define __NR_dup 23
+#define __NR_dup3 24
+#define __NR_fcntl 25
+#define __NR_inotify_init1 26
+#define __NR_inotify_add_watch 27
+#define __NR_inotify_rm_watch 28
+#define __NR_ioctl 29
+#define __NR_ioprio_set 30
+#define __NR_ioprio_get 31
+#define __NR_flock 32
+#define __NR_mknodat 33
+#define __NR_mkdirat 34
+#define __NR_unlinkat 35
+#define __NR_symlinkat 36
+#define __NR_linkat 37
+#define __NR_renameat 38
+#define __NR_umount2 39
+#define __NR_mount 40
+#define __NR_pivot_root 41
+#define __NR_nfsservctl 42
+#define __NR_statfs 43
+#define __NR_fstatfs 44
+#define __NR_truncate 45
+#define __NR_ftruncate 46
+#define __NR_fallocate 47
+#define __NR_faccessat 48
+#define __NR_chdir 49
+#define __NR_fchdir 50
+#define __NR_chroot 51
+#define __NR_fchmod 52
+#define __NR_fchmodat 53
+#define __NR_fchownat 54
+#define __NR_fchown 55
+#define __NR_openat 56
+#define __NR_close 57
+#define __NR_vhangup 58
+#define __NR_pipe2 59
+#define __NR_quotactl 60
+#define __NR_getdents64 61
+#define __NR_lseek 62
+#define __NR_read 63
+#define __NR_write 64
+#define __NR_readv 65
+#define __NR_writev 66
+#define __NR_pread64 67
+#define __NR_pwrite64 68
+#define __NR_preadv 69
+#define __NR_pwritev 70
+#define __NR_sendfile 71
+#define __NR_pselect6 72
+#define __NR_ppoll 73
+#define __NR_signalfd4 74
+#define __NR_vmsplice 75
+#define __NR_splice 76
+#define __NR_tee 77
+#define __NR_readlinkat 78
+#define __NR_fstatat 79
+#define __NR_fstat 80
+#define __NR_sync 81
+#define __NR_fsync 82
+#define __NR_fdatasync 83
+#define __NR_sync_file_range2 84
+#define __NR_sync_file_range 84
+#define __NR_timerfd_create 85
+#define __NR_timerfd_settime 86
+#define __NR_timerfd_gettime 87
+#define __NR_utimensat 88
+#define __NR_acct 89
+#define __NR_capget 90
+#define __NR_capset 91
+#define __NR_personality 92
+#define __NR_exit 93
+#define __NR_exit_group 94
+#define __NR_waitid 95
+#define __NR_set_tid_address 96
+#define __NR_unshare 97
+#define __NR_futex 98
+#define __NR_set_robust_list 99
+#define __NR_get_robust_list 100
+#define __NR_nanosleep 101
+#define __NR_getitimer 102
+#define __NR_setitimer 103
+#define __NR_kexec_load 104
+#define __NR_init_module 105
+#define __NR_delete_module 106
+#define __NR_timer_create 107
+#define __NR_timer_gettime 108
+#define __NR_timer_getoverrun 109
+#define __NR_timer_settime 110
+#define __NR_timer_delete 111
+#define __NR_clock_settime 112
+#define __NR_clock_gettime32 113
+#define __NR_clock_getres 114
+#define __NR_clock_nanosleep 115
+#define __NR_syslog 116
+#define __NR_ptrace 117
+#define __NR_sched_setparam 118
+#define __NR_sched_setscheduler 119
+#define __NR_sched_getscheduler 120
+#define __NR_sched_getparam 121
+#define __NR_sched_setaffinity 122
+#define __NR_sched_getaffinity 123
+#define __NR_sched_yield 124
+#define __NR_sched_get_priority_max 125
+#define __NR_sched_get_priority_min 126
+#define __NR_sched_rr_get_interval 127
+#define __NR_restart_syscall 128
+#define __NR_kill 129
+#define __NR_tkill 130
+#define __NR_tgkill 131
+#define __NR_sigaltstack 132
+#define __NR_rt_sigsuspend 133
+#define __NR_rt_sigaction 134
+#define __NR_rt_sigprocmask 135
+#define __NR_rt_sigpending 136
+#define __NR_rt_sigtimedwait 137
+#define __NR_rt_sigqueueinfo 138
+#define __NR_rt_sigreturn 139
+#define __NR_setpriority 140
+#define __NR_getpriority 141
+#define __NR_reboot 142
+#define __NR_setregid 143
+#define __NR_setgid 144
+#define __NR_setreuid 145
+#define __NR_setuid 146
+#define __NR_setresuid 147
+#define __NR_getresuid 148
+#define __NR_setresgid 149
+#define __NR_getresgid 150
+#define __NR_setfsuid 151
+#define __NR_setfsgid 152
+#define __NR_times 153
+#define __NR_setpgid 154
+#define __NR_getpgid 155
+#define __NR_getsid 156
+#define __NR_setsid 157
+#define __NR_getgroups 158
+#define __NR_setgroups 159
+#define __NR_uname 160
+#define __NR_sethostname 161
+#define __NR_setdomainname 162
+#define __NR_getrlimit 163
+#define __NR_setrlimit 164
+#define __NR_getrusage 165
+#define __NR_umask 166
+#define __NR_prctl 167
+#define __NR_getcpu 168
+#define __NR_gettimeofday_time32 169
+#define __NR_settimeofday 170
+#define __NR_adjtimex 171
+#define __NR_getpid 172
+#define __NR_getppid 173
+#define __NR_getuid 174
+#define __NR_geteuid 175
+#define __NR_getgid 176
+#define __NR_getegid 177
+#define __NR_gettid 178
+#define __NR_sysinfo 179
+#define __NR_mq_open 180
+#define __NR_mq_unlink 181
+#define __NR_mq_timedsend 182
+#define __NR_mq_timedreceive 183
+#define __NR_mq_notify 184
+#define __NR_mq_getsetattr 185
+#define __NR_msgget 186
+#define __NR_msgctl 187
+#define __NR_msgrcv 188
+#define __NR_msgsnd 189
+#define __NR_semget 190
+#define __NR_semctl 191
+#define __NR_semtimedop 192
+#define __NR_semop 193
+#define __NR_shmget 194
+#define __NR_shmctl 195
+#define __NR_shmat 196
+#define __NR_shmdt 197
+#define __NR_socket 198
+#define __NR_socketpair 199
+#define __NR_bind 200
+#define __NR_listen 201
+#define __NR_accept 202
+#define __NR_connect 203
+#define __NR_getsockname 204
+#define __NR_getpeername 205
+#define __NR_sendto 206
+#define __NR_recvfrom 207
+#define __NR_setsockopt 208
+#define __NR_getsockopt 209
+#define __NR_shutdown 210
+#define __NR_sendmsg 211
+#define __NR_recvmsg 212
+#define __NR_readahead 213
+#define __NR_brk 214
+#define __NR_munmap 215
+#define __NR_mremap 216
+#define __NR_add_key 217
+#define __NR_request_key 218
+#define __NR_keyctl 219
+#define __NR_clone 220
+#define __NR_execve 221
+#define __NR_mmap 222
+#define __NR_fadvise64 223
+#define __NR_swapon 224
+#define __NR_swapoff 225
+#define __NR_mprotect 226
+#define __NR_msync 227
+#define __NR_mlock 228
+#define __NR_munlock 229
+#define __NR_mlockall 230
+#define __NR_munlockall 231
+#define __NR_mincore 232
+#define __NR_madvise 233
+#define __NR_remap_file_pages 234
+#define __NR_mbind 235
+#define __NR_get_mempolicy 236
+#define __NR_set_mempolicy 237
+#define __NR_migrate_pages 238
+#define __NR_move_pages 239
+#define __NR_rt_tgsigqueueinfo 240
+#define __NR_perf_event_open 241
+#define __NR_accept4 242
+#define __NR_recvmmsg 243
+#define __NR_arch_specific_syscall 244
+#define __NR_wait4 260
+#define __NR_prlimit64 261
+#define __NR_fanotify_init 262
+#define __NR_fanotify_mark 263
+#define __NR_name_to_handle_at 264
+#define __NR_open_by_handle_at 265
+#define __NR_clock_adjtime 266
+#define __NR_syncfs 267
+#define __NR_setns 268
+#define __NR_sendmmsg 269
+#define __NR_process_vm_readv 270
+#define __NR_process_vm_writev 271
+#define __NR_kcmp 272
+#define __NR_finit_module 273
+#define __NR_sched_setattr 274
+#define __NR_sched_getattr 275
+#define __NR_renameat2 276
+#define __NR_seccomp 277
+#define __NR_getrandom 278
+#define __NR_memfd_create 279
+#define __NR_bpf 280
+#define __NR_execveat 281
+#define __NR_userfaultfd 282
+#define __NR_membarrier 283
+#define __NR_mlock2 284
+#define __NR_copy_file_range 285
+#define __NR_preadv2 286
+#define __NR_pwritev2 287
+#define __NR_pkey_mprotect 288
+#define __NR_pkey_alloc 289
+#define __NR_pkey_free 290
+#define __NR_statx 291
+#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_close_range 436
+#define __NR_openat2 437
+#define __NR_pidfd_getfd 438
+#define __NR_faccessat2 439
+#define __NR_process_madvise 440
+#define __NR_syscalls (__NR_process_madvise+1)
+#define __NR_newfstatat  __NR_fstatat
+#define __NR_fcntl64  __NR_fcntl
+#define __NR_statfs64  __NR_statfs
+#define __NR_fstatfs64  __NR_fstatfs
+#define __NR_truncate64  __NR_truncate
+#define __NR_ftruncate64  __NR_ftruncate
+#define __NR__llseek  __NR_lseek
+#define __NR_sendfile64  __NR_sendfile
+#define __NR_fstatat64  __NR_fstatat
+#define __NR_fstat64  __NR_fstat
+#define __NR_mmap2  __NR_mmap
+#define __NR_fadvise64_64  __NR_fadvise64
diff --git a/arch/hexagon/crt_arch.h b/arch/hexagon/crt_arch.h
new file mode 100644
index 00000000..9f9428cf
--- /dev/null
+++ b/arch/hexagon/crt_arch.h
@@ -0,0 +1,22 @@
+__asm__(
+".weak _DYNAMIC \n"
+".hidden _DYNAMIC \n"
+".text \n"
+".global " START " \n"
+".type " START ", %function \n"
+START ": \n"
+"                                       // Find _DYNAMIC\n"
+"       jump 1f\n"
+".word  _DYNAMIC - .\n"
+"1:     r2 = pc\n"
+"       r2 = add(r2, #-4)\n"
+"       r1 = memw(r2)\n"
+"       r1 = add(r2, r1)\n"
+"	r30 = #0			// Signals the end of backtrace\n"
+"	r0 = r29			// Pointer to argc/argv\n"
+"	r29 = and(r29, #-16)		// Align\n"
+"	memw(r29+#-8) = r29\n"
+"	r29 = add(r29, #-8)\n"
+"	call " START "_c \n"
+".size " START ", .-" START "\n"
+);
diff --git a/arch/hexagon/kstat.h b/arch/hexagon/kstat.h
new file mode 100644
index 00000000..92625f36
--- /dev/null
+++ b/arch/hexagon/kstat.h
@@ -0,0 +1,21 @@
+struct kstat {
+	dev_t st_dev;
+	ino_t st_ino;
+	mode_t st_mode;
+	nlink_t st_nlink;
+	uid_t st_uid;
+	gid_t st_gid;
+	dev_t st_rdev;
+	unsigned long __pad;
+	off_t st_size;
+	blksize_t st_blksize;
+	int __pad2;
+	blkcnt_t st_blocks;
+	long st_atime_sec;
+	long st_atime_nsec;
+	long st_mtime_sec;
+	long st_mtime_nsec;
+	long st_ctime_sec;
+	long st_ctime_nsec;
+	unsigned __unused[2];
+};
diff --git a/arch/hexagon/pthread_arch.h b/arch/hexagon/pthread_arch.h
new file mode 100644
index 00000000..b614fdd1
--- /dev/null
+++ b/arch/hexagon/pthread_arch.h
@@ -0,0 +1,13 @@
+// Hexagon supports variant 2 TLS.
+static inline uintptr_t __get_tp()
+{
+  uintptr_t tp;
+  __asm__ ( "%0 = ugp" : "=r"(tp));
+  return tp;
+}
+
+#define TP_ADJ(p) (p)
+
+#define CANCEL_REG_IP 43
+
+#define MC_PC pc
diff --git a/arch/hexagon/reloc.h b/arch/hexagon/reloc.h
new file mode 100644
index 00000000..de171961
--- /dev/null
+++ b/arch/hexagon/reloc.h
@@ -0,0 +1,16 @@
+#include <endian.h>
+
+#define LDSO_ARCH "hexagon"
+#define TPOFF_K 0
+
+#define REL_SYMBOLIC    R_HEX_32
+#define REL_GOT         R_HEX_GLOB_DAT
+#define REL_PLT         R_HEX_JMP_SLOT
+#define REL_RELATIVE    R_HEX_RELATIVE
+#define REL_COPY        R_HEX_COPY
+#define REL_DTPMOD      R_HEX_DTPMOD_32
+#define REL_TPOFF       R_HEX_TPREL_32
+#define REL_DTPOFF      R_HEX_DTPREL_32
+
+#define CRTJMP(pc,sp) __asm__ __volatile__( \
+	"r29 = %1 ; jumpr %0" : : "r"(pc), "r"(sp) : "memory" )
diff --git a/arch/hexagon/syscall_arch.h b/arch/hexagon/syscall_arch.h
new file mode 100644
index 00000000..625ec039
--- /dev/null
+++ b/arch/hexagon/syscall_arch.h
@@ -0,0 +1,78 @@
+
+#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) 0, __SYSCALL_LL_E((x))
+
+#define __asm_syscall(...) do { \
+    __asm__ __volatile__ ( "trap0(#1)" \
+    : "=r"(r0) : __VA_ARGS__ : "memory"); \
+    return r0; \
+    } while (0)
+
+static inline long __syscall0(long n)
+{
+  register long r6 __asm__("r6") = n;
+  register long r0 __asm__("r0");
+  __asm_syscall("r"(r6));
+}
+
+static inline long __syscall1(long n, long a)
+{
+  register long r6 __asm__("r6") = n;
+  register long r0 __asm__("r0") = a;
+  __asm_syscall("r"(r6), "0"(r0));
+}
+
+static inline long __syscall2(long n, long a, long b)
+{
+  register long r6 __asm__("r6") = n;
+  register long r0 __asm__("r0") = a;
+  register long r1 __asm__("r1") = b;
+  __asm_syscall("r"(r6), "0"(r0), "r"(r1));
+}
+
+static inline long __syscall3(long n, long a, long b, long c)
+{
+  register long r6 __asm__("r6") = n;
+  register long r0 __asm__("r0") = a;
+  register long r1 __asm__("r1") = b;
+  register long r2 __asm__("r2") = c;
+  __asm_syscall("r"(r6), "0"(r0), "r"(r1), "r"(r2));
+}
+
+static inline long __syscall4(long n, long a, long b, long c, long d)
+{
+  register long r6 __asm__("r6") = n;
+  register long r0 __asm__("r0") = a;
+  register long r1 __asm__("r1") = b;
+  register long r2 __asm__("r2") = c;
+  register long r3 __asm__("r3") = d;
+  __asm_syscall("r"(r6), "0"(r0), "r"(r1), "r"(r2), "r"(r3));
+}
+
+static inline long __syscall5(long n, long a, long b, long c, long d, long e)
+{
+  register long r6 __asm__("r6") = n;
+  register long r0 __asm__("r0") = a;
+  register long r1 __asm__("r1") = b;
+  register long r2 __asm__("r2") = c;
+  register long r3 __asm__("r3") = d;
+  register long r4 __asm__("r4") = e;
+  __asm_syscall("r"(r6), "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4));
+}
+
+static inline long __syscall6(long n, long a, long b, long c, long d, long e,
+                              long f)
+{
+  register long r6 __asm__("r6") = n;
+  register long r0 __asm__("r0") = a;
+  register long r1 __asm__("r1") = b;
+  register long r2 __asm__("r2") = c;
+  register long r3 __asm__("r3") = d;
+  register long r4 __asm__("r4") = e;
+  register long r5 __asm__("r5") = f;
+  __asm_syscall("r"(r6), "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5));
+}
+
+#define SYSCALL_FADVISE_6_ARG
diff --git a/configure b/configure
index 0b966ede..a381aef6 100755
--- a/configure
+++ b/configure
@@ -323,6 +323,7 @@ case "$target" in
 # Catch these early to simplify matching for 32-bit archs
 arm*) ARCH=arm ;;
 aarch64*) ARCH=aarch64 ;;
+hexagon*) ARCH=hexagon ;;
 i?86-nt32*) ARCH=nt32 ;;
 i?86*) ARCH=i386 ;;
 x86_64-x32*|x32*|x86_64*x32) ARCH=x32 ;;
diff --git a/include/elf.h b/include/elf.h
index 23f2c4bc..5b2551c3 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -3293,6 +3293,107 @@ enum
 #define R_RISCV_SET32           56
 #define R_RISCV_32_PCREL        57
 
+#define R_HEX_NONE               0
+#define R_HEX_B22_PCREL          1
+#define R_HEX_B15_PCREL          2
+#define R_HEX_B7_PCREL           3
+#define R_HEX_LO16               4
+#define R_HEX_HI16               5
+#define R_HEX_32                 6
+#define R_HEX_16                 7
+#define R_HEX_8                  8
+#define R_HEX_GPREL16_0          9
+#define R_HEX_GPREL16_1         10
+#define R_HEX_GPREL16_2         11
+#define R_HEX_GPREL16_3         12
+#define R_HEX_HL16              13
+#define R_HEX_B13_PCREL         14
+#define R_HEX_B9_PCREL          15
+#define R_HEX_B32_PCREL_X       16
+#define R_HEX_32_6_X            17
+#define R_HEX_B22_PCREL_X       18
+#define R_HEX_B15_PCREL_X       19
+#define R_HEX_B13_PCREL_X       20
+#define R_HEX_B9_PCREL_X        21
+#define R_HEX_B7_PCREL_X        22
+#define R_HEX_16_X              23
+#define R_HEX_12_X              24
+#define R_HEX_11_X              25
+#define R_HEX_10_X              26
+#define R_HEX_9_X               27
+#define R_HEX_8_X               28
+#define R_HEX_7_X               29
+#define R_HEX_6_X               30
+#define R_HEX_32_PCREL          31
+#define R_HEX_COPY              32
+#define R_HEX_GLOB_DAT          33
+#define R_HEX_JMP_SLOT          34
+#define R_HEX_RELATIVE          35
+#define R_HEX_PLT_B22_PCREL     36
+#define R_HEX_GOTOFF_LO16       37
+#define R_HEX_GOTOFF_HI16       38
+#define R_HEX_GOTOFF_32         39
+#define R_HEX_GOT_LO16          40
+#define R_HEX_GOT_HI16          41
+#define R_HEX_GOT_32            42
+#define R_HEX_GOT_16            43
+#define R_HEX_DTPMOD_32         44
+#define R_HEX_DTPREL_LO16       45
+#define R_HEX_DTPREL_HI16       46
+#define R_HEX_DTPREL_32         47
+#define R_HEX_DTPREL_16         48
+#define R_HEX_GD_PLT_B22_PCREL  49
+#define R_HEX_GD_GOT_LO16       50
+#define R_HEX_GD_GOT_HI16       51
+#define R_HEX_GD_GOT_32         52
+#define R_HEX_GD_GOT_16         53
+#define R_HEX_IE_LO16           54
+#define R_HEX_IE_HI16           55
+#define R_HEX_IE_32             56
+#define R_HEX_IE_GOT_LO16       57
+#define R_HEX_IE_GOT_HI16       58
+#define R_HEX_IE_GOT_32         59
+#define R_HEX_IE_GOT_16         60
+#define R_HEX_TPREL_LO16        61
+#define R_HEX_TPREL_HI16        62
+#define R_HEX_TPREL_32          63
+#define R_HEX_TPREL_16          64
+#define R_HEX_6_PCREL_X         65
+#define R_HEX_GOTREL_32_6_X     66
+#define R_HEX_GOTREL_16_X       67
+#define R_HEX_GOTREL_11_X       68
+#define R_HEX_GOT_32_6_X        69
+#define R_HEX_GOT_16_X          70
+#define R_HEX_GOT_11_X          71
+#define R_HEX_DTPREL_32_6_X     72
+#define R_HEX_DTPREL_16_X       73
+#define R_HEX_DTPREL_11_X       74
+#define R_HEX_GD_GOT_32_6_X     75
+#define R_HEX_GD_GOT_16_X       76
+#define R_HEX_GD_GOT_11_X       77
+#define R_HEX_IE_32_6_X         78
+#define R_HEX_IE_16_X           79
+#define R_HEX_IE_GOT_32_6_X     80
+#define R_HEX_IE_GOT_16_X       81
+#define R_HEX_IE_GOT_11_X       82
+#define R_HEX_TPREL_32_6_X      83
+#define R_HEX_TPREL_16_X        84
+#define R_HEX_TPREL_11_X        85
+#define R_HEX_LD_PLT_B22_PCREL  86
+#define R_HEX_LD_GOT_LO16       87
+#define R_HEX_LD_GOT_HI16       88
+#define R_HEX_LD_GOT_32         89
+#define R_HEX_LD_GOT_16         90
+#define R_HEX_LD_GOT_32_6_X     91
+#define R_HEX_LD_GOT_16_X       92
+#define R_HEX_LD_GOT_11_X       93
+#define R_HEX_23_REG            94
+#define R_HEX_GD_PLT_B22_PCREL_X 95
+#define R_HEX_GD_PLT_B32_PCREL_X 96
+#define R_HEX_LD_PLT_B22_PCREL_X 97
+#define R_HEX_LD_PLT_B32_PCREL_X 98
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/setjmp/hexagon/longjmp.s b/src/setjmp/hexagon/longjmp.s
new file mode 100644
index 00000000..691b67dd
--- /dev/null
+++ b/src/setjmp/hexagon/longjmp.s
@@ -0,0 +1,25 @@
+.text
+.global _longjmp
+.global longjmp
+.type _longjmp,%function
+.type longjmp,%function
+_longjmp:
+longjmp:
+    { r17:16=memd(r0+#0)
+      r19:18=memd(r0+#8) }
+    { r21:20=memd(r0+#16)
+      r23:22=memd(r0+#24) }
+    { r25:24=memd(r0+#32)
+      r27:26=memd(r0+#40) }
+    { r29:28=memd(r0+#48)
+      r31:30=memd(r0+#56) }
+
+    r0 = r1
+    r1 = #0
+    p0 = cmp.eq(r0,r1)
+    if (!p0) jumpr r31
+    r0 = #1
+
+    jumpr r31
+.size _longjmp, .-_longjmp
+.size longjmp, .-longjmp
diff --git a/src/setjmp/hexagon/setjmp.s b/src/setjmp/hexagon/setjmp.s
new file mode 100644
index 00000000..d29f036e
--- /dev/null
+++ b/src/setjmp/hexagon/setjmp.s
@@ -0,0 +1,24 @@
+.text
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type __setjmp,@function
+.type _setjmp,@function
+.type setjmp,@function
+__setjmp:
+_setjmp:
+setjmp:
+    { memd(r0+#0)=r17:16
+      memd(r0+#8)=r19:18 }
+    { memd(r0+#16)=r21:20
+      memd(r0+#24)=r23:22 }
+    { memd(r0+#32)=r25:24
+      memd(r0+#40)=r27:26 }
+    { memd(r0+#48)=r29:28
+      memd(r0+#56)=r31:30 }
+
+    r0 = #0
+    jumpr r31
+.size __setjmp, .-__setjmp
+.size _setjmp, .-_setjmp
+.size setjmp, .-setjmp
diff --git a/src/signal/hexagon/restore.s b/src/signal/hexagon/restore.s
new file mode 100644
index 00000000..f43f5e02
--- /dev/null
+++ b/src/signal/hexagon/restore.s
@@ -0,0 +1,11 @@
+// TODO - Test this if sa_restorer is ever supported in our kernel
+.global __restore
+.type __restore,%function
+.global __restore_rt
+.type __restore_rt,%function
+__restore:
+__restore_rt:
+	r6 = #139				// SYS_rt_sigreturn
+	trap0(#0)
+.size __restore, .-__restore
+.size __restore_rt, .-__restore_rt
diff --git a/src/signal/hexagon/sigsetjmp.s b/src/signal/hexagon/sigsetjmp.s
new file mode 100644
index 00000000..f1aaf165
--- /dev/null
+++ b/src/signal/hexagon/sigsetjmp.s
@@ -0,0 +1,28 @@
+.global sigsetjmp
+.global __sigsetjmp
+.type sigsetjmp,@function
+.type __sigsetjmp,@function
+.balign 4
+sigsetjmp:
+__sigsetjmp:
+	// if savemask is 0 sigsetjmp behaves like setjmp
+	{
+		p0 = cmp.eq(r1, #0)
+		if (p0.new) jump:t ##setjmp
+	}
+	{
+		memw(r0+#64+4+8) = r16  // save r16 in __ss[2]
+		memw(r0+#64)   = r31  // save linkregister in __fl
+		r16 = r0
+	}
+		call ##setjmp
+	{
+		r1 = r0;
+		r0  = r16             // restore r0
+		r31 = memw(r16+#64)   // restore linkregister
+		r16 = memw(r16+#64+4+8) // restore r16 from __ss[2]
+	}
+.hidden __sigsetjmp_tail
+	jump ##__sigsetjmp_tail
+
+.size	sigsetjmp, .-sigsetjmp
diff --git a/src/thread/hexagon/__set_thread_area.s b/src/thread/hexagon/__set_thread_area.s
new file mode 100644
index 00000000..87a991b7
--- /dev/null
+++ b/src/thread/hexagon/__set_thread_area.s
@@ -0,0 +1,7 @@
+.global __set_thread_area
+.type   __set_thread_area,@function
+__set_thread_area:
+	{ ugp = r0
+	  r0 = #0
+	  jumpr r31 }
+.size __set_thread_area, .-__set_thread_area
diff --git a/src/thread/hexagon/__unmapself.s b/src/thread/hexagon/__unmapself.s
new file mode 100644
index 00000000..c47dce21
--- /dev/null
+++ b/src/thread/hexagon/__unmapself.s
@@ -0,0 +1,11 @@
+#include <syscall.h>
+
+.global __unmapself
+.type   __unmapself,%function
+__unmapself:
+	r6 = #215			// SYS_munmap
+	trap0(#1)
+	r6 = #93			// SYS_exit
+	trap0(#1)
+	jumpr r31
+.size __unmapself, .-__unmapself
diff --git a/src/thread/hexagon/clone.s b/src/thread/hexagon/clone.s
new file mode 100644
index 00000000..42aab67a
--- /dev/null
+++ b/src/thread/hexagon/clone.s
@@ -0,0 +1,37 @@
+// __clone(func, stack, flags, arg, ptid, tls, ctid)
+//         r0,   r1,    r2,    r3,  r4,   r5,  stack
+
+// tid = syscall(SYS_clone, flags, stack, ptid, ctid, tls)
+//               r6,        r0,    r1,    r2,   r3,   r4
+// if (tid != 0) return
+// func(arg)
+// syscall(SYS_exit)
+
+.text
+.global __clone
+.type   __clone,%function
+__clone:
+	allocframe(#8)
+	// Save pointers for later
+	{ r11 = r0
+	  r10 = r3 }
+
+	// Set up syscall args - The stack must be 8 byte aligned.
+	{ r0 = r2
+	  r1 = and(r1, ##0xfffffff8)
+	  r2 = r4 }
+	{
+	  r3 = memw(r30+#8)
+	  r4 = r5 }
+	r6 = #220			// SYS_clone
+	trap0(#1)
+
+	p0 = cmp.eq(r0, #0)
+	if (!p0) dealloc_return
+
+	{ r0 = r10
+	  callr r11 }
+
+	r6 = #93			// SYS_exit
+	trap0(#1)
+.size __clone, .-__clone
diff --git a/src/thread/hexagon/syscall_cp.s b/src/thread/hexagon/syscall_cp.s
new file mode 100644
index 00000000..50383cad
--- /dev/null
+++ b/src/thread/hexagon/syscall_cp.s
@@ -0,0 +1,35 @@
+// __syscall_cp_asm(&self->cancel, nr,  u, v, w, x, y,    z)
+//                  r0             r1  r2 r3 r4 r5  stack stack
+
+// syscall(nr,  u, v, w, x, y, z)
+//         r6  r0 r1 r2 r3 r4 r5
+
+.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:
+	r0 = memw(r0+#0)
+	{
+	  p0 = cmp.eq(r0, #0); if (!p0.new) jump:nt __cancel
+	}
+	{ r6 = r1
+	  r1:0 = combine(r3, r2)
+	  r3:2 = combine(r5, r4) }
+	{ r4 = memw(r29+#0)
+	  r5 = memw(r29+#4) }
+	trap0(#1)
+__cp_end:
+	jumpr r31
+.size __syscall_cp_asm, .-__syscall_cp_asm
+__cp_cancel:
+        jump __cancel
+.size __cp_cancel, .-__cp_cancel
-- 
2.37.2

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.