From 3df67dc4148b9d2db8cd4b95a64048123b2a3b58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Mon, 7 Apr 2025 19:08:07 +0200 Subject: [PATCH] musl: Add hexagon-linux-musl sources. This is from Qualcomm's fork: https://github.com/quic/musl I maintain a fork of musl where I rebase Qualcomm's changes on top of the latest musl release, which I then use as the basis for musl updates in Zig. My fork can be found here: https://github.com/alexrp/musl/tree/hexagon --- lib/libc/musl/arch/hexagon/atomic_arch.h | 191 ++++++++++++++++++ lib/libc/musl/arch/hexagon/bits/fenv.h | 20 ++ lib/libc/musl/arch/hexagon/bits/float.h | 16 ++ lib/libc/musl/arch/hexagon/bits/ipcstat.h | 1 + lib/libc/musl/arch/hexagon/bits/msg.h | 18 ++ lib/libc/musl/arch/hexagon/bits/posix.h | 2 + lib/libc/musl/arch/hexagon/bits/sem.h | 13 ++ lib/libc/musl/arch/hexagon/bits/setjmp.h | 1 + lib/libc/musl/arch/hexagon/bits/shm.h | 31 +++ lib/libc/musl/arch/hexagon/bits/signal.h | 103 ++++++++++ lib/libc/musl/arch/hexagon/bits/stat.h | 20 ++ lib/libc/musl/arch/hexagon/bits/stdint.h | 20 ++ lib/libc/musl/arch/hexagon/bits/user.h | 60 ++++++ lib/libc/musl/arch/hexagon/crt_arch.h | 22 ++ lib/libc/musl/arch/hexagon/kstat.h | 21 ++ lib/libc/musl/arch/hexagon/pthread_arch.h | 13 ++ lib/libc/musl/arch/hexagon/reloc.h | 16 ++ lib/libc/musl/arch/hexagon/syscall_arch.h | 78 +++++++ lib/libc/musl/include/elf.h | 101 +++++++++ lib/libc/musl/src/fenv/hexagon/fenv.S | 144 +++++++++++++ lib/libc/musl/src/setjmp/hexagon/longjmp.s | 25 +++ lib/libc/musl/src/setjmp/hexagon/setjmp.s | 24 +++ lib/libc/musl/src/signal/hexagon/restore.s | 11 + lib/libc/musl/src/signal/hexagon/sigsetjmp.s | 28 +++ .../src/thread/hexagon/__set_thread_area.s | 7 + .../musl/src/thread/hexagon/__unmapself.s | 11 + lib/libc/musl/src/thread/hexagon/clone.s | 37 ++++ lib/libc/musl/src/thread/hexagon/syscall_cp.s | 35 ++++ 28 files changed, 1069 insertions(+) create mode 100644 lib/libc/musl/arch/hexagon/atomic_arch.h create mode 100644 lib/libc/musl/arch/hexagon/bits/fenv.h create mode 100644 lib/libc/musl/arch/hexagon/bits/float.h create mode 100644 lib/libc/musl/arch/hexagon/bits/ipcstat.h create mode 100644 lib/libc/musl/arch/hexagon/bits/msg.h create mode 100644 lib/libc/musl/arch/hexagon/bits/posix.h create mode 100644 lib/libc/musl/arch/hexagon/bits/sem.h create mode 100644 lib/libc/musl/arch/hexagon/bits/setjmp.h create mode 100644 lib/libc/musl/arch/hexagon/bits/shm.h create mode 100644 lib/libc/musl/arch/hexagon/bits/signal.h create mode 100644 lib/libc/musl/arch/hexagon/bits/stat.h create mode 100644 lib/libc/musl/arch/hexagon/bits/stdint.h create mode 100644 lib/libc/musl/arch/hexagon/bits/user.h create mode 100644 lib/libc/musl/arch/hexagon/crt_arch.h create mode 100644 lib/libc/musl/arch/hexagon/kstat.h create mode 100644 lib/libc/musl/arch/hexagon/pthread_arch.h create mode 100644 lib/libc/musl/arch/hexagon/reloc.h create mode 100644 lib/libc/musl/arch/hexagon/syscall_arch.h create mode 100644 lib/libc/musl/src/fenv/hexagon/fenv.S create mode 100644 lib/libc/musl/src/setjmp/hexagon/longjmp.s create mode 100644 lib/libc/musl/src/setjmp/hexagon/setjmp.s create mode 100644 lib/libc/musl/src/signal/hexagon/restore.s create mode 100644 lib/libc/musl/src/signal/hexagon/sigsetjmp.s create mode 100644 lib/libc/musl/src/thread/hexagon/__set_thread_area.s create mode 100644 lib/libc/musl/src/thread/hexagon/__unmapself.s create mode 100644 lib/libc/musl/src/thread/hexagon/clone.s create mode 100644 lib/libc/musl/src/thread/hexagon/syscall_cp.s diff --git a/lib/libc/musl/arch/hexagon/atomic_arch.h b/lib/libc/musl/arch/hexagon/atomic_arch.h new file mode 100644 index 0000000000..b25af3d453 --- /dev/null +++ b/lib/libc/musl/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/lib/libc/musl/arch/hexagon/bits/fenv.h b/lib/libc/musl/arch/hexagon/bits/fenv.h new file mode 100644 index 0000000000..d33493061b --- /dev/null +++ b/lib/libc/musl/arch/hexagon/bits/fenv.h @@ -0,0 +1,20 @@ +#define FE_INVALID (1 << 1) +#define FE_DIVBYZERO (1 << 2) +#define FE_OVERFLOW (1 << 3) +#define FE_UNDERFLOW (1 << 4) +#define FE_INEXACT (1 << 5) +#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \ + FE_OVERFLOW | FE_UNDERFLOW) + +#define FE_TONEAREST 0x00 +#define FE_TOWARDZERO 0x01 +#define FE_DOWNWARD 0x02 +#define FE_UPWARD 0x03 + +typedef unsigned long fexcept_t; + +typedef struct { + unsigned long __cw; +} fenv_t; + +#define FE_DFL_ENV ((const fenv_t *) -1) diff --git a/lib/libc/musl/arch/hexagon/bits/float.h b/lib/libc/musl/arch/hexagon/bits/float.h new file mode 100644 index 0000000000..c4a655e7b5 --- /dev/null +++ b/lib/libc/musl/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/lib/libc/musl/arch/hexagon/bits/ipcstat.h b/lib/libc/musl/arch/hexagon/bits/ipcstat.h new file mode 100644 index 0000000000..4f4fcb0c5b --- /dev/null +++ b/lib/libc/musl/arch/hexagon/bits/ipcstat.h @@ -0,0 +1 @@ +#define IPC_STAT 0x102 diff --git a/lib/libc/musl/arch/hexagon/bits/msg.h b/lib/libc/musl/arch/hexagon/bits/msg.h new file mode 100644 index 0000000000..7bbbb2bf43 --- /dev/null +++ b/lib/libc/musl/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/lib/libc/musl/arch/hexagon/bits/posix.h b/lib/libc/musl/arch/hexagon/bits/posix.h new file mode 100644 index 0000000000..30a38714f3 --- /dev/null +++ b/lib/libc/musl/arch/hexagon/bits/posix.h @@ -0,0 +1,2 @@ +#define _POSIX_V6_ILP32_OFFBIG 1 +#define _POSIX_V7_ILP32_OFFBIG 1 diff --git a/lib/libc/musl/arch/hexagon/bits/sem.h b/lib/libc/musl/arch/hexagon/bits/sem.h new file mode 100644 index 0000000000..65661542a5 --- /dev/null +++ b/lib/libc/musl/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/lib/libc/musl/arch/hexagon/bits/setjmp.h b/lib/libc/musl/arch/hexagon/bits/setjmp.h new file mode 100644 index 0000000000..2d75319a37 --- /dev/null +++ b/lib/libc/musl/arch/hexagon/bits/setjmp.h @@ -0,0 +1 @@ +typedef long long __jmp_buf[8]; diff --git a/lib/libc/musl/arch/hexagon/bits/shm.h b/lib/libc/musl/arch/hexagon/bits/shm.h new file mode 100644 index 0000000000..725fb46968 --- /dev/null +++ b/lib/libc/musl/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/lib/libc/musl/arch/hexagon/bits/signal.h b/lib/libc/musl/arch/hexagon/bits/signal.h new file mode 100644 index 0000000000..b119f16378 --- /dev/null +++ b/lib/libc/musl/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/lib/libc/musl/arch/hexagon/bits/stat.h b/lib/libc/musl/arch/hexagon/bits/stat.h new file mode 100644 index 0000000000..55e81fd979 --- /dev/null +++ b/lib/libc/musl/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/lib/libc/musl/arch/hexagon/bits/stdint.h b/lib/libc/musl/arch/hexagon/bits/stdint.h new file mode 100644 index 0000000000..d1b2712199 --- /dev/null +++ b/lib/libc/musl/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/lib/libc/musl/arch/hexagon/bits/user.h b/lib/libc/musl/arch/hexagon/bits/user.h new file mode 100644 index 0000000000..4396385df6 --- /dev/null +++ b/lib/libc/musl/arch/hexagon/bits/user.h @@ -0,0 +1,60 @@ +#ifndef HEXAGON_ASM_USER_H +#define HEXAGON_ASM_USER_H + +struct user_regs_struct { + unsigned long r0; + unsigned long r1; + unsigned long r2; + unsigned long r3; + unsigned long r4; + unsigned long r5; + unsigned long r6; + unsigned long r7; + unsigned long r8; + unsigned long r9; + unsigned long r10; + unsigned long r11; + unsigned long r12; + unsigned long r13; + unsigned long r14; + unsigned long r15; + unsigned long r16; + unsigned long r17; + unsigned long r18; + unsigned long r19; + unsigned long r20; + unsigned long r21; + unsigned long r22; + unsigned long r23; + unsigned long r24; + unsigned long r25; + unsigned long r26; + unsigned long r27; + unsigned long r28; + unsigned long r29; + unsigned long r30; + unsigned long 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 cs0; + unsigned long cs1; + unsigned long pad1; +}; + +#define ELF_NGREG 48 +typedef unsigned long elf_greg_t, elf_gregset_t[ELF_NGREG]; + +typedef unsigned long elf_fpregset_t; + +#endif diff --git a/lib/libc/musl/arch/hexagon/crt_arch.h b/lib/libc/musl/arch/hexagon/crt_arch.h new file mode 100644 index 0000000000..9f9428cf19 --- /dev/null +++ b/lib/libc/musl/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/lib/libc/musl/arch/hexagon/kstat.h b/lib/libc/musl/arch/hexagon/kstat.h new file mode 100644 index 0000000000..92625f3639 --- /dev/null +++ b/lib/libc/musl/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/lib/libc/musl/arch/hexagon/pthread_arch.h b/lib/libc/musl/arch/hexagon/pthread_arch.h new file mode 100644 index 0000000000..b614fdd177 --- /dev/null +++ b/lib/libc/musl/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/lib/libc/musl/arch/hexagon/reloc.h b/lib/libc/musl/arch/hexagon/reloc.h new file mode 100644 index 0000000000..de17196135 --- /dev/null +++ b/lib/libc/musl/arch/hexagon/reloc.h @@ -0,0 +1,16 @@ +#include + +#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/lib/libc/musl/arch/hexagon/syscall_arch.h b/lib/libc/musl/arch/hexagon/syscall_arch.h new file mode 100644 index 0000000000..625ec03963 --- /dev/null +++ b/lib/libc/musl/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/lib/libc/musl/include/elf.h b/lib/libc/musl/include/elf.h index 3d5e13e4b6..01dd31a6ff 100644 --- a/lib/libc/musl/include/elf.h +++ b/lib/libc/musl/include/elf.h @@ -3406,6 +3406,107 @@ enum #define R_LARCH_32_PCREL 99 #define R_LARCH_RELAX 100 +#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/lib/libc/musl/src/fenv/hexagon/fenv.S b/lib/libc/musl/src/fenv/hexagon/fenv.S new file mode 100644 index 0000000000..f5080a22cd --- /dev/null +++ b/lib/libc/musl/src/fenv/hexagon/fenv.S @@ -0,0 +1,144 @@ +/* + * The Hexagon user status register includes five status fields which work + * as sticky flags for the five IEEE-defined exception conditions: + * inexact, overflow, underflow, divide by zero, and invalid. + * A sticky flag is set when the corresponding exception occurs, + * and remains set until explicitly cleared. + * + * usr:23:22 - Rounding Mode + * 00: Round toward nearest + * 01: Round toward zero + * 10: Downward Round toward negative infinity + * 11: Upward Round toward positive infinity + * + * usr:5 - Floating-point IEEE Inexact Sticky Flag. + * usr:4 - Floating-point IEEE Underflow Sticky Flag. + * usr:3 - Floating-point IEEE Overflow Sticky Flag. + * usr:2 - Floating-point IEEE Divide-By-Zero Sticky Flag. + * usr:1 - Floating-point IEEE Invalid Sticky Flag. + * usr:0 - Sticky Saturation Overflow, when 1 saturation occurred. + */ + +#define FE_ALL_EXCEPT 0x3f + +#define USR_FE_MASK 0x3fc0003f +#define RND_MASK (0x3 << 22) +#define RND_NEAR (0x0 << 22) +#define RND_ZERO (0x1 << 22) +#define RND_DOWN (0x2 << 22) +#define RND_UP (0x3 << 22) + +/* + * int feclearexcept(int mask) + */ +.global feclearexcept +.type feclearexcept,@function +feclearexcept: + { + r0 = and(r0, #FE_ALL_EXCEPT) // Only touch the IEEE flag bits. + r1 = usr + } + r1 = and(r1, ~r0) + { + usr = r1 + r0 = #0 + jumpr r31 + } + +/* + * int feraiseexcept(int mask) + */ +.global feraiseexcept +.type feraiseexcept,@function +feraiseexcept: + { + r0 = and(r0, #FE_ALL_EXCEPT) // Only touch the IEEE flag bits. + r1 = usr + } + r1 = or(r1, r0) + { + usr = r1 + r0 = #0 + jumpr r31 + } + + +/* + * int fetestexcept(int mask) + */ +.global fetestexcept +.type fetestexcept,@function +fetestexcept: + { + r0 = and(r0, #FE_ALL_EXCEPT) // Only touch the IEEE flag bits. + r1 = usr + } + { + r0 = and(r1, r0) + jumpr r31 + } + +/* + *int fegetround(void) + */ +.global fegetround +.type fegetround,@function +fegetround: + r0 = usr + r0 = and(r0, ##RND_MASK) + r0 = lsr(r0, #22); + jumpr r31 + +/* + * int __fesetround(int r) + */ +.global __fesetround +.type __fesetround,@function +__fesetround: + { + r0 = and(r0, #0x3) // Can only be 0,1,2, or 3 + r1 = usr + r2 = ##RND_MASK + } + { + r1 = and (r1, ~r2) // Clear the current rounding bits. + r0 = asl (r0, #22) + } + r1 = or(r1, r0) + usr = r1 + { + r0 = #0; jumpr r31 + } + +/* + * int fegetenv(fenv_t *envp) + */ +.global fegetenv +.type fegetenv,@function +fegetenv: + r1 = usr + memw(r0) = r1 + { + r0 = #0 + jumpr r31 + } + +/* + * int fesetenv(const fenv_t *envp) + */ +.global fesetenv +.type fesetenv,@function +fesetenv: + { p0 = cmp.eq(r0, #-1); if (p0.new) r1 = #0 } /* The default mode */ + if (!p0) r1 = memw(r0) /* stored in fenv_t */ + + r2 = ##USR_FE_MASK // USR:FE bit mask + r1 = and(r1, r2) // MASK the input bits with the FE bits + r3 = usr + r3 = and(r3, ~r2) // Clear any currently set FE bits + r3 = or(r3, r1) // Set the newbits + usr = r3 + { + r0 = #0 + jumpr r31 + } diff --git a/lib/libc/musl/src/setjmp/hexagon/longjmp.s b/lib/libc/musl/src/setjmp/hexagon/longjmp.s new file mode 100644 index 0000000000..691b67dddb --- /dev/null +++ b/lib/libc/musl/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/lib/libc/musl/src/setjmp/hexagon/setjmp.s b/lib/libc/musl/src/setjmp/hexagon/setjmp.s new file mode 100644 index 0000000000..d29f036e33 --- /dev/null +++ b/lib/libc/musl/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/lib/libc/musl/src/signal/hexagon/restore.s b/lib/libc/musl/src/signal/hexagon/restore.s new file mode 100644 index 0000000000..f43f5e02dc --- /dev/null +++ b/lib/libc/musl/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/lib/libc/musl/src/signal/hexagon/sigsetjmp.s b/lib/libc/musl/src/signal/hexagon/sigsetjmp.s new file mode 100644 index 0000000000..f1aaf1650a --- /dev/null +++ b/lib/libc/musl/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/lib/libc/musl/src/thread/hexagon/__set_thread_area.s b/lib/libc/musl/src/thread/hexagon/__set_thread_area.s new file mode 100644 index 0000000000..87a991b749 --- /dev/null +++ b/lib/libc/musl/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/lib/libc/musl/src/thread/hexagon/__unmapself.s b/lib/libc/musl/src/thread/hexagon/__unmapself.s new file mode 100644 index 0000000000..c47dce21e2 --- /dev/null +++ b/lib/libc/musl/src/thread/hexagon/__unmapself.s @@ -0,0 +1,11 @@ +#include + +.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/lib/libc/musl/src/thread/hexagon/clone.s b/lib/libc/musl/src/thread/hexagon/clone.s new file mode 100644 index 0000000000..42aab67a37 --- /dev/null +++ b/lib/libc/musl/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/lib/libc/musl/src/thread/hexagon/syscall_cp.s b/lib/libc/musl/src/thread/hexagon/syscall_cp.s new file mode 100644 index 0000000000..50383cad11 --- /dev/null +++ b/lib/libc/musl/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