@@ -0,0 +1,144 @@
#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 8192
#define SIGSTKSZ (MINSIGSTKSZ + 32768)
#endif

#define ARCH_MIN_TASKALIGN 32
#define FPU_REG_WIDTH 256
#define FPU_ALIGN __attribute__((aligned(32)))

#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
typedef unsigned long greg_t, gregset_t[32];

struct sigcontext {
unsigned long sc_pc;
unsigned long sc_regs[32];
unsigned int sc_flags;
unsigned int sc_fcsr;
unsigned int sc_vcsr;
unsigned long sc_fcc;
unsigned long sc_scr[4];
union {
unsigned int val32[FPU_REG_WIDTH / 32];
unsigned long long val64[FPU_REG_WIDTH / 64];
} sc_fpregs[32] FPU_ALIGN;
unsigned char sc_reserved[4096] __attribute__((__aligned__(16)));
};

typedef struct {
unsigned long pc;
unsigned long gregs[32];
unsigned int flags;
unsigned int fcsr;
unsigned int vcsr;
unsigned long fcc;
unsigned long scr[4];
union {
unsigned int val32[FPU_REG_WIDTH / 32];
unsigned long long val64[FPU_REG_WIDTH / 64];
} fpregs[32] FPU_ALIGN;
unsigned char reserved[4096] __attribute__((__aligned__(16)));
} mcontext_t;

#else
typedef struct {
unsigned long __mc1[32];
union {
unsigned int val32[FPU_REG_WIDTH / 32];
unsigned long long val64[FPU_REG_WIDTH / 64];
} _mc2[32] FPU_ALIGN;
unsigned int __mc3[3];
unsigned long __mc4[2];
unsigned long __mc5[4];
unsigned char reserved[4096] __attribute__((__aligned__(16)));
} 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 /* Don't send SIGCHLD when children stop. */
#define SA_NOCLDWAIT 2 /* Don't create zombie on child death. */
#define SA_SIGINFO 4 /* Invoke signal-catching function with
three arguments instead of one. */
#define SA_ONSTACK 0x08000000 /* Use signal stack by using `sa_restorer'. */
#define SA_RESTART 0x10000000 /* Restart syscall on signal return. */
#define SA_NODEFER 0x40000000 /* Don't automatically block the signal when
its handler is being executed. */
#define SA_RESETHAND 0x80000000 /* Reset to SIG_DFL on entry to handler. */
#define SA_RESTORER 0x04000000

#undef SIG_BLOCK
#undef SIG_UNBLOCK
#undef SIG_SETMASK
#define SIG_BLOCK 0
#define SIG_UNBLOCK 1
#define SIG_SETMASK 2

#undef SI_ASYNCIO
#undef SI_MESGQ
#undef SI_TIMER
#define SI_ASYNCIO (-4)
#define SI_MESGQ (-3)
#define SI_TIMER (-2)


#endif

#define SIGHUP 1
#define SIGINT 2
#define SIGQUIT 3
#define SIGILL 4
#define SIGTRAP 5
#define SIGABRT 6
#define SIGIOT 6
#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 SIGIO
/*
#define SIGLOST 29
*/
#define SIGPWR 30
#define SIGSYS 31

#define SIGUNUSED SIGSYS

#define _NSIG 128
@@ -0,0 +1,20 @@
struct stat {
dev_t st_dev;
int __pad1[3];
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 int __pad2[2];
off_t st_size;
int __pad3;
struct timespec st_atim;
struct timespec st_mtim;
struct timespec st_ctim;
blksize_t st_blksize;
unsigned int __pad4;
blkcnt_t st_blocks;
int __pad5[14];
};
@@ -0,0 +1,6 @@
struct statfs {
long f_type, f_bsize;
unsigned long f_blocks, f_bfree, f_bavail, f_files, f_ffree;
fsid_t f_fsid;
long f_namelen, f_frsize, f_flags, f_spare[4];
};
@@ -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 INT64_MIN
#define INTPTR_MAX INT64_MAX
#define UINTPTR_MAX UINT64_MAX
#define PTRDIFF_MIN INT64_MIN
#define PTRDIFF_MAX INT64_MAX
#define SIZE_MAX UINT64_MAX
@@ -0,0 +1,291 @@
#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 __NR3264_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_umount2 39
#define __NR_mount 40
#define __NR_pivot_root 41
#define __NR_nfsservctl 42
#define __NR3264_statfs 43
#define __NR3264_fstatfs 44
#define __NR3264_truncate 45
#define __NR3264_ftruncate 46
#define __NR_fallocate 47
#define __NR_faccessat 48
#define __NR_faccessat2 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 __NR3264_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 __NR3264_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 __NR3264_fstatat 79
#define __NR3264_fstat 80
#define __NR_sync 81
#define __NR_fsync 82
#define __NR_fdatasync 83
#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_gettime 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 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 __NR3264_mmap 222
#define __NR3264_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_io_pgetevents 292
#define __NR_rseq 293
#define __NR_syscalls 294
#define __NR_fcntl __NR3264_fcntl
#define __NR_statfs __NR3264_statfs
#define __NR_fstatfs __NR3264_fstatfs
#define __NR_truncate __NR3264_truncate
#define __NR_ftruncate __NR3264_ftruncate
#define __NR_lseek __NR3264_lseek
#define __NR_sendfile __NR3264_sendfile
#define __NR_newfstatat __NR3264_fstatat
#define __NR_fstat __NR3264_fstat
#define __NR_mmap __NR3264_mmap
#define __NR_fadvise64 __NR3264_fadvise64
@@ -0,0 +1,5 @@
#define ELF_NGREG 45
#define ELF_NFPREG 33

typedef unsigned long elf_greg_t, elf_gregset_t[ELF_NGREG];
typedef double elf_fpreg_t, elf_fpregset_t[ELF_NFPREG];
@@ -0,0 +1,23 @@
__asm__(
".text \n"
".global _" START "\n"
".global " START "\n"
".global " START "_data\n"
".type _" START ", @function\n"
".type " START ", @function\n"
".type " START "_data, @function\n"
"_" START ":\n"
"" START ":\n"
".align 8 \n"
" add.w $fp, $r0,$r0 \n"
" bl 1f \n"
"" START "_data: \n"
".weak _DYNAMIC \n"
".hidden _DYNAMIC \n"
"1: or $a0, $sp, $zero \n"
" la.local $a1, _DYNAMIC \n"
" addi.w $r19, $r0, -16 \n"
" and $sp, $sp, $r19 \n"
" la.local $t0," START "_c \n"
" jirl $t1,$t0,0 \n"
);
@@ -0,0 +1,13 @@
#include <features.h>

/* This is the structure used for the rt_sigaction syscall on most archs,
* but it can be overridden by a file with the same name in the top-level
* arch dir for a given arch, if necessary. */
struct k_sigaction {
void (*handler)(int);
unsigned long flags;
unsigned long mask[2];
void (*restorer)();
};

hidden void __restore(), __restore_rt();
@@ -0,0 +1,22 @@
struct kstat {
unsigned long st_dev; /* Device. */
unsigned long st_ino; /* File serial number. */
unsigned int st_mode; /* File mode. */
unsigned int st_nlink; /* Link count. */
unsigned int st_uid; /* User ID of the file's owner. */
unsigned int st_gid; /* Group ID of the file's group. */
unsigned long st_rdev; /* Device number, if device. */
unsigned long __pad1;
long st_size; /* Size of file, in bytes. */
int st_blksize; /* Optimal block size for I/O. */
int __pad2;
long st_blocks; /* Number 512-byte blocks allocated. */
long st_atime_sec; /* Time of last access. */
unsigned long st_atime_nsec;
long st_mtime_sec; /* Time of last modification. */
unsigned long st_mtime_nsec;
long st_ctime_sec; /* Time of last status change. */
unsigned long st_ctime_nsec;
unsigned int __unused4;
unsigned int __unused5;
};
@@ -0,0 +1,13 @@
static inline uintptr_t __get_tp()
{
uintptr_t tp;
__asm__ ("or %0, $tp, $zero" : "=r" (tp) );
return tp;
}

#define TLS_ABOVE_TP
#define GAP_ABOVE_TP 0

#define DTP_OFFSET 0

#define MC_PC pc
@@ -0,0 +1,43 @@
#ifndef __RELOC_H__
#define __RELOC_H__

#define _GNU_SOURCE
#include <endian.h>

#ifdef __loongarch64_soft_float
#define FP_SUFFIX "-sf"
#else
#define FP_SUFFIX ""
#endif

#define LDSO_ARCH "loongarch64" FP_SUFFIX

#define TPOFF_K (0x0)

//#define REL_SYM_OR_REL 4611
#define REL_PLT R_LOONGARCH_JUMP_SLOT
#define REL_COPY R_LOONGARCH_COPY
#define REL_DTPMOD R_LOONGARCH_TLS_DTPMOD64
#define REL_DTPOFF R_LOONGARCH_TLS_DTPREL64
#define REL_TPOFF R_LOONGARCH_TLS_TPREL64
#define REL_RELATIVE R_LOONGARCH_RELATIVE
#define REL_SYMBOLIC R_LOONGARCH_64

//#undef R_TYPE
//#undef R_SYM
//#undef R_INFO
//#define R_TYPE(x) (be64toh(x)&0x7fffffff)
//#define R_SYM(x) (be32toh(be64toh(x)>>32))
//#define R_INFO(s,t) (htobe64((uint64_t)htobe32(s)<<32 | (uint64_t)t))

#define CRTJMP(pc,sp) __asm__ __volatile__( \
"move $sp,%1 ; jr %0" : : "r"(pc), "r"(sp) : "memory" )

#define GETFUNCSYM(fp, sym, got) __asm__ ( \
".hidden " #sym "\n" \
".align 8 \n" \
" la.local $t1, "#sym" \n" \
" or %0, $t1, $zero \n" \
: "=r"(*(fp)) : : "memory" )

#endif
@@ -0,0 +1,121 @@
#define IPC_64 0x0

#define __SYSCALL_LL_E(x) (x)
#define __SYSCALL_LL_O(x) (x)

#define SYSCALL_CLOBBERLIST \
"$t0", "$t1", "$t2", "$t3", \
"$t4", "$t5", "$t6", "$t7", "$t8", "memory"

static inline long __syscall0(long n)
{
register long a0 __asm__("$a0");
register long a7 __asm__("$a7") = n;

__asm__ __volatile__ (
"syscall 0"
: "+&r"(a0)
: "r"(a7)
: SYSCALL_CLOBBERLIST);
return a0;
}

static inline long __syscall1(long n, long a)
{
register long a0 __asm__("$a0") = a;
register long a7 __asm__("$a7") = n;

__asm__ __volatile__ (
"syscall 0"
: "+&r"(a0)
: "r"(a7)
: SYSCALL_CLOBBERLIST);
return a0;
}

static inline long __syscall2(long n, long a, long b)
{
register long a0 __asm__("$a0") = a;
register long a1 __asm__("$a1") = b;
register long a7 __asm__("$a7") = n;

__asm__ __volatile__ (
"syscall 0"
: "+&r"(a0)
: "r"(a7), "r"(a1)
: SYSCALL_CLOBBERLIST);
return a0;
}

static inline long __syscall3(long n, long a, long b, long c)
{
register long a0 __asm__("$a0") = a;
register long a1 __asm__("$a1") = b;
register long a2 __asm__("$a2") = c;
register long a7 __asm__("$a7") = n;

__asm__ __volatile__ (
"syscall 0"
: "+&r"(a0)
: "r"(a7), "r"(a1), "r"(a2)
: SYSCALL_CLOBBERLIST);
return a0;
}

static inline long __syscall4(long n, long a, long b, long c, long d)
{
register long a0 __asm__("$a0") = a;
register long a1 __asm__("$a1") = b;
register long a2 __asm__("$a2") = c;
register long a3 __asm__("$a3") = d;
register long a7 __asm__("$a7") = n;

__asm__ __volatile__ (
"syscall 0"
: "+&r"(a0)
: "r"(a7), "r"(a1), "r"(a2), "r"(a3)
: SYSCALL_CLOBBERLIST);
return a0;
}

