mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 03:27:39 +00:00
Make more code aarch64 friendly
This commit is contained in:
parent
ca2860947f
commit
2b73e72d59
568 changed files with 2197 additions and 1061 deletions
4
Makefile
4
Makefile
|
@ -117,8 +117,8 @@ include libc/sysv/sysv.mk # ├──SYSTEM SUPPORT
|
|||
include libc/nt/nt.mk # │ You can do math
|
||||
include libc/intrin/intrin.mk # │ You can use the stack
|
||||
include libc/linux/linux.mk # │ You can manipulate arrays
|
||||
include libc/tinymath/tinymath.mk # │ You can issue raw system calls
|
||||
include third_party/compiler_rt/compiler_rt.mk # │
|
||||
include third_party/compiler_rt/compiler_rt.mk # │ You can issue raw system calls
|
||||
include libc/tinymath/tinymath.mk # │
|
||||
include libc/str/str.mk # │
|
||||
include third_party/xed/xed.mk # │
|
||||
include third_party/puff/puff.mk # │
|
||||
|
|
11
ape/ape.mk
11
ape/ape.mk
|
@ -13,10 +13,14 @@
|
|||
# build like turning off the System V "Red Zone" optimization, because
|
||||
# αcτµαlly pδrταblε εxεcµταblεs need to be able to run in kernelspace.
|
||||
|
||||
ifneq ($(MODE), aarch64)
|
||||
|
||||
PKGS += APE
|
||||
|
||||
APE_FILES := $(wildcard ape/*.*)
|
||||
APE_HDRS = $(filter %.h,$(APE_FILES))
|
||||
APE_INCS = $(filter %.inc,$(APE_FILES))
|
||||
|
||||
ifneq ($(MODE), aarch64)
|
||||
|
||||
APE = o/$(MODE)/ape/ape.o \
|
||||
o/$(MODE)/ape/ape.lds
|
||||
|
||||
|
@ -51,9 +55,6 @@ APE_LOADER_FLAGS = \
|
|||
$(OUTPUT_OPTION) \
|
||||
$<
|
||||
|
||||
APE_FILES := $(wildcard ape/*.*)
|
||||
APE_HDRS = $(filter %.h,$(APE_FILES))
|
||||
APE_INCS = $(filter %.inc,$(APE_FILES))
|
||||
APE_SRCS_C = ape/loader.c
|
||||
APE_SRCS_S = $(filter %.S,$(APE_FILES))
|
||||
APE_SRCS = $(APE_SRCS_C) $(APE_SRCS_S)
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
*/
|
||||
privileged int getpriority(int which, unsigned who) {
|
||||
int rc;
|
||||
#ifdef __x86_64__
|
||||
char cf;
|
||||
if (IsLinux()) {
|
||||
asm volatile("syscall"
|
||||
|
@ -73,6 +74,23 @@ privileged int getpriority(int which, unsigned who) {
|
|||
} else {
|
||||
rc = sys_getpriority_nt(which, who);
|
||||
}
|
||||
#elif defined(__aarch64__)
|
||||
register long r0 asm("x0") = (long)which;
|
||||
register long r1 asm("x1") = (long)who;
|
||||
register long res_x0 asm("x0");
|
||||
asm volatile("mov\tx8,%1\n"
|
||||
"svc\t0"
|
||||
: "=r"(res_x0)
|
||||
: "i"(141), "r"(r0), "r"(r1)
|
||||
: "x8", "memory");
|
||||
rc = res_x0;
|
||||
if (rc >= 0) {
|
||||
rc = NZERO - rc;
|
||||
} else {
|
||||
errno = -rc;
|
||||
rc = -1;
|
||||
}
|
||||
#endif
|
||||
STRACE("getpriority(%s, %u) → %d% m", DescribeWhichPrio(which), who, rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "libc/sysv/consts/pr.h"
|
||||
|
||||
privileged bool __is_linux_2_6_23(void) {
|
||||
#ifdef __x86_64__
|
||||
int rc;
|
||||
if (!IsLinux()) return false;
|
||||
if (IsGenuineBlink()) return true;
|
||||
|
@ -30,4 +31,7 @@ privileged bool __is_linux_2_6_23(void) {
|
|||
: "0"(157), "D"(PR_GET_SECCOMP)
|
||||
: "rcx", "r11", "memory");
|
||||
return rc != -EINVAL;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include "libc/str/oldutf16.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/str/thompike.h"
|
||||
#include "libc/str/tpdecode.internal.h"
|
||||
#include "libc/str/utf16.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/asmflag.h"
|
||||
|
@ -34,34 +35,52 @@
|
|||
* features like ASAN memory safety and kprintf() won't work as well.
|
||||
*/
|
||||
privileged void *sys_mremap(void *p, size_t n, size_t m, int f, void *q) {
|
||||
#ifdef __x86_64__
|
||||
bool cf;
|
||||
uintptr_t rax, rdi, rsi, rdx;
|
||||
uintptr_t res, rdi, rsi, rdx;
|
||||
register uintptr_t r8 asm("r8");
|
||||
register uintptr_t r10 asm("r10");
|
||||
if (IsLinux()) {
|
||||
r10 = f;
|
||||
r8 = (uintptr_t)q;
|
||||
asm("syscall"
|
||||
: "=a"(rax)
|
||||
: "=a"(res)
|
||||
: "0"(0x019), "D"(p), "S"(n), "d"(m), "r"(r10), "r"(r8)
|
||||
: "rcx", "r11", "memory", "cc");
|
||||
if (rax > -4096ul) errno = -rax, rax = -1;
|
||||
if (res > -4096ul) errno = -res, res = -1;
|
||||
} else if (IsNetbsd()) {
|
||||
if (f & MREMAP_MAYMOVE) {
|
||||
rax = 0x19B;
|
||||
res = 0x19B;
|
||||
r10 = m;
|
||||
r8 = (f & MREMAP_FIXED) ? MAP_FIXED : 0;
|
||||
asm(CFLAG_ASM("syscall")
|
||||
: CFLAG_CONSTRAINT(cf), "+a"(rax), "=d"(rdx)
|
||||
: CFLAG_CONSTRAINT(cf), "+a"(res), "=d"(rdx)
|
||||
: "D"(p), "S"(n), "2"(q), "r"(r10), "r"(r8)
|
||||
: "rcx", "r9", "r11", "memory", "cc");
|
||||
if (cf) errno = rax, rax = -1;
|
||||
if (cf) errno = res, res = -1;
|
||||
} else {
|
||||
rax = einval();
|
||||
res = einval();
|
||||
}
|
||||
} else {
|
||||
rax = enosys();
|
||||
res = enosys();
|
||||
}
|
||||
KERNTRACE("sys_mremap(%p, %'zu, %'zu, %#b, %p) → %p% m", p, n, m, f, q, rax);
|
||||
return (void *)rax;
|
||||
#elif defined(__aarch64__)
|
||||
long res;
|
||||
register long r0 asm("x0") = (long)p;
|
||||
register long r1 asm("x1") = (long)n;
|
||||
register long r2 asm("x2") = (long)m;
|
||||
register long r3 asm("x3") = (long)f;
|
||||
register long r4 asm("x4") = (long)q;
|
||||
register long res_x0 asm("x0");
|
||||
asm volatile("mov\tx8,%1\n"
|
||||
"svc\t0"
|
||||
: "=r"(res_x0)
|
||||
: "i"(216), "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4)
|
||||
: "x8", "memory");
|
||||
res = _sysret64(res_x0);
|
||||
#else
|
||||
#error "arch unsupported"
|
||||
#endif
|
||||
KERNTRACE("sys_mremap(%p, %'zu, %'zu, %#b, %p) → %p% m", p, n, m, f, q, res);
|
||||
return (void *)res;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/directmap.internal.h"
|
||||
#include "libc/runtime/pc.internal.h"
|
||||
#ifdef __x86_64__
|
||||
|
||||
noasan int sys_munmap_metal(void *addr, size_t size) {
|
||||
size_t i;
|
||||
|
@ -36,3 +37,5 @@ noasan int sys_munmap_metal(void *addr, size_t size) {
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/consts/pr.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
#ifdef __x86_64__
|
||||
|
||||
/**
|
||||
* @fileoverview OpenBSD pledge() Polyfill Payload for GNU/Systemd
|
||||
|
@ -2060,3 +2061,5 @@ privileged int sys_pledge_linux(unsigned long ipromises, int mode) {
|
|||
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "libc/sock/internal.h"
|
||||
#include "libc/sock/struct/pollfd.h"
|
||||
#include "libc/sysv/consts/poll.h"
|
||||
#ifdef __x86_64__
|
||||
|
||||
int sys_poll_metal(struct pollfd *fds, size_t nfds, unsigned timeout_ms) {
|
||||
int rc;
|
||||
|
@ -80,3 +81,5 @@ int sys_poll_metal(struct pollfd *fds, size_t nfds, unsigned timeout_ms) {
|
|||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
|
@ -41,6 +42,7 @@ privileged int prctl(int operation, ...) {
|
|||
d = va_arg(va, intptr_t);
|
||||
va_end(va);
|
||||
|
||||
#ifdef __x86_64__
|
||||
if (IsLinux()) {
|
||||
asm volatile("mov\t%5,%%r10\n\t"
|
||||
"mov\t%6,%%r8\n\t"
|
||||
|
@ -52,6 +54,22 @@ privileged int prctl(int operation, ...) {
|
|||
} else {
|
||||
rc = enosys();
|
||||
}
|
||||
#elif defined(__aarch64__)
|
||||
register long r0 asm("x0") = (long)operation;
|
||||
register long r1 asm("x1") = (long)a;
|
||||
register long r2 asm("x2") = (long)b;
|
||||
register long r3 asm("x3") = (long)c;
|
||||
register long r4 asm("x4") = (long)d;
|
||||
register long res_x0 asm("x0");
|
||||
asm volatile("mov\tx8,%1\n"
|
||||
"svc\t0"
|
||||
: "=r"(res_x0)
|
||||
: "i"(167), "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4)
|
||||
: "x8", "memory");
|
||||
rc = _sysret32(res_x0);
|
||||
#else
|
||||
#error "arch unsupported"
|
||||
#endif
|
||||
|
||||
#ifdef SYSDEBUG
|
||||
if (operation == PR_CAPBSET_READ || operation == PR_CAPBSET_DROP) {
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "libc/calls/struct/iovec.internal.h"
|
||||
#include "libc/nexgen32e/uart.internal.h"
|
||||
#include "libc/runtime/pc.internal.h"
|
||||
#ifdef __x86_64__
|
||||
|
||||
static bool IsDataAvailable(struct Fd *fd) {
|
||||
return inb(fd->handle + UART_LSR) & UART_TTYDA;
|
||||
|
@ -47,3 +48,5 @@ ssize_t sys_readv_serial(struct Fd *fd, const struct iovec *iov, int iovlen) {
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/struct/seccomp.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
|
@ -36,6 +37,7 @@
|
|||
*/
|
||||
privileged int seccomp(unsigned operation, unsigned flags, void *args) {
|
||||
int rc;
|
||||
#ifdef __x86_64__
|
||||
if (IsLinux()) {
|
||||
asm volatile("syscall"
|
||||
: "=a"(rc)
|
||||
|
@ -62,6 +64,20 @@ privileged int seccomp(unsigned operation, unsigned flags, void *args) {
|
|||
} else {
|
||||
rc = enosys();
|
||||
}
|
||||
#elif defined(__aarch64__)
|
||||
register long r0 asm("x0") = (long)operation;
|
||||
register long r1 asm("x1") = (long)flags;
|
||||
register long r2 asm("x2") = (long)args;
|
||||
register long res_x0 asm("x0");
|
||||
asm volatile("mov\tx8,%1\n"
|
||||
"svc\t0"
|
||||
: "=r"(res_x0)
|
||||
: "i"(211), "r"(r0), "r"(r1), "r"(r2)
|
||||
: "x8", "memory");
|
||||
rc = _sysret32(res_x0);
|
||||
#else
|
||||
#error "arch unsupported"
|
||||
#endif
|
||||
STRACE("seccomp(%s, %#x, %p) → %d% m", DescribeSeccompOperation(operation),
|
||||
flags, args, rc);
|
||||
return rc;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/sa.h"
|
||||
#ifdef __x86_64__
|
||||
|
||||
/**
|
||||
* @fileoverview XNU kernel callback normalization.
|
||||
|
@ -527,3 +528,5 @@ privileged void __sigenter_xnu(void *fn, int infostyle, int sig,
|
|||
: "rcx", "r11", "memory", "cc");
|
||||
notpossible;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -10,6 +10,9 @@ COSMOPOLITAN_C_START_
|
|||
│ cosmopolitan § syscalls » system five » structless synthetic jump slots ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
int _sysret32(long) asm("_sysret");
|
||||
long _sysret64(long) asm("_sysret");
|
||||
|
||||
axdx_t __sys_fork(void) _Hide;
|
||||
axdx_t __sys_pipe(i32[hasatleast 2], i32) _Hide;
|
||||
axdx_t sys_getpid(void) _Hide;
|
||||
|
@ -62,7 +65,6 @@ i32 sys_getresgid(u32 *, u32 *, u32 *) _Hide;
|
|||
i32 sys_getresuid(u32 *, u32 *, u32 *) _Hide;
|
||||
i32 sys_getsid(i32) _Hide;
|
||||
i32 sys_gettid(void) _Hide;
|
||||
i32 sys_ioctl(i32, u64, ...) _Hide;
|
||||
i32 sys_ioctl_cp(i32, u64, ...) _Hide;
|
||||
i32 sys_issetugid(void) _Hide;
|
||||
i32 sys_kill(i32, i32, i32) _Hide;
|
||||
|
@ -131,7 +133,6 @@ i64 sys_readlink(const char *, char *, u64) _Hide;
|
|||
i64 sys_readlinkat(i32, const char *, char *, u64) _Hide;
|
||||
i64 sys_sendfile(i32, i32, i64 *, u64) _Hide;
|
||||
i64 sys_splice(i32, i64 *, i32, i64 *, u64, u32) _Hide;
|
||||
i64 sys_write(i32, const void *, u64) _Hide;
|
||||
u32 sys_getegid(void) _Hide;
|
||||
u32 sys_geteuid(void) _Hide;
|
||||
u32 sys_getgid(void) _Hide;
|
||||
|
@ -141,6 +142,45 @@ void *__sys_mmap(void *, u64, u32, u32, i64, i64, i64) _Hide;
|
|||
void *sys_mremap(void *, u64, u64, i32, void *) _Hide;
|
||||
void sys_exit(i32) _Hide;
|
||||
|
||||
#ifdef __x86_64__
|
||||
i64 sys_write(i32, const void *, u64) _Hide;
|
||||
#elif defined(__aarch64__)
|
||||
static inline ssize_t sys_write(int f, const void *b, size_t c) {
|
||||
register long r0 asm("x0") = (long)f;
|
||||
register long r1 asm("x1") = (long)b;
|
||||
register long r2 asm("x2") = (long)c;
|
||||
register long res_x0 asm("x0");
|
||||
asm volatile("mov\tx8,%1\n"
|
||||
"svc\t0"
|
||||
: "=r"(res_x0)
|
||||
: "i"(64), "r"(r0), "r"(r1), "r"(r2)
|
||||
: "x8", "memory");
|
||||
return _sysret64(res_x0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __x86_64__
|
||||
i32 sys_ioctl(i32, u64, ...) _Hide;
|
||||
#elif defined(__aarch64__)
|
||||
static inline int sys_ioctl(int d, int r, ...) {
|
||||
void *a;
|
||||
va_list va;
|
||||
va_start(va, r);
|
||||
a = va_arg(va, void *);
|
||||
va_end(va);
|
||||
register long r0 asm("x0") = (long)d;
|
||||
register long r1 asm("x1") = (long)r;
|
||||
register long r2 asm("x2") = (long)a;
|
||||
register long res_x0 asm("x0");
|
||||
asm volatile("mov\tx8,%1\n"
|
||||
"svc\t0"
|
||||
: "=r"(res_x0)
|
||||
: "i"(29), "r"(r0), "r"(r1), "r"(r2)
|
||||
: "x8", "memory");
|
||||
return _sysret32(res_x0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef i32
|
||||
#undef i64
|
||||
#undef u32
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/intrin/lockxchg.h"
|
||||
|
||||
// TODO(jart): DELETE
|
||||
|
||||
/**
|
||||
* Deletes file.
|
||||
|
@ -29,6 +30,7 @@
|
|||
* @asyncsignalsafe
|
||||
*/
|
||||
int unlink_s(const char **namep) {
|
||||
const char *name = NULL;
|
||||
return unlink(lockxchg(namep, &name));
|
||||
const char *name = *namep;
|
||||
*namep = 0;
|
||||
return unlink(name);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "libc/calls/struct/iovec.internal.h"
|
||||
#include "libc/nexgen32e/uart.internal.h"
|
||||
#include "libc/runtime/pc.internal.h"
|
||||
#ifdef __x86_64__
|
||||
|
||||
ssize_t sys_writev_serial(struct Fd *fd, const struct iovec *iov, int iovlen) {
|
||||
size_t i, j, wrote = 0;
|
||||
|
@ -35,3 +36,5 @@ ssize_t sys_writev_serial(struct Fd *fd, const struct iovec *iov, int iovlen) {
|
|||
}
|
||||
return wrote;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
.privileged
|
||||
.balignfunc
|
||||
.alignfunc
|
||||
|
||||
// Returns 𝑥+𝑦, aborting on overflow.
|
||||
//
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
.privileged
|
||||
.balignfunc
|
||||
.alignfunc
|
||||
|
||||
// Returns 𝑥+𝑦, aborting on overflow.
|
||||
//
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
.privileged
|
||||
.balignfunc
|
||||
.alignfunc
|
||||
|
||||
// Returns 𝑥+𝑦, aborting on overflow.
|
||||
//
|
||||
|
|
|
@ -38,8 +38,6 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define QUAD_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
|
@ -37,6 +37,7 @@
|
|||
*/
|
||||
struct DirectMap sys_mmap(void *addr, size_t size, int prot, int flags, int fd,
|
||||
int64_t off) {
|
||||
#ifdef __x86_64__
|
||||
struct DirectMap d;
|
||||
if (!IsWindows() && !IsMetal()) {
|
||||
d.addr = __sys_mmap(addr, size, prot, flags, fd, off, off);
|
||||
|
@ -51,4 +52,27 @@ struct DirectMap sys_mmap(void *addr, size_t size, int prot, int flags, int fd,
|
|||
DescribeProtFlags(prot), DescribeMapFlags(flags), fd, off, d.addr,
|
||||
d.maphandle);
|
||||
return d;
|
||||
#elif defined(__aarch64__)
|
||||
register long r0 asm("x0") = (long)addr;
|
||||
register long r1 asm("x1") = (long)size;
|
||||
register long r2 asm("x2") = (long)prot;
|
||||
register long r3 asm("x3") = (long)flags;
|
||||
register long r4 asm("x4") = (long)fd;
|
||||
register long r5 asm("x5") = (long)off;
|
||||
register long res_x0 asm("x0");
|
||||
long res;
|
||||
asm volatile("mov\tx8,%1\n"
|
||||
"svc\t0"
|
||||
: "=r"(res_x0)
|
||||
: "i"(222), "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5)
|
||||
: "x8", "memory");
|
||||
res = res_x0;
|
||||
if ((unsigned long)res >= (unsigned long)-4095) {
|
||||
errno = (int)-res;
|
||||
res = -1;
|
||||
}
|
||||
return (struct DirectMap){(void *)res, kNtInvalidHandleValue};
|
||||
#else
|
||||
#error "arch unsupported"
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -73,5 +73,7 @@ privileged wontreturn void _Exit(int exitcode) {
|
|||
: "i"(94), "r"(x0)
|
||||
: "x8", "memory");
|
||||
notpossible;
|
||||
#else
|
||||
#error "arch unsupported"
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -81,5 +81,7 @@ privileged wontreturn void _Exit1(int rc) {
|
|||
: "i"(93), "r"(r0)
|
||||
: "x8", "memory");
|
||||
notpossible;
|
||||
#else
|
||||
#error "arch unsupported"
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/runtime/runtime.h"
|
||||
|
||||
const char *GetCpuidEmulator(void) {
|
||||
#ifdef __x86_64__
|
||||
static bool once;
|
||||
static char s[13];
|
||||
if (!once) {
|
||||
|
@ -26,4 +27,7 @@ const char *GetCpuidEmulator(void) {
|
|||
once = true;
|
||||
}
|
||||
return s;
|
||||
#else
|
||||
return "";
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/runtime/runtime.h"
|
||||
|
||||
const char *GetCpuidOs(void) {
|
||||
#ifdef __x86_64__
|
||||
static bool once;
|
||||
static char s[13];
|
||||
if (!once) {
|
||||
|
@ -26,4 +27,7 @@ const char *GetCpuidOs(void) {
|
|||
once = true;
|
||||
}
|
||||
return s;
|
||||
#else
|
||||
return "";
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -48,7 +48,19 @@ int getpid(void) {
|
|||
} else if (!__vforked) {
|
||||
rc = __pid;
|
||||
} else {
|
||||
#ifdef __x86_64__
|
||||
rc = sys_getpid().ax;
|
||||
#elif defined(__aarch64__)
|
||||
register long res_x0 asm("x0");
|
||||
asm volatile("mov\tx8,%1\n"
|
||||
"svc\t0"
|
||||
: "=r"(res_x0)
|
||||
: "i"(172)
|
||||
: "x8", "memory");
|
||||
rc = res_x0;
|
||||
#else
|
||||
#error "arch unsupported"
|
||||
#endif
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -189,6 +189,28 @@ o/$(MODE)/libc/intrin/memmove.o: private \
|
|||
# these assembly files are safe to build on aarch64
|
||||
o/$(MODE)/libc/intrin/kclocknames.o: libc/intrin/kclocknames.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
o/$(MODE)/libc/intrin/kdos2errno.o: libc/intrin/kdos2errno.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
o/$(MODE)/libc/intrin/kerrnodocs.o: libc/intrin/kerrnodocs.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
o/$(MODE)/libc/intrin/kipoptnames.o: libc/intrin/kipoptnames.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
o/$(MODE)/libc/intrin/kerrnonames.o: libc/intrin/kerrnonames.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
o/$(MODE)/libc/intrin/kfcntlcmds.o: libc/intrin/kfcntlcmds.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
o/$(MODE)/libc/intrin/kopenflags.o: libc/intrin/kopenflags.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
o/$(MODE)/libc/intrin/krlimitnames.o: libc/intrin/krlimitnames.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
o/$(MODE)/libc/intrin/ksignalnames.o: libc/intrin/ksignalnames.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
o/$(MODE)/libc/intrin/ksockoptnames.o: libc/intrin/ksockoptnames.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
o/$(MODE)/libc/intrin/ktcpoptnames.o: libc/intrin/ktcpoptnames.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
o/$(MODE)/libc/intrin/sched_yield.o: libc/intrin/sched_yield.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
|
||||
LIBC_INTRIN_LIBS = $(foreach x,$(LIBC_INTRIN_ARTIFACTS),$($(x)))
|
||||
LIBC_INTRIN_HDRS = $(foreach x,$(LIBC_INTRIN_ARTIFACTS),$($(x)_HDRS))
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
* Returns true if host platform is WSL 1.0.
|
||||
*/
|
||||
bool IsWsl1(void) {
|
||||
#ifdef __x86_64__
|
||||
static char res;
|
||||
if (res) return res & 1;
|
||||
if (!IsLinux()) return res = 2, false;
|
||||
|
@ -43,4 +44,7 @@ bool IsWsl1(void) {
|
|||
errno = e;
|
||||
res = 2 | tmp;
|
||||
return tmp;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -31,10 +31,10 @@
|
|||
.balign 4
|
||||
.underrun
|
||||
kIpOptnames:
|
||||
.e IP_TOS,"TOS" # int
|
||||
.e IP_MTU,"MTU" # int
|
||||
.e IP_TTL,"TTL" # int
|
||||
.e IP_HDRINCL,"HDRINCL" # bool32
|
||||
.e IP_TOS,"TOS" // int
|
||||
.e IP_MTU,"MTU" // int
|
||||
.e IP_TTL,"TTL" // int
|
||||
.e IP_HDRINCL,"HDRINCL" // bool32
|
||||
.long MAGNUM_TERMINATOR
|
||||
.endobj kIpOptnames,globl,hidden
|
||||
.overrun
|
||||
|
|
|
@ -62,11 +62,11 @@ kSignalNames:
|
|||
.e SIGIO,"SIGIO"
|
||||
.e SIGSYS,"SIGSYS"
|
||||
.e SIGPWR,"SIGPWR"
|
||||
.e SIGINFO,"SIGINFO" # order matters
|
||||
.e SIGTHR,"SIGTHR" # order matters
|
||||
.e SIGINFO,"SIGINFO" // order matters
|
||||
.e SIGTHR,"SIGTHR" // order matters
|
||||
.e SIGRTMAX,"SIGRTMAX"
|
||||
.e SIGRTMIN,"SIGRTMIN"
|
||||
.e SIGEMT,"SIGEMT" # order matters
|
||||
.e SIGEMT,"SIGEMT" // order matters
|
||||
.long MAGNUM_TERMINATOR
|
||||
.endobj kSignalNames,globl,hidden
|
||||
.overrun
|
||||
|
|
|
@ -31,22 +31,22 @@
|
|||
.balign 4
|
||||
.underrun
|
||||
kSockOptnames:
|
||||
.e SO_DEBUG,"DEBUG" # bool32
|
||||
.e SO_ACCEPTCONN,"ACCEPTCONN" # bool32
|
||||
.e SO_BROADCAST,"BROADCAST" # bool32
|
||||
.e SO_REUSEADDR,"REUSEADDR" # bool32
|
||||
.e SO_REUSEPORT,"REUSEPORT" # bool32
|
||||
.e SO_KEEPALIVE,"KEEPALIVE" # bool32
|
||||
.e SO_DONTROUTE,"DONTROUTE" # bool32
|
||||
.e SO_RCVTIMEO,"RCVTIMEO" # timeval
|
||||
.e SO_SNDTIMEO,"SNDTIMEO" # timeval
|
||||
.e SO_LINGER,"LINGER" # linger
|
||||
.e SO_TYPE,"TYPE" # int
|
||||
.e SO_SNDBUF,"SNDBUF" # int
|
||||
.e SO_RCVBUF,"RCVBUF" # int
|
||||
.e SO_RCVLOWAT,"RCVLOWAT" # int
|
||||
.e SO_SNDLOWAT,"SNDLOWAT" # int
|
||||
.e SO_ERROR,"ERROR" # int
|
||||
.e SO_DEBUG,"DEBUG" // bool32
|
||||
.e SO_ACCEPTCONN,"ACCEPTCONN" // bool32
|
||||
.e SO_BROADCAST,"BROADCAST" // bool32
|
||||
.e SO_REUSEADDR,"REUSEADDR" // bool32
|
||||
.e SO_REUSEPORT,"REUSEPORT" // bool32
|
||||
.e SO_KEEPALIVE,"KEEPALIVE" // bool32
|
||||
.e SO_DONTROUTE,"DONTROUTE" // bool32
|
||||
.e SO_RCVTIMEO,"RCVTIMEO" // timeval
|
||||
.e SO_SNDTIMEO,"SNDTIMEO" // timeval
|
||||
.e SO_LINGER,"LINGER" // linger
|
||||
.e SO_TYPE,"TYPE" // int
|
||||
.e SO_SNDBUF,"SNDBUF" // int
|
||||
.e SO_RCVBUF,"RCVBUF" // int
|
||||
.e SO_RCVLOWAT,"RCVLOWAT" // int
|
||||
.e SO_SNDLOWAT,"SNDLOWAT" // int
|
||||
.e SO_ERROR,"ERROR" // int
|
||||
.long MAGNUM_TERMINATOR
|
||||
.endobj kSockOptnames,globl,hidden
|
||||
.overrun
|
||||
|
|
|
@ -31,21 +31,21 @@
|
|||
.balign 4
|
||||
.underrun
|
||||
kTcpOptnames:
|
||||
.e TCP_NODELAY,"NODELAY" # bool32
|
||||
.e TCP_CORK,"CORK" # bool32
|
||||
.e TCP_QUICKACK,"QUICKACK" # bool32
|
||||
.e TCP_FASTOPEN_CONNECT,"FASTOPEN_CONNECT" # bool32
|
||||
.e TCP_DEFER_ACCEPT,"DEFER_ACCEPT" # bool32
|
||||
.e TCP_KEEPIDLE,"KEEPIDLE" # int (seconds)
|
||||
.e TCP_KEEPINTVL,"KEEPINTVL" # int (seconds)
|
||||
.e TCP_FASTOPEN,"FASTOPEN" # int
|
||||
.e TCP_KEEPCNT,"KEEPCNT" # int
|
||||
.e TCP_MAXSEG,"MAXSEG" # int
|
||||
.e TCP_SYNCNT,"SYNCNT" # int
|
||||
.e TCP_NOTSENT_LOWAT,"NOTSENT_LOWAT" # int
|
||||
.e TCP_WINDOW_CLAMP,"WINDOW_CLAMP" # int
|
||||
.e TCP_SAVE_SYN,"SAVE_SYN" # int
|
||||
.e TCP_SAVED_SYN,"SAVED_SYN" # buffer
|
||||
.e TCP_NODELAY,"NODELAY" // bool32
|
||||
.e TCP_CORK,"CORK" // bool32
|
||||
.e TCP_QUICKACK,"QUICKACK" // bool32
|
||||
.e TCP_FASTOPEN_CONNECT,"FASTOPEN_CONNECT" // bool32
|
||||
.e TCP_DEFER_ACCEPT,"DEFER_ACCEPT" // bool32
|
||||
.e TCP_KEEPIDLE,"KEEPIDLE" // int (seconds)
|
||||
.e TCP_KEEPINTVL,"KEEPINTVL" // int (seconds)
|
||||
.e TCP_FASTOPEN,"FASTOPEN" // int
|
||||
.e TCP_KEEPCNT,"KEEPCNT" // int
|
||||
.e TCP_MAXSEG,"MAXSEG" // int
|
||||
.e TCP_SYNCNT,"SYNCNT" // int
|
||||
.e TCP_NOTSENT_LOWAT,"NOTSENT_LOWAT" // int
|
||||
.e TCP_WINDOW_CLAMP,"WINDOW_CLAMP" // int
|
||||
.e TCP_SAVE_SYN,"SAVE_SYN" // int
|
||||
.e TCP_SAVED_SYN,"SAVED_SYN" // buffer
|
||||
.long MAGNUM_TERMINATOR
|
||||
.endobj kTcpOptnames,globl,hidden
|
||||
.overrun
|
||||
|
|
|
@ -26,8 +26,6 @@
|
|||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/math.h"
|
||||
#include "libc/tinymath/feval.internal.h"
|
||||
#include "libc/tinymath/kernel.internal.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Musl libc (MIT License)\\n\
|
|
@ -26,8 +26,6 @@
|
|||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/math.h"
|
||||
#include "libc/tinymath/feval.internal.h"
|
||||
#include "libc/tinymath/kernel.internal.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Musl libc (MIT License)\\n\
|
|
@ -1,7 +1,7 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ Copyright 2023 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
|
@ -16,18 +16,8 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/math.h"
|
||||
|
||||
// Returns log₂ₓ exponent part of long double.
|
||||
//
|
||||
// @param 𝑥 is long double passed on stack
|
||||
// @return result in %st0
|
||||
logbl: push %rbp
|
||||
mov %rsp,%rbp
|
||||
.profilable
|
||||
fldt 16(%rbp)
|
||||
fxtract
|
||||
fstp %st
|
||||
pop %rbp
|
||||
ret
|
||||
.endfn logbl,globl
|
||||
long double ldexpl(long double x, int n) {
|
||||
return scalbnl(x, n);
|
||||
}
|
|
@ -13,8 +13,6 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
STATIC_YOINK("huge_compiler_rt_license");
|
||||
|
||||
#define QUAD_PRECISION
|
||||
#include "third_party/compiler_rt/fp_lib.inc"
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
.privileged
|
||||
.balignfunc
|
||||
.alignfunc
|
||||
|
||||
// Returns 𝑥*𝑦, aborting on overflow.
|
||||
//
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
.privileged
|
||||
.balignfunc
|
||||
.alignfunc
|
||||
|
||||
// Returns 𝑥*𝑦, aborting on overflow.
|
||||
//
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
.privileged
|
||||
.balignfunc
|
||||
.alignfunc
|
||||
|
||||
// Returns 𝑥*𝑦, aborting on overflow.
|
||||
//
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
.privileged
|
||||
.balignfunc
|
||||
.alignfunc
|
||||
|
||||
// Returns -𝑥, aborting on overflow (two's complement bane).
|
||||
//
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
.privileged
|
||||
.balignfunc
|
||||
.alignfunc
|
||||
|
||||
// Returns -𝑥, aborting on overflow (two's complement bane).
|
||||
//
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
.privileged
|
||||
.balignfunc
|
||||
.alignfunc
|
||||
|
||||
// Returns -𝑥, aborting on overflow.
|
||||
//
|
||||
|
|
|
@ -6,6 +6,7 @@ COSMOPOLITAN_C_START_
|
|||
|
||||
uint32_t pmovmskb(const uint8_t[16]);
|
||||
|
||||
#if defined(__x86_64__) && defined(__GNUC__)
|
||||
#define pmovmskb(A) \
|
||||
({ \
|
||||
uint32_t Mask; \
|
||||
|
@ -21,6 +22,7 @@ uint32_t pmovmskb(const uint8_t[16]);
|
|||
} \
|
||||
Mask; \
|
||||
})
|
||||
#endif
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
51
libc/intrin/scalblnl.c
Normal file
51
libc/intrin/scalblnl.c
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/limits.h"
|
||||
#include "libc/math.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Musl libc (MIT License)\\n\
|
||||
Copyright 2005-2014 Rich Felker, et. al.\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
/* clang-format off */
|
||||
|
||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||
long double scalblnl(long double x, long n)
|
||||
{
|
||||
return scalbln(x, n);
|
||||
}
|
||||
#else
|
||||
long double scalblnl(long double x, long n)
|
||||
{
|
||||
if (n > INT_MAX)
|
||||
n = INT_MAX;
|
||||
else if (n < INT_MIN)
|
||||
n = INT_MIN;
|
||||
return scalbnl(x, n);
|
||||
}
|
||||
#endif
|
70
libc/intrin/scalbnl.c
Normal file
70
libc/intrin/scalbnl.c
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/math.h"
|
||||
#include "libc/tinymath/ldshape.internal.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Musl libc (MIT License)\\n\
|
||||
Copyright 2005-2014 Rich Felker, et. al.\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
/* clang-format off */
|
||||
|
||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||
long double scalbnl(long double x, int n)
|
||||
{
|
||||
return scalbn(x, n);
|
||||
}
|
||||
#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
|
||||
long double scalbnl(long double x, int n)
|
||||
{
|
||||
union ldshape u;
|
||||
|
||||
if (n > 16383) {
|
||||
x *= 0x1p16383L;
|
||||
n -= 16383;
|
||||
if (n > 16383) {
|
||||
x *= 0x1p16383L;
|
||||
n -= 16383;
|
||||
if (n > 16383)
|
||||
n = 16383;
|
||||
}
|
||||
} else if (n < -16382) {
|
||||
x *= 0x1p-16382L * 0x1p113L;
|
||||
n += 16382 - 113;
|
||||
if (n < -16382) {
|
||||
x *= 0x1p-16382L * 0x1p113L;
|
||||
n += 16382 - 113;
|
||||
if (n < -16382)
|
||||
n = -16382;
|
||||
}
|
||||
}
|
||||
u.f = 1.0;
|
||||
u.i.se = 0x3fff + n;
|
||||
return x * u.f;
|
||||
}
|
||||
#endif
|
|
@ -26,6 +26,7 @@
|
|||
// @return 0 on success, or -1 w/ errno
|
||||
// @norestart
|
||||
sched_yield:
|
||||
#ifdef __x86_64__
|
||||
push %rbp
|
||||
mov %rsp,%rbp
|
||||
xor %eax,%eax
|
||||
|
@ -86,5 +87,15 @@ sched_yield:
|
|||
|
||||
9: leave
|
||||
ret
|
||||
|
||||
#elif defined(__aarch64__)
|
||||
mov x8,#0x7c
|
||||
svc 0
|
||||
mov w0,#0
|
||||
ret
|
||||
|
||||
#else
|
||||
#error "arch unsupported"
|
||||
#endif
|
||||
.endfn sched_yield,globl
|
||||
.previous
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
.privileged
|
||||
.balignfunc
|
||||
.alignfunc
|
||||
|
||||
// Returns 𝑥-𝑦, aborting on overflow.
|
||||
//
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
.privileged
|
||||
.balignfunc
|
||||
.alignfunc
|
||||
|
||||
// Returns 𝑥-𝑦, aborting on overflow.
|
||||
//
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
.privileged
|
||||
.balignfunc
|
||||
.alignfunc
|
||||
|
||||
// Returns 𝑥-𝑦, aborting on overflow.
|
||||
//
|
||||
|
|
|
@ -70,5 +70,7 @@ privileged int sys_gettid(void) {
|
|||
: "i"(178)
|
||||
: "x8", "memory");
|
||||
return res_x0;
|
||||
#else
|
||||
#error "arch unsupported"
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#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");
|
||||
|
@ -45,3 +46,5 @@ 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
|
||||
|
|
|
@ -5,7 +5,8 @@ COSMOPOLITAN_C_START_
|
|||
|
||||
uint64_t _tpenc(int32_t) pureconst;
|
||||
|
||||
#if defined(__MNO_RED_ZONE__) && defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
#if defined(__x86_64__) && defined(__MNO_RED_ZONE__) && defined(__GNUC__) && \
|
||||
!defined(__STRICT_ANSI__)
|
||||
#define _tpenc(CODE) \
|
||||
({ \
|
||||
long Edi, Buf; \
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ Copyright 2023 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
|
@ -16,41 +16,31 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/tpenc.h"
|
||||
#include "libc/str/internal.h"
|
||||
#include "libc/str/tpencode.internal.h"
|
||||
#include "libc/intrin/bsr.h"
|
||||
#include "libc/intrin/intrin.h"
|
||||
#ifndef __x86_64__
|
||||
|
||||
/* TODO: DELETE */
|
||||
static const uint16_t kTpEnc[32 - 7] = {
|
||||
1 | 0300 << 8, 1 | 0300 << 8, 1 | 0300 << 8, 1 | 0300 << 8, 2 | 0340 << 8,
|
||||
2 | 0340 << 8, 2 | 0340 << 8, 2 | 0340 << 8, 2 | 0340 << 8, 3 | 0360 << 8,
|
||||
3 | 0360 << 8, 3 | 0360 << 8, 3 | 0360 << 8, 3 | 0360 << 8, 4 | 0370 << 8,
|
||||
4 | 0370 << 8, 4 | 0370 << 8, 4 | 0370 << 8, 4 | 0370 << 8, 5 | 0374 << 8,
|
||||
5 | 0374 << 8, 5 | 0374 << 8, 5 | 0374 << 8, 5 | 0374 << 8, 5 | 0374 << 8,
|
||||
};
|
||||
|
||||
/**
|
||||
* Thompson-Pike Varint Encoder.
|
||||
*
|
||||
* Implementation Details: The header macro should ensure this function
|
||||
* is only called for non-ASCII, or DCE'd entirely. In addition to that
|
||||
* this function makes a promise to not clobber any registers but %rax.
|
||||
*
|
||||
* @param p is what ch gets encoded to
|
||||
* @param size is the number of bytes available in buf
|
||||
* @param ch is a 32-bit integer
|
||||
* @param awesome mode enables numbers the IETF unilaterally banned
|
||||
* @return number of bytes written
|
||||
* @note this encoding was designed on a napkin in a new jersey diner
|
||||
* @deprecated
|
||||
*/
|
||||
unsigned(tpencode)(char *p, size_t size, wint_t wc, bool32 awesome) {
|
||||
int i, j;
|
||||
unsigned long w;
|
||||
if ((0 <= wc && wc < 32) && awesome && size >= 2) {
|
||||
p[0] = 0xc0;
|
||||
p[1] = 0x80;
|
||||
p[1] |= wc;
|
||||
return 2;
|
||||
}
|
||||
i = 0;
|
||||
w = _tpenc(wc);
|
||||
uint64_t _tpenc(int32_t c) {
|
||||
int e, n;
|
||||
uint64_t w;
|
||||
if (0 <= c && c <= 127) return c;
|
||||
e = kTpEnc[_bsr(c) - 7];
|
||||
n = e & 0xff;
|
||||
w = 0;
|
||||
do {
|
||||
if (!size--) break;
|
||||
p[i++] = w & 0xff;
|
||||
} while (w >>= 8);
|
||||
return i;
|
||||
w |= 0200 | (c & 077);
|
||||
w <<= 8;
|
||||
c >>= 6;
|
||||
} while (--n);
|
||||
return c | w | e >> 8;
|
||||
}
|
||||
|
||||
#endif /* __x86_64__ */
|
|
@ -142,6 +142,14 @@
|
|||
.section .privileged,"ax",@progbits
|
||||
.endm
|
||||
|
||||
// Declares alternative implementation of function.
|
||||
// @param implement e.g. tinymath_pow
|
||||
// @param canonical e.g. pow
|
||||
.macro .alias implement:req canonical:req
|
||||
.equ \canonical,\implement
|
||||
.weak \canonical
|
||||
.endm
|
||||
|
||||
// Pulls unrelated module into linkage.
|
||||
//
|
||||
// In order for this technique to work with --gc-sections, another
|
||||
|
@ -231,14 +239,6 @@
|
|||
.previous
|
||||
.endm
|
||||
|
||||
// Declares alternative implementation of function.
|
||||
// @param implement e.g. tinymath_pow
|
||||
// @param canonical e.g. pow
|
||||
.macro .alias implement:req canonical:req
|
||||
.equ \canonical,\implement
|
||||
.weak \canonical
|
||||
.endm
|
||||
|
||||
// LOOP Instruction Replacement.
|
||||
.macro .loop label:req
|
||||
.byte 0x83
|
||||
|
|
|
@ -58,37 +58,37 @@
|
|||
// @see libc/str/str.h
|
||||
// @see kCp437i[]
|
||||
kCp437:
|
||||
.short 0x00a0,0x263a,0x263b,0x2665,0x2666,0x2663,0x2660,0x2022 #00: ☺☻♥♦♣♠•
|
||||
.short 0x25d8,0x25cb,0x25d9,0x2642,0x2640,0x266a,0x266b,0x263c #08:◘○◙♂♀♪♫☼
|
||||
.short 0x25ba,0x25c4,0x2195,0x203c,0x00b6,0x00a7,0x25ac,0x21a8 #10:►◄↕‼¶§▬↨
|
||||
.short 0x2191,0x2193,0x2192,0x2190,0x221f,0x2194,0x25b2,0x25bc #18:↑↓→←∟↔▲▼
|
||||
.short 0x0020,0x0021,0x201c,0x0023,0x0024,0x0025,0x0026,0x2018 #20: !“#$%&‘
|
||||
.short 0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f #28:()*+,-./
|
||||
.short 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037 #30:01234567
|
||||
.short 0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x2047 #38:89:;<=>⁇
|
||||
.short 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047 #40:@ABCDEFG
|
||||
.short 0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f #48:HIJKLMNO
|
||||
.short 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057 #50:PQRSTUVW
|
||||
.short 0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f #58:XYZ[\]^_
|
||||
.short 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067 #60:`abcdefg
|
||||
.short 0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f #68:hijklmno
|
||||
.short 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077 #70:pqrstuvw
|
||||
.short 0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x2302 #78:xyz{|}~⌂
|
||||
.short 0x00c7,0x00fc,0x00e9,0x00e2,0x00e4,0x00e0,0x00e5,0x00e7 #80:Çüéâäàåç
|
||||
.short 0x00ea,0x00eb,0x00e8,0x00ef,0x00ee,0x00ec,0x00c4,0x00c5 #88:êëèïîìÄÅ
|
||||
.short 0x00c9,0x00e6,0x00c6,0x00f4,0x00f6,0x00f2,0x00fb,0x00f9 #90:ÉæÆôöòûù
|
||||
.short 0x00ff,0x00d6,0x00dc,0x00a2,0x00a3,0x00a5,0x20ac,0x0192 #98:ÿÖÜ¢£¥€ƒ
|
||||
.short 0x00e1,0x00ed,0x00f3,0x00fa,0x00f1,0x00d1,0x00aa,0x00ba #a0:áíóúñѪº
|
||||
.short 0x00bf,0x2310,0x00ac,0x00bd,0x00bc,0x00a1,0x00ab,0x00bb #a8:¿⌐¬½¼¡«»
|
||||
.short 0x2591,0x2592,0x2593,0x2502,0x2524,0x2561,0x2562,0x2556 #b0:░▒▓│┤╡╢╖
|
||||
.short 0x2555,0x2563,0x2551,0x2557,0x255d,0x255c,0x255b,0x2510 #b8:╕╣║╗╝╜╛┐
|
||||
.short 0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x255e,0x255f #c0:└┴┬├─┼╞╟
|
||||
.short 0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x2567 #c8:╚╔╩╦╠═╬╧
|
||||
.short 0x2568,0x2564,0x2565,0x2559,0x2558,0x2552,0x2553,0x256b #d0:╨╤╥╙╘╒╓╫
|
||||
.short 0x256a,0x2518,0x250c,0x2588,0x2584,0x258c,0x2590,0x2580 #d8:╪┘┌█▄▌▐▀
|
||||
.short 0x03b1,0x00df,0x0393,0x03c0,0x03a3,0x03c3,0x03bc,0x03c4 #e0:αßΓπΣσμτ
|
||||
.short 0x03a6,0x0398,0x03a9,0x03b4,0x221e,0x03c6,0x03b5,0x2229 #e8:ΦΘΩδ∞φε∩
|
||||
.short 0x2261,0x00b1,0x2265,0x2264,0x2320,0x2321,0x00f7,0x2248 #f0:≡±≥≤⌠⌡÷≈
|
||||
.short 0x00b0,0x2219,0x00d7,0x221a,0x207f,0x00b2,0x25a0,0x03bb #f8:°∙×√ⁿ²■λ
|
||||
.short 0x00a0,0x263a,0x263b,0x2665,0x2666,0x2663,0x2660,0x2022 //00: ☺☻♥♦♣♠•
|
||||
.short 0x25d8,0x25cb,0x25d9,0x2642,0x2640,0x266a,0x266b,0x263c //08:◘○◙♂♀♪♫☼
|
||||
.short 0x25ba,0x25c4,0x2195,0x203c,0x00b6,0x00a7,0x25ac,0x21a8 //10:►◄↕‼¶§▬↨
|
||||
.short 0x2191,0x2193,0x2192,0x2190,0x221f,0x2194,0x25b2,0x25bc //18:↑↓→←∟↔▲▼
|
||||
.short 0x0020,0x0021,0x201c,0x0023,0x0024,0x0025,0x0026,0x2018 //20: !“//$%&‘
|
||||
.short 0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f //28:()*+,-./
|
||||
.short 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037 //30:01234567
|
||||
.short 0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x2047 //38:89:;<=>⁇
|
||||
.short 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047 //40:@ABCDEFG
|
||||
.short 0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f //48:HIJKLMNO
|
||||
.short 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057 //50:PQRSTUVW
|
||||
.short 0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f //58:XYZ[\]^_
|
||||
.short 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067 //60:`abcdefg
|
||||
.short 0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f //68:hijklmno
|
||||
.short 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077 //70:pqrstuvw
|
||||
.short 0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x2302 //78:xyz{|}~⌂
|
||||
.short 0x00c7,0x00fc,0x00e9,0x00e2,0x00e4,0x00e0,0x00e5,0x00e7 //80:Çüéâäàåç
|
||||
.short 0x00ea,0x00eb,0x00e8,0x00ef,0x00ee,0x00ec,0x00c4,0x00c5 //88:êëèïîìÄÅ
|
||||
.short 0x00c9,0x00e6,0x00c6,0x00f4,0x00f6,0x00f2,0x00fb,0x00f9 //90:ÉæÆôöòûù
|
||||
.short 0x00ff,0x00d6,0x00dc,0x00a2,0x00a3,0x00a5,0x20ac,0x0192 //98:ÿÖÜ¢£¥€ƒ
|
||||
.short 0x00e1,0x00ed,0x00f3,0x00fa,0x00f1,0x00d1,0x00aa,0x00ba //a0:áíóúñѪº
|
||||
.short 0x00bf,0x2310,0x00ac,0x00bd,0x00bc,0x00a1,0x00ab,0x00bb //a8:¿⌐¬½¼¡«»
|
||||
.short 0x2591,0x2592,0x2593,0x2502,0x2524,0x2561,0x2562,0x2556 //b0:░▒▓│┤╡╢╖
|
||||
.short 0x2555,0x2563,0x2551,0x2557,0x255d,0x255c,0x255b,0x2510 //b8:╕╣║╗╝╜╛┐
|
||||
.short 0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x255e,0x255f //c0:└┴┬├─┼╞╟
|
||||
.short 0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x2567 //c8:╚╔╩╦╠═╬╧
|
||||
.short 0x2568,0x2564,0x2565,0x2559,0x2558,0x2552,0x2553,0x256b //d0:╨╤╥╙╘╒╓╫
|
||||
.short 0x256a,0x2518,0x250c,0x2588,0x2584,0x258c,0x2590,0x2580 //d8:╪┘┌█▄▌▐▀
|
||||
.short 0x03b1,0x00df,0x0393,0x03c0,0x03a3,0x03c3,0x03bc,0x03c4 //e0:αßΓπΣσμτ
|
||||
.short 0x03a6,0x0398,0x03a9,0x03b4,0x221e,0x03c6,0x03b5,0x2229 //e8:ΦΘΩδ∞φε∩
|
||||
.short 0x2261,0x00b1,0x2265,0x2264,0x2320,0x2321,0x00f7,0x2248 //f0:≡±≥≤⌠⌡÷≈
|
||||
.short 0x00b0,0x2219,0x00d7,0x221a,0x207f,0x00b2,0x25a0,0x03bb //f8:°∙×√ⁿ²■λ
|
||||
.endobj kCp437,globl
|
||||
.previous
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
// static const uint64_t kTens[] = {
|
||||
// 1ull,
|
||||
// 10ull,
|
||||
// 100ull,
|
||||
// 1000ull,
|
||||
// 10000ull,
|
||||
// 100000ull,
|
||||
// 1000000ull,
|
||||
// 10000000ull,
|
||||
// 100000000ull,
|
||||
// 1000000000ull,
|
||||
// 10000000000ull,
|
||||
// 100000000000ull,
|
||||
// 1000000000000ull,
|
||||
// 10000000000000ull,
|
||||
// 100000000000000ull,
|
||||
// 1000000000000000ull,
|
||||
// 10000000000000000ull,
|
||||
// 100000000000000000ull,
|
||||
// 1000000000000000000ull,
|
||||
// 10000000000000000000ull,
|
||||
// };
|
||||
|
||||
.initbss 201,_init_kTens
|
||||
kTens: .rept 20
|
||||
.quad 0
|
||||
.endr
|
||||
.endobj kTens,globl
|
||||
.previous
|
||||
|
||||
.init.start 201,_init_kTens
|
||||
push $20
|
||||
pop %rcx
|
||||
push $10
|
||||
pop %r8
|
||||
push $1
|
||||
pop %rax
|
||||
1: stosq
|
||||
mul %r8
|
||||
.loop 1b
|
||||
.init.end 201,_init_kTens
|
|
@ -1,7 +1,7 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ Copyright 2023 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
|
@ -16,26 +16,27 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/errno.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/str/tpdecode.internal.h"
|
||||
#include "libc/str/tpdecodecb.internal.h"
|
||||
#include "libc/nexgen32e/nexgen32e.h"
|
||||
|
||||
/* TODO(jart): DELETE */
|
||||
|
||||
forceinline int getbyte(void *arg, uint32_t i) {
|
||||
return ((const unsigned char *)arg)[i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Thompson-Pike Varint Decoder.
|
||||
*
|
||||
* @param s is a NUL-terminated string
|
||||
* @return number of bytes successfully consumed or -1 w/ errno
|
||||
* @note synchronization is performed
|
||||
* @see libc/str/tpdecodecb.internal.h (for implementation)
|
||||
* @deprecated
|
||||
*/
|
||||
int(tpdecode)(const char *s, wint_t *out) {
|
||||
return tpdecodecb(out, (unsigned char)s[0], getbyte, (void *)s);
|
||||
}
|
||||
const uint64_t kTens[] = {
|
||||
1ull,
|
||||
10ull,
|
||||
100ull,
|
||||
1000ull,
|
||||
10000ull,
|
||||
100000ull,
|
||||
1000000ull,
|
||||
10000000ull,
|
||||
100000000ull,
|
||||
1000000000ull,
|
||||
10000000000ull,
|
||||
100000000000ull,
|
||||
1000000000000ull,
|
||||
10000000000000ull,
|
||||
100000000000000ull,
|
||||
1000000000000000ull,
|
||||
10000000000000000ull,
|
||||
100000000000000000ull,
|
||||
1000000000000000000ull,
|
||||
10000000000000000000ull,
|
||||
};
|
|
@ -26,6 +26,7 @@
|
|||
// @see _gclongjmp()
|
||||
// @see siglongjmp()
|
||||
longjmp:
|
||||
#ifdef __x86_64__
|
||||
mov %esi,%eax
|
||||
test %eax,%eax
|
||||
jnz 1f
|
||||
|
@ -38,5 +39,22 @@ longjmp:
|
|||
mov 40(%rdi),%r14
|
||||
mov 48(%rdi),%r15
|
||||
jmp *56(%rdi)
|
||||
#elif defined(__aarch64__)
|
||||
ldp x19,x20,[x0,#0]
|
||||
ldp x21,x22,[x0,#16]
|
||||
ldp x23,x24,[x0,#32]
|
||||
ldp x25,x26,[x0,#48]
|
||||
ldp x27,x28,[x0,#64]
|
||||
ldp x29,x30,[x0,#80]
|
||||
ldr x2,[x0,#104]
|
||||
mov sp,x2
|
||||
ldp d8 ,d9,[x0,#112]
|
||||
ldp d10,d11,[x0,#128]
|
||||
ldp d12,d13,[x0,#144]
|
||||
ldp d14,d15,[x0,#160]
|
||||
cmp w1,0
|
||||
csinc w0,w1,wzr,ne
|
||||
br x30
|
||||
#endif
|
||||
.endfn longjmp,globl
|
||||
.alias longjmp,_longjmp
|
||||
|
|
|
@ -23,4 +23,4 @@
|
|||
// cc -pg adds this to the start of global functions.
|
||||
mcount: ret
|
||||
.endfn mcount,weak
|
||||
.alias mcount,.mcount # freebsd weirdness?
|
||||
.alias mcount,.mcount // freebsd weirdness?
|
||||
|
|
|
@ -48,8 +48,22 @@ o/$(MODE)/libc/nexgen32e/threaded.o: private \
|
|||
-fno-sanitize=all
|
||||
|
||||
# these assembly files are safe to build on aarch64
|
||||
o/$(MODE)/libc/nexgen32e/mcount.o: libc/nexgen32e/mcount.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
o/$(MODE)/libc/nexgen32e/ksha256.o: libc/nexgen32e/ksha256.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
o/$(MODE)/libc/nexgen32e/ksha512.o: libc/nexgen32e/ksha512.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
o/$(MODE)/libc/nexgen32e/kcp437.o: libc/nexgen32e/kcp437.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
o/$(MODE)/libc/nexgen32e/kreversebits.o: libc/nexgen32e/kreversebits.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
o/$(MODE)/libc/nexgen32e/ktensindex.o: libc/nexgen32e/ktensindex.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
o/$(MODE)/libc/nexgen32e/longjmp.o: libc/nexgen32e/longjmp.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
o/$(MODE)/libc/nexgen32e/setjmp.o: libc/nexgen32e/setjmp.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
|
||||
LIBC_NEXGEN32E_LIBS = $(foreach x,$(LIBC_NEXGEN32E_ARTIFACTS),$($(x)))
|
||||
LIBC_NEXGEN32E_SRCS = $(foreach x,$(LIBC_NEXGEN32E_ARTIFACTS),$($(x)_SRCS))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ Copyright 2023 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
|
@ -16,22 +16,6 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
|
||||
// Returns log₂x exponent part of long double.
|
||||
//
|
||||
// @param 𝑥 is long double passed on stack
|
||||
// @return result in %eax
|
||||
// @note needs sse3
|
||||
ilogbl: push %rbp
|
||||
mov %rsp,%rbp
|
||||
.profilable
|
||||
fldt 16(%rbp)
|
||||
fxtract
|
||||
fstp %st
|
||||
push %rax
|
||||
fisttpl (%rsp)
|
||||
mov (%rsp),%eax
|
||||
leave
|
||||
ret
|
||||
.endfn ilogbl,globl
|
||||
int __pid;
|
|
@ -26,7 +26,9 @@
|
|||
// @assume system five nexgen32e abi conformant
|
||||
// @note code built w/ microsoft abi compiler can't call this
|
||||
// @see longjmp(), _gclongjmp()
|
||||
setjmp: lea 8(%rsp),%rax
|
||||
setjmp:
|
||||
#ifdef __x86_64__
|
||||
lea 8(%rsp),%rax
|
||||
mov %rax,(%rdi)
|
||||
mov %rbx,8(%rdi)
|
||||
mov %rbp,16(%rdi)
|
||||
|
@ -38,5 +40,21 @@ setjmp: lea 8(%rsp),%rax
|
|||
mov %rax,56(%rdi)
|
||||
xor %eax,%eax
|
||||
ret
|
||||
#elif defined(__aarch64__)
|
||||
stp x19,x20,[x0,#0]
|
||||
stp x21,x22,[x0,#16]
|
||||
stp x23,x24,[x0,#32]
|
||||
stp x25,x26,[x0,#48]
|
||||
stp x27,x28,[x0,#64]
|
||||
stp x29,x30,[x0,#80]
|
||||
mov x2,sp
|
||||
str x2,[x0,#104]
|
||||
stp d8,d9,[x0,#112]
|
||||
stp d10,d11,[x0,#128]
|
||||
stp d12,d13,[x0,#144]
|
||||
stp d14,d15,[x0,#160]
|
||||
mov x0,#0
|
||||
ret
|
||||
#endif
|
||||
.endfn setjmp,globl
|
||||
.alias setjmp,_setjmp
|
||||
|
|
|
@ -7,7 +7,7 @@ COSMOPOLITAN_C_START_
|
|||
bool IsAtLeastWindows10(void) pureconst;
|
||||
bool32 GetVersionEx(struct NtOsVersionInfo *lpVersionInformation);
|
||||
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__) && defined(__x86_64__)
|
||||
#define IsAtLeastWindows10() (GetNtMajorVersion() >= 10)
|
||||
#define GetNtMajorVersion() \
|
||||
({ \
|
||||
|
|
|
@ -6,7 +6,12 @@ COSMOPOLITAN_C_START_
|
|||
│ cosmopolitan § runtime ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
#ifdef __x86_64__
|
||||
typedef long jmp_buf[8];
|
||||
#elif defined(__aarch64__)
|
||||
typedef long jmp_buf[22];
|
||||
#endif
|
||||
|
||||
typedef long sigjmp_buf[12];
|
||||
|
||||
extern char **environ; /* CRT */
|
||||
|
|
|
@ -38,6 +38,7 @@ static dontinline antiquity int bcmp_sse(const char *p, const char *q,
|
|||
return !!(a[0] | a[1]);
|
||||
}
|
||||
|
||||
#ifdef __x86_64__
|
||||
microarchitecture("avx") static int bcmp_avx(const char *p, const char *q,
|
||||
size_t n) {
|
||||
xmm_t a, b, c, d;
|
||||
|
@ -67,6 +68,7 @@ microarchitecture("avx") static int bcmp_avx(const char *p, const char *q,
|
|||
*(const xmm_t *)(p + n - 16) ^ *(const xmm_t *)(q + n - 16);
|
||||
return !!(a[0] | a[1]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Tests inequality of first 𝑛 bytes of 𝑝 and 𝑞.
|
||||
|
@ -122,8 +124,10 @@ int bcmp(const void *a, const void *b, size_t n) {
|
|||
__builtin_memcpy(&j, q + n - 4, 4);
|
||||
return !!(i ^ j);
|
||||
}
|
||||
#ifdef __x86_64__
|
||||
} else if (LIKELY(X86_HAVE(AVX))) {
|
||||
return bcmp_avx(p, q, n);
|
||||
#endif
|
||||
} else {
|
||||
return bcmp_sse(p, q, n);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "libc/intrin/bits.h"
|
||||
#include "libc/nexgen32e/cachesize.h"
|
||||
#include "libc/nexgen32e/cpuid4.internal.h"
|
||||
#ifdef __x86_64__
|
||||
|
||||
static unsigned _getcachesize_cpuid4(int type, int level) {
|
||||
unsigned i, k;
|
||||
|
@ -55,3 +56,5 @@ unsigned _getcachesize(int type, int level) {
|
|||
_unassert(level >= 1);
|
||||
return _getcachesize_cpuid4(type, level);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -45,6 +45,7 @@ void *GetZipCdir(const uint8_t *p, size_t n) {
|
|||
i = n - 4;
|
||||
asm("" : "+x"(pk));
|
||||
do {
|
||||
#ifdef __x86_64__
|
||||
if (i >= 14) {
|
||||
x = *(const v2di *)(p + i - 14);
|
||||
if (!(__builtin_ia32_pmovmskb128(
|
||||
|
@ -55,6 +56,7 @@ void *GetZipCdir(const uint8_t *p, size_t n) {
|
|||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
while (magic = READ32LE(p + i), magic != kZipCdir64LocatorMagic &&
|
||||
magic != kZipCdirHdrMagic &&
|
||||
i + 0x10000 + 0x1000 >= n && i > 0) {
|
||||
|
|
|
@ -60,6 +60,7 @@ noasan bool _isutf8(const void *data, size_t size) {
|
|||
p = data;
|
||||
e = p + size;
|
||||
while (p < e) {
|
||||
#ifdef __x86_64__
|
||||
if (!((intptr_t)p & 15)) {
|
||||
for (;;) {
|
||||
if ((m = __builtin_ia32_pmovmskb128(*(xmm_t *)p >= (xmm_t){0}) ^
|
||||
|
@ -75,6 +76,7 @@ noasan bool _isutf8(const void *data, size_t size) {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (LIKELY((c = *p++ & 255) < 0200)) continue;
|
||||
if (UNLIKELY(c < 0300)) return false;
|
||||
switch (kUtf8Dispatch[c - 0300]) {
|
||||
|
|
|
@ -43,7 +43,7 @@ textstartup void *lz4cpy(void *dest, const void *blockdata, size_t blocksize) {
|
|||
length += *ip;
|
||||
} while (*ip++ == 255);
|
||||
}
|
||||
repmovsb(&op, &ip, length);
|
||||
repmovsb((void **)&op, (const void **)&ip, length);
|
||||
if (ip >= ipe) break;
|
||||
offset = READ16LE(ip);
|
||||
matchlen = token & fifteen;
|
||||
|
@ -54,7 +54,7 @@ textstartup void *lz4cpy(void *dest, const void *blockdata, size_t blocksize) {
|
|||
} while (*ip++ == 255);
|
||||
}
|
||||
match = op - offset;
|
||||
repmovsb(&op, &match, (matchlen += 4));
|
||||
repmovsb((void **)&op, (const void **)&match, (matchlen += 4));
|
||||
}
|
||||
return op;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ static inline const unsigned char *memchr_pure(const unsigned char *s,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __x86_64__
|
||||
noasan static inline const unsigned char *memchr_sse(const unsigned char *s,
|
||||
unsigned char c,
|
||||
size_t n) {
|
||||
|
@ -57,6 +58,7 @@ noasan static inline const unsigned char *memchr_sse(const unsigned char *s,
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Returns pointer to first instance of character.
|
||||
|
@ -68,6 +70,7 @@ noasan static inline const unsigned char *memchr_sse(const unsigned char *s,
|
|||
* @asyncsignalsafe
|
||||
*/
|
||||
void *memchr(const void *s, int c, size_t n) {
|
||||
#ifdef __x86_64__
|
||||
const void *r;
|
||||
if (!IsTiny() && X86_HAVE(SSE)) {
|
||||
if (IsAsan()) __asan_verify(s, n);
|
||||
|
@ -76,4 +79,7 @@ void *memchr(const void *s, int c, size_t n) {
|
|||
r = memchr_pure(s, c, n);
|
||||
}
|
||||
return (void *)r;
|
||||
#else
|
||||
return memchr_pure(s, c, n);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(16)));
|
|||
*/
|
||||
noasan void *memmem(const void *haystack, size_t haystacklen,
|
||||
const void *needle, size_t needlelen) {
|
||||
#ifdef __x86_64__
|
||||
char c;
|
||||
xmm_t n, *v;
|
||||
unsigned i, k, m;
|
||||
|
@ -69,4 +70,17 @@ noasan void *memmem(const void *haystack, size_t haystacklen,
|
|||
m &= ~(1 << k);
|
||||
} while (m);
|
||||
}
|
||||
#else
|
||||
size_t i, j;
|
||||
if (!needlelen) return haystack;
|
||||
if (needlelen > haystacklen) return 0;
|
||||
for (i = 0; i < haystacklen; ++i) {
|
||||
for (j = 0;; ++j) {
|
||||
if (j == needlelen) return (/*unconst*/ char *)haystack + i;
|
||||
if (i + j == haystacklen) break;
|
||||
if (((char *)haystack)[i + j] != ((char *)needle)[j]) break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ static inline const unsigned char *memrchr_pure(const unsigned char *s,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __x86_64__
|
||||
noasan static inline const unsigned char *memrchr_sse(const unsigned char *s,
|
||||
unsigned char c,
|
||||
size_t n) {
|
||||
|
@ -55,6 +56,7 @@ noasan static inline const unsigned char *memrchr_sse(const unsigned char *s,
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Returns pointer to first instance of character.
|
||||
|
@ -66,6 +68,7 @@ noasan static inline const unsigned char *memrchr_sse(const unsigned char *s,
|
|||
* @asyncsignalsafe
|
||||
*/
|
||||
void *memrchr(const void *s, int c, size_t n) {
|
||||
#ifdef __x86_64__
|
||||
const void *r;
|
||||
if (!IsTiny() && X86_HAVE(SSE)) {
|
||||
if (IsAsan()) __asan_verify(s, n);
|
||||
|
@ -74,4 +77,7 @@ void *memrchr(const void *s, int c, size_t n) {
|
|||
r = memrchr_pure(s, c, n);
|
||||
}
|
||||
return (void *)r;
|
||||
#else
|
||||
return memrchr_pure(s, c, n);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ static inline const char16_t *memrchr16_pure(const char16_t *s, char16_t c,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __x86_64__
|
||||
noasan static inline const char16_t *memrchr16_sse(const char16_t *s,
|
||||
char16_t c, size_t n) {
|
||||
size_t i;
|
||||
|
@ -54,6 +55,7 @@ noasan static inline const char16_t *memrchr16_sse(const char16_t *s,
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Returns pointer to first instance of character.
|
||||
|
@ -65,6 +67,7 @@ noasan static inline const char16_t *memrchr16_sse(const char16_t *s,
|
|||
* @asyncsignalsafe
|
||||
*/
|
||||
void *memrchr16(const void *s, int c, size_t n) {
|
||||
#ifdef __x86_64__
|
||||
const void *r;
|
||||
if (!IsTiny() && X86_HAVE(SSE)) {
|
||||
if (IsAsan()) __asan_verify(s, n * 2);
|
||||
|
@ -73,4 +76,7 @@ void *memrchr16(const void *s, int c, size_t n) {
|
|||
r = memrchr16_pure(s, c, n);
|
||||
}
|
||||
return (void *)r;
|
||||
#else
|
||||
return memrchr16_pure(s, c, n);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ static inline const unsigned char *rawmemchr_pure(const unsigned char *s,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef __x86_64__
|
||||
noasan static inline const char *rawmemchr_sse(const char *s, unsigned char c) {
|
||||
unsigned k;
|
||||
unsigned m;
|
||||
|
@ -51,6 +52,7 @@ noasan static inline const char *rawmemchr_sse(const char *s, unsigned char c) {
|
|||
m = __builtin_ctzll(m);
|
||||
return (const char *)p + m;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Returns pointer to first instance of character.
|
||||
|
@ -60,6 +62,7 @@ noasan static inline const char *rawmemchr_sse(const char *s, unsigned char c) {
|
|||
* @return is pointer to first instance of c
|
||||
*/
|
||||
void *rawmemchr(const void *s, int c) {
|
||||
#ifdef __x86_64__
|
||||
const void *r;
|
||||
if (X86_HAVE(SSE)) {
|
||||
if (IsAsan()) __asan_verify(s, 1);
|
||||
|
@ -68,4 +71,7 @@ void *rawmemchr(const void *s, int c) {
|
|||
r = rawmemchr_pure(s, c);
|
||||
}
|
||||
return (void *)r;
|
||||
#else
|
||||
return rawmemchr_pure(s, c);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ char *strrchr(const char *, int) strlenesque;
|
|||
void *memrchr(const void *, int, size_t) strlenesque;
|
||||
char16_t *strrchr16(const char16_t *, int) strlenesque;
|
||||
void *memrchr16(const void *, int, size_t) strlenesque;
|
||||
wchar_t *wcsrchr(const wchar_t *, int) strlenesque;
|
||||
wchar_t *wcsrchr(const wchar_t *, wchar_t) strlenesque;
|
||||
void *wmemrchr(const wchar_t *, wchar_t, size_t) strlenesque;
|
||||
char *strpbrk(const char *, const char *) strlenesque;
|
||||
char16_t *strpbrk16(const char16_t *, const char16_t *) strlenesque;
|
||||
|
|
|
@ -36,6 +36,7 @@ typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(16)));
|
|||
* @see strstr()
|
||||
*/
|
||||
noasan char *strcasestr(const char *haystack, const char *needle) {
|
||||
#ifdef __x86_64__
|
||||
char c;
|
||||
xmm_t *p;
|
||||
size_t i;
|
||||
|
@ -68,4 +69,18 @@ noasan char *strcasestr(const char *haystack, const char *needle) {
|
|||
if (!*haystack++) break;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
size_t i;
|
||||
unsigned k, m;
|
||||
if (haystack == needle || !*needle) return haystack;
|
||||
for (;;) {
|
||||
for (i = 0;; ++i) {
|
||||
if (!needle[i]) return (/*unconst*/ char *)haystack;
|
||||
if (!haystack[i]) break;
|
||||
if (kToLower[needle[i] & 255] != kToLower[haystack[i] & 255]) break;
|
||||
}
|
||||
if (!*haystack++) break;
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ static inline const char *strchr_pure(const char *s, int c) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef __x86_64__
|
||||
noasan static inline const char *strchr_sse(const char *s, unsigned char c) {
|
||||
unsigned k;
|
||||
unsigned m;
|
||||
|
@ -52,6 +53,7 @@ noasan static inline const char *strchr_sse(const char *s, unsigned char c) {
|
|||
if (c && !*s) s = 0;
|
||||
return s;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Returns pointer to first instance of character.
|
||||
|
@ -64,6 +66,7 @@ noasan static inline const char *strchr_sse(const char *s, unsigned char c) {
|
|||
* @vforksafe
|
||||
*/
|
||||
char *strchr(const char *s, int c) {
|
||||
#ifdef __x86_64__
|
||||
const char *r;
|
||||
if (X86_HAVE(SSE)) {
|
||||
if (IsAsan()) __asan_verify(s, 1);
|
||||
|
@ -73,4 +76,7 @@ char *strchr(const char *s, int c) {
|
|||
}
|
||||
_unassert(!r || *r || !(c & 255));
|
||||
return (char *)r;
|
||||
#else
|
||||
return strchr_pure(s, c);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ static inline const char *strchrnul_pure(const char *s, int c) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef __x86_64__
|
||||
noasan static inline const char *strchrnul_sse(const char *s, unsigned char c) {
|
||||
unsigned k;
|
||||
unsigned m;
|
||||
|
@ -49,6 +50,7 @@ noasan static inline const char *strchrnul_sse(const char *s, unsigned char c) {
|
|||
}
|
||||
return (const char *)p + __builtin_ctzl(m);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Returns pointer to first instance of character.
|
||||
|
@ -61,6 +63,7 @@ noasan static inline const char *strchrnul_sse(const char *s, unsigned char c) {
|
|||
* NUL terminator if c is not found
|
||||
*/
|
||||
char *strchrnul(const char *s, int c) {
|
||||
#ifdef __x86_64__
|
||||
const char *r;
|
||||
if (X86_HAVE(SSE)) {
|
||||
if (IsAsan()) __asan_verify(s, 1);
|
||||
|
@ -70,4 +73,7 @@ char *strchrnul(const char *s, int c) {
|
|||
}
|
||||
_unassert((*r & 255) == (c & 255) || !*r);
|
||||
return (char *)r;
|
||||
#else
|
||||
return strchrnul_pure(s, c);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ typedef char16_t xmm_t __attribute__((__vector_size__(16), __aligned__(16)));
|
|||
* @asyncsignalsafe
|
||||
*/
|
||||
noasan size_t strlen16(const char16_t *s) {
|
||||
#ifdef __x86_64__
|
||||
size_t n;
|
||||
xmm_t z = {0};
|
||||
unsigned m, k = (uintptr_t)s & 15;
|
||||
|
@ -40,4 +41,9 @@ noasan size_t strlen16(const char16_t *s) {
|
|||
n = (const char16_t *)p + (__builtin_ctzl(m) >> 1) - s;
|
||||
if (IsAsan()) __asan_verify(s, n * 2);
|
||||
return n;
|
||||
#else
|
||||
size_t n = 0;
|
||||
while (*s++) ++n;
|
||||
return n;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(16)));
|
|||
* @see memmem()
|
||||
*/
|
||||
noasan char *strstr(const char *haystack, const char *needle) {
|
||||
#ifdef __x86_64__
|
||||
xmm_t *p;
|
||||
size_t i;
|
||||
unsigned k, m;
|
||||
|
@ -66,4 +67,18 @@ noasan char *strstr(const char *haystack, const char *needle) {
|
|||
if (!*haystack++) break;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
size_t i;
|
||||
unsigned k, m;
|
||||
if (haystack == needle || !*needle) return haystack;
|
||||
for (;;) {
|
||||
for (i = 0;; ++i) {
|
||||
if (!needle[i]) return (/*unconst*/ char *)haystack;
|
||||
if (!haystack[i]) break;
|
||||
if (needle[i] != haystack[i]) break;
|
||||
}
|
||||
if (!*haystack++) break;
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ noasan static dontinline antiquity unsigned timingsafe_bcmp_sse(const char *p,
|
|||
return w | w >> 32;
|
||||
}
|
||||
|
||||
#ifdef __x86_64__
|
||||
noasan static microarchitecture("avx") int timingsafe_bcmp_avx(const char *p,
|
||||
const char *q,
|
||||
size_t n) {
|
||||
|
@ -74,6 +75,7 @@ noasan static microarchitecture("avx") int timingsafe_bcmp_avx(const char *p,
|
|||
w = a[0] | a[1];
|
||||
return w | w >> 32;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Tests inequality of first 𝑛 bytes of 𝑝 and 𝑞.
|
||||
|
@ -140,11 +142,12 @@ int timingsafe_bcmp(const void *a, const void *b, size_t n) {
|
|||
__asan_verify(a, n);
|
||||
__asan_verify(b, n);
|
||||
}
|
||||
#ifdef __x86_64__
|
||||
if (X86_HAVE(AVX)) {
|
||||
return timingsafe_bcmp_avx(p, q, n);
|
||||
} else {
|
||||
return timingsafe_bcmp_sse(p, q, n);
|
||||
}
|
||||
#endif
|
||||
return timingsafe_bcmp_sse(p, q, n);
|
||||
}
|
||||
} else if (n >= 4) {
|
||||
__builtin_memcpy(&u0, p, 4);
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_STR_TPDECODE_H_
|
||||
#define COSMOPOLITAN_LIBC_STR_TPDECODE_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
int tpdecode(const char *, wint_t *) paramsnonnull((1)) libcesque;
|
||||
|
||||
#if defined(__MNO_RED_ZONE__) && defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
#define tpdecode(S, OUT) __tpdecode(S, OUT)
|
||||
forceinline int __tpdecode(const char *s, wint_t *out) {
|
||||
int ax;
|
||||
if (0 <= *s && *s <= 0x7f) {
|
||||
*out = *s;
|
||||
return 1;
|
||||
}
|
||||
asm("call\ttpdecode"
|
||||
: "=a"(ax), "=m"(*(char(*)[6])s)
|
||||
: "D"(s), "S"(out)
|
||||
: "cc");
|
||||
return ax;
|
||||
}
|
||||
#endif
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_STR_TPDECODE_H_ */
|
|
@ -1,29 +0,0 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_STR_TPENCODE_H_
|
||||
#define COSMOPOLITAN_LIBC_STR_TPENCODE_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
unsigned tpencode(char *, size_t, wint_t, bool32) paramsnonnull() libcesque;
|
||||
|
||||
#ifndef __STRICT_ANSI__
|
||||
#define tpencode(...) __tpencode(__VA_ARGS__)
|
||||
forceinline unsigned __tpencode(char *p, size_t size, wint_t wc,
|
||||
bool32 awesome) {
|
||||
if (size >= 1 && (0x00 <= wc && wc <= 0x7f)) {
|
||||
if (wc >= 32 || !awesome) {
|
||||
p[0] = wc;
|
||||
return 1;
|
||||
} else if (size >= 2) {
|
||||
p[0] = 0xc0;
|
||||
p[1] = 0x80;
|
||||
p[1] |= wc;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
return (tpencode)(p, size, wc, awesome);
|
||||
}
|
||||
#endif
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_STR_TPENCODE_H_ */
|
|
@ -30,6 +30,7 @@ typedef wchar_t xmm_t __attribute__((__vector_size__(16), __aligned__(16)));
|
|||
* @asyncsignalsafe
|
||||
*/
|
||||
noasan size_t wcslen(const wchar_t *s) {
|
||||
#ifdef __x86_64__
|
||||
size_t n;
|
||||
xmm_t z = {0};
|
||||
unsigned m, k = (uintptr_t)s & 15;
|
||||
|
@ -40,4 +41,9 @@ noasan size_t wcslen(const wchar_t *s) {
|
|||
n = (const wchar_t *)p + (__builtin_ctzl(m) >> 2) - s;
|
||||
if (IsAsan()) __asan_verify(s, n);
|
||||
return n;
|
||||
#else
|
||||
size_t n = 0;
|
||||
while (*s++) ++n;
|
||||
return n;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ static inline const wchar_t *wmemrchr_pure(const wchar_t *s, wchar_t c,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __x86_64__
|
||||
noasan static inline const wchar_t *wmemrchr_sse(const wchar_t *s, wchar_t c,
|
||||
size_t n) {
|
||||
size_t i;
|
||||
|
@ -54,6 +55,7 @@ noasan static inline const wchar_t *wmemrchr_sse(const wchar_t *s, wchar_t c,
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Returns pointer to first instance of character.
|
||||
|
@ -65,6 +67,7 @@ noasan static inline const wchar_t *wmemrchr_sse(const wchar_t *s, wchar_t c,
|
|||
* @asyncsignalsafe
|
||||
*/
|
||||
void *wmemrchr(const wchar_t *s, wchar_t c, size_t n) {
|
||||
#ifdef __x86_64__
|
||||
size_t bytes;
|
||||
const void *r;
|
||||
if (!IsTiny() && X86_HAVE(SSE)) {
|
||||
|
@ -77,4 +80,7 @@ void *wmemrchr(const wchar_t *s, wchar_t c, size_t n) {
|
|||
r = wmemrchr_pure(s, c, n);
|
||||
}
|
||||
return (void *)r;
|
||||
#else
|
||||
return wmemrchr_pure(s, c, n);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -42,6 +42,10 @@ $(LIBC_STUBS_A).pkg: \
|
|||
$(LIBC_STUBS_A_OBJS) \
|
||||
$(foreach x,$(LIBC_STUBS_A_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
# these assembly files are safe to build on aarch64
|
||||
o/$(MODE)/libc/stubs/ld.o: libc/stubs/ld.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
|
||||
LIBC_STUBS_LIBS = $(foreach x,$(LIBC_STUBS_ARTIFACTS),$($(x)))
|
||||
LIBC_STUBS_SRCS = $(foreach x,$(LIBC_STUBS_ARTIFACTS),$($(x)_SRCS))
|
||||
LIBC_STUBS_CHECKS = $(foreach x,$(LIBC_STUBS_ARTIFACTS),$($(x)_CHECKS))
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __bsd_setegid,0xfff0b60b620b6fff,globl,hidden
|
|
@ -1,2 +1,2 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __bsd_seteuid,0xfff0b70b720b7fff,globl,hidden
|
|
@ -1,2 +1,2 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_accept,0x81e81ea1d281e82b,globl,hidden
|
|
@ -1,2 +1,2 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_accept4,0xfff85da1dffff920,globl,hidden
|
|
@ -1,2 +1,2 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_bind,0x0680680682068031,globl,hidden
|
|
@ -1,2 +1,2 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_clock_nanosleep,0x9ddfff8f4ffff8e6,globl,hidden
|
|
@ -1,2 +1,2 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_connect,0x862862862286282a,globl,hidden
|
|
@ -1,2 +1,2 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_dup3,0x1c6066fffffff124,globl,hidden
|
|
@ -1,2 +1,2 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
#include "libc/sysv/macros.internal.h"
|
||||
.scall __sys_execve,0x03b03b03b203b03b,globl,hidden
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue