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
This commit is contained in:
Alex Rønne Petersen 2025-04-07 19:08:07 +02:00
parent 30200edc1e
commit 3df67dc414
No known key found for this signature in database
28 changed files with 1069 additions and 0 deletions

View File

@ -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" );
}

View File

@ -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)

View File

@ -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

View File

@ -0,0 +1 @@
#define IPC_STAT 0x102

View File

@ -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;
};

View File

@ -0,0 +1,2 @@
#define _POSIX_V6_ILP32_OFFBIG 1
#define _POSIX_V7_ILP32_OFFBIG 1

View File

@ -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;
};

View File

@ -0,0 +1 @@
typedef long long __jmp_buf[8];

View File

@ -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;
};

View File

@ -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

View File

@ -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];
};

View File

@ -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

View File

@ -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

View File

@ -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"
);

View File

@ -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];
};

View File

@ -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

View File

@ -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" )

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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