static inline long __syscall5(long n, long a, long b, long c, long d, long e)
{
register long a0 __asm__("$a0") = a;
register long a1 __asm__("$a1") = b;
register long a2 __asm__("$a2") = c;
register long a3 __asm__("$a3") = d;
register long a4 __asm__("$a4") = e;
register long a7 __asm__("$a7") = n;

__asm__ __volatile__ (
"syscall 0"
: "+&r"(a0)
: "r"(a7), "r"(a1), "r"(a2), "r"(a3), "r"(a4)
: SYSCALL_CLOBBERLIST);
return a0;
}

static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)
{
register long a0 __asm__("$a0") = a;
register long a1 __asm__("$a1") = b;
register long a2 __asm__("$a2") = c;
register long a3 __asm__("$a3") = d;
register long a4 __asm__("$a4") = e;
register long a5 __asm__("$a5") = f;
register long a7 __asm__("$a7") = n;

__asm__ __volatile__ (
"syscall 0"
: "+&r"(a0)
: "r"(a7), "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5)
: SYSCALL_CLOBBERLIST);
return a0;
}

#define VDSO_USEFUL
#define VDSO_CGT_SYM "__vdso_clock_gettime"
#define VDSO_CGT_VER "LINUX_2.6"

#define SO_SNDTIMEO_OLD 21
#define SO_RCVTIMEO_OLD 20
@@ -338,6 +338,7 @@ powerpc*|ppc*) ARCH=powerpc ;;
riscv64*) ARCH=riscv64 ;;
sh[1-9bel-]*|sh|superh*) ARCH=sh ;;
s390x*) ARCH=s390x ;;
loongarch64*) ARCH=loongarch64 ;;
unknown) fail "$0: unable to detect target arch; try $0 --target=..." ;;
*) fail "$0: unknown or unsupported target \"$target\"" ;;
esac
@@ -0,0 +1,15 @@
.section .init
.global _init
.align 3
_init:
addi.d $r3,$r3,-32
st.d $r31,$r3,16
st.d $r1,$r3,24

.section .fini
.global _fini
.align 3
_fini:
addi.d $r3,$r3,-32
st.d $r31,$r3,16
st.d $r1,$r3,24
@@ -0,0 +1,12 @@
.section .init
ld.d $r31,$r3,16
ld.d $r1,$r3,24
addi.d $r3,$r3,32
jirl $r0,$r1,0


.section .fini
ld.d $r31,$r3,16
ld.d $r1,$r3,24
addi.d $r3,$r3,32
jirl $r0,$r1,0
@@ -696,6 +696,10 @@ typedef struct {
#define NT_MIPS_FP_MODE 0x801
#define NT_MIPS_MSA 0x802
#define NT_VERSION 1
#define NT_LOONGARCH_CPUCFG 0x900 /* Loongarch CPU config registers */
#define NT_LOONGARCH_LBT 0x901 /* Loongarch Loongson Binary Translation registers */
#define NT_LOONGARCH_LSX 0x902 /* Loongarch Loongson SIMD Extension registers */
#define NT_LOONGARCH_LASX 0x903 /* Loongarch Loongson Advanced SIMD Extension registers */



@@ -3287,6 +3291,67 @@ enum
#define R_RISCV_SET32 56
#define R_RISCV_32_PCREL 57

/* LoongISA ELF Flags */
#define EM_LOONGARCH 258
#define EF_LOONGARCH_ABI 0x0003
#define EF_LOONGARCH_ABI_LP64 0x0003
#define EF_LOONGARCH_ABI_LPX32 0x0002
#define EF_LOONGARCH_ABI_LP32 0x0001

/* Loongarch specific dynamic relocations. */
#define R_LOONGARCH_NONE 0
#define R_LOONGARCH_32 1
#define R_LOONGARCH_64 2
#define R_LOONGARCH_RELATIVE 3
#define R_LOONGARCH_COPY 4
#define R_LOONGARCH_JUMP_SLOT 5
#define R_LOONGARCH_TLS_DTPMOD32 6
#define R_LOONGARCH_TLS_DTPMOD64 7
#define R_LOONGARCH_TLS_DTPREL32 8
#define R_LOONGARCH_TLS_DTPREL64 9
#define R_LOONGARCH_TLS_TPREL32 10
#define R_LOONGARCH_TLS_TPREL64 11
#define R_LOONGARCH_IRELATIVE 12
#define R_LOONGARCH_MARK_LA 20
#define R_LOONGARCH_MARK_PCREL 21
#define R_LOONGARCH_SOP_PUSH_PCREL 22
#define R_LOONGARCH_SOP_PUSH_ABSOLUTE 23
#define R_LOONGARCH_SOP_PUSH_DUP 24
#define R_LOONGARCH_SOP_PUSH_GPREL 25
#define R_LOONGARCH_SOP_PUSH_TLS_TPREL 26
#define R_LOONGARCH_SOP_PUSH_TLS_GOT 27
#define R_LOONGARCH_SOP_PUSH_TLS_GD 28
#define R_LOONGARCH_SOP_PUSH_PLT_PCREL 29
#define R_LOONGARCH_SOP_ASSERT 30
#define R_LOONGARCH_SOP_NOT 31
#define R_LOONGARCH_SOP_SUB 32
#define R_LOONGARCH_SOP_SL 33
#define R_LOONGARCH_SOP_SR 34
#define R_LOONGARCH_SOP_ADD 35
#define R_LOONGARCH_SOP_AND 36
#define R_LOONGARCH_SOP_IF_ELSE 37
#define R_LOONGARCH_SOP_POP_32_S_10_5 38
#define R_LOONGARCH_SOP_POP_32_U_10_12 39
#define R_LOONGARCH_SOP_POP_32_S_10_12 40
#define R_LOONGARCH_SOP_POP_32_S_10_16 41
#define R_LOONGARCH_SOP_POP_32_S_10_16_S2 42
#define R_LOONGARCH_SOP_POP_32_S_5_20 43
#define R_LOONGARCH_SOP_POP_32_S_0_5_10_16_S2 44
#define R_LOONGARCH_SOP_POP_32_S_0_10_10_16_S2 45
#define R_LOONGARCH_SOP_POP_32_U 46
#define R_LOONGARCH_ADD8 47
#define R_LOONGARCH_ADD16 48
#define R_LOONGARCH_ADD24 49
#define R_LOONGARCH_ADD32 50
#define R_LOONGARCH_ADD64 51
#define R_LOONGARCH_SUB8 52
#define R_LOONGARCH_SUB16 53
#define R_LOONGARCH_SUB24 54
#define R_LOONGARCH_SUB32 55
#define R_LOONGARCH_SUB64 56
#define R_LOONGARCH_GNU_VTINHERIT 57
#define R_LOONGARCH_GNU_VTENTRY 58

#ifdef __cplusplus
}
#endif
@@ -0,0 +1,3 @@
#ifdef __loongarch64_soft_float
#include "../fenv.c"
#endif
@@ -0,0 +1,75 @@
#ifndef __loongarch_soft_float

.global feclearexcept
.type feclearexcept,@function
feclearexcept:
//andi $a0, $a0, 0x1f0000 // la: exception bits in 16-20 bit of fcsr0.
li $a1, 0x1f0000
and $a0, $a0, $a1
movfcsr2gr $a1, $r0 // r0 is fpu control status register 0(fcsr0), r0 -> fcsr0, r1 -> fcsr1, r2 -> fcsr2, r3 - fcsr3
or $a1, $a1, $a0
xor $a1, $a1, $a0
movgr2fcsr $r0, $a1
li $v0, 0
jr $ra

.global feraiseexcept
.type feraiseexcept,@function
feraiseexcept:
//andi $a0, $a0, 0x1f0000
li $a1, 0x1f0000
and $a0, $a0, $a1
movfcsr2gr $a1, $r0
or $a1, $a1, $a0
movgr2fcsr $r0, $a1
li $v0, 0
jr $ra

