Make more code aarch64 friendly

This commit is contained in:
Justine Tunney 2023-05-02 13:38:16 -07:00
parent ca2860947f
commit 2b73e72d59
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
568 changed files with 2197 additions and 1061 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -18,7 +18,7 @@
*/
#include "libc/macros.internal.h"
.privileged
.balignfunc
.alignfunc
// Returns 𝑥+𝑦, aborting on overflow.
//

View file

@ -18,7 +18,7 @@
*/
#include "libc/macros.internal.h"
.privileged
.balignfunc
.alignfunc
// Returns 𝑥+𝑦, aborting on overflow.
//

View file

@ -18,7 +18,7 @@
*/
#include "libc/macros.internal.h"
.privileged
.balignfunc
.alignfunc
// Returns 𝑥+𝑦, aborting on overflow.
//

View file

@ -38,8 +38,6 @@
//
//===----------------------------------------------------------------------===//
STATIC_YOINK("huge_compiler_rt_license");
#define QUAD_PRECISION
#include "third_party/compiler_rt/fp_lib.inc"

View file

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

View file

@ -73,5 +73,7 @@ privileged wontreturn void _Exit(int exitcode) {
: "i"(94), "r"(x0)
: "x8", "memory");
notpossible;
#else
#error "arch unsupported"
#endif
}

View file

@ -81,5 +81,7 @@ privileged wontreturn void _Exit1(int rc) {
: "i"(93), "r"(r0)
: "x8", "memory");
notpossible;
#else
#error "arch unsupported"
#endif
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -13,8 +13,6 @@
//
//===----------------------------------------------------------------------===//
STATIC_YOINK("huge_compiler_rt_license");
#define QUAD_PRECISION
#include "third_party/compiler_rt/fp_lib.inc"

View file

@ -18,7 +18,7 @@
*/
#include "libc/macros.internal.h"
.privileged
.balignfunc
.alignfunc
// Returns 𝑥*𝑦, aborting on overflow.
//

View file

@ -18,7 +18,7 @@
*/
#include "libc/macros.internal.h"
.privileged
.balignfunc
.alignfunc
// Returns 𝑥*𝑦, aborting on overflow.
//

View file

@ -18,7 +18,7 @@
*/
#include "libc/macros.internal.h"
.privileged
.balignfunc
.alignfunc
// Returns 𝑥*𝑦, aborting on overflow.
//

View file

@ -18,7 +18,7 @@
*/
#include "libc/macros.internal.h"
.privileged
.balignfunc
.alignfunc
// Returns -𝑥, aborting on overflow (two's complement bane).
//

View file

@ -18,7 +18,7 @@
*/
#include "libc/macros.internal.h"
.privileged
.balignfunc
.alignfunc
// Returns -𝑥, aborting on overflow (two's complement bane).
//

View file

@ -18,7 +18,7 @@
*/
#include "libc/macros.internal.h"
.privileged
.balignfunc
.alignfunc
// Returns -𝑥, aborting on overflow.
//

View file

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

View file

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

View file

@ -18,7 +18,7 @@
*/
#include "libc/macros.internal.h"
.privileged
.balignfunc
.alignfunc
// Returns 𝑥-𝑦, aborting on overflow.
//

View file

@ -18,7 +18,7 @@
*/
#include "libc/macros.internal.h"
.privileged
.balignfunc
.alignfunc
// Returns 𝑥-𝑦, aborting on overflow.
//

View file

@ -18,7 +18,7 @@
*/
#include "libc/macros.internal.h"
.privileged
.balignfunc
.alignfunc
// Returns 𝑥-𝑦, aborting on overflow.
//

View file

@ -70,5 +70,7 @@ privileged int sys_gettid(void) {
: "i"(178)
: "x8", "memory");
return res_x0;
#else
#error "arch unsupported"
#endif
}

View file

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

View file

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

View file

@ -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__ */

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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() \
({ \

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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_ */

View file

@ -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_ */

View file

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

View file

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

View file

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

View file

@ -1,2 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
#include "libc/sysv/macros.internal.h"
.scall __bsd_setegid,0xfff0b60b620b6fff,globl,hidden

View file

@ -1,2 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
#include "libc/sysv/macros.internal.h"
.scall __bsd_seteuid,0xfff0b70b720b7fff,globl,hidden

View file

@ -1,2 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
#include "libc/sysv/macros.internal.h"
.scall __sys_accept,0x81e81ea1d281e82b,globl,hidden

View file

@ -1,2 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
#include "libc/sysv/macros.internal.h"
.scall __sys_accept4,0xfff85da1dffff920,globl,hidden

View file

@ -1,2 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
#include "libc/sysv/macros.internal.h"
.scall __sys_bind,0x0680680682068031,globl,hidden

View file

@ -1,2 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
#include "libc/sysv/macros.internal.h"
.scall __sys_clock_nanosleep,0x9ddfff8f4ffff8e6,globl,hidden

View file

@ -1,2 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
#include "libc/sysv/macros.internal.h"
.scall __sys_connect,0x862862862286282a,globl,hidden

View file

@ -1,2 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
#include "libc/sysv/macros.internal.h"
.scall __sys_dup3,0x1c6066fffffff124,globl,hidden

View file

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