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

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

135
libc/intrin/comparetf2.c Normal file
View file

@ -0,0 +1,135 @@
/* clang-format off */
//===-- lib/comparetf2.c - Quad-precision comparisons -------------*- C -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// // This file implements the following soft-float comparison routines:
//
// __eqtf2 __getf2 __unordtf2
// __letf2 __gttf2
// __lttf2
// __netf2
//
// The semantics of the routines grouped in each column are identical, so there
// is a single implementation for each, and wrappers to provide the other names.
//
// The main routines behave as follows:
//
// __letf2(a,b) returns -1 if a < b
// 0 if a == b
// 1 if a > b
// 1 if either a or b is NaN
//
// __getf2(a,b) returns -1 if a < b
// 0 if a == b
// 1 if a > b
// -1 if either a or b is NaN
//
// __unordtf2(a,b) returns 0 if both a and b are numbers
// 1 if either a or b is NaN
//
// Note that __letf2( ) and __getf2( ) are identical except in their handling of
// NaN values.
//
//===----------------------------------------------------------------------===//
#define QUAD_PRECISION
#include "third_party/compiler_rt/fp_lib.inc"
#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
enum LE_RESULT {
LE_LESS = -1,
LE_EQUAL = 0,
LE_GREATER = 1,
LE_UNORDERED = 1
};
COMPILER_RT_ABI enum LE_RESULT __letf2(fp_t a, fp_t b) {
const srep_t aInt = toRep(a);
const srep_t bInt = toRep(b);
const rep_t aAbs = aInt & absMask;
const rep_t bAbs = bInt & absMask;
// If either a or b is NaN, they are unordered.
if (aAbs > infRep || bAbs > infRep) return LE_UNORDERED;
// If a and b are both zeros, they are equal.
if ((aAbs | bAbs) == 0) return LE_EQUAL;
// If at least one of a and b is positive, we get the same result comparing
// a and b as signed integers as we would with a floating-point compare.
if ((aInt & bInt) >= 0) {
if (aInt < bInt) return LE_LESS;
else if (aInt == bInt) return LE_EQUAL;
else return LE_GREATER;
}
else {
// Otherwise, both are negative, so we need to flip the sense of the
// comparison to get the correct result. (This assumes a twos- or ones-
// complement integer representation; if integers are represented in a
// sign-magnitude representation, then this flip is incorrect).
if (aInt > bInt) return LE_LESS;
else if (aInt == bInt) return LE_EQUAL;
else return LE_GREATER;
}
}
// Alias for libgcc compatibility
COMPILER_RT_ABI enum LE_RESULT __cmptf2(fp_t a, fp_t b) {
return __letf2(a, b);
}
enum GE_RESULT {
GE_LESS = -1,
GE_EQUAL = 0,
GE_GREATER = 1,
GE_UNORDERED = -1 // Note: different from LE_UNORDERED
};
COMPILER_RT_ABI enum GE_RESULT __getf2(fp_t a, fp_t b) {
const srep_t aInt = toRep(a);
const srep_t bInt = toRep(b);
const rep_t aAbs = aInt & absMask;
const rep_t bAbs = bInt & absMask;
if (aAbs > infRep || bAbs > infRep) return GE_UNORDERED;
if ((aAbs | bAbs) == 0) return GE_EQUAL;
if ((aInt & bInt) >= 0) {
if (aInt < bInt) return GE_LESS;
else if (aInt == bInt) return GE_EQUAL;
else return GE_GREATER;
} else {
if (aInt > bInt) return GE_LESS;
else if (aInt == bInt) return GE_EQUAL;
else return GE_GREATER;
}
}
COMPILER_RT_ABI int __unordtf2(fp_t a, fp_t b) {
const rep_t aAbs = toRep(a) & absMask;
const rep_t bAbs = toRep(b) & absMask;
return aAbs > infRep || bAbs > infRep;
}
// The following are alternative names for the preceding routines.
COMPILER_RT_ABI enum LE_RESULT __eqtf2(fp_t a, fp_t b) {
return __letf2(a, b);
}
COMPILER_RT_ABI enum LE_RESULT __lttf2(fp_t a, fp_t b) {
return __letf2(a, b);
}
COMPILER_RT_ABI enum LE_RESULT __netf2(fp_t a, fp_t b) {
return __letf2(a, b);
}
COMPILER_RT_ABI enum GE_RESULT __gttf2(fp_t a, fp_t b) {
return __getf2(a, b);
}
#endif

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
}

35
libc/intrin/fmax.c Normal file
View file

@ -0,0 +1,35 @@
/*-*- 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
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"
/**
* Returns maximum of two doubles.
*
* If one argument is NAN then the other is returned.
* This function is designed to do the right thing with
* signed zeroes.
*/
double fmax(double x, double y) {
if (__builtin_isnan(x)) return y;
if (__builtin_isnan(y)) return x;
if (__builtin_signbit(x) != __builtin_signbit(y)) {
return __builtin_signbit(x) ? y : x; /* C99 Annex F.9.9.2 */
}
return x < y ? y : x;
}