.global fetestexcept
.type fetestexcept,@function
fetestexcept:
//andi $a0, $a0, 0x1f0000
li $a1, 0x1f0000
and $a0, $a0, $a1
movfcsr2gr $a1, $r0
and $v0, $a1, $a0
jr $ra

.global fegetround
.type fegetround,@function
fegetround:
movfcsr2gr $v0, $r0
andi $v0, $v0, 0x300 // RM
jr $ra

.global __fesetround
.hidden __fesetround
.type __fesetround,@function
__fesetround:
movfcsr2gr $a1, $r0
li $a2, -769
and $a1, $a1, $a2
or $a1, $a1, $a0
movgr2fcsr $r0, $a1
li $v0, 0
jr $ra

.global fegetenv
.type fegetenv,@function
fegetenv:
movfcsr2gr $a1, $r0
st.w $a1, $a0, 0
li $v0, 0
jr $ra

.global fesetenv
.type fesetenv,@function
fesetenv:
addi.d $a1, $a0, 1
beq $a1, $r0, 1f
ld.w $a1, $a0, 0
1: movgr2fcsr $r0, $a1
li $v0, 0
jr $ra

#endif
@@ -0,0 +1,12 @@
.global dlsym
.hidden __dlsym
.type dlsym,@function
dlsym:
move $r6, $ra
la.global $r16, __dlsym
addi.d $sp, $sp, -32
st.d $ra, $sp, 24
jirl $ra, $r16, 0
ld.d $ra, $sp, 24
addi.d $sp, $sp, 32
jr $ra
@@ -0,0 +1,37 @@
.global _longjmp
.global longjmp
.type _longjmp,@function
.type longjmp,@function
_longjmp:
longjmp:
add.d $t5, $a0, $zero
add.d $v0, $a1, $zero

bne $v0, $zero, 1f
addi.d $v0, $v0, 1

1:
ld.d $ra, $t5, 0
ld.d $sp, $t5, 8
ld.d $fp, $t5, 16
ld.d $s0, $t5, 24
ld.d $s1, $t5, 32
ld.d $s2, $t5, 40
ld.d $s3, $t5, 48
ld.d $s4, $t5, 56
ld.d $s5, $t5, 64
ld.d $s6, $t5, 72
ld.d $s7, $t5, 80
ld.d $s8, $t5, 88
#ifndef __loongarch64_soft_float
fld.d $fs0, $t5, 96
fld.d $fs1, $t5, 104
fld.d $fs2, $t5, 112
fld.d $fs3, $t5, 120
fld.d $fs4, $t5, 128
fld.d $fs5, $t5, 136
fld.d $fs6, $t5, 144
fld.d $fs7, $t5, 152
#endif
jirl $zero, $ra, 0

@@ -0,0 +1,35 @@
.global __setjmp
.global _setjmp
.global setjmp
.type __setjmp,@function
.type _setjmp,@function
.type setjmp,@function
__setjmp:
_setjmp:
setjmp:
st.d $ra, $a0, 0
st.d $sp, $a0, 8

st.d $fp, $a0, 16
st.d $s0, $a0, 24
st.d $s1, $a0, 32
st.d $s2, $a0, 40
st.d $s3, $a0, 48
st.d $s4, $a0, 56
st.d $s5, $a0, 64
st.d $s6, $a0, 72
st.d $s7, $a0, 80
st.d $s8, $a0, 88
#ifndef __loongarch64_soft_float
fst.d $fs0, $a0, 96
fst.d $fs1, $a0, 104
fst.d $fs2, $a0, 112
fst.d $fs3, $a0, 120
fst.d $fs4, $a0, 128
fst.d $fs5, $a0, 136
fst.d $fs6, $a0, 144
fst.d $fs7, $a0, 152
#endif
xor $v0, $v0, $v0
jirl $zero, $ra, 0

@@ -0,0 +1,10 @@
.global __restore_rt
.global __restore
.hidden __restore_rt
.hidden __restore
.type __restore_rt,@function
.type __restore,@function
__restore_rt:
__restore:
ori $a7, $zero, 139
syscall 0
@@ -0,0 +1,33 @@
.global sigsetjmp
.global __sigsetjmp
.type sigsetjmp,@function
.type __sigsetjmp,@function
sigsetjmp:
__sigsetjmp:
or $t5, $a0, $zero
or $t6, $a1, $zero

# comparing save mask with 0, if equals to 0 then
# sigsetjmp is equal to setjmp.
beq $t6, $zero, 1f
st.d $ra, $t5, 160
st.d $s0, $t5, 168

# save base of got so that we can use it later
# once we return from 'longjmp'
la.global $t8, setjmp
or $s0, $a0, $zero
jirl $ra, $t8, 0

or $v1, $v0, $zero # Return from 'setjmp' or 'longjmp'
ld.d $ra, $t5, 160 # Restore ra of sigsetjmp
ld.d $s0, $t5, 168 # Restore $s0 of sigsetjmp
or $a0, $t5, $zero

.hidden __sigsetjmp_tail
la.global $t8, __sigsetjmp_tail
jr $t8
1:
la.global $t8, setjmp
jr $t8

@@ -0,0 +1,7 @@
.global __set_thread_area
.type __set_thread_area, @function
__set_thread_area:
or $tp, $a0, $zero
ori $a0, $zero, 0
jirl $zero, $ra, 0

@@ -0,0 +1,8 @@
.global __unmapself
.type __unmapself, @function
__unmapself:
ori $a7, $zero, 215
syscall 0 # call munmap
ori $a0, $zero, 0
ori $a7, $zero, 93
syscall 0 # call exit
@@ -0,0 +1,27 @@
.global __clone
.hidden __clone
.type __clone,@function
__clone:
# Save function pointer and argument pointer on new thread stack
addi.d $a1, $a1, -16 # aligning stack to double word
st.d $a0, $a1, 0 # save function pointer
st.d $a3, $a1, 8 # save argument pointer

# Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid)
# sys_clone(u64 flags, u64 ustack_base, u64 parent_tidptr, u64 child_tidptr, u64 tls)
or $a0, $a2, $zero
or $a2, $a4, $zero
or $a3, $a6, $zero
or $a4, $a5, $zero
ori $a7, $zero, 220
syscall 0 # call clone

beqz $a0, 1f # whether child process
jirl $zero, $ra, 0 # parent process return
1:
ld.d $t8, $sp, 0 # function pointer
ld.d $a0, $sp, 8 # argument pointer
jirl $ra, $t8, 0 # call the user's function
ori $a7, $zero, 93
syscall 0 # child process exit

@@ -0,0 +1,34 @@
.global __cp_begin
.hidden __cp_begin
.type __cp_begin,@function
.global __cp_end
.hidden __cp_end
.type __cp_end,@function
.global __cp_cancel
.hidden __cp_cancel
.type __cp_cancel,@function
.hidden __cancel
.global __syscall_cp_asm
.hidden __syscall_cp_asm
.type __syscall_cp_asm,@function

__syscall_cp_asm:
__cp_begin:
ld.w $a0, $a0, 0
bnez $a0, __cp_cancel
or $t8, $a1, $zero # reserve system call number
or $a0, $a2, $zero
or $a1, $a3, $zero
or $a2, $a4, $zero
or $a3, $a5, $zero
or $a4, $a6, $zero
or $a5, $a7, $zero
ld.d $a6, $sp, 0
or $a7, $t8, $zero
syscall 0
__cp_end:
jirl $zero, $ra, 0
__cp_cancel:
la.local $t8, __cancel
jirl $zero, $t8, 0

@@ -0,0 +1,12 @@
.global pipe
.type pipe,@function
pipe:
move $a1, $r0
li $a7, 59
syscall 0
li $t0, -4096
bgeu $t0, $v0, 1f
la.global $t1, __syscall_ret
jr $t1
1: move $v0, $r0
jr $ra