Make more progress on aarch64

This commit is contained in:
Justine Tunney 2023-05-03 00:00:09 -07:00
parent 135080fd3e
commit aef9a69a60
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
42 changed files with 563 additions and 387 deletions

View file

@ -151,7 +151,6 @@ DEFAULT_OFLAGS = \
DEFAULT_COPTS = \
-fno-math-errno \
-fno-trapping-math \
-fno-fp-int-builtin-inexact \
-fno-ident \
-fno-common \

View file

@ -29,8 +29,8 @@ static inline long sys_set_tid_address(int *t) {
register int64_t __r0 asm("x0") = (int64_t)t;
register int64_t __res_x0 asm("x0");
int64_t __res;
asm volatile("mov x8, %1\n"
"svc 0x0\n"
asm volatile("mov\tx8,%1\n\t"
"svc\t0x0\n"
: "=r"(__res_x0)
: "i"(96), "r"(__r0)
: "x8", "memory");

View file

@ -30,11 +30,7 @@
int32_t sys_fstat(int32_t fd, struct stat *st) {
void *p;
union metastat ms;
if (IsLinux()) {
_Static_assert(sizeof(*st) == sizeof(ms.linux), "assumption broken");
if (IsAsan() && !__asan_is_valid(st, sizeof(*st))) return efault();
p = st;
} else if (st) {
if (st) {
p = &ms;
} else {
p = 0;

View file

@ -32,11 +32,7 @@ int32_t sys_fstatat(int32_t dirfd, const char *path, struct stat *st,
void *p;
union metastat ms;
if (IsAsan() && !__asan_is_valid_str(path)) return efault();
if (IsLinux()) {
_Static_assert(sizeof(*st) == sizeof(ms.linux), "assumption broken");
if (IsAsan() && (st && !__asan_is_valid(st, sizeof(*st)))) return efault();
p = st;
} else if (st) {
if (st) {
p = &ms;
} else {
p = 0;

View file

@ -78,7 +78,7 @@ privileged int getpriority(int which, unsigned who) {
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"
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: "=r"(res_x0)
: "i"(141), "r"(r0), "r"(r1)

View file

@ -72,7 +72,7 @@ privileged void *sys_mremap(void *p, size_t n, size_t m, int f, void *q) {
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"
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: "=r"(res_x0)
: "i"(216), "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4)

View file

@ -61,7 +61,7 @@ privileged int prctl(int operation, ...) {
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"
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: "=r"(res_x0)
: "i"(167), "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4)

View file

@ -69,7 +69,7 @@ privileged int seccomp(unsigned operation, unsigned flags, void *args) {
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"
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: "=r"(res_x0)
: "i"(211), "r"(r0), "r"(r1), "r"(r2)

View file

@ -22,6 +22,20 @@
void __stat2cosmo(struct stat *restrict st, const union metastat *ms) {
if (st) {
if (IsLinux()) {
st->st_dev = ms->linux.st_dev;
st->st_ino = ms->linux.st_ino;
st->st_nlink = ms->linux.st_nlink;
st->st_mode = ms->linux.st_mode;
st->st_uid = ms->linux.st_uid;
st->st_gid = ms->linux.st_gid;
st->st_flags = 0;
st->st_rdev = ms->linux.st_rdev;
st->st_size = ms->linux.st_size;
st->st_blksize = ms->linux.st_blksize;
st->st_blocks = ms->linux.st_blocks;
st->st_atim = ms->linux.st_atim;
st->st_mtim = ms->linux.st_mtim;
st->st_ctim = ms->linux.st_ctim;
st->st_birthtim = st->st_ctim;
if (st->st_atim.tv_sec < st->st_ctim.tv_sec)
st->st_birthtim = st->st_atim;

View file

@ -16,6 +16,7 @@ COSMOPOLITAN_C_START_
struct stat_linux {
uint64_t st_dev;
uint64_t st_ino;
#ifdef __x86_64__
uint64_t st_nlink;
uint32_t st_mode;
uint32_t st_uid;
@ -29,6 +30,23 @@ struct stat_linux {
struct timespec st_mtim;
struct timespec st_ctim;
int64_t __unused[3];
#elif defined(__aarch64__)
uint32_t st_mode;
uint32_t st_nlink;
uint32_t st_uid;
uint32_t st_gid;
uint64_t st_rdev;
uint64_t __pad1;
int64_t st_size;
int32_t st_blksize;
int32_t __pad2;
int64_t st_blocks;
struct timespec st_atim;
struct timespec st_mtim;
struct timespec st_ctim;
uint32_t __unused4;
uint32_t __unused5;
#endif
};
struct stat_xnu {

View file

@ -150,7 +150,7 @@ static inline ssize_t sys_write(int f, const void *b, size_t c) {
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"
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: "=r"(res_x0)
: "i"(64), "r"(r0), "r"(r1), "r"(r2)
@ -172,7 +172,7 @@ static inline int sys_ioctl(int d, int r, ...) {
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"
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: "=r"(res_x0)
: "i"(29), "r"(r0), "r"(r1), "r"(r2)

View file

@ -7,7 +7,6 @@
*/
#define blkcnt_t int64_t
#define blksize_t int64_t /* int32_t on xnu */
#define cc_t uint8_t
#define clock_t int64_t /* uint64_t on xnu */
#define dev_t uint64_t /* int32_t on xnu */
@ -38,7 +37,14 @@
#define uid_t uint32_t
#define rlim_t uint64_t /* int64_t on bsd */
#define clockid_t int32_t
#define nlink_t uint64_t
#ifdef __x86_64__
#define blksize_t int64_t /* int32_t on xnu */
#define nlink_t uint64_t
#elif defined(__aarch64__)
#define blksize_t int32_t
#define nlink_t uint32_t
#endif
#define TIME_T_MAX __INT64_MAX__
#define TIME_T_MIN (-TIME_T_MAX - 1)

View file

@ -61,7 +61,7 @@ struct DirectMap sys_mmap(void *addr, size_t size, int prot, int flags, int fd,
register long r5 asm("x5") = (long)off;
register long res_x0 asm("x0");
long res;
asm volatile("mov\tx8,%1\n"
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: "=r"(res_x0)
: "i"(222), "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5)

View file

@ -67,7 +67,7 @@ privileged wontreturn void _Exit(int exitcode) {
for (;;) asm("ud2");
#elif defined(__aarch64__)
register long x0 asm("x0") = exitcode;
asm volatile("mov\tx8,%1\n"
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: /* no outputs */
: "i"(94), "r"(x0)

View file

@ -75,7 +75,7 @@ privileged wontreturn void _Exit1(int rc) {
notpossible;
#elif defined(__aarch64__)
register long r0 asm("x0") = rc;
asm volatile("mov\tx8,%1\n"
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: /* no outputs */
: "i"(93), "r"(r0)

View file

@ -52,7 +52,7 @@ int getpid(void) {
rc = sys_getpid().ax;
#elif defined(__aarch64__)
register long res_x0 asm("x0");
asm volatile("mov\tx8,%1\n"
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: "=r"(res_x0)
: "i"(172)

View file

@ -202,7 +202,7 @@ privileged static void klog(const char *b, size_t n) {
register long r1 asm("x1") = (long)b;
register long r2 asm("x2") = (long)n;
register long res_x0 asm("x0");
asm volatile("mov\tx8,%1\n"
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: "=r"(res_x0)
: "i"(64), "r"(r0), "r"(r1), "r"(r2)

View file

@ -64,7 +64,7 @@ privileged int sys_gettid(void) {
return tid;
#elif defined(__aarch64__)
register long res_x0 asm("x0");
asm volatile("mov\tx8,%1\n"
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: "=r"(res_x0)
: "i"(178)

View file

@ -20,7 +20,7 @@ forceinline long __sysv_exit(long rc) {
#elif defined(__aarch64__)
register long r0 asm("x0") = rc;
register long res_x0 asm("x0");
asm volatile("mov\tx8,%1\n"
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: "=r"(res_x0)
: "i"(94), "r"(r0)
@ -42,7 +42,7 @@ forceinline int __sysv_close(long fd) {
#elif defined(__aarch64__)
register long r0 asm("x0") = fd;
register long res_x0 asm("x0");
asm volatile("mov\tx8,%1\n"
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: "=r"(res_x0)
: "i"(57), "r"(r0)
@ -67,7 +67,7 @@ forceinline int __sysv_open(const char *path, long flags, long mode) {
register long r2 asm("x2") = (long)flags;
register long r3 asm("x3") = (long)mode;
register long res_x0 asm("x0");
asm volatile("mov\tx8,%1\n"
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: "=r"(res_x0)
: "i"(56), "r"(r0), "r"(r1), "r"(r2), "r"(r3)
@ -91,7 +91,7 @@ forceinline long __sysv_read(long fd, void *data, unsigned long size) {
register long r1 asm("x1") = (long)data;
register long r2 asm("x2") = (long)size;
register long res_x0 asm("x0");
asm volatile("mov\tx8,%1\n"
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: "=r"(res_x0)
: "i"(63), "r"(r0), "r"(r1), "r"(r2)
@ -115,7 +115,7 @@ forceinline long __sysv_write(long fd, const void *data, unsigned long size) {
register long r1 asm("x1") = (long)data;
register long r2 asm("x2") = (long)size;
register long res_x0 asm("x0");
asm volatile("mov\tx8,%1\n"
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: "=r"(res_x0)
: "i"(64), "r"(r0), "r"(r1), "r"(r2)
@ -139,7 +139,7 @@ forceinline long __sysv_mprotect(void *addr, size_t size, long prot) {
register long r1 asm("x1") = (long)size;
register long r2 asm("x2") = (long)prot;
register long res_x0 asm("x0");
asm volatile("mov\tx8,%1\n"
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: "=r"(res_x0)
: "i"(226), "r"(r0), "r"(r1), "r"(r2)
@ -160,7 +160,7 @@ forceinline int __sysv_getpid(void) {
: "rdx", "memory", "cc");
#elif defined(__aarch64__)
register long res_x0 asm("x0");
asm volatile("mov\tx8,%1\n"
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: "=r"(res_x0)
: "i"(172)

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,13 +16,15 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/macros.internal.h"
#include "libc/nexgen32e/nexgen32e.h"
// Computes Phil Katz CRC-32 used by zip/zlib/gzip/etc.
//
// @param edi is init crc32 value
// @param rsi is nullable pointer to data
// @param edx is int size per zlib interface
crc32: mov %edx,%edx
jmp crc32_z
.endfn crc32,globl
void crc32init(uint32_t table[256], uint32_t polynomial) {
uint32_t d, i, r;
for (d = 0; d < 256; ++d) {
r = d;
for (i = 0; i < 8; ++i) {
r = r >> 1 ^ (r & 1 ? polynomial : 0);
}
table[d] = r;
}
}

41
libc/nexgen32e/ktolower.c Normal file
View file

@ -0,0 +1,41 @@
/*-*- 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 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
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/str/tab.internal.h"
const uint8_t kToLower[256] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
28, 29, 30, 31, ' ', '!', '\"', '#', '$', '%', '&', '\'', '(', ')',
'*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', ':', ';', '<', '=', '>', '?', '@', 'a', 'b', 'c', 'd', 'e',
'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
't', 'u', 'v', 'w', 'x', 'y', 'z', '[', '\\', ']', '^', '_', '`', 'a',
'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}',
'~', 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153,
154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167,
168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181,
182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195,
196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209,
210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237,
238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251,
252, 253, 254, 255,
};

41
libc/nexgen32e/ktoupper.c Normal file
View file

@ -0,0 +1,41 @@
/*-*- 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 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
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/str/tab.internal.h"
const uint8_t kToUpper[256] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
28, 29, 30, 31, ' ', '!', '\"', '#', '$', '%', '&', '\'', '(', ')',
'*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E',
'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '`', 'A',
'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '{', '|', '}',
'~', 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153,
154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167,
168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181,
182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195,
196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209,
210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237,
238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251,
252, 253, 254, 255,
};

View file

@ -1,158 +0,0 @@
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi
Copyright 2020 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/nexgen32e/x86feature.h"
#include "libc/macros.internal.h"
// Returns pointer to first instance of character.
//
// @param rdi is a non-null NUL-terminated char16_t string pointer
// @param esi is the search word
// @return rax points to character, or to NUL word if not found
// @note this won't return NULL if search character is NUL
strchrnul16:
.leafprologue
.profilable
or $-1,%r9
jmp 0f
.endfn strchrnul16,globl
// Returns pointer to first instance of character.
//
// @param rdi is a non-null NUL-terminated char16_t string pointer
// @param esi is the search word
// @return rax points to first result, or NULL if not found
// @note this won't return NULL if search character is NUL
// @asyncsignalsafe
strchr16:
.leafprologue
.profilable
xor %r9,%r9
0: mov %esi,%edx
xor %r11d,%r11d
or $-1,%rsi
xor %r8,%r8
jmp strsak16
.endfn strchr16,globl
// Returns pointer to first instance of character in range.
//
// @param rdi is a non-null pointer to memory
// @param esi is the search word
// @return rax points to word if found, or else undefined behavior
rawmemchr16:
or $-1,%rdx
// fallthrough
.endfn rawmemchr16,globl
// Returns pointer to first instance of character in range.
//
// @param rdi is a non-null pointer to memory
// @param esi is the search word
// @param rdx is length of memory in shorts
// @return rax points to word if found or NULL
// @asyncsignalsafe
memchr16:
.leafprologue
.profilable
xchg %rsi,%rdx
mov %edx,%r11d
xor %r8,%r8
xor %r10,%r10
jmp strsak16
.endfn memchr16,globl
// Returns length of char16_t string w/ security blankets.
//
// This is like strnlen() except it'll return 0 if (1) RDI is NULL
// or (2) a NUL-terminator wasn't found in the first RSI shorts.
//
// @param rdi is a nullable NUL-terminated char16_t string pointer
// @param rsi is the maximum number of shorts to consider
// @return rax is the number of shorts, excluding the NUL
strnlen16_s:
.leafprologue
.profilable
xor %eax,%eax
xor %r10d,%r10d
test %rdi,%rdi
jnz 0f
.leafepilogue
.endfn strnlen16_s,globl
// Swiss Army Knife of string char16_t scanning.
// Sixteen fast functions in one.
//
// @param rdi is non-null string memory
// @param rsi is max number of shorts to consider
// @param dx is search character #1
// @param r11w is search character #2
// @param r8 is subtracted from result (for length vs. pointer)
// @param r9 masks result if DH is found (for NUL vs. NULL)
// @param r10 masks result on shorts exhausted (for length v. NULL)
// @return rax end pointer after r8/r9/r10 modifications
strsak16:
lea -2(%rdi),%rax
1: add $2,%rax
sub $1,%rsi
jb .Lend
test $31,%al
jz .Lfast
.Lword: mov (%rax),%cx
cmp %cx,%dx
je .Ldone
cmp %cx,%r11w
je .Lnul
jmp 1b
.Ldone: sub %r8,%rax
jmp .Lret
.Lend: mov %r10,%r9
.Lnul: sub %r8,%rax
and %r9,%rax
.Lret: test %r8,%r8
jz 0f
shr %rax
0: .leafepilogue
.Lslow: add $32,%rsi
jmp .Lword
.Lfast:
#if !X86_NEED(AVX2)
testb X86_HAVE(AVX2)+kCpuids(%rip)
jz .Lword
#endif
movzwl %dx,%ecx
movd %ecx,%xmm0
movzwl %r11w,%ecx
movd %ecx,%xmm1
vpbroadcastw %xmm0,%ymm0
vpbroadcastw %xmm1,%ymm1
sub $32,%rax
1: add $32,%rax
sub $16,%rsi
jb .Lslow
vmovdqa (%rax),%ymm2
vpcmpeqw %ymm0,%ymm2,%ymm3
vpcmpeqw %ymm1,%ymm2,%ymm2
vpor %ymm3,%ymm2,%ymm2
vpmovmskb %ymm2,%ecx
bsf %ecx,%ecx
je 1b
vzeroupper
add %rcx,%rax
jmp .Lword
.endfn strsak16

View file

@ -19,34 +19,6 @@
#include "libc/nexgen32e/x86feature.h"
#include "libc/macros.internal.h"
// Returns pointer to first instance of character.
//
// @param rdi is a non-null NUL-terminated wchar_t string pointer
// @param esi is the search word
// @return rax points to character, or to NUL word if not found
// @note this won't return NULL if search character is NUL
wcschrnul:
.leafprologue
.profilable
or $-1,%r9
jmp 0f
// Returns pointer to first instance of character.
//
// @param rdi is a non-null NUL-terminated wchar_t string pointer
// @param esi is the search word
// @return rax points to first result, or NULL if not found
// @note this won't return NULL if search character is NUL
// @asyncsignalsafe
wcschr: .leafprologue
.profilable
xor %r9,%r9
0: mov %esi,%edx
xor %r11d,%r11d
pushpop -1,%rsi
xor %r8,%r8
jmp wcssak
// Returns length of wchar_t string w/ security blankets.
//
// This is like wcsnlen() except it'll return 0 if (1) RDI is NULL
@ -168,5 +140,3 @@ wcssak: lea -4(%rdi),%rax
.endfn wmemchr,globl
.endfn rawwmemchr,globl
.endfn wcsnlen,globl
.endfn wcschr,globl
.endfn wcschrnul,globl

View file

@ -53,6 +53,7 @@ int fesetround(int);
int fetestexcept(int);
int feupdateenv(const fenv_t *);
int __flt_rounds(void);
int __fesetround(int);
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

@ -26,23 +26,13 @@
* @param mode may be FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, or FE_TOWARDZERO
* @return 0 on success, or -1 on error
*/
int fesetround(int mode) {
uint16_t x87cw;
uint32_t ssecw;
switch (mode) {
int fesetround(int r) {
switch (r) {
case FE_TONEAREST:
case FE_DOWNWARD:
case FE_UPWARD:
case FE_TOWARDZERO:
asm("fnstcw\t%0" : "=m"(x87cw));
x87cw &= ~0x0c00;
x87cw |= mode;
asm volatile("fldcw\t%0" : /* no outputs */ : "m"(x87cw));
asm("stmxcsr\t%0" : "=m"(ssecw));
ssecw &= ~(0x0c00 << 3);
ssecw |= (mode << 3);
asm volatile("ldmxcsr\t%0" : /* no outputs */ : "m"(ssecw));
return 0;
return __fesetround(r);
default:
return -1;
}

View file

@ -46,7 +46,7 @@ static inline int __morph_rt_sigprocmask(int h, const sigset_t *s, sigset_t *o,
register long r2 asm("x2") = (long)o;
register long r3 asm("x3") = (long)c;
register long res_x0 asm("x0");
asm volatile("mov\tx8,%1\n"
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: "=r"(res_x0)
: "i"(135), "r"(r0), "r"(r1), "r"(r2), "r"(r3)
@ -90,7 +90,7 @@ static privileged void __morph_mprotect(void *addr, size_t size, int prot,
register long r1 asm("x1") = (long)size;
register long r2 asm("x2") = (long)prot;
register long res_x0 asm("x0");
asm volatile("mov\tx8,%1\n"
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: "=r"(res_x0)
: "i"(226), "r"(r0), "r"(r1), "r"(r2)

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 sw=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,29 +16,9 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/macros.internal.h"
#include "libc/nexgen32e/crc32.h"
#include "third_party/zlib/zlib.h"
.initbss 300,_init_kToUpper
// ASCII lowercase → uppercase translation tables.
//
// char kToUpper[256];
//
// @see kToLower
kToUpper:
.rept 256
.byte 0
.endr
.endobj kToUpper,globl,hidden
.previous
.init.start 300,_init_kToUpper
push %rdi
call imapxlatab
xchg %rsi,(%rsp)
xor %ecx,%ecx
0: inc %ecx
subb $0x20,'a'-1(%rsi,%rcx)
cmp $'z'-'a'+1,%ecx
jne 0b
pop %rsi
.init.end 300,_init_kToUpper
uLong crc32(uLong crc, const Bytef *buf, uInt len) {
return crc32_z(crc, buf, len);
}

View file

@ -19,6 +19,54 @@
#include "libc/nexgen32e/crc32.h"
#include "libc/nexgen32e/x86feature.h"
#ifndef __x86_64__
const uint32_t kCrc32cTab[256] = {
0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4, 0xc79a971f, 0x35f1141c,
0x26a1e7e8, 0xd4ca64eb, 0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b,
0x4d43cfd0, 0xbf284cd3, 0xac78bf27, 0x5e133c24, 0x105ec76f, 0xe235446c,
0xf165b798, 0x030e349b, 0xd7c45070, 0x25afd373, 0x36ff2087, 0xc494a384,
0x9a879fa0, 0x68ec1ca3, 0x7bbcef57, 0x89d76c54, 0x5d1d08bf, 0xaf768bbc,
0xbc267848, 0x4e4dfb4b, 0x20bd8ede, 0xd2d60ddd, 0xc186fe29, 0x33ed7d2a,
0xe72719c1, 0x154c9ac2, 0x061c6936, 0xf477ea35, 0xaa64d611, 0x580f5512,
0x4b5fa6e6, 0xb93425e5, 0x6dfe410e, 0x9f95c20d, 0x8cc531f9, 0x7eaeb2fa,
0x30e349b1, 0xc288cab2, 0xd1d83946, 0x23b3ba45, 0xf779deae, 0x05125dad,
0x1642ae59, 0xe4292d5a, 0xba3a117e, 0x4851927d, 0x5b016189, 0xa96ae28a,
0x7da08661, 0x8fcb0562, 0x9c9bf696, 0x6ef07595, 0x417b1dbc, 0xb3109ebf,
0xa0406d4b, 0x522bee48, 0x86e18aa3, 0x748a09a0, 0x67dafa54, 0x95b17957,
0xcba24573, 0x39c9c670, 0x2a993584, 0xd8f2b687, 0x0c38d26c, 0xfe53516f,
0xed03a29b, 0x1f682198, 0x5125dad3, 0xa34e59d0, 0xb01eaa24, 0x42752927,
0x96bf4dcc, 0x64d4cecf, 0x77843d3b, 0x85efbe38, 0xdbfc821c, 0x2997011f,
0x3ac7f2eb, 0xc8ac71e8, 0x1c661503, 0xee0d9600, 0xfd5d65f4, 0x0f36e6f7,
0x61c69362, 0x93ad1061, 0x80fde395, 0x72966096, 0xa65c047d, 0x5437877e,
0x4767748a, 0xb50cf789, 0xeb1fcbad, 0x197448ae, 0x0a24bb5a, 0xf84f3859,
0x2c855cb2, 0xdeeedfb1, 0xcdbe2c45, 0x3fd5af46, 0x7198540d, 0x83f3d70e,
0x90a324fa, 0x62c8a7f9, 0xb602c312, 0x44694011, 0x5739b3e5, 0xa55230e6,
0xfb410cc2, 0x092a8fc1, 0x1a7a7c35, 0xe811ff36, 0x3cdb9bdd, 0xceb018de,
0xdde0eb2a, 0x2f8b6829, 0x82f63b78, 0x709db87b, 0x63cd4b8f, 0x91a6c88c,
0x456cac67, 0xb7072f64, 0xa457dc90, 0x563c5f93, 0x082f63b7, 0xfa44e0b4,
0xe9141340, 0x1b7f9043, 0xcfb5f4a8, 0x3dde77ab, 0x2e8e845f, 0xdce5075c,
0x92a8fc17, 0x60c37f14, 0x73938ce0, 0x81f80fe3, 0x55326b08, 0xa759e80b,
0xb4091bff, 0x466298fc, 0x1871a4d8, 0xea1a27db, 0xf94ad42f, 0x0b21572c,
0xdfeb33c7, 0x2d80b0c4, 0x3ed04330, 0xccbbc033, 0xa24bb5a6, 0x502036a5,
0x4370c551, 0xb11b4652, 0x65d122b9, 0x97baa1ba, 0x84ea524e, 0x7681d14d,
0x2892ed69, 0xdaf96e6a, 0xc9a99d9e, 0x3bc21e9d, 0xef087a76, 0x1d63f975,
0x0e330a81, 0xfc588982, 0xb21572c9, 0x407ef1ca, 0x532e023e, 0xa145813d,
0x758fe5d6, 0x87e466d5, 0x94b49521, 0x66df1622, 0x38cc2a06, 0xcaa7a905,
0xd9f75af1, 0x2b9cd9f2, 0xff56bd19, 0x0d3d3e1a, 0x1e6dcdee, 0xec064eed,
0xc38d26c4, 0x31e6a5c7, 0x22b65633, 0xd0ddd530, 0x0417b1db, 0xf67c32d8,
0xe52cc12c, 0x1747422f, 0x49547e0b, 0xbb3ffd08, 0xa86f0efc, 0x5a048dff,
0x8ecee914, 0x7ca56a17, 0x6ff599e3, 0x9d9e1ae0, 0xd3d3e1ab, 0x21b862a8,
0x32e8915c, 0xc083125f, 0x144976b4, 0xe622f5b7, 0xf5720643, 0x07198540,
0x590ab964, 0xab613a67, 0xb831c993, 0x4a5a4a90, 0x9e902e7b, 0x6cfbad78,
0x7fab5e8c, 0x8dc0dd8f, 0xe330a81a, 0x115b2b19, 0x020bd8ed, 0xf0605bee,
0x24aa3f05, 0xd6c1bc06, 0xc5914ff2, 0x37faccf1, 0x69e9f0d5, 0x9b8273d6,
0x88d28022, 0x7ab90321, 0xae7367ca, 0x5c18e4c9, 0x4f48173d, 0xbd23943e,
0xf36e6f75, 0x0105ec76, 0x12551f82, 0xe03e9c81, 0x34f4f86a, 0xc69f7b69,
0xd5cf889d, 0x27a40b9e, 0x79b737ba, 0x8bdcb4b9, 0x988c474d, 0x6ae7c44e,
0xbe2da0a5, 0x4c4623a6, 0x5f16d052, 0xad7d5351,
};
#endif
/**
* Computes 32-bit Castagnoli Cyclic Redundancy Check.
*

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 sw=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,33 +16,18 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/macros.internal.h"
#include "libc/str/str.h"
.initbss 300,_init_kToLower
// ASCII uppercase → lowercase translation tables.
//
// char kToLower[256];
//
// @see kToUpper
kToLower:
.rept 256
.byte 0
.endr
.endobj kToLower,globl,hidden
.previous
.init.start 300,_init_kToLower
push %rdi
call imapxlatab
xchg %rsi,(%rsp)
xor %ecx,%ecx
0: inc %ecx
addb $0x20,'A'-1(%rsi,%rcx)
cmp $'Z'-'A'+1,%ecx
jne 0b
pop %rsi
.init.end 300,_init_kToLower
.type gperf_downcase,@object
.globl gperf_downcase
gperf_downcase = kToLower
/**
* Returns pointer to first instance of character in range.
*/
void *memchr16(const void *s, int c, size_t n) {
size_t i;
const char *p = (const char *)s;
for (i = 0; i < n; ++i) {
if ((p[i] & 65535) == (c & 65535)) {
return (void *)(p + i);
}
}
return 0;
}

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,54 +16,16 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/macros.internal.h"
#include "libc/str/str.h"
// Generates lookup table for computing CRC-32 byte-by-byte.
//
// void crc32init(uint32_t table[256], uint32_t polynomial) {
// uint32_t d, i, r;
// for (d = 0; d < 256; ++d) {
// r = d;
// for (i = 0; i < 8; ++i) {
// r = r >> 1 ^ (r & 1 ? polynomial : 0);
// }
// table[d] = r;
// }
// }
//
// @param rdi is pointer to uint32_t[256] array
// @param esi 32-bit binary polynomial config
// @note imposes ~300ns one-time cost
crc32init:
push %rbp
mov %rsp,%rbp
.profilable
lea 256*4(%rdi),%rdx
movd %esi,%xmm0
pshufd $0,%xmm0,%xmm0 # (uint32_t[]){esi,esi,esi,esi} %xmm0
pushpop 4,%rax
movd %eax,%xmm2 # (int[]){4,4,4,4} %xmm2
pshufd $0,%xmm2,%xmm2
0: sub $4,%rsp # (int[]){0,1,2,3} %xmm1
dec %eax
mov %eax,(%rsp)
jnz 0b
movdqu (%rsp),%xmm1
1: mov $8,%ecx
movdqa %xmm1,%xmm3
2: movdqa %xmm3,%xmm4
psrld $1,%xmm4
pslld $31,%xmm3
psrad $31,%xmm3
pand %xmm0,%xmm3
pxor %xmm4,%xmm3
movdqa %xmm3,%xmm4
.loop 2b
movdqu %xmm3,(%rdi)
add $16,%rdi
paddd %xmm2,%xmm1
cmp %rdx,%rdi
jb 1b
leave
ret
.endfn crc32init,globl
/**
* Returns pointer to first instance of character in range.
*/
void *rawmemchr16(const void *s, int c) {
const char *p = (const char *)s;
for (;; ++p) {
if ((*p & 65535) == (c & 65535)) {
return (void *)p;
}
}
}

View file

@ -69,7 +69,6 @@ char *strchrnul(const char *, int) strlenesque returnsnonnull;
void *rawmemchr(const void *, int) strlenesque returnsnonnull;
size_t strlen16(const char16_t *) strlenesque;
size_t strnlen16(const char16_t *, size_t) strlenesque;
size_t strnlen16_s(const char16_t *, size_t);
char16_t *strchr16(const char16_t *, int) strlenesque;
void *memchr16(const void *, int, size_t) strlenesque;
char16_t *strchrnul16(const char16_t *, int) strlenesque returnsnonnull;

View file

@ -55,6 +55,35 @@ noasan static inline const char *strchr_sse(const char *s, unsigned char c) {
}
#endif
static noasan inline const char *strchr_x64(const char *p, uint64_t c) {
unsigned a, b;
uint64_t w, x, y;
for (c *= 0x0101010101010101;; p += 8) {
w = (uint64_t)(255 & p[7]) << 070 | (uint64_t)(255 & p[6]) << 060 |
(uint64_t)(255 & p[5]) << 050 | (uint64_t)(255 & p[4]) << 040 |
(uint64_t)(255 & p[3]) << 030 | (uint64_t)(255 & p[2]) << 020 |
(uint64_t)(255 & p[1]) << 010 | (uint64_t)(255 & p[0]) << 000;
if ((x = ~(w ^ c) & ((w ^ c) - 0x0101010101010101) & 0x8080808080808080) |
(y = ~w & (w - 0x0101010101010101) & 0x8080808080808080)) {
if (x) {
a = __builtin_ctzll(x);
if (y) {
b = __builtin_ctzll(y);
if (a <= b) {
return p + (a >> 3);
} else {
return 0;
}
} else {
return p + (a >> 3);
}
} else {
return 0;
}
}
}
}
/**
* Returns pointer to first instance of character.
*
@ -77,6 +106,13 @@ char *strchr(const char *s, int c) {
_unassert(!r || *r || !(c & 255));
return (char *)r;
#else
return strchr_pure(s, c);
char *r;
for (c &= 255; (uintptr_t)s & 7; ++s) {
if ((*s & 255) == c) return s;
if (!*s) return NULL;
}
r = strchr_x64(s, c);
_unassert(!r || *r || !c);
return r;
#endif
}

29
libc/str/strchr16.c Normal file
View file

@ -0,0 +1,29 @@
/*-*- 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 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
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/str/str.h"
/**
* Returns pointer to first instance of character.
*/
char16_t *strchr16(const char16_t *s, int c) {
for (;; ++s) {
if ((*s & 65535) == (c & 65535)) return (char16_t *)s;
if (!*s) return (char16_t *)0;
}
}

29
libc/str/strchrnul16.c Normal file
View file

@ -0,0 +1,29 @@
/*-*- 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 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
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/str/str.h"
/**
* Returns pointer to first instance of character.
*/
char16_t *strchrnul16(const char16_t *s, int c) {
for (;; ++s) {
if ((*s & 65535) == (c & 65535)) return (char16_t *)s;
if (!*s) return (char16_t *)s;
}
}

View file

@ -3,8 +3,9 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
#define gperf_downcase kToLower
extern const int8_t kHexToInt[256];
extern const uint8_t gperf_downcase[256];
extern const uint8_t kToLower[256];
extern const uint8_t kToUpper[256];
extern const uint8_t kBase36[256];

29
libc/str/wcschr.c Normal file
View file

@ -0,0 +1,29 @@
/*-*- 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 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
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/str/str.h"
/**
* Returns pointer to first instance of character.
*/
wchar_t *wcschr(const wchar_t *s, wchar_t c) {
for (;; ++s) {
if (*s == c) return s;
if (!*s) return 0;
}
}

26
libc/str/wcschrnul.c Normal file
View file

@ -0,0 +1,26 @@
/*-*- 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 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
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/str/str.h"
wchar_t *wcschrnul(const wchar_t *s, wchar_t c) {
for (;; ++s) {
if (*s == c) return s;
if (!*s) return s;
}
}

View file

@ -0,0 +1,23 @@
/*-*- 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 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
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/math.h"
long double significandl(long double x) {
return scalbnl(x, -ilogbl(x));
}

125
libc/tinymath/sqrtf.c Normal file
View file

@ -0,0 +1,125 @@
/*-*- 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/intrin/likely.h"
#include "libc/math.h"
#include "libc/tinymath/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
#define FENV_SUPPORT 1
static inline uint32_t mul32(uint32_t a, uint32_t b)
{
return (uint64_t)a*b >> 32;
}
/* see sqrt.c for more detailed comments. */
float sqrtf(float x)
{
#ifdef __x86__
float res;
asm("sqrtss\t%1,%0" : "=x"(res) : "x"(x));
return res;
#else
uint32_t ix, m, m1, m0, even, ey;
ix = asuint(x);
if (UNLIKELY(ix - 0x00800000 >= 0x7f800000 - 0x00800000)) {
/* x < 0x1p-126 or inf or nan. */
if (ix * 2 == 0)
return x;
if (ix == 0x7f800000)
return x;
if (ix > 0x7f800000)
return __math_invalidf(x);
/* x is subnormal, normalize it. */
ix = asuint(x * 0x1p23f);
ix -= 23 << 23;
}
/* x = 4^e m; with int e and m in [1, 4). */
even = ix & 0x00800000;
m1 = (ix << 8) | 0x80000000;
m0 = (ix << 7) & 0x7fffffff;
m = even ? m0 : m1;
/* 2^e is the exponent part of the return value. */
ey = ix >> 1;
ey += 0x3f800000 >> 1;
ey &= 0x7f800000;
/* compute r ~ 1/sqrt(m), s ~ sqrt(m) with 2 goldschmidt iterations. */
static const uint32_t three = 0xc0000000;
uint32_t r, s, d, u, i;
i = (ix >> 17) % 128;
r = (uint32_t)__rsqrt_tab[i] << 16;
/* |r*sqrt(m) - 1| < 0x1p-8 */
s = mul32(m, r);
/* |s/sqrt(m) - 1| < 0x1p-8 */
d = mul32(s, r);
u = three - d;
r = mul32(r, u) << 1;
/* |r*sqrt(m) - 1| < 0x1.7bp-16 */
s = mul32(s, u) << 1;
/* |s/sqrt(m) - 1| < 0x1.7bp-16 */
d = mul32(s, r);
u = three - d;
s = mul32(s, u);
/* -0x1.03p-28 < s/sqrt(m) - 1 < 0x1.fp-31 */
s = (s - 1)>>6;
/* s < sqrt(m) < s + 0x1.08p-23 */
/* compute nearest rounded result. */
uint32_t d0, d1, d2;
float y, t;
d0 = (m << 16) - s*s;
d1 = s - d0;
d2 = d1 + s + 1;
s += d1 >> 31;
s &= 0x007fffff;
s |= ey;
y = asfloat(s);
if (FENV_SUPPORT) {
/* handle rounding and inexact exception. */
uint32_t tiny = UNLIKELY(d2==0) ? 0 : 0x01000000;
tiny |= (d1^d2) & 0x80000000;
t = asfloat(tiny);
y = eval_as_float(y + t);
}
return y;
#endif
}

View file

@ -42,13 +42,19 @@ $(LIBC_TINYMATH_A).pkg: \
$(LIBC_TINYMATH_A_OBJS) \
$(foreach x,$(LIBC_TINYMATH_A_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/libc/tinymath/cpow.o \
o/$(MODE)/libc/tinymath/cpowf.o \
o/$(MODE)/libc/tinymath/cpowl.o \
o/$(MODE)/libc/tinymath/cpow.o \
o/$(MODE)/libc/tinymath/cpowf.o \
o/$(MODE)/libc/tinymath/cpowl.o \
o/$(MODE)/libc/tinymath/powfin.o : private \
OVERRIDE_CFLAGS += \
-ffast-math
o/$(MODE)/libc/tinymath/lround.o \
o/$(MODE)/libc/tinymath/lroundf.o \
o/$(MODE)/libc/tinymath/lroundl.o : private \
OVERRIDE_CFLAGS += \
-fno-builtin
LIBC_TINYMATH_LIBS = $(foreach x,$(LIBC_TINYMATH_ARTIFACTS),$($(x)))
LIBC_TINYMATH_HDRS = $(foreach x,$(LIBC_TINYMATH_ARTIFACTS),$($(x)_HDRS))
LIBC_TINYMATH_SRCS = $(foreach x,$(LIBC_TINYMATH_ARTIFACTS),$($(x)_SRCS))

View file

@ -211,25 +211,7 @@
cpp-font-lock-keywords
`(;; GNU-Style Assembler Comment (Ltd. 80x86 &c.)
;;
;; - Valid
;;
;; * #heyho
;; * # heyho
;; * .org . #heyho
;; * .org . ####euhhcue
;; * .org .# ###euhhcue
;;
;; - Ignored
;;
;; * #if 0
;; * #endif
;; * .ascii "#heyho"
;;
("\\(#.*\\)$" 1 font-lock-comment-face)
("'\\(\\\\?.\\)\\>" 1 font-lock-constant-face)
`(("'\\(\\\\?.\\)\\>" 1 font-lock-constant-face)
;; Register Value
;;