35
libc/intrin/fmaxf.c Normal file
View file

@ -0,0 +1,35 @@
/*-*- 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
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"
/**
* Returns maximum of two floats.
*
* If one argument is NAN then the other is returned.
* This function is designed to do the right thing with
* signed zeroes.
*/
float fmaxf(float x, float y) {
if (__builtin_isnan(x)) return y;
if (__builtin_isnan(y)) return x;
if (__builtin_signbitf(x) != __builtin_signbitf(y)) {
return __builtin_signbitf(x) ? y : x; /* C99 Annex F.9.9.2 */
}
return x < y ? y : x;
}

35
libc/intrin/fmaxl.c Normal file
View file

@ -0,0 +1,35 @@
/*-*- 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
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"
/**
* Returns maximum of two long doubles.
*
* If one argument is NAN then the other is returned.
* This function is designed to do the right thing with
* signed zeroes.
*/
long double fmaxl(long double x, long double y) {
if (__builtin_isnan(x)) return y;
if (__builtin_isnan(y)) return x;
if (__builtin_signbitl(x) != __builtin_signbitl(y)) {
return __builtin_signbitl(x) ? y : x; /* C99 Annex F.9.9.2 */
}
return x < y ? y : x;
}

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

68
libc/intrin/ldexp.c Normal file
View file

@ -0,0 +1,68 @@
/*-*- 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"
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 */
/**
* Returns 𝑥 × 2ʸ.
*/
double ldexp(double x, int n)
{
union {double f; uint64_t i;} u;
double_t y = x;
if (n > 1023) {
y *= 0x1p1023;
n -= 1023;
if (n > 1023) {
y *= 0x1p1023;
n -= 1023;
if (n > 1023)
n = 1023;
}
} else if (n < -1022) {
/* make sure final n < -53 to avoid double
rounding in the subnormal range */
y *= 0x1p-1022 * 0x1p53;
n += 1022 - 53;
if (n < -1022) {
y *= 0x1p-1022 * 0x1p53;
n += 1022 - 53;
if (n < -1022)
n = -1022;
}
}
u.i = (uint64_t)(0x3ff+n)<<52;
x = y * u.f;
return x;
}

66
libc/intrin/ldexpf.c Normal file
View file

@ -0,0 +1,66 @@
/*-*- 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"
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 */
/**
* Returns 𝑥 × 2ʸ.
*/
float ldexpf(float x, int n)
{
union {float f; uint32_t i;} u;
float_t y = x;
if (n > 127) {
y *= 0x1p127f;
n -= 127;
if (n > 127) {
y *= 0x1p127f;
n -= 127;
if (n > 127)
n = 127;
}
} else if (n < -126) {
y *= 0x1p-126f * 0x1p24f;
n += 126 - 24;
if (n < -126) {
y *= 0x1p-126f * 0x1p24f;
n += 126 - 24;
if (n < -126)
n = -126;
}
}
u.i = (uint32_t)(0x7f+n)<<23;
x = y * u.f;
return x;
}

23
libc/intrin/ldexpl.c Normal file
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 ldexpl(long double x, int n) {
return scalbnl(x, n);
}

26
libc/intrin/multf3.c Normal file
View file

@ -0,0 +1,26 @@
/* clang-format off */
//===-- lib/multf3.c - Quad-precision multiplication --------------*- C -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements quad-precision soft-float multiplication
// with the IEEE-754 default rounding (to nearest, ties to even).
//
//===----------------------------------------------------------------------===//
#define QUAD_PRECISION
#include "third_party/compiler_rt/fp_lib.inc"
#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
#include "third_party/compiler_rt/fp_mul_impl.inc"
COMPILER_RT_ABI fp_t __multf3(fp_t a, fp_t b) {
return __mulXf3__(a, b);
}
#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

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

26
libc/intrin/scalbn.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 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/math.h"
/**
* Returns 𝑥 × 2ʸ.
*/
double scalbn(double x, int n) {
return ldexp(x, n);
}

26
libc/intrin/scalbnf.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 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/math.h"
/**
* Returns 𝑥 × 2ʸ.
*/
float scalbnf(float x, int n) {
return ldexpf(x, n);
}

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

46
libc/intrin/tpenc2.c Normal file
View file

@ -0,0 +1,46 @@
/*-*- 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/intrin/bsr.h"
#include "libc/intrin/intrin.h"
#ifndef __x86_64__
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,
};
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 {
w |= 0200 | (c & 077);
w <<= 8;
c >>= 6;
} while (--n);
return c | w | e >> 8;
}
#endif /* __x86_64__ */