Make improvements

- Introduce portable sched_getcpu() api
- Support GCC's __target_clones__ feature
- Make fma() go faster on x86 in default mode
- Remove some asan checks from core libraries
- WinMain() now ensures $HOME and $USER are defined
This commit is contained in:
Justine Tunney 2024-02-01 03:39:46 -08:00
parent d5225a693b
commit 2ab9e9f7fd
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
192 changed files with 2809 additions and 932 deletions

View file

@ -88,7 +88,7 @@ o/$(MODE)/libc/str/windowstimetotimespec.o: private \
-O2
$(LIBC_STR_A_OBJS): private \
COPTS += \
CFLAGS += \
-fno-sanitize=all \
-Wframe-larger-than=4096 \
-Walloca-larger-than=4096

View file

@ -17,7 +17,6 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/nexgen32e/x86feature.h"
#include "libc/runtime/runtime.h"
#include "libc/stdckdint.h"
@ -28,11 +27,6 @@ void djbsort_avx2(int32_t *, long);
* D.J. Bernstein's outrageously fast integer sorting algorithm.
*/
void djbsort(int32_t *a, size_t n) {
size_t m;
if (IsAsan()) {
if (ckd_mul(&m, n, 4)) m = -1;
__asan_verify(a, m);
}
if (n > 1) {
#if defined(__x86_64__) && !defined(__chibicc__)
if (X86_HAVE(AVX2)) {

View file

@ -17,7 +17,6 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/likely.h"
#include "libc/str/str.h"
@ -53,7 +52,6 @@ bool32 isutf8(const void *data, size_t size) {
long c;
const char *p, *e;
if (size == -1) size = data ? strlen(data) : 0;
if (IsAsan()) __asan_verify(data, size);
p = data;
e = p + size;
while (p < e) {

View file

@ -17,7 +17,6 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/likely.h"
#include "libc/str/str.h"
@ -32,16 +31,14 @@ typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(16)));
* @param needlelen is its character count
* @return pointer to first result or NULL if not found
*/
void *memmem(const void *haystack, size_t haystacklen,
const void *needle, size_t needlelen) {
__vex void *memmem(const void *haystack, size_t haystacklen, const void *needle,
size_t needlelen) {
#if defined(__x86_64__) && !defined(__chibicc__)
char c;
xmm_t n;
const xmm_t *v;
unsigned i, k, m;
const char *p, *q, *e;
if (IsAsan()) __asan_verify(needle, needlelen);
if (IsAsan()) __asan_verify(haystack, haystacklen);
if (!needlelen) return (void *)haystack;
if (UNLIKELY(needlelen > haystacklen)) return 0;
q = needle;

View file

@ -17,7 +17,6 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/limits.h"
#include "libc/nexgen32e/x86feature.h"
#include "libc/str/str.h"
@ -36,8 +35,8 @@ static inline const char16_t *memrchr16_pure(const char16_t *s, char16_t c,
}
#if defined(__x86_64__) && !defined(__chibicc__)
static inline const char16_t *memrchr16_sse(const char16_t *s,
char16_t c, size_t n) {
static inline const char16_t *memrchr16_sse(const char16_t *s, char16_t c,
size_t n) {
size_t i;
unsigned m;
xmm_t v, t = {c, c, c, c, c, c, c, c};
@ -67,11 +66,10 @@ static inline const char16_t *memrchr16_sse(const char16_t *s,
* @return is pointer to first instance of c or NULL if not found
* @asyncsignalsafe
*/
void *memrchr16(const void *s, int c, size_t n) {
__vex void *memrchr16(const void *s, int c, size_t n) {
#if defined(__x86_64__) && !defined(__chibicc__)
const void *r;
if (!IsTiny() && X86_HAVE(SSE)) {
if (IsAsan()) __asan_verify(s, n * 2);
r = memrchr16_sse(s, c, n);
} else {
r = memrchr16_pure(s, c, n);

View file

@ -18,7 +18,6 @@
*/
#include "libc/assert.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/nexgen32e/x86feature.h"
#include "libc/str/str.h"
@ -33,8 +32,7 @@ static inline const unsigned char *rawmemchr_pure(const unsigned char *s,
#if defined(__x86_64__) && !defined(__chibicc__)
typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(16)));
static inline const char *rawmemchr_sse(const char *s,
unsigned char c) {
static inline const char *rawmemchr_sse(const char *s, unsigned char c) {
unsigned k;
unsigned m;
const xmm_t *p;
@ -67,11 +65,10 @@ static inline uint64_t UncheckedAlignedRead64(const unsigned char *p) {
* @param c is search byte which is masked with 255
* @return is pointer to first instance of c
*/
void *rawmemchr(const void *s, int c) {
__vex void *rawmemchr(const void *s, int c) {
#if defined(__x86_64__) && !defined(__chibicc__)
const void *r;
if (X86_HAVE(SSE)) {
if (IsAsan()) __asan_verify(s, 1);
r = rawmemchr_sse(s, c);
} else {
r = rawmemchr_pure(s, c);

View file

@ -167,7 +167,7 @@ wint_t towctrans(wint_t, wctrans_t) libcesque;
int getsubopt(char **, char *const *, char **) libcesque paramsnonnull();
char *strsignal(int) returnsnonnull libcesque;
char *strerror(int) returnsnonnull dontthrow nocallback;
char *strerror(int) returnsnonnull dontthrow dontcallback;
errno_t strerror_r(int, char *, size_t) libcesque;
char *__xpg_strerror_r(int, char *, size_t) libcesque;

View file

@ -17,7 +17,6 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/str/str.h"
#include "libc/str/tab.internal.h"
@ -34,8 +33,6 @@ int strcasecmp(const char *a, const char *b) {
size_t i = 0;
uint64_t v, w;
if (a == b) return 0;
if (IsAsan()) __asan_verify_str(a);
if (IsAsan()) __asan_verify_str(b);
if (((uintptr_t)a & 7) == ((uintptr_t)b & 7)) {
for (; (uintptr_t)(a + i) & 7; ++i) {
CheckEm:

View file

@ -18,7 +18,6 @@
*/
#include "libc/str/str.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/str/tab.internal.h"
typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(16)));
@ -35,15 +34,13 @@ typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(16)));
* @asyncsignalsafe
* @see strstr()
*/
char *strcasestr(const char *haystack, const char *needle) {
__vex char *strcasestr(const char *haystack, const char *needle) {
#if defined(__x86_64__) && !defined(__chibicc__)
char c;
size_t i;
unsigned k, m;
const xmm_t *p;
xmm_t v, n1, n2, z = {0};
if (IsAsan()) __asan_verify(needle, 1);
if (IsAsan()) __asan_verify(haystack, 1);
if (haystack == needle || !*needle) return (char *)haystack;
c = *needle;
n1 = (xmm_t){c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c};

View file

@ -17,7 +17,6 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/str/str.h"
typedef char16_t xmm_t __attribute__((__vector_size__(16), __aligned__(16)));
@ -29,17 +28,15 @@ typedef char16_t xmm_t __attribute__((__vector_size__(16), __aligned__(16)));
* @return number of shorts (excluding NUL)
* @asyncsignalsafe
*/
size_t strlen16(const char16_t *s) {
__vex size_t strlen16(const char16_t *s) {
#if defined(__x86_64__) && !defined(__chibicc__)
size_t n;
xmm_t z = {0};
unsigned m, k = (uintptr_t)s & 15;
const xmm_t *p = (const xmm_t *)((uintptr_t)s & -16);
if (IsAsan()) __asan_verify(s, 2);
m = __builtin_ia32_pmovmskb128(*p == z) >> k << k;
while (!m) m = __builtin_ia32_pmovmskb128(*++p == z);
n = (const char16_t *)p + (__builtin_ctzl(m) >> 1) - s;
if (IsAsan()) __asan_verify(s, n * 2);
return n;
#else
size_t n = 0;

View file

@ -18,7 +18,6 @@
*/
#include "libc/assert.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/str/str.h"
static size_t strnlen_s_x64(const char *s, size_t n, size_t i) {
@ -48,7 +47,6 @@ static size_t strnlen_s_x64(const char *s, size_t n, size_t i) {
size_t strnlen_s(const char *s, size_t n) {
size_t i;
if (!s) return 0;
if (IsAsan()) __asan_verify(s, n);
for (i = 0; (uintptr_t)(s + i) & 7; ++i) {
if (i == n || !s[i]) return i;
}

View file

@ -18,7 +18,6 @@
*/
#include "libc/str/str.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(16)));
@ -35,14 +34,12 @@ typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(16)));
* @see strcasestr()
* @see memmem()
*/
char *strstr(const char *haystack, const char *needle) {
__vex char *strstr(const char *haystack, const char *needle) {
#if defined(__x86_64__) && !defined(__chibicc__)
size_t i;
unsigned k, m;
const xmm_t *p;
xmm_t v, n, z = {0};
if (IsAsan()) __asan_verify(needle, 1);
if (IsAsan()) __asan_verify(haystack, 1);
if (haystack == needle || !*needle) return (char *)haystack;
n = (xmm_t){*needle, *needle, *needle, *needle, *needle, *needle,
*needle, *needle, *needle, *needle, *needle, *needle,

View file

@ -17,7 +17,6 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/str/str.h"
typedef wchar_t xmm_t __attribute__((__vector_size__(16), __aligned__(16)));
@ -29,17 +28,15 @@ typedef wchar_t xmm_t __attribute__((__vector_size__(16), __aligned__(16)));
* @return number of wide characters (excluding NUL)
* @asyncsignalsafe
*/
size_t wcslen(const wchar_t *s) {
__vex size_t wcslen(const wchar_t *s) {
#if defined(__x86_64__) && !defined(__chibicc__)
size_t n;
xmm_t z = {0};
unsigned m, k = (uintptr_t)s & 15;
const xmm_t *p = (const xmm_t *)((uintptr_t)s & -16);
if (IsAsan()) __asan_verify(s, 4);
m = __builtin_ia32_pmovmskb128(*p == z) >> k << k;
while (!m) m = __builtin_ia32_pmovmskb128(*++p == z);
n = (const wchar_t *)p + (__builtin_ctzl(m) >> 2) - s;
if (IsAsan()) __asan_verify(s, n);
return n;
#else
size_t n = 0;

View file

@ -17,7 +17,6 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/limits.h"
#include "libc/nexgen32e/x86feature.h"
#include "libc/stdckdint.h"
@ -38,7 +37,7 @@ static inline const wchar_t *wmemrchr_pure(const wchar_t *s, wchar_t c,
#if defined(__x86_64__) && !defined(__chibicc__)
static inline const wchar_t *wmemrchr_sse(const wchar_t *s, wchar_t c,
size_t n) {
size_t n) {
size_t i;
unsigned m;
xmm_t v, t = {c, c, c, c};
@ -68,16 +67,9 @@ static inline const wchar_t *wmemrchr_sse(const wchar_t *s, wchar_t c,
* @return is pointer to first instance of c or NULL if not found
* @asyncsignalsafe
*/
void *wmemrchr(const wchar_t *s, wchar_t c, size_t n) {
__vex void *wmemrchr(const wchar_t *s, wchar_t c, size_t n) {
#if defined(__x86_64__) && !defined(__chibicc__)
size_t bytes;
const void *r;
if (IsAsan()) {
if (ckd_mul(&bytes, n, sizeof(wchar_t))) bytes = -1;
__asan_verify(s, bytes);
}
r = wmemrchr_sse(s, c, n);
return (void *)r;
return (void *)wmemrchr_sse(s, c, n);
#else
return (void *)wmemrchr_pure(s, c, n);
#endif