mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-28 08:12:28 +00:00
Introduce FreeBSD ARM64 support
It's 100% passing test fleet. Solid as a rock.
This commit is contained in:
parent
43fe5956ad
commit
83107f78ed
455 changed files with 778 additions and 551 deletions
|
@ -231,60 +231,6 @@ static errno_t CloneXnu(int (*fn)(void *), char *stk, size_t stksz, int flags,
|
|||
return sys_clone_xnu(fn, arg, wt, 0, PTHREAD_START_CUSTOM_XNU);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// FREE BESIYATA DISHMAYA
|
||||
|
||||
static wontreturn void FreebsdThreadMain(void *p) {
|
||||
struct CloneArgs *wt = p;
|
||||
*wt->ctid = wt->tid;
|
||||
wt->func(wt->arg, wt->tid);
|
||||
// we no longer use the stack after this point
|
||||
// void thr_exit(%rdi = long *state);
|
||||
asm volatile("movl\t$0,%0\n\t" // *wt->ztid = 0
|
||||
"syscall\n\t" // _umtx_op(wt->ztid, WAKE, INT_MAX)
|
||||
"movl\t$431,%%eax\n\t" // thr_exit(long *nonzeroes_and_wake)
|
||||
"xor\t%%edi,%%edi\n\t" // sad we can't use this free futex op
|
||||
"syscall\n\t" // exit1() fails if thread is orphaned
|
||||
"movl\t$1,%%eax\n\t" // exit()
|
||||
"syscall" //
|
||||
: "=m"(*wt->ztid)
|
||||
: "a"(454), "D"(wt->ztid), "S"(UMTX_OP_WAKE), "d"(INT_MAX)
|
||||
: "rcx", "r8", "r9", "r10", "r11", "memory");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
static errno_t CloneFreebsd(int (*func)(void *, int), char *stk, size_t stksz,
|
||||
int flags, void *arg, void *tls, int *ptid,
|
||||
int *ctid) {
|
||||
int ax;
|
||||
bool failed;
|
||||
int64_t tid;
|
||||
struct CloneArgs *wt;
|
||||
wt = AllocateCloneArgs(stk, stksz);
|
||||
wt->ctid = flags & CLONE_CHILD_SETTID ? ctid : &wt->tid;
|
||||
wt->ztid = flags & CLONE_CHILD_CLEARTID ? ctid : &wt->tid;
|
||||
wt->tls = tls;
|
||||
wt->func = func;
|
||||
wt->arg = arg;
|
||||
struct thr_param params = {
|
||||
.start_func = FreebsdThreadMain,
|
||||
.arg = wt,
|
||||
.stack_base = stk,
|
||||
.stack_size = (uintptr_t)wt - (uintptr_t)stk,
|
||||
.tls_base = flags & CLONE_SETTLS ? tls : 0,
|
||||
.tls_size = 64,
|
||||
.child_tid = &wt->tid64,
|
||||
.parent_tid = &tid,
|
||||
};
|
||||
asm volatile(CFLAG_ASM("syscall")
|
||||
: CFLAG_CONSTRAINT(failed), "=a"(ax)
|
||||
: "1"(__NR_thr_new), "D"(¶ms), "S"(sizeof(params))
|
||||
: "rcx", "rdx", "r8", "r9", "r10", "r11", "memory");
|
||||
if (failed) return ax;
|
||||
if (flags & CLONE_PARENT_SETTID) *ptid = tid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// OPEN BESIYATA DISHMAYA
|
||||
|
||||
|
@ -441,6 +387,95 @@ static int CloneNetbsd(int (*func)(void *, int), char *stk, size_t stksz,
|
|||
|
||||
#endif /* __x86_64__ */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// FREE BESIYATA DISHMAYA
|
||||
|
||||
void bone(struct CloneArgs *wt) {
|
||||
*wt->ztid = 0;
|
||||
}
|
||||
|
||||
static wontreturn void FreebsdThreadMain(void *p) {
|
||||
struct CloneArgs *wt = p;
|
||||
#ifdef __aarch64__
|
||||
asm volatile("mov\tx28,%0" : /* no outputs */ : "r"(wt->tls));
|
||||
#endif
|
||||
*wt->ctid = wt->tid;
|
||||
wt->func(wt->arg, wt->tid);
|
||||
// we no longer use the stack after this point
|
||||
// void thr_exit(%rdi = long *state);
|
||||
#ifdef __x86_64__
|
||||
asm volatile("movl\t$0,%0\n\t" // *wt->ztid = 0
|
||||
"syscall\n\t" // _umtx_op(wt->ztid, WAKE, INT_MAX)
|
||||
"movl\t$431,%%eax\n\t" // thr_exit(long *nonzeroes_and_wake)
|
||||
"xor\t%%edi,%%edi\n\t" // sad we can't use this free futex op
|
||||
"syscall\n\t" // thr_exit() fails if thread is orphaned
|
||||
"movl\t$1,%%eax\n\t" // _exit()
|
||||
"syscall" //
|
||||
: "=m"(*wt->ztid)
|
||||
: "a"(454), "D"(wt->ztid), "S"(UMTX_OP_WAKE), "d"(INT_MAX)
|
||||
: "rcx", "r8", "r9", "r10", "r11", "memory");
|
||||
#elif defined(__aarch64__)
|
||||
register long x0 asm("x0") = (long)wt->ztid;
|
||||
register long x1 asm("x1") = UMTX_OP_WAKE;
|
||||
register long x2 asm("x2") = INT_MAX;
|
||||
register long x8 asm("x8") = 454; // _umtx_op
|
||||
asm volatile("str\twzr,%0\n\t" // *wt->ztid = 0
|
||||
"svc\t0\n\t" // _umtx_op(wt->ztid, WAKE, INT_MAX)
|
||||
"mov\tx0,#0\n\t" // arg0 = 0
|
||||
"mov\tx8,#431\n\t" // thr_exit
|
||||
"svc\t0\n\t" // thr_exit(long *nonzeroes_and_wake = 0)
|
||||
"mov\tx8,#1\n\t" // _exit
|
||||
"svc\t0" // _exit(long *nonzeroes_and_wake = 0)
|
||||
: "=m"(*wt->ztid)
|
||||
: "r"(x0), "r"(x1), "r"(x2), "r"(x8));
|
||||
#else
|
||||
#error "unsupported architecture"
|
||||
#endif
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
static errno_t CloneFreebsd(int (*func)(void *, int), char *stk, size_t stksz,
|
||||
int flags, void *arg, void *tls, int *ptid,
|
||||
int *ctid) {
|
||||
int64_t tid;
|
||||
struct CloneArgs *wt;
|
||||
wt = AllocateCloneArgs(stk, stksz);
|
||||
wt->ctid = flags & CLONE_CHILD_SETTID ? ctid : &wt->tid;
|
||||
wt->ztid = flags & CLONE_CHILD_CLEARTID ? ctid : &wt->tid;
|
||||
wt->tls = tls;
|
||||
wt->func = func;
|
||||
wt->arg = arg;
|
||||
struct thr_param params = {
|
||||
.start_func = FreebsdThreadMain,
|
||||
.arg = wt,
|
||||
.stack_base = stk,
|
||||
.stack_size = (uintptr_t)wt - (uintptr_t)stk,
|
||||
.tls_base = flags & CLONE_SETTLS ? tls : 0,
|
||||
.tls_size = 64,
|
||||
.child_tid = &wt->tid64,
|
||||
.parent_tid = &tid,
|
||||
};
|
||||
#ifdef __x86_64__
|
||||
int ax;
|
||||
bool failed;
|
||||
asm volatile(CFLAG_ASM("syscall")
|
||||
: CFLAG_CONSTRAINT(failed), "=a"(ax)
|
||||
: "1"(__NR_thr_new), "D"(¶ms), "S"(sizeof(params))
|
||||
: "rcx", "rdx", "r8", "r9", "r10", "r11", "memory");
|
||||
if (failed) return ax;
|
||||
#elif defined(__aarch64__)
|
||||
register long x0 asm("x0") = (long)¶ms;
|
||||
register long x1 asm("x1") = sizeof(params);
|
||||
register int x8 asm("x8") = 0x1c7; // thr_new
|
||||
asm volatile("svc\t0" : "+r"(x0) : "r"(x1), "r"(x8) : "memory");
|
||||
if (x0) return x0;
|
||||
#else
|
||||
#error "unsupported architecture"
|
||||
#endif
|
||||
if (flags & CLONE_PARENT_SETTID) *ptid = tid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __aarch64__
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -675,9 +710,9 @@ errno_t clone(void *func, void *stk, size_t stksz, int flags, void *arg,
|
|||
#else
|
||||
#error "unsupported architecture"
|
||||
#endif
|
||||
#ifdef __x86_64__
|
||||
} else if (IsFreebsd()) {
|
||||
rc = CloneFreebsd(func, stk, stksz, flags, arg, tls, ptid, ctid);
|
||||
#ifdef __x86_64__
|
||||
} else if (IsNetbsd()) {
|
||||
rc = CloneNetbsd(func, stk, stksz, flags, arg, tls, ptid, ctid);
|
||||
} else if (IsOpenbsd()) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue