Introduce FreeBSD ARM64 support

It's 100% passing test fleet. Solid as a rock.
This commit is contained in:
Justine Tunney 2023-12-29 20:11:23 -08:00
parent 43fe5956ad
commit 83107f78ed
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
455 changed files with 778 additions and 551 deletions

View file

@ -59,12 +59,12 @@ wontreturn void _Exit(int exitcode) {
: "rcx", "r11", "memory");
#elif defined(__aarch64__)
register long x0 asm("x0") = exitcode;
asm volatile("mov\tx8,%0\n\t"
"mov\tx16,%1\n\t"
register long x8 asm("x8") = IsLinux() ? 94 : 1;
asm volatile("mov\tx16,%1\n\t"
"svc\t0"
: /* no outputs */
: "i"(94), "i"(1), "r"(x0)
: "x8", "x16", "memory");
: "r"(x8), "i"(1), "r"(x0)
: "x16", "memory");
#else
#error "unsupported architecture"
#endif
@ -77,12 +77,12 @@ wontreturn void _Exit(int exitcode) {
: "rcx", "r11", "memory");
#else
register long r0 asm("x0") = exitcode;
asm volatile("mov\tx8,%0\n\t"
"mov\tx16,%1\n\t"
register long x8 asm("x8") = IsLinux() ? 93 : 431;
asm volatile("mov\tx16,%1\n\t"
"svc\t0"
: /* no outputs */
: "i"(93), "i"(0x169), "r"(r0)
: "x8", "memory");
: "r"(x8), "i"(0x169), "r"(r0)
: "memory");
#endif
} else if (IsWindows()) {
uint32_t waitstatus;

View file

@ -74,13 +74,27 @@ wontreturn void _Exit1(int rc) {
}
notpossible;
#elif defined(__aarch64__)
if (IsLinux()) {
register long r0 asm("x0") = rc;
asm volatile("mov\tx8,%0\n\t"
"svc\t0"
: /* no outputs */
: "i"(93), "r"(r0)
: "x8", "memory");
if (IsLinux() || IsFreebsd()) {
register int x0 asm("x0") = rc;
register int x8 asm("x8");
if (IsLinux()) {
x8 = 93; // exit
} else if (IsFreebsd()) {
x8 = 431; // thr_exit
} else {
__builtin_unreachable();
}
asm volatile("svc\t0" : "+r"(x0) : "r"(x8) : "memory");
if (SupportsFreebsd()) {
// On FreeBSD, thr_exit() fails if the current thread is orphaned.
// In that case we're really better off just calling plain _exit()
x0 = rc;
asm volatile("mov\tx8,#1\n\t"
"svc\t0"
: /* no outputs */
: "r"(x0)
: "memory");
}
} else if (IsXnu()) {
__syslib->__pthread_exit(0);
}

View file

@ -32,10 +32,19 @@ _futex:
neg %eax
1: pop %rbp
#elif defined(__aarch64__)
mov x8,#0x062
svc #0
ldr x7,=__hostos
ldr w7,[x7]
tst x7,1 // IsLinux()
mov x7,98 // futex (Linux)
mov x8,454 // _umtx_op (FreeBSD)
csel x8,x7,x8,ne // choose syscall magnum
mov x7,0 // clear carry (for Linux)
adds x7,x7,0 // clear carry
svc #0 // call kernel
bcc 1f // jump if not carry
neg x0,x0 // linux style errno
#else
#error "unsupported architecture"
#endif /* __x86_64__ */
ret
1: ret
.endfn _futex,globl,hidden

View file

@ -79,7 +79,7 @@ static textwindows void SetupWinStd(struct Fds *fds, int i, uint32_t x) {
textstartup void __init_fds(int argc, char **argv, char **envp) {
struct Fds *fds;
fds = __veil("r", &g_fds);
fds = &g_fds;
fds->n = 4;
atomic_store_explicit(&fds->f, 3, memory_order_relaxed);
if (_weaken(_extend)) {

View file

@ -18,6 +18,7 @@
*/
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/intrin/kprintf.h"
#include "libc/nt/thread.h"
#include "libc/nt/thunk/msabi.h"
#include "libc/runtime/internal.h"
@ -25,9 +26,9 @@
__msabi extern typeof(GetCurrentThreadId) *const __imp_GetCurrentThreadId;
int sys_gettid(void) {
int64_t wut;
#ifdef __x86_64__
int tid;
int64_t wut;
if (IsWindows()) {
tid = __imp_GetCurrentThreadId();
} else if (IsLinux()) {
@ -65,11 +66,23 @@ int sys_gettid(void) {
#elif defined(__aarch64__)
// this can't be used on xnu
register long res asm("x0");
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: "=r"(res)
: "i"(178)
: "x8", "memory");
if (IsLinux()) {
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: "=r"(res)
: "i"(178)
: "x8", "memory");
} else if (IsFreebsd()) {
res = (long)&wut;
asm volatile("mov\tx8,%2\n\t"
"svc\t0"
: "+r"(res), "=m"(wut)
: "i"(432) // thr_self()
: "x8", "memory");
res = wut;
} else {
res = __pid;
}
return res;
#else
#error "arch unsupported"

View file

@ -19,7 +19,6 @@
#include "libc/atomic.h"
#include "libc/sysv/consts/clock.h"
#include "libc/thread/freebsd.internal.h"
#ifdef __x86_64__
int sys_umtx_timedwait_uint_cp(atomic_int *, int, int, size_t,
struct _umtx_time *) asm("sys_futex_cp");
@ -46,5 +45,3 @@ int sys_umtx_timedwait_uint(atomic_int *p, int expect, bool pshare,
}
return sys_umtx_timedwait_uint_cp(p, op, expect, size, tm_p);
}
#endif