mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-22 21:32:31 +00:00
Make improvements
- More timspec_*() and timeval_*() APIs have been introduced. - The copyfd() function is now simplified thanks to POSIX rules. - More Cosmo-specific APIs have been moved behind the COSMO define. - The setitimer() polyfill for Windows NT is now much higher quality. - Fixed build error for MODE=aarch64 due to -mstringop-strategy=loop. - This change introduces `make MODE=nox87 toolchain` which makes it possible to build programs using your cosmocc toolchain that don't have legacy fpu instructions. This is useful, for example, if you want to have a ~22kb tinier blink virtual machine.
This commit is contained in:
parent
8dc11afcf6
commit
c3440d040c
132 changed files with 539 additions and 587 deletions
|
@ -364,6 +364,28 @@ TARGET_ARCH ?= \
|
||||||
-msse3
|
-msse3
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# no x87 instructions mode
|
||||||
|
#
|
||||||
|
# export MODE=nox87
|
||||||
|
# make -j8 toolchain
|
||||||
|
# cosmocc -o /tmp/hello.com hello.c
|
||||||
|
#
|
||||||
|
# lets you shave ~23kb off blink
|
||||||
|
#
|
||||||
|
# git clone https://github.com/jart/blink
|
||||||
|
# cd blink
|
||||||
|
# ./configure --disable-x87
|
||||||
|
# make -j8
|
||||||
|
# o//blink/blink /tmp/hello.com
|
||||||
|
#
|
||||||
|
ifeq ($(MODE), nox87)
|
||||||
|
ENABLE_FTRACE = 1
|
||||||
|
CONFIG_COPTS += -mlong-double-64
|
||||||
|
CONFIG_CCFLAGS += $(BACKTRACES) -O2
|
||||||
|
CONFIG_CPPFLAGS += -DSYSDEBUG -DNOX87
|
||||||
|
TARGET_ARCH ?= -msse3
|
||||||
|
endif
|
||||||
|
|
||||||
# LLVM Mode
|
# LLVM Mode
|
||||||
ifeq ($(MODE), llvm)
|
ifeq ($(MODE), llvm)
|
||||||
TARGET_ARCH ?= -msse3
|
TARGET_ARCH ?= -msse3
|
||||||
|
|
|
@ -33,7 +33,6 @@
|
||||||
#include "libc/sysv/consts/sig.h"
|
#include "libc/sysv/consts/sig.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
#include "libc/thread/tls.h"
|
#include "libc/thread/tls.h"
|
||||||
|
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -42,14 +42,6 @@
|
||||||
|
|
||||||
#define MAP_FAILED ((void *)-1)
|
#define MAP_FAILED ((void *)-1)
|
||||||
|
|
||||||
#define ARCH_SET_GS 0x1001
|
|
||||||
#define ARCH_SET_FS 0x1002
|
|
||||||
#define ARCH_GET_FS 0x1003
|
|
||||||
#define ARCH_GET_GS 0x1004
|
|
||||||
|
|
||||||
#define MAP_HUGE_2MB (21 << MAP_HUGE_SHIFT)
|
|
||||||
#define MAP_HUGE_1GB (30 << MAP_HUGE_SHIFT)
|
|
||||||
|
|
||||||
#define WCOREDUMP(s) (128 & (s))
|
#define WCOREDUMP(s) (128 & (s))
|
||||||
#define WEXITSTATUS(s) ((0xff00 & (s)) >> 8)
|
#define WEXITSTATUS(s) ((0xff00 & (s)) >> 8)
|
||||||
#define WIFCONTINUED(s) ((s) == 0xffff)
|
#define WIFCONTINUED(s) ((s) == 0xffff)
|
||||||
|
@ -69,11 +61,9 @@ COSMOPOLITAN_C_START_
|
||||||
typedef int sig_atomic_t;
|
typedef int sig_atomic_t;
|
||||||
|
|
||||||
bool32 isatty(int) nosideeffect;
|
bool32 isatty(int) nosideeffect;
|
||||||
char *commandv(const char *, char *, size_t);
|
|
||||||
char *get_current_dir_name(void) dontdiscard;
|
char *get_current_dir_name(void) dontdiscard;
|
||||||
char *getcwd(char *, size_t);
|
char *getcwd(char *, size_t);
|
||||||
char *realpath(const char *, char *);
|
char *realpath(const char *, char *);
|
||||||
char *replaceuser(const char *) dontdiscard;
|
|
||||||
char *ttyname(int);
|
char *ttyname(int);
|
||||||
int access(const char *, int) dontthrow;
|
int access(const char *, int) dontthrow;
|
||||||
int chdir(const char *);
|
int chdir(const char *);
|
||||||
|
@ -122,7 +112,6 @@ int getpriority(int, unsigned);
|
||||||
int getresgid(unsigned *, unsigned *, unsigned *);
|
int getresgid(unsigned *, unsigned *, unsigned *);
|
||||||
int getresuid(unsigned *, unsigned *, unsigned *);
|
int getresuid(unsigned *, unsigned *, unsigned *);
|
||||||
int getsid(int) nosideeffect libcesque;
|
int getsid(int) nosideeffect libcesque;
|
||||||
int gettid(void) libcesque;
|
|
||||||
int ioprio_get(int, int);
|
int ioprio_get(int, int);
|
||||||
int ioprio_set(int, int, int);
|
int ioprio_set(int, int, int);
|
||||||
int issetugid(void);
|
int issetugid(void);
|
||||||
|
@ -133,8 +122,6 @@ int lchown(const char *, unsigned, unsigned);
|
||||||
int link(const char *, const char *) dontthrow;
|
int link(const char *, const char *) dontthrow;
|
||||||
int linkat(int, const char *, int, const char *, int);
|
int linkat(int, const char *, int, const char *, int);
|
||||||
int madvise(void *, uint64_t, int);
|
int madvise(void *, uint64_t, int);
|
||||||
int makedirs(const char *, unsigned);
|
|
||||||
int memfd_create(const char *, unsigned int);
|
|
||||||
int mincore(void *, size_t, unsigned char *);
|
int mincore(void *, size_t, unsigned char *);
|
||||||
int mkdir(const char *, unsigned);
|
int mkdir(const char *, unsigned);
|
||||||
int mkdirat(int, const char *, unsigned);
|
int mkdirat(int, const char *, unsigned);
|
||||||
|
@ -146,14 +133,10 @@ int nice(int);
|
||||||
int open(const char *, int, ...);
|
int open(const char *, int, ...);
|
||||||
int openat(int, const char *, int, ...);
|
int openat(int, const char *, int, ...);
|
||||||
int pause(void);
|
int pause(void);
|
||||||
int personality(uint64_t);
|
|
||||||
int pipe(int[hasatleast 2]);
|
int pipe(int[hasatleast 2]);
|
||||||
int pipe2(int[hasatleast 2], int);
|
int pipe2(int[hasatleast 2], int);
|
||||||
int pivot_root(const char *, const char *);
|
|
||||||
int pledge(const char *, const char *);
|
|
||||||
int posix_fadvise(int, int64_t, int64_t, int);
|
int posix_fadvise(int, int64_t, int64_t, int);
|
||||||
int posix_madvise(void *, uint64_t, int);
|
int posix_madvise(void *, uint64_t, int);
|
||||||
int prctl(int, ...);
|
|
||||||
int raise(int);
|
int raise(int);
|
||||||
int reboot(int);
|
int reboot(int);
|
||||||
int remove(const char *);
|
int remove(const char *);
|
||||||
|
@ -161,7 +144,6 @@ int rename(const char *, const char *);
|
||||||
int renameat(int, const char *, int, const char *);
|
int renameat(int, const char *, int, const char *);
|
||||||
int rmdir(const char *);
|
int rmdir(const char *);
|
||||||
int sched_yield(void);
|
int sched_yield(void);
|
||||||
int seccomp(unsigned, unsigned, void *);
|
|
||||||
int setegid(unsigned);
|
int setegid(unsigned);
|
||||||
int seteuid(unsigned);
|
int seteuid(unsigned);
|
||||||
int setfsgid(unsigned);
|
int setfsgid(unsigned);
|
||||||
|
@ -182,37 +164,21 @@ int siginterrupt(int, int);
|
||||||
int symlink(const char *, const char *);
|
int symlink(const char *, const char *);
|
||||||
int symlinkat(const char *, int, const char *);
|
int symlinkat(const char *, int, const char *);
|
||||||
int sync_file_range(int, int64_t, int64_t, unsigned);
|
int sync_file_range(int, int64_t, int64_t, unsigned);
|
||||||
int sys_iopl(int);
|
|
||||||
int sys_mlock(const void *, size_t);
|
|
||||||
int sys_mlock2(const void *, size_t, int);
|
|
||||||
int sys_mlockall(int);
|
|
||||||
int sys_munlock(const void *, size_t);
|
|
||||||
int sys_munlockall(void);
|
|
||||||
int sys_ptrace(int, ...);
|
|
||||||
int sys_sysctl(const int *, unsigned, void *, size_t *, void *, size_t);
|
|
||||||
int tcgetpgrp(int);
|
int tcgetpgrp(int);
|
||||||
int tcsetpgrp(int, int);
|
int tcsetpgrp(int, int);
|
||||||
int tgkill(int, int, int);
|
|
||||||
int tkill(int, int);
|
|
||||||
int tmpfd(void);
|
|
||||||
int touch(const char *, unsigned);
|
|
||||||
int truncate(const char *, int64_t);
|
int truncate(const char *, int64_t);
|
||||||
int ttyname_r(int, char *, size_t);
|
int ttyname_r(int, char *, size_t);
|
||||||
int unlink(const char *);
|
int unlink(const char *);
|
||||||
int unlink_s(const char **);
|
|
||||||
int unlinkat(int, const char *, int);
|
int unlinkat(int, const char *, int);
|
||||||
int unveil(const char *, const char *);
|
|
||||||
int usleep(unsigned);
|
int usleep(unsigned);
|
||||||
int vfork(void) returnstwice;
|
int vfork(void) returnstwice;
|
||||||
int wait(int *);
|
int wait(int *);
|
||||||
int waitpid(int, int *, int);
|
int waitpid(int, int *, int);
|
||||||
long ptrace(int, ...);
|
|
||||||
ssize_t copy_file_range(int, long *, int, long *, size_t, unsigned);
|
ssize_t copy_file_range(int, long *, int, long *, size_t, unsigned);
|
||||||
ssize_t lseek(int, int64_t, int);
|
ssize_t lseek(int, int64_t, int);
|
||||||
ssize_t pread(int, void *, size_t, int64_t);
|
ssize_t pread(int, void *, size_t, int64_t);
|
||||||
ssize_t pwrite(int, const void *, size_t, int64_t);
|
ssize_t pwrite(int, const void *, size_t, int64_t);
|
||||||
ssize_t read(int, void *, size_t);
|
ssize_t read(int, void *, size_t);
|
||||||
ssize_t readansi(int, char *, size_t);
|
|
||||||
ssize_t readlink(const char *, char *, size_t);
|
ssize_t readlink(const char *, char *, size_t);
|
||||||
ssize_t readlinkat(int, const char *, char *, size_t);
|
ssize_t readlinkat(int, const char *, char *, size_t);
|
||||||
ssize_t splice(int, int64_t *, int, int64_t *, size_t, unsigned);
|
ssize_t splice(int, int64_t *, int, int64_t *, size_t, unsigned);
|
||||||
|
@ -225,20 +191,38 @@ unsigned umask(unsigned);
|
||||||
void sync(void);
|
void sync(void);
|
||||||
|
|
||||||
#ifdef COSMO
|
#ifdef COSMO
|
||||||
#define fileexists __fileexists
|
|
||||||
#define isdirectory __isdirectory
|
|
||||||
#define isexecutable __isexecutable
|
|
||||||
#define isregularfile __isregularfile
|
|
||||||
#define issymlink __issymlink
|
|
||||||
#define ischardev __ischardev
|
|
||||||
#define copyfd __copyfd
|
|
||||||
bool fileexists(const char *);
|
bool fileexists(const char *);
|
||||||
bool isdirectory(const char *);
|
bool isdirectory(const char *);
|
||||||
bool isexecutable(const char *);
|
bool isexecutable(const char *);
|
||||||
bool isregularfile(const char *);
|
bool isregularfile(const char *);
|
||||||
bool issymlink(const char *);
|
bool issymlink(const char *);
|
||||||
bool32 ischardev(int) nosideeffect;
|
bool32 ischardev(int);
|
||||||
ssize_t copyfd(int, int64_t *, int, int64_t *, size_t, unsigned);
|
char *commandv(const char *, char *, size_t);
|
||||||
|
char *replaceuser(const char *) dontdiscard;
|
||||||
|
int gettid(void) libcesque;
|
||||||
|
int makedirs(const char *, unsigned);
|
||||||
|
int memfd_create(const char *, unsigned int);
|
||||||
|
int personality(uint64_t);
|
||||||
|
int pivot_root(const char *, const char *);
|
||||||
|
int pledge(const char *, const char *);
|
||||||
|
int prctl(int, ...);
|
||||||
|
int seccomp(unsigned, unsigned, void *);
|
||||||
|
int sys_iopl(int);
|
||||||
|
int sys_mlock(const void *, size_t);
|
||||||
|
int sys_mlock2(const void *, size_t, int);
|
||||||
|
int sys_mlockall(int);
|
||||||
|
int sys_munlock(const void *, size_t);
|
||||||
|
int sys_munlockall(void);
|
||||||
|
int sys_ptrace(int, ...);
|
||||||
|
int sys_sysctl(const int *, unsigned, void *, size_t *, void *, size_t);
|
||||||
|
int tgkill(int, int, int);
|
||||||
|
int tkill(int, int);
|
||||||
|
int tmpfd(void);
|
||||||
|
int touch(const char *, unsigned);
|
||||||
|
int unveil(const char *, const char *);
|
||||||
|
long ptrace(int, ...);
|
||||||
|
ssize_t copyfd(int, int, size_t);
|
||||||
|
ssize_t readansi(int, char *, size_t);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
COSMOPOLITAN_C_END_
|
COSMOPOLITAN_C_END_
|
||||||
|
|
|
@ -103,6 +103,7 @@ o/$(MODE)/libc/calls/ntcontext2linux.o: private \
|
||||||
COPTS += \
|
COPTS += \
|
||||||
-fno-sanitize=all
|
-fno-sanitize=all
|
||||||
|
|
||||||
|
ifneq ($(ARCH), aarch64)
|
||||||
# we always want -O3 because:
|
# we always want -O3 because:
|
||||||
# it makes the code size smaller too
|
# it makes the code size smaller too
|
||||||
# we need -mstringop-strategy=loop because:
|
# we need -mstringop-strategy=loop because:
|
||||||
|
@ -116,6 +117,7 @@ o/$(MODE)/libc/calls/ntcontext2linux.o: private \
|
||||||
COPTS += \
|
COPTS += \
|
||||||
-O3 \
|
-O3 \
|
||||||
-mstringop-strategy=loop
|
-mstringop-strategy=loop
|
||||||
|
endif
|
||||||
|
|
||||||
# we must disable static stack safety because:
|
# we must disable static stack safety because:
|
||||||
# these functions use alloca(n)
|
# these functions use alloca(n)
|
||||||
|
|
|
@ -42,7 +42,6 @@
|
||||||
* time. Among the more popular is CLOCK_MONOTONIC. This function has a
|
* time. Among the more popular is CLOCK_MONOTONIC. This function has a
|
||||||
* zero syscall implementation of that on modern x86.
|
* zero syscall implementation of that on modern x86.
|
||||||
*
|
*
|
||||||
* nowl l: 45𝑐 15𝑛𝑠
|
|
||||||
* rdtsc l: 13𝑐 4𝑛𝑠
|
* rdtsc l: 13𝑐 4𝑛𝑠
|
||||||
* gettimeofday l: 44𝑐 14𝑛𝑠
|
* gettimeofday l: 44𝑐 14𝑛𝑠
|
||||||
* clock_gettime l: 40𝑐 13𝑛𝑠
|
* clock_gettime l: 40𝑐 13𝑛𝑠
|
||||||
|
|
|
@ -17,59 +17,34 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/mem/mem.h"
|
|
||||||
|
|
||||||
#define CHUNK 32768
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies data between fds the old fashioned way.
|
* Copies data between file descriptors the old fashioned way.
|
||||||
*
|
*
|
||||||
* @return bytes successfully exchanged
|
* This function is intended for simple programs without signals. If
|
||||||
|
* signals are in play, then `SA_RESTART` needs to be used.
|
||||||
|
*
|
||||||
|
* @param in is input file descriptor
|
||||||
|
* @param out is input file descriptor
|
||||||
|
* @param n is number of bytes to exchange, or -1 for until eof
|
||||||
|
* @return bytes successfully exchanged, or -1 w/ errno
|
||||||
*/
|
*/
|
||||||
ssize_t _copyfd(int infd, int outfd, size_t n) {
|
ssize_t copyfd(int in, int out, size_t n) {
|
||||||
int e;
|
size_t i;
|
||||||
char *buf;
|
char buf[512];
|
||||||
ssize_t rc;
|
ssize_t dr, dw;
|
||||||
size_t i, j, got, sent;
|
for (i = 0; i < n; i += dr) {
|
||||||
rc = 0;
|
dr = read(in, buf, MIN(n - i, sizeof(buf)));
|
||||||
if (n) {
|
if (dr == -1) return -1;
|
||||||
if ((buf = malloc(CHUNK))) {
|
if (!dr) break;
|
||||||
for (e = errno, i = 0; i < n; i += j) {
|
dw = write(out, buf, dr);
|
||||||
rc = read(infd, buf, CHUNK);
|
if (dw == -1) return -1;
|
||||||
if (rc == -1) {
|
if (dw != dr) {
|
||||||
// eintr may interrupt the read operation
|
// POSIX requires atomic IO up to PIPE_BUF
|
||||||
if (i && errno == EINTR) {
|
// The minimum permissible PIPE_BUF is 512
|
||||||
// suppress error if partially completed
|
__builtin_trap();
|
||||||
errno = e;
|
|
||||||
rc = i;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
got = rc;
|
|
||||||
if (!got) {
|
|
||||||
rc = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// write operation must complete
|
|
||||||
for (j = 0; j < got; j += sent) {
|
|
||||||
rc = write(outfd, buf + j, got - j);
|
|
||||||
if (rc != -1) {
|
|
||||||
sent = rc;
|
|
||||||
} else if (errno == EINTR) {
|
|
||||||
// write operation must be uninterruptible
|
|
||||||
errno = e;
|
|
||||||
sent = 0;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (rc == -1) break;
|
|
||||||
}
|
|
||||||
free(buf);
|
|
||||||
} else {
|
|
||||||
rc = -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rc;
|
return i;
|
||||||
}
|
}
|
|
@ -17,10 +17,10 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/asan.internal.h"
|
#include "libc/calls/asan.internal.h"
|
||||||
#include "libc/calls/struct/itimerval.internal.h"
|
|
||||||
#include "libc/calls/struct/timespec.h"
|
#include "libc/calls/struct/timespec.h"
|
||||||
#include "libc/calls/struct/timespec.internal.h"
|
#include "libc/calls/struct/timespec.internal.h"
|
||||||
#include "libc/calls/struct/timeval.h"
|
#include "libc/calls/struct/timeval.h"
|
||||||
|
#include "libc/calls/struct/timeval.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/intrin/strace.internal.h"
|
#include "libc/intrin/strace.internal.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "libc/calls/struct/itimerval.internal.h"
|
#include "libc/calls/struct/itimerval.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
|
#include "libc/intrin/describeflags.internal.h"
|
||||||
#include "libc/intrin/strace.internal.h"
|
#include "libc/intrin/strace.internal.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
|
||||||
|
@ -41,12 +42,7 @@ int getitimer(int which, struct itimerval *curvalue) {
|
||||||
} else {
|
} else {
|
||||||
rc = sys_setitimer_nt(which, 0, curvalue);
|
rc = sys_setitimer_nt(which, 0, curvalue);
|
||||||
}
|
}
|
||||||
if (curvalue) {
|
STRACE("getitimer(%s, [%s]) → %d% m", DescribeItimer(which),
|
||||||
STRACE("getitimer(%d, [{{%'ld, %'ld}, {%'ld, %'ld}}]) → %d% m", which,
|
DescribeItimerval(rc, curvalue), rc);
|
||||||
curvalue->it_interval.tv_sec, curvalue->it_interval.tv_usec,
|
|
||||||
curvalue->it_value.tv_sec, curvalue->it_value.tv_usec, rc);
|
|
||||||
} else {
|
|
||||||
STRACE("getitimer(%d, 0) → %d% m", which, rc);
|
|
||||||
}
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,13 +38,13 @@ static gettimeofday_f *__gettimeofday = __gettimeofday_init;
|
||||||
* Returns system wall time in microseconds, e.g.
|
* Returns system wall time in microseconds, e.g.
|
||||||
*
|
*
|
||||||
* int64_t t;
|
* int64_t t;
|
||||||
* char p[30];
|
* char p[20];
|
||||||
* struct tm tm;
|
* struct tm tm;
|
||||||
* struct timeval tv;
|
* struct timeval tv;
|
||||||
* gettimeofday(&tv, 0);
|
* gettimeofday(&tv, 0);
|
||||||
* t = tv.tv_sec;
|
* t = tv.tv_sec;
|
||||||
* gmtime_r(&t, &tm);
|
* gmtime_r(&t, &tm);
|
||||||
* FormatHttpDateTime(p, &tm);
|
* iso8601(p, &tm);
|
||||||
* printf("%s\n", p);
|
* printf("%s\n", p);
|
||||||
*
|
*
|
||||||
* @param tv points to timeval that receives result if non-NULL
|
* @param tv points to timeval that receives result if non-NULL
|
||||||
|
|
|
@ -16,120 +16,49 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/assert.h"
|
|
||||||
#include "libc/calls/calls.h"
|
|
||||||
#include "libc/calls/sig.internal.h"
|
#include "libc/calls/sig.internal.h"
|
||||||
#include "libc/calls/struct/itimerval.h"
|
#include "libc/calls/struct/itimerval.h"
|
||||||
#include "libc/calls/struct/siginfo.h"
|
#include "libc/calls/struct/timeval.h"
|
||||||
#include "libc/dce.h"
|
|
||||||
#include "libc/errno.h"
|
|
||||||
#include "libc/fmt/conv.h"
|
|
||||||
#include "libc/intrin/bits.h"
|
|
||||||
#include "libc/intrin/strace.internal.h"
|
|
||||||
#include "libc/log/check.h"
|
|
||||||
#include "libc/math.h"
|
|
||||||
#include "libc/nexgen32e/nexgen32e.h"
|
|
||||||
#include "libc/nexgen32e/nt2sysv.h"
|
|
||||||
#include "libc/nt/files.h"
|
|
||||||
#include "libc/nt/runtime.h"
|
|
||||||
#include "libc/nt/synchronization.h"
|
|
||||||
#include "libc/nt/thread.h"
|
|
||||||
#include "libc/str/str.h"
|
|
||||||
#include "libc/sysv/consts/itimer.h"
|
#include "libc/sysv/consts/itimer.h"
|
||||||
#include "libc/sysv/consts/sicode.h"
|
#include "libc/sysv/consts/sicode.h"
|
||||||
#include "libc/sysv/consts/sig.h"
|
#include "libc/sysv/consts/sig.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
#include "libc/time/time.h"
|
|
||||||
|
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
|
|
||||||
/**
|
static struct itimerval g_setitimer;
|
||||||
* @fileoverview Heartbreaking polyfill for SIGALRM on NT.
|
|
||||||
*
|
|
||||||
* Threads are used to trigger the SIGALRM handler, which should
|
|
||||||
* hopefully be an unfancy function like this:
|
|
||||||
*
|
|
||||||
* void OnAlarm(int sig, struct siginfo *si, struct ucontext *uc) {
|
|
||||||
* g_alarmed = true;
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* This is needed because WIN32 provides no obvious solutions for
|
|
||||||
* interrupting i/o operations on the standard input handle.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static bool __hastimer;
|
|
||||||
static bool __singleshot;
|
|
||||||
static long double __lastalrm;
|
|
||||||
static long double __interval;
|
|
||||||
|
|
||||||
textwindows void _check_sigalrm(void) {
|
textwindows void _check_sigalrm(void) {
|
||||||
// TODO(jart): use a different timing source
|
struct timeval now;
|
||||||
// TODO(jart): synchronize across intervals?
|
if (timeval_iszero(g_setitimer.it_value)) return;
|
||||||
long double now, elapsed;
|
now = timeval_real();
|
||||||
if (!__hastimer) return;
|
if (timeval_cmp(now, g_setitimer.it_value) < 0) return;
|
||||||
now = nowl();
|
if (timeval_iszero(g_setitimer.it_interval)) {
|
||||||
elapsed = now - __lastalrm;
|
g_setitimer.it_value = timeval_zero;
|
||||||
if (elapsed > __interval) {
|
} else {
|
||||||
__sig_add(0, SIGALRM, SI_TIMER);
|
do {
|
||||||
if (__singleshot) {
|
g_setitimer.it_value =
|
||||||
__hastimer = false;
|
timeval_add(g_setitimer.it_value, g_setitimer.it_interval);
|
||||||
} else {
|
} while (timeval_cmp(now, g_setitimer.it_value) > 0);
|
||||||
__lastalrm = now;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
__sig_add(0, SIGALRM, SI_TIMER);
|
||||||
}
|
}
|
||||||
|
|
||||||
textwindows int sys_setitimer_nt(int which, const struct itimerval *newvalue,
|
textwindows int sys_setitimer_nt(int which, const struct itimerval *neu,
|
||||||
struct itimerval *out_opt_oldvalue) {
|
struct itimerval *old) {
|
||||||
long double elapsed, untilnext;
|
if (which != ITIMER_REAL || (neu && (!timeval_isvalid(neu->it_value) ||
|
||||||
|
!timeval_isvalid(neu->it_interval)))) {
|
||||||
if (which != ITIMER_REAL ||
|
|
||||||
(newvalue && (!(0 <= newvalue->it_value.tv_usec &&
|
|
||||||
newvalue->it_value.tv_usec < 1000000) ||
|
|
||||||
!(0 <= newvalue->it_interval.tv_usec &&
|
|
||||||
newvalue->it_interval.tv_usec < 1000000)))) {
|
|
||||||
return einval();
|
return einval();
|
||||||
}
|
}
|
||||||
|
if (old) {
|
||||||
if (out_opt_oldvalue) {
|
old->it_interval = g_setitimer.it_interval;
|
||||||
if (__hastimer) {
|
old->it_value = timeval_subz(g_setitimer.it_value, timeval_real());
|
||||||
elapsed = nowl() - __lastalrm;
|
|
||||||
if (elapsed > __interval) {
|
|
||||||
untilnext = 0;
|
|
||||||
} else {
|
|
||||||
untilnext = __interval - elapsed;
|
|
||||||
}
|
|
||||||
out_opt_oldvalue->it_interval.tv_sec = __interval;
|
|
||||||
out_opt_oldvalue->it_interval.tv_usec = 1 / 1e6 * fmodl(__interval, 1);
|
|
||||||
out_opt_oldvalue->it_value.tv_sec = untilnext;
|
|
||||||
out_opt_oldvalue->it_value.tv_usec = 1 / 1e6 * fmodl(untilnext, 1);
|
|
||||||
} else {
|
|
||||||
out_opt_oldvalue->it_interval.tv_sec = 0;
|
|
||||||
out_opt_oldvalue->it_interval.tv_usec = 0;
|
|
||||||
out_opt_oldvalue->it_value.tv_sec = 0;
|
|
||||||
out_opt_oldvalue->it_value.tv_usec = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (neu) {
|
||||||
if (newvalue) {
|
g_setitimer.it_interval = neu->it_interval;
|
||||||
if (newvalue->it_interval.tv_sec || newvalue->it_interval.tv_usec ||
|
g_setitimer.it_value = timeval_iszero(neu->it_value)
|
||||||
newvalue->it_value.tv_sec || newvalue->it_value.tv_usec) {
|
? timeval_zero
|
||||||
__hastimer = true;
|
: timeval_add(timeval_real(), neu->it_value);
|
||||||
if (newvalue->it_interval.tv_sec || newvalue->it_interval.tv_usec) {
|
|
||||||
__singleshot = false;
|
|
||||||
__interval = newvalue->it_interval.tv_sec +
|
|
||||||
1 / 1e6 * newvalue->it_interval.tv_usec;
|
|
||||||
} else {
|
|
||||||
__singleshot = true;
|
|
||||||
__interval =
|
|
||||||
newvalue->it_value.tv_sec + 1 / 1e6 * newvalue->it_value.tv_usec;
|
|
||||||
}
|
|
||||||
__lastalrm = nowl();
|
|
||||||
} else {
|
|
||||||
__hastimer = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "libc/calls/struct/itimerval.internal.h"
|
#include "libc/calls/struct/itimerval.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
|
#include "libc/intrin/describeflags.internal.h"
|
||||||
#include "libc/intrin/strace.internal.h"
|
#include "libc/intrin/strace.internal.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
#include "libc/time/time.h"
|
#include "libc/time/time.h"
|
||||||
|
@ -66,7 +67,6 @@
|
||||||
int setitimer(int which, const struct itimerval *newvalue,
|
int setitimer(int which, const struct itimerval *newvalue,
|
||||||
struct itimerval *oldvalue) {
|
struct itimerval *oldvalue) {
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (IsAsan() &&
|
if (IsAsan() &&
|
||||||
((newvalue && !__asan_is_valid(newvalue, sizeof(*newvalue))) ||
|
((newvalue && !__asan_is_valid(newvalue, sizeof(*newvalue))) ||
|
||||||
(oldvalue && !__asan_is_valid(oldvalue, sizeof(*oldvalue))))) {
|
(oldvalue && !__asan_is_valid(oldvalue, sizeof(*oldvalue))))) {
|
||||||
|
@ -80,28 +80,7 @@ int setitimer(int which, const struct itimerval *newvalue,
|
||||||
} else {
|
} else {
|
||||||
rc = sys_setitimer_nt(which, newvalue, oldvalue);
|
rc = sys_setitimer_nt(which, newvalue, oldvalue);
|
||||||
}
|
}
|
||||||
|
STRACE("setitimer(%s, %s, [%s]) → %d% m", DescribeItimer(which),
|
||||||
#ifdef SYSDEBUG
|
DescribeItimerval(0, newvalue), DescribeItimerval(rc, oldvalue), rc);
|
||||||
if (newvalue && oldvalue) {
|
|
||||||
STRACE("setitimer(%d, "
|
|
||||||
"{{%'ld, %'ld}, {%'ld, %'ld}}, "
|
|
||||||
"[{{%'ld, %'ld}, {%'ld, %'ld}}]) → %d% m",
|
|
||||||
which, newvalue->it_interval.tv_sec, newvalue->it_interval.tv_usec,
|
|
||||||
newvalue->it_value.tv_sec, newvalue->it_value.tv_usec,
|
|
||||||
oldvalue->it_interval.tv_sec, oldvalue->it_interval.tv_usec,
|
|
||||||
oldvalue->it_value.tv_sec, oldvalue->it_value.tv_usec, rc);
|
|
||||||
} else if (newvalue) {
|
|
||||||
STRACE("setitimer(%d, {{%'ld, %'ld}, {%'ld, %'ld}}, NULL) → %d% m", which,
|
|
||||||
newvalue->it_interval.tv_sec, newvalue->it_interval.tv_usec,
|
|
||||||
newvalue->it_value.tv_sec, newvalue->it_value.tv_usec, rc);
|
|
||||||
} else if (oldvalue) {
|
|
||||||
STRACE("setitimer(%d, NULL, [{{%'ld, %'ld}, {%'ld, %'ld}}]) → %d% m", which,
|
|
||||||
oldvalue->it_interval.tv_sec, oldvalue->it_interval.tv_usec,
|
|
||||||
oldvalue->it_value.tv_sec, oldvalue->it_value.tv_usec, rc);
|
|
||||||
} else {
|
|
||||||
STRACE("setitimer(%d, NULL, NULL) → %d% m", which, rc);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,8 @@ int sys_getitimer(int, struct itimerval *) _Hide;
|
||||||
int sys_setitimer(int, const struct itimerval *, struct itimerval *) _Hide;
|
int sys_setitimer(int, const struct itimerval *, struct itimerval *) _Hide;
|
||||||
int sys_setitimer_nt(int, const struct itimerval *, struct itimerval *) _Hide;
|
int sys_setitimer_nt(int, const struct itimerval *, struct itimerval *) _Hide;
|
||||||
|
|
||||||
const char *DescribeTimeval(char[45], int, const struct timeval *);
|
const char *DescribeItimerval(char[90], int, const struct itimerval *);
|
||||||
#define DescribeTimeval(rc, ts) DescribeTimeval(alloca(45), rc, ts)
|
#define DescribeItimerval(rc, ts) DescribeItimerval(alloca(90), rc, ts)
|
||||||
|
|
||||||
COSMOPOLITAN_C_END_
|
COSMOPOLITAN_C_END_
|
||||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
|
|
|
@ -14,14 +14,14 @@ int clock_nanosleep(int, int, const struct timespec *, struct timespec *);
|
||||||
int futimens(int, const struct timespec[2]);
|
int futimens(int, const struct timespec[2]);
|
||||||
int nanosleep(const struct timespec *, struct timespec *);
|
int nanosleep(const struct timespec *, struct timespec *);
|
||||||
int utimensat(int, const char *, const struct timespec[2], int);
|
int utimensat(int, const char *, const struct timespec[2], int);
|
||||||
|
int timespec_getres(struct timespec *, int);
|
||||||
|
int timespec_get(struct timespec *, int);
|
||||||
|
|
||||||
#ifdef COSMO
|
#ifdef COSMO
|
||||||
/* cosmopolitan libc's non-posix timespec library
|
/* cosmopolitan libc's non-posix timespec library
|
||||||
removed by default due to emacs codebase clash */
|
removed by default due to emacs codebase clash */
|
||||||
#define timespec_zero ((struct timespec){0})
|
#define timespec_zero ((struct timespec){0})
|
||||||
#define timespec_max ((struct timespec){0x7fffffffffffffff, 999999999})
|
#define timespec_max ((struct timespec){0x7fffffffffffffff, 999999999})
|
||||||
int timespec_get(struct timespec *, int);
|
|
||||||
int timespec_getres(struct timespec *, int);
|
|
||||||
int timespec_cmp(struct timespec, struct timespec) pureconst;
|
int timespec_cmp(struct timespec, struct timespec) pureconst;
|
||||||
int64_t timespec_tomicros(struct timespec) pureconst;
|
int64_t timespec_tomicros(struct timespec) pureconst;
|
||||||
int64_t timespec_tomillis(struct timespec) pureconst;
|
int64_t timespec_tomillis(struct timespec) pureconst;
|
||||||
|
@ -35,7 +35,14 @@ struct timespec timespec_mono(void);
|
||||||
struct timespec timespec_sleep(struct timespec);
|
struct timespec timespec_sleep(struct timespec);
|
||||||
int timespec_sleep_until(struct timespec);
|
int timespec_sleep_until(struct timespec);
|
||||||
struct timespec timespec_sub(struct timespec, struct timespec) pureconst;
|
struct timespec timespec_sub(struct timespec, struct timespec) pureconst;
|
||||||
|
struct timespec timespec_subz(struct timespec, struct timespec) pureconst;
|
||||||
int sys_futex(int *, int, int, const struct timespec *, int *);
|
int sys_futex(int *, int, int, const struct timespec *, int *);
|
||||||
|
static inline bool timespec_iszero(struct timespec __ts) {
|
||||||
|
return !(__ts.tv_sec | __ts.tv_nsec);
|
||||||
|
}
|
||||||
|
static inline bool timespec_isvalid(struct timespec __ts) {
|
||||||
|
return __ts.tv_sec >= 0 && __ts.tv_nsec < 1000000000ull;
|
||||||
|
}
|
||||||
#endif /* COSMO */
|
#endif /* COSMO */
|
||||||
|
|
||||||
COSMOPOLITAN_C_END_
|
COSMOPOLITAN_C_END_
|
||||||
|
|
|
@ -19,13 +19,23 @@ int utimes(const char *, const struct timeval[2]);
|
||||||
#ifdef COSMO
|
#ifdef COSMO
|
||||||
/* cosmopolitan libc's non-posix timevals library
|
/* cosmopolitan libc's non-posix timevals library
|
||||||
removed by default due to emacs codebase clash */
|
removed by default due to emacs codebase clash */
|
||||||
|
#define timeval_zero ((struct timeval){0})
|
||||||
|
#define timeval_max ((struct timeval){0x7fffffffffffffff, 999999})
|
||||||
int timeval_cmp(struct timeval, struct timeval) pureconst;
|
int timeval_cmp(struct timeval, struct timeval) pureconst;
|
||||||
|
struct timeval timeval_real(void);
|
||||||
struct timeval timeval_frommicros(int64_t) pureconst;
|
struct timeval timeval_frommicros(int64_t) pureconst;
|
||||||
struct timeval timeval_frommillis(int64_t) pureconst;
|
struct timeval timeval_frommillis(int64_t) pureconst;
|
||||||
struct timeval timeval_add(struct timeval, struct timeval) pureconst;
|
struct timeval timeval_add(struct timeval, struct timeval) pureconst;
|
||||||
struct timeval timeval_sub(struct timeval, struct timeval) pureconst;
|
struct timeval timeval_sub(struct timeval, struct timeval) pureconst;
|
||||||
|
struct timeval timeval_subz(struct timeval, struct timeval) pureconst;
|
||||||
struct timeval timespec_totimeval(struct timespec) pureconst;
|
struct timeval timespec_totimeval(struct timespec) pureconst;
|
||||||
struct timespec timeval_totimespec(struct timeval) pureconst;
|
struct timespec timeval_totimespec(struct timeval) pureconst;
|
||||||
|
static inline bool timeval_iszero(struct timeval __tv) {
|
||||||
|
return !(__tv.tv_sec | __tv.tv_usec);
|
||||||
|
}
|
||||||
|
static inline bool timeval_isvalid(struct timeval __tv) {
|
||||||
|
return __tv.tv_sec >= 0 && __tv.tv_usec < 1000000ull;
|
||||||
|
}
|
||||||
#endif /* COSMO */
|
#endif /* COSMO */
|
||||||
|
|
||||||
COSMOPOLITAN_C_END_
|
COSMOPOLITAN_C_END_
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_TIMEVAL_INTERNAL_H_
|
#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_TIMEVAL_INTERNAL_H_
|
||||||
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_TIMEVAL_INTERNAL_H_
|
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_TIMEVAL_INTERNAL_H_
|
||||||
#include "libc/calls/struct/timeval.h"
|
#include "libc/calls/struct/timeval.h"
|
||||||
|
#include "libc/mem/alloca.h"
|
||||||
#include "libc/time/struct/timezone.h"
|
#include "libc/time/struct/timezone.h"
|
||||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
COSMOPOLITAN_C_START_
|
COSMOPOLITAN_C_START_
|
||||||
|
@ -15,6 +16,9 @@ axdx_t sys_gettimeofday_nt(struct timeval *, struct timezone *, void *) _Hide;
|
||||||
int sys_utimes_nt(const char *, const struct timeval[2]) _Hide;
|
int sys_utimes_nt(const char *, const struct timeval[2]) _Hide;
|
||||||
axdx_t sys_gettimeofday_metal(struct timeval *, struct timezone *, void *);
|
axdx_t sys_gettimeofday_metal(struct timeval *, struct timezone *, void *);
|
||||||
|
|
||||||
|
const char *DescribeTimeval(char[45], int, const struct timeval *);
|
||||||
|
#define DescribeTimeval(rc, ts) DescribeTimeval(alloca(45), rc, ts)
|
||||||
|
|
||||||
COSMOPOLITAN_C_END_
|
COSMOPOLITAN_C_END_
|
||||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_TIMEVAL_INTERNAL_H_ */
|
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_TIMEVAL_INTERNAL_H_ */
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│
|
│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 │
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
│ any purpose with or without fee is hereby granted, provided that the │
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
@ -16,30 +16,17 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/runtime/pc.internal.h"
|
#include "libc/calls/struct/timespec.h"
|
||||||
#include "libc/macros.internal.h"
|
|
||||||
|
|
||||||
// fmod [sic] does (𝑥 rem 𝑦) w/ round()-style rounding.
|
/**
|
||||||
//
|
* Subtracts two nanosecond timestamps.
|
||||||
// @param 𝑥 is an 80-bit long double passed on stack in 16-bytes
|
*
|
||||||
// @param 𝑦 is the power, also pushed on stack, in reverse order
|
* Unlike `timespec_sub()` this function will return zero if `x < y`.
|
||||||
// @return remainder ∈ (-|𝑦|,|𝑦|) in %st
|
*/
|
||||||
// @define 𝑥-truncl(𝑥/𝑦)*𝑦
|
struct timespec timespec_subz(struct timespec x, struct timespec y) {
|
||||||
// @see emod()
|
if (timespec_cmp(x, y) > 0) {
|
||||||
.ftrace1
|
return timespec_sub(x, y);
|
||||||
fmodl: .ftrace2
|
} else {
|
||||||
push %rbp
|
return timespec_zero;
|
||||||
mov %rsp,%rbp
|
}
|
||||||
fldt 32(%rbp)
|
}
|
||||||
fldt 16(%rbp)
|
|
||||||
1: fprem
|
|
||||||
fnstsw
|
|
||||||
test $FPU_C2>>8,%ah
|
|
||||||
jnz 1b
|
|
||||||
fstp %st(1)
|
|
||||||
pop %rbp
|
|
||||||
ret
|
|
||||||
1: int3
|
|
||||||
pop %rbp
|
|
||||||
ret
|
|
||||||
.endfn fmodl,globl
|
|
31
libc/calls/timeval_real.c
Normal file
31
libc/calls/timeval_real.c
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/*-*- 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/assert.h"
|
||||||
|
#include "libc/calls/struct/timeval.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns current time w/ microsecond precision.
|
||||||
|
*
|
||||||
|
* @see timespec_real()
|
||||||
|
*/
|
||||||
|
struct timeval timeval_real(void) {
|
||||||
|
struct timeval tv;
|
||||||
|
_npassert(!gettimeofday(&tv, 0));
|
||||||
|
return tv;
|
||||||
|
}
|
30
libc/calls/timeval_subz.c
Normal file
30
libc/calls/timeval_subz.c
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/*-*- 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/calls/struct/timeval.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subtracts two nanosecond timestamps.
|
||||||
|
*/
|
||||||
|
struct timeval timeval_subz(struct timeval x, struct timeval y) {
|
||||||
|
if (timeval_cmp(x, y) > 0) {
|
||||||
|
return timeval_sub(x, y);
|
||||||
|
} else {
|
||||||
|
return timeval_zero;
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,10 +16,10 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/struct/itimerval.internal.h"
|
|
||||||
#include "libc/calls/struct/timespec.h"
|
#include "libc/calls/struct/timespec.h"
|
||||||
#include "libc/calls/struct/timespec.internal.h"
|
#include "libc/calls/struct/timespec.internal.h"
|
||||||
#include "libc/calls/struct/timeval.h"
|
#include "libc/calls/struct/timeval.h"
|
||||||
|
#include "libc/calls/struct/timeval.internal.h"
|
||||||
#include "libc/intrin/strace.internal.h"
|
#include "libc/intrin/strace.internal.h"
|
||||||
#include "libc/sysv/consts/at.h"
|
#include "libc/sysv/consts/at.h"
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
#include "libc/intrin/atomic.h"
|
#include "libc/intrin/atomic.h"
|
||||||
|
#include "libc/intrin/bits.h"
|
||||||
#include "libc/intrin/cmpxchg.h"
|
#include "libc/intrin/cmpxchg.h"
|
||||||
#include "libc/intrin/directmap.internal.h"
|
#include "libc/intrin/directmap.internal.h"
|
||||||
#include "libc/intrin/kmalloc.h"
|
#include "libc/intrin/kmalloc.h"
|
||||||
|
@ -437,10 +438,7 @@ static struct AsanFault __asan_checka(const signed char *s, long ndiv8) {
|
||||||
if (UNLIKELY(!((intptr_t)s & (FRAMESIZE - 1))) && kisdangerous(s)) {
|
if (UNLIKELY(!((intptr_t)s & (FRAMESIZE - 1))) && kisdangerous(s)) {
|
||||||
return (struct AsanFault){kAsanUnmapped, s};
|
return (struct AsanFault){kAsanUnmapped, s};
|
||||||
}
|
}
|
||||||
if ((w = ((uint64_t)(255 & s[0]) << 000 | (uint64_t)(255 & s[1]) << 010 |
|
if ((w = READ64LE(s))) {
|
||||||
(uint64_t)(255 & s[2]) << 020 | (uint64_t)(255 & s[3]) << 030 |
|
|
||||||
(uint64_t)(255 & s[4]) << 040 | (uint64_t)(255 & s[5]) << 050 |
|
|
||||||
(uint64_t)(255 & s[6]) << 060 | (uint64_t)(255 & s[7]) << 070))) {
|
|
||||||
s += __asan_bsf(w) >> 3;
|
s += __asan_bsf(w) >> 3;
|
||||||
return __asan_fault(s, kAsanHeapOverrun);
|
return __asan_fault(s, kAsanHeapOverrun);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/fmt/itoa.h"
|
#include "libc/fmt/itoa.h"
|
||||||
#include "libc/intrin/describeflags.internal.h"
|
#include "libc/intrin/describeflags.internal.h"
|
||||||
|
#include "libc/sysv/consts/arch.h"
|
||||||
|
|
||||||
const char *(DescribeArchPrctlCode)(char buf[12], int x) {
|
const char *(DescribeArchPrctlCode)(char buf[12], int x) {
|
||||||
if (x == ARCH_SET_FS) return "ARCH_SET_FS";
|
if (x == ARCH_SET_FS) return "ARCH_SET_FS";
|
||||||
|
|
|
@ -24,6 +24,7 @@ const char *DescribeFrame(char[32], int);
|
||||||
const char *DescribeFutexOp(char[64], int);
|
const char *DescribeFutexOp(char[64], int);
|
||||||
const char *DescribeHow(char[12], int);
|
const char *DescribeHow(char[12], int);
|
||||||
const char *DescribeInOutInt64(char[23], ssize_t, int64_t *);
|
const char *DescribeInOutInt64(char[23], ssize_t, int64_t *);
|
||||||
|
const char *DescribeItimer(char[12], int);
|
||||||
const char *DescribeMapFlags(char[64], int);
|
const char *DescribeMapFlags(char[64], int);
|
||||||
const char *DescribeMapping(char[8], int, int);
|
const char *DescribeMapping(char[8], int, int);
|
||||||
const char *DescribeNtConsoleInFlags(char[256], uint32_t);
|
const char *DescribeNtConsoleInFlags(char[256], uint32_t);
|
||||||
|
@ -77,6 +78,7 @@ const char *DescribeWhichPrio(char[12], int);
|
||||||
#define DescribeFutexOp(x) DescribeFutexOp(alloca(64), x)
|
#define DescribeFutexOp(x) DescribeFutexOp(alloca(64), x)
|
||||||
#define DescribeHow(x) DescribeHow(alloca(12), x)
|
#define DescribeHow(x) DescribeHow(alloca(12), x)
|
||||||
#define DescribeInOutInt64(rc, x) DescribeInOutInt64(alloca(23), rc, x)
|
#define DescribeInOutInt64(rc, x) DescribeInOutInt64(alloca(23), rc, x)
|
||||||
|
#define DescribeItimer(x) DescribeItimer(alloca(12), x)
|
||||||
#define DescribeMapFlags(x) DescribeMapFlags(alloca(64), x)
|
#define DescribeMapFlags(x) DescribeMapFlags(alloca(64), x)
|
||||||
#define DescribeMapping(x, y) DescribeMapping(alloca(8), x, y)
|
#define DescribeMapping(x, y) DescribeMapping(alloca(8), x, y)
|
||||||
#define DescribeNtConsoleInFlags(x) DescribeNtConsoleInFlags(alloca(256), x)
|
#define DescribeNtConsoleInFlags(x) DescribeNtConsoleInFlags(alloca(256), x)
|
||||||
|
|
29
libc/intrin/describeitimer.c
Normal file
29
libc/intrin/describeitimer.c
Normal 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/fmt/itoa.h"
|
||||||
|
#include "libc/intrin/describeflags.internal.h"
|
||||||
|
#include "libc/sysv/consts/itimer.h"
|
||||||
|
|
||||||
|
const char *(DescribeItimer)(char buf[12], int which) {
|
||||||
|
if (which == ITIMER_REAL) return "ITIMER_REAL";
|
||||||
|
if (which == ITIMER_VIRTUAL) return "ITIMER_VIRTUAL";
|
||||||
|
if (which == ITIMER_PROF) return "ITIMER_PROF";
|
||||||
|
FormatInt32(buf, which);
|
||||||
|
return buf;
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
/*-*- 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│
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||||
│ │
|
│ │
|
||||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
│ any purpose with or without fee is hereby granted, provided that the │
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
@ -16,67 +16,26 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/fmt/conv.h"
|
#include "libc/calls/struct/itimerval.internal.h"
|
||||||
#include "libc/limits.h"
|
#include "libc/calls/struct/timeval.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/calls/struct/timeval.internal.h"
|
||||||
#include "libc/mem/gc.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/stdio/stdio.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/intrin/describeflags.internal.h"
|
||||||
#include "libc/x/x.h"
|
#include "libc/intrin/kprintf.h"
|
||||||
#include "libc/x/xasprintf.h"
|
|
||||||
|
|
||||||
float b32;
|
#define N 90
|
||||||
double b64;
|
|
||||||
long double b80;
|
|
||||||
uint32_t u32;
|
|
||||||
uint64_t u64;
|
|
||||||
int128_t x;
|
|
||||||
|
|
||||||
void int2float(const char *s) {
|
const char *(DescribeItimerval)(char buf[N], int rc,
|
||||||
x = strtoi128(s, NULL, 0);
|
const struct itimerval *it) {
|
||||||
if ((0 <= x && x <= UINT32_MAX) && !_startswith(s, "-") &&
|
if (!it) return "NULL";
|
||||||
(!_endswith(s, "l") && !_endswith(s, "L"))) {
|
if (rc == -1) return "n/a";
|
||||||
u32 = x;
|
if ((!IsAsan() && kisdangerous(it)) ||
|
||||||
memcpy(&b32, &u32, 4);
|
(IsAsan() && !__asan_is_valid(it, sizeof(*it)))) {
|
||||||
s = _gc(xdtoa(b32));
|
ksnprintf(buf, N, "%p", it);
|
||||||
if (!strchr(s, '.')) s = _gc(xasprintf("%s.", s));
|
|
||||||
s = _gc(xasprintf("%sf", s));
|
|
||||||
puts(s);
|
|
||||||
} else if ((0 <= x && x <= UINT64_MAX) && !_startswith(s, "-")) {
|
|
||||||
u64 = x;
|
|
||||||
memcpy(&b64, &u64, 8);
|
|
||||||
s = _gc(xdtoa(b64));
|
|
||||||
if (!strchr(s, '.')) s = _gc(xasprintf("%s.", s));
|
|
||||||
puts(s);
|
|
||||||
} else if ((INT32_MIN <= x && x <= 0) &&
|
|
||||||
(!_endswith(s, "l") && !_endswith(s, "L"))) {
|
|
||||||
u32 = ABS(x);
|
|
||||||
memcpy(&b32, &u32, 4);
|
|
||||||
b32 = -b32;
|
|
||||||
s = _gc(xdtoa(b32));
|
|
||||||
if (!strchr(s, '.')) s = _gc(xasprintf("%s.", s));
|
|
||||||
s = _gc(xasprintf("%sf", s));
|
|
||||||
puts(s);
|
|
||||||
} else if (INT64_MIN <= x && x <= 0) {
|
|
||||||
u64 = ABS(x);
|
|
||||||
memcpy(&b64, &u64, 8);
|
|
||||||
b64 = -b64;
|
|
||||||
s = _gc(xdtoa(b64));
|
|
||||||
if (!strchr(s, '.')) s = _gc(xasprintf("%s.", s));
|
|
||||||
puts(s);
|
|
||||||
} else {
|
} else {
|
||||||
memcpy(&b80, &x, 16);
|
ksnprintf(buf, N, "{%s, %s}", DescribeTimeval(0, &it->it_interval),
|
||||||
s = _gc(xdtoa(b80));
|
DescribeTimeval(0, &it->it_value));
|
||||||
if (!strchr(s, '.')) s = _gc(xasprintf("%s.", s));
|
|
||||||
s = _gc(xasprintf("%sL", s));
|
|
||||||
puts(s);
|
|
||||||
}
|
}
|
||||||
}
|
return buf;
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
int i;
|
|
||||||
for (i = 1; i < argc; ++i) {
|
|
||||||
int2float(argv[i]);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
|
@ -31,7 +31,6 @@ const char *(DescribeMapFlags)(char buf[64], int x) {
|
||||||
{MAP_FIXED, "FIXED"}, //
|
{MAP_FIXED, "FIXED"}, //
|
||||||
{MAP_FIXED_NOREPLACE, "FIXED_NOREPLACE"}, //
|
{MAP_FIXED_NOREPLACE, "FIXED_NOREPLACE"}, //
|
||||||
{MAP_CONCEAL, "CONCEAL"}, //
|
{MAP_CONCEAL, "CONCEAL"}, //
|
||||||
{MAP_HUGETLB, "HUGETLB"}, //
|
|
||||||
{MAP_LOCKED, "LOCKED"}, //
|
{MAP_LOCKED, "LOCKED"}, //
|
||||||
{MAP_NORESERVE, "NORESERVE"}, //
|
{MAP_NORESERVE, "NORESERVE"}, //
|
||||||
{MAP_NONBLOCK, "NONBLOCK"}, //
|
{MAP_NONBLOCK, "NONBLOCK"}, //
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
#include "libc/fmt/magnumstrs.internal.h"
|
#include "libc/fmt/magnumstrs.internal.h"
|
||||||
#include "libc/intrin/describeflags.internal.h"
|
#include "libc/intrin/describeflags.internal.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
|
#include "libc/str/str.h"
|
||||||
|
#include "libc/sysv/consts/o.h"
|
||||||
#include "libc/sysv/consts/sol.h"
|
#include "libc/sysv/consts/sol.h"
|
||||||
|
|
||||||
#define N (PAGESIZE / 2 / sizeof(struct DescribeFlags))
|
#define N (PAGESIZE / 2 / sizeof(struct DescribeFlags))
|
||||||
|
@ -29,17 +31,42 @@
|
||||||
* Describes clock_gettime() clock argument.
|
* Describes clock_gettime() clock argument.
|
||||||
*/
|
*/
|
||||||
const char *(DescribeOpenFlags)(char buf[128], int x) {
|
const char *(DescribeOpenFlags)(char buf[128], int x) {
|
||||||
char *s;
|
char *p;
|
||||||
int i, n;
|
int i, n;
|
||||||
|
const char *pipe;
|
||||||
struct DescribeFlags d[N];
|
struct DescribeFlags d[N];
|
||||||
if (x == -1) return "-1";
|
if (x == -1) return "-1";
|
||||||
// TODO(jart): unify DescribeFlags and MagnumStr data structures
|
p = buf;
|
||||||
for (n = 0; kOpenFlags[n].x != MAGNUM_TERMINATOR; ++n) {
|
switch (x & O_ACCMODE) {
|
||||||
if (n == N) notpossible;
|
case O_RDONLY:
|
||||||
|
p = stpcpy(p, "O_RDONLY");
|
||||||
|
x &= ~O_ACCMODE;
|
||||||
|
pipe = "|";
|
||||||
|
break;
|
||||||
|
case O_WRONLY:
|
||||||
|
p = stpcpy(p, "O_WRONLY");
|
||||||
|
x &= ~O_ACCMODE;
|
||||||
|
pipe = "|";
|
||||||
|
break;
|
||||||
|
case O_RDWR:
|
||||||
|
p = stpcpy(p, "O_RDWR");
|
||||||
|
x &= ~O_ACCMODE;
|
||||||
|
pipe = "|";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pipe = "";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
for (i = 0; i < n; ++i) {
|
if (x) {
|
||||||
d[i].flag = MAGNUM_NUMBER(kOpenFlags, i);
|
p = stpcpy(p, pipe);
|
||||||
d[i].name = MAGNUM_STRING(kOpenFlags, i);
|
for (n = 0; kOpenFlags[n].x != MAGNUM_TERMINATOR; ++n) {
|
||||||
|
if (n == N) notpossible;
|
||||||
|
}
|
||||||
|
for (i = 0; i < n; ++i) {
|
||||||
|
d[i].flag = MAGNUM_NUMBER(kOpenFlags, i);
|
||||||
|
d[i].name = MAGNUM_STRING(kOpenFlags, i);
|
||||||
|
}
|
||||||
|
DescribeFlags(p, 128 - (p - buf), d, n, "O_", x);
|
||||||
}
|
}
|
||||||
return DescribeFlags(buf, 128, d, n, "O_", x);
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,8 @@
|
||||||
#include "libc/intrin/kprintf.h"
|
#include "libc/intrin/kprintf.h"
|
||||||
|
|
||||||
const char *(DescribeTimeval)(char buf[45], int rc, const struct timeval *tv) {
|
const char *(DescribeTimeval)(char buf[45], int rc, const struct timeval *tv) {
|
||||||
if (rc == -1) return "n/a";
|
|
||||||
if (!tv) return "NULL";
|
if (!tv) return "NULL";
|
||||||
|
if (rc == -1) return "n/a";
|
||||||
if ((!IsAsan() && kisdangerous(tv)) ||
|
if ((!IsAsan() && kisdangerous(tv)) ||
|
||||||
(IsAsan() && !__asan_is_valid(tv, sizeof(*tv)))) {
|
(IsAsan() && !__asan_is_valid(tv, sizeof(*tv)))) {
|
||||||
ksnprintf(buf, 45, "%p", tv);
|
ksnprintf(buf, 45, "%p", tv);
|
||||||
|
|
|
@ -46,11 +46,14 @@ feclearexcept:
|
||||||
// maintain exceptions in the sse mxcsr, clear x87 exceptions
|
// maintain exceptions in the sse mxcsr, clear x87 exceptions
|
||||||
mov %edi,%ecx
|
mov %edi,%ecx
|
||||||
and $0x3f,%ecx
|
and $0x3f,%ecx
|
||||||
|
#ifndef NOX87
|
||||||
fnstsw %ax
|
fnstsw %ax
|
||||||
test %eax,%ecx
|
test %eax,%ecx
|
||||||
jz 1f
|
jz 1f
|
||||||
fnclex
|
fnclex
|
||||||
1: stmxcsr -8(%rsp)
|
1:
|
||||||
|
#endif
|
||||||
|
stmxcsr -8(%rsp)
|
||||||
and $0x3f,%eax
|
and $0x3f,%eax
|
||||||
or %eax,-8(%rsp)
|
or %eax,-8(%rsp)
|
||||||
test %ecx,-8(%rsp)
|
test %ecx,-8(%rsp)
|
||||||
|
@ -96,12 +99,16 @@ fetestexcept:
|
||||||
.ftrace2
|
.ftrace2
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
and $0x3f,%edi
|
and $0x3f,%edi
|
||||||
push %rax
|
push $0
|
||||||
stmxcsr (%rsp)
|
stmxcsr (%rsp)
|
||||||
|
#ifdef NOX87
|
||||||
|
pop %rax
|
||||||
|
#else
|
||||||
pop %rsi
|
pop %rsi
|
||||||
fnstsw %ax
|
fnstsw %ax
|
||||||
or %esi,%eax
|
or %esi,%eax
|
||||||
and %edi,%eax
|
and %edi,%eax
|
||||||
|
#endif
|
||||||
ret
|
ret
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
and w0,w0,#0x1f
|
and w0,w0,#0x1f
|
||||||
|
@ -138,10 +145,12 @@ __fesetround:
|
||||||
push %rax
|
push %rax
|
||||||
xor %eax,%eax
|
xor %eax,%eax
|
||||||
mov %edi,%ecx
|
mov %edi,%ecx
|
||||||
|
#ifndef NOX87
|
||||||
fnstcw (%rsp)
|
fnstcw (%rsp)
|
||||||
andb $0xf3,1(%rsp)
|
andb $0xf3,1(%rsp)
|
||||||
or %ch,1(%rsp)
|
or %ch,1(%rsp)
|
||||||
fldcw (%rsp)
|
fldcw (%rsp)
|
||||||
|
#endif
|
||||||
stmxcsr (%rsp)
|
stmxcsr (%rsp)
|
||||||
shl $3,%ch
|
shl $3,%ch
|
||||||
andb $0x9f,1(%rsp)
|
andb $0x9f,1(%rsp)
|
||||||
|
@ -181,7 +190,9 @@ fegetenv:
|
||||||
.ftrace2
|
.ftrace2
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
xor %eax,%eax
|
xor %eax,%eax
|
||||||
|
#ifndef NOX87
|
||||||
fnstenv (%rdi)
|
fnstenv (%rdi)
|
||||||
|
#endif
|
||||||
stmxcsr 28(%rdi)
|
stmxcsr 28(%rdi)
|
||||||
ret
|
ret
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
|
@ -200,14 +211,18 @@ fesetenv:
|
||||||
xor %eax,%eax
|
xor %eax,%eax
|
||||||
inc %rdi
|
inc %rdi
|
||||||
jz 1f
|
jz 1f
|
||||||
|
#ifndef NOX87
|
||||||
fldenv -1(%rdi)
|
fldenv -1(%rdi)
|
||||||
|
#endif
|
||||||
ldmxcsr 27(%rdi)
|
ldmxcsr 27(%rdi)
|
||||||
ret
|
ret
|
||||||
1: push %rax
|
1: push %rax
|
||||||
push %rax
|
push %rax
|
||||||
pushq $0xffff
|
pushq $0xffff
|
||||||
pushq $0x37f
|
pushq $0x37f
|
||||||
|
#ifndef NOX87
|
||||||
fldenv (%rsp)
|
fldenv (%rsp)
|
||||||
|
#endif
|
||||||
pushq $0x1f80
|
pushq $0x1f80
|
||||||
ldmxcsr (%rsp)
|
ldmxcsr (%rsp)
|
||||||
add $40,%rsp
|
add $40,%rsp
|
||||||
|
|
|
@ -35,5 +35,5 @@ double fmax(double x, double y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(fmax, fmaxl);
|
__weak_reference(fmax, fmaxl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -69,6 +69,6 @@ double scalbn(double x, int n)
|
||||||
|
|
||||||
__strong_reference(scalbn, ldexp);
|
__strong_reference(scalbn, ldexp);
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(scalbn, ldexpl);
|
__weak_reference(scalbn, ldexpl);
|
||||||
__strong_reference(scalbn, scalbnl);
|
__weak_reference(scalbn, scalbnl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
#ifndef COSMOPOLITAN_LIBC_MEM_IO_H_
|
|
||||||
#define COSMOPOLITAN_LIBC_MEM_IO_H_
|
|
||||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
|
||||||
COSMOPOLITAN_C_START_
|
|
||||||
|
|
||||||
ssize_t _copyfd(int, int, size_t);
|
|
||||||
|
|
||||||
COSMOPOLITAN_C_END_
|
|
||||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
|
||||||
#endif /* COSMOPOLITAN_LIBC_MEM_IO_H_ */
|
|
|
@ -45,6 +45,7 @@ cosmo: push %rbp
|
||||||
mov %eax,%r12d
|
mov %eax,%r12d
|
||||||
#endif /* SYSDEBUG */
|
#endif /* SYSDEBUG */
|
||||||
|
|
||||||
|
#ifndef NOX87
|
||||||
// Windows always initializes FPU to douuble precision.
|
// Windows always initializes FPU to douuble precision.
|
||||||
// WSL breaks Linux ABI by initializing FPU to double precision.
|
// WSL breaks Linux ABI by initializing FPU to double precision.
|
||||||
// This code makes long double long again.
|
// This code makes long double long again.
|
||||||
|
@ -70,6 +71,7 @@ cosmo: push %rbp
|
||||||
// d││││rr││││││
|
// d││││rr││││││
|
||||||
1: .short 0b00000000000000000001101111111
|
1: .short 0b00000000000000000001101111111
|
||||||
.previous
|
.previous
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __FAST_MATH__
|
#ifdef __FAST_MATH__
|
||||||
push %rax
|
push %rax
|
||||||
|
|
|
@ -20,24 +20,9 @@ typedef unsigned long jmp_buf[26];
|
||||||
|
|
||||||
typedef long sigjmp_buf[12];
|
typedef long sigjmp_buf[12];
|
||||||
|
|
||||||
extern char **environ; /* CRT */
|
extern char **environ;
|
||||||
extern int __argc; /* CRT */
|
extern char *program_invocation_name;
|
||||||
extern char **__argv; /* CRT */
|
extern char *program_invocation_short_name;
|
||||||
extern char **__envp; /* CRT */
|
|
||||||
extern unsigned long *__auxv; /* CRT */
|
|
||||||
extern intptr_t __oldstack; /* CRT */
|
|
||||||
extern uint64_t __nosync; /* SYS */
|
|
||||||
extern int __strace; /* SYS */
|
|
||||||
extern int __ftrace; /* SYS */
|
|
||||||
extern char *program_invocation_name; /* RII */
|
|
||||||
extern char *program_invocation_short_name; /* RII */
|
|
||||||
extern uint64_t __syscount; /* RII */
|
|
||||||
extern uint64_t kStartTsc; /* RII */
|
|
||||||
extern char kTmpPath[]; /* RII */
|
|
||||||
extern const char kNtSystemDirectory[]; /* RII */
|
|
||||||
extern const char kNtWindowsDirectory[]; /* RII */
|
|
||||||
extern size_t __virtualmax;
|
|
||||||
extern bool __isworker;
|
|
||||||
|
|
||||||
void mcount(void);
|
void mcount(void);
|
||||||
int daemon(int, int);
|
int daemon(int, int);
|
||||||
|
@ -83,6 +68,21 @@ int sethostname(const char *, size_t);
|
||||||
int acct(const char *);
|
int acct(const char *);
|
||||||
|
|
||||||
#ifdef COSMO
|
#ifdef COSMO
|
||||||
|
extern int __argc;
|
||||||
|
extern char **__argv;
|
||||||
|
extern char **__envp;
|
||||||
|
extern unsigned long *__auxv;
|
||||||
|
extern intptr_t __oldstack;
|
||||||
|
extern uint64_t __nosync;
|
||||||
|
extern int __strace;
|
||||||
|
extern int __ftrace;
|
||||||
|
extern uint64_t __syscount;
|
||||||
|
extern uint64_t kStartTsc;
|
||||||
|
extern char kTmpPath[];
|
||||||
|
extern const char kNtSystemDirectory[];
|
||||||
|
extern const char kNtWindowsDirectory[];
|
||||||
|
extern size_t __virtualmax;
|
||||||
|
extern bool __isworker;
|
||||||
/* utilities */
|
/* utilities */
|
||||||
void _intsort(int *, size_t);
|
void _intsort(int *, size_t);
|
||||||
void _longsort(long *, size_t);
|
void _longsort(long *, size_t);
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/nexgen32e/msr.internal.h"
|
#include "libc/nexgen32e/msr.internal.h"
|
||||||
#include "libc/nt/thread.h"
|
#include "libc/nt/thread.h"
|
||||||
|
#include "libc/sysv/consts/arch.h"
|
||||||
#include "libc/thread/tls.h"
|
#include "libc/thread/tls.h"
|
||||||
#include "libc/thread/tls2.h"
|
#include "libc/thread/tls2.h"
|
||||||
|
|
||||||
|
@ -60,8 +61,10 @@ textstartup void __set_tls(struct CosmoTib *tib) {
|
||||||
: "c"(MSR_IA32_FS_BASE), "a"((uint32_t)val),
|
: "c"(MSR_IA32_FS_BASE), "a"((uint32_t)val),
|
||||||
"d"((uint32_t)(val >> 32)));
|
"d"((uint32_t)(val >> 32)));
|
||||||
}
|
}
|
||||||
#else
|
#elif defined(__aarch64__)
|
||||||
register long x28 asm("x28") = (long)tib;
|
register long x28 asm("x28") = (long)tib;
|
||||||
asm volatile("" : "+r"(x28));
|
asm volatile("" : "+r"(x28));
|
||||||
|
#else
|
||||||
|
#error "unsupported architecture"
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -231,14 +231,11 @@ syscon mmap MAP_LOCKED 0x00002000 0x00002000 0 0 0 0 0 0
|
||||||
syscon mmap MAP_NORESERVE 0x00004000 0x00004000 0x00000040 0x00000040 0 0 0x00000040 0 # Linux calls it "reserve"; NT calls it "commit"? which is default?
|
syscon mmap MAP_NORESERVE 0x00004000 0x00004000 0x00000040 0x00000040 0 0 0x00000040 0 # Linux calls it "reserve"; NT calls it "commit"? which is default?
|
||||||
syscon mmap MAP_POPULATE 0x00008000 0x00008000 0 0 0x00040000 0 0 0 # MAP_PREFAULT_READ on FreeBSD; can avoid madvise(MADV_WILLNEED) on private file mapping
|
syscon mmap MAP_POPULATE 0x00008000 0x00008000 0 0 0x00040000 0 0 0 # MAP_PREFAULT_READ on FreeBSD; can avoid madvise(MADV_WILLNEED) on private file mapping
|
||||||
syscon mmap MAP_NONBLOCK 0x00010000 0x00010000 0 0 0 0 0 0
|
syscon mmap MAP_NONBLOCK 0x00010000 0x00010000 0 0 0 0 0 0
|
||||||
syscon mmap MAP_HUGETLB 0x00040000 0x00040000 0 0 0 0 0 0x80000000 # kNtSecLargePages
|
|
||||||
syscon mmap MAP_SYNC 0x00080000 0x00080000 0 0 0 0 0 0 # perform synchronous page faults for mapping (Linux 4.15+)
|
syscon mmap MAP_SYNC 0x00080000 0x00080000 0 0 0 0 0 0 # perform synchronous page faults for mapping (Linux 4.15+)
|
||||||
syscon mmap MAP_INHERIT -1 -1 -1 -1 -1 -1 0x00000080 -1 # make it inherit across execve()
|
syscon mmap MAP_INHERIT -1 -1 -1 -1 -1 -1 0x00000080 -1 # make it inherit across execve()
|
||||||
syscon mmap MAP_HASSEMAPHORE 0 0 0x00000200 0x00000200 0x00000200 0 0x00000200 0 # does it matter on x86?
|
syscon mmap MAP_HASSEMAPHORE 0 0 0x00000200 0x00000200 0x00000200 0 0x00000200 0 # does it matter on x86?
|
||||||
syscon mmap MAP_NOSYNC 0 0 0 0 0x00000800 0 0 0 # flush to physical media only when necessary rather than gratuitously; be sure to use write() rather than ftruncate() with this!
|
syscon mmap MAP_NOSYNC 0 0 0 0 0x00000800 0 0 0 # flush to physical media only when necessary rather than gratuitously; be sure to use write() rather than ftruncate() with this!
|
||||||
syscon mmap MAP_CONCEAL 0 0 0 0 0x00020000 0x00008000 0x00008000 0 # omit from core dumps; MAP_NOCORE on FreeBSD
|
syscon mmap MAP_CONCEAL 0 0 0 0 0x00020000 0x00008000 0x00008000 0 # omit from core dumps; MAP_NOCORE on FreeBSD
|
||||||
syscon mmap MAP_HUGE_MASK 63 63 0 0 0 0 0 0
|
|
||||||
syscon mmap MAP_HUGE_SHIFT 26 26 0 0 0 0 0 0
|
|
||||||
syscon compat MAP_NOCORE 0 0 0 0 0x00020000 0x00008000 0x00008000 0 # use MAP_CONCEAL
|
syscon compat MAP_NOCORE 0 0 0 0 0x00020000 0x00008000 0x00008000 0 # use MAP_CONCEAL
|
||||||
syscon compat MAP_ANON 0x00000020 0x00000020 0x00001000 0x00001000 0x00001000 0x00001000 0x00001000 0x00000020 # bsd consensus; faked nt
|
syscon compat MAP_ANON 0x00000020 0x00000020 0x00001000 0x00001000 0x00001000 0x00001000 0x00001000 0x00000020 # bsd consensus; faked nt
|
||||||
syscon compat MAP_EXECUTABLE 0x00001000 0x00001000 0 0 0 0 0 0 # ignored
|
syscon compat MAP_EXECUTABLE 0x00001000 0x00001000 0 0 0 0 0 0 # ignored
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon mmap,MAP_HUGETLB,0x00040000,0x00040000,0,0,0,0,0,0x80000000
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon mmap,MAP_HUGE_MASK,63,63,0,0,0,0,0,0
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon mmap,MAP_HUGE_SHIFT,26,26,0,0,0,0,0,0
|
|
9
libc/sysv/consts/arch.h
Normal file
9
libc/sysv/consts/arch.h
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_ARCH_H_
|
||||||
|
#define COSMOPOLITAN_LIBC_SYSV_CONSTS_ARCH_H_
|
||||||
|
|
||||||
|
#define ARCH_SET_GS 0x1001
|
||||||
|
#define ARCH_SET_FS 0x1002
|
||||||
|
#define ARCH_GET_FS 0x1003
|
||||||
|
#define ARCH_GET_GS 0x1004
|
||||||
|
|
||||||
|
#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_ARCH_H_ */
|
|
@ -13,9 +13,6 @@ extern const int MAP_FILE;
|
||||||
extern const int MAP_FIXED;
|
extern const int MAP_FIXED;
|
||||||
extern const int MAP_FIXED_NOREPLACE;
|
extern const int MAP_FIXED_NOREPLACE;
|
||||||
extern const int MAP_HASSEMAPHORE;
|
extern const int MAP_HASSEMAPHORE;
|
||||||
extern const int MAP_HUGETLB;
|
|
||||||
extern const int MAP_HUGE_MASK;
|
|
||||||
extern const int MAP_HUGE_SHIFT;
|
|
||||||
extern const int MAP_INHERIT;
|
extern const int MAP_INHERIT;
|
||||||
extern const int MAP_LOCKED;
|
extern const int MAP_LOCKED;
|
||||||
extern const int MAP_NONBLOCK;
|
extern const int MAP_NONBLOCK;
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/mem/copyfd.internal.h"
|
|
||||||
#include "libc/sysv/consts/o.h"
|
#include "libc/sysv/consts/o.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
||||||
|
@ -34,7 +33,7 @@ void testlib_extract(const char *zip, const char *to, int mode) {
|
||||||
int fdin, fdout;
|
int fdin, fdout;
|
||||||
ASSERT_NE(-1, (fdin = open(zip, O_RDONLY)));
|
ASSERT_NE(-1, (fdin = open(zip, O_RDONLY)));
|
||||||
ASSERT_NE(-1, (fdout = creat(to, mode)));
|
ASSERT_NE(-1, (fdout = creat(to, mode)));
|
||||||
ASSERT_NE(-1, _copyfd(fdin, fdout, -1));
|
ASSERT_NE(-1, copyfd(fdin, fdout, -1));
|
||||||
ASSERT_NE(-1, close(fdout));
|
ASSERT_NE(-1, close(fdout));
|
||||||
ASSERT_NE(-1, close(fdin));
|
ASSERT_NE(-1, close(fdin));
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,5 +143,5 @@ double acos(double x)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(acos, acosl);
|
__weak_reference(acos, acosl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -55,5 +55,5 @@ double acosh(double x)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(acosh, acoshl);
|
__weak_reference(acosh, acoshl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -149,5 +149,5 @@ double asin(double x)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(asin, asinl);
|
__weak_reference(asin, asinl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -66,5 +66,5 @@ double asinh(double x)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(asinh, asinhl);
|
__weak_reference(asinh, asinhl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -156,5 +156,5 @@ double atan(double x)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(atan, atanl);
|
__weak_reference(atan, atanl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -155,5 +155,5 @@ atan2(double y, double x)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(atan2, atan2l);
|
__weak_reference(atan2, atan2l);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -66,5 +66,5 @@ double atanh(double x)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(atanh, atanhl);
|
__weak_reference(atanh, atanhl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -27,5 +27,5 @@ double cabs(double complex z) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(cabs, cabsl);
|
__weak_reference(cabs, cabsl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -45,5 +45,5 @@ double complex cacosh(double complex z)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(cacosh, cacoshl);
|
__weak_reference(cacosh, cacoshl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,5 +24,5 @@ double carg(double complex z) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(carg, cargl);
|
__weak_reference(carg, cargl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -52,5 +52,5 @@ double complex casin(double complex z)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(casin, casinl);
|
__weak_reference(casin, casinl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -147,5 +147,5 @@ double complex catan(double complex z)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(catan, catanl);
|
__weak_reference(catan, catanl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -32,5 +32,5 @@ double copysign(double x, double y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(copysign, copysignl);
|
__weak_reference(copysign, copysignl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -122,5 +122,5 @@ double cos(double x)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(cos, cosl);
|
__weak_reference(cos, cosl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -76,3 +76,7 @@ double cosh(double x)
|
||||||
t = __expo2(x, 1.0);
|
t = __expo2(x, 1.0);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
|
__weak_reference(cosh, coshl);
|
||||||
|
#endif
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/math.h"
|
#include "libc/math.h"
|
||||||
#include "libc/tinymath/freebsd.internal.h"
|
#include "libc/tinymath/freebsd.internal.h"
|
||||||
|
#if !(LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024)
|
||||||
|
|
||||||
asm(".ident\t\"\\n\\n\
|
asm(".ident\t\"\\n\\n\
|
||||||
FreeBSD libm (BSD-2 License)\\n\
|
FreeBSD libm (BSD-2 License)\\n\
|
||||||
|
@ -155,3 +156,5 @@ coshl(long double x)
|
||||||
/* |x| > o_threshold, cosh(x) overflow */
|
/* |x| > o_threshold, cosh(x) overflow */
|
||||||
RETURNI(huge*huge);
|
RETURNI(huge*huge);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* long double is long */
|
||||||
|
|
|
@ -170,5 +170,5 @@ double exp(double x)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(exp, expl);
|
__weak_reference(exp, expl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -57,5 +57,6 @@ double exp10(double x)
|
||||||
|
|
||||||
__strong_reference(exp10, pow10);
|
__strong_reference(exp10, pow10);
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(exp10, exp10l);
|
__weak_reference(exp10, exp10l);
|
||||||
|
__weak_reference(exp10, pow10l);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -57,6 +57,6 @@ long double exp10l(long double x)
|
||||||
return powl(10.0, x);
|
return powl(10.0, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
__strong_reference(exp10l, pow10l);
|
__weak_reference(exp10l, pow10l);
|
||||||
|
|
||||||
#endif /* long double is long */
|
#endif /* long double is long */
|
||||||
|
|
|
@ -157,5 +157,5 @@ double exp2(double x)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(exp2, exp2l);
|
__weak_reference(exp2, exp2l);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -238,5 +238,5 @@ double expm1(double x)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(expm1, expm1l);
|
__weak_reference(expm1, expm1l);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,5 +31,5 @@ double fabs(double x) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(fabs, fabsl);
|
__weak_reference(fabs, fabsl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -27,5 +27,5 @@ double fdim(double x, double y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(fdim, fdiml);
|
__weak_reference(fdim, fdiml);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -96,5 +96,5 @@ double floor(double x)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(floor, floorl);
|
__weak_reference(floor, floorl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -35,5 +35,5 @@ double fmin(double x, double y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(fmin, fminl);
|
__weak_reference(fmin, fminl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -103,3 +103,7 @@ double fmod(double x, double y)
|
||||||
ux.i = uxi;
|
ux.i = uxi;
|
||||||
return ux.f;
|
return ux.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
|
__weak_reference(fmod, fmodl);
|
||||||
|
#endif
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/math.h"
|
#include "libc/math.h"
|
||||||
#include "libc/tinymath/ldshape.internal.h"
|
#include "libc/tinymath/ldshape.internal.h"
|
||||||
|
#if !(LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024)
|
||||||
|
|
||||||
asm(".ident\t\"\\n\\n\
|
asm(".ident\t\"\\n\\n\
|
||||||
Musl libc (MIT License)\\n\
|
Musl libc (MIT License)\\n\
|
||||||
|
@ -34,10 +35,13 @@ Copyright 2005-2014 Rich Felker, et. al.\"");
|
||||||
asm(".include \"libc/disclaimer.inc\"");
|
asm(".include \"libc/disclaimer.inc\"");
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does (𝑥 rem 𝑦) w/ round()-style rounding.
|
||||||
|
* @return remainder ∈ (-|𝑦|,|𝑦|) in %xmm0
|
||||||
|
* @define 𝑥-trunc(𝑥/𝑦)*𝑦
|
||||||
|
*/
|
||||||
long double fmodl(long double x, long double y) {
|
long double fmodl(long double x, long double y) {
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
|
||||||
return fmod(x, y);
|
|
||||||
#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
|
|
||||||
union ldshape ux = {x}, uy = {y};
|
union ldshape ux = {x}, uy = {y};
|
||||||
int ex = ux.i.se & 0x7fff;
|
int ex = ux.i.se & 0x7fff;
|
||||||
int ey = uy.i.se & 0x7fff;
|
int ey = uy.i.se & 0x7fff;
|
||||||
|
@ -135,3 +139,5 @@ long double fmodl(long double x, long double y) {
|
||||||
#error "architecture unsupported"
|
#error "architecture unsupported"
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* long double is long */
|
||||||
|
|
|
@ -58,5 +58,5 @@ double frexp(double x, int *e)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(frexp, frexpl);
|
__weak_reference(frexp, frexpl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -101,5 +101,5 @@ double hypot(double x, double y)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(hypot, hypotl);
|
__weak_reference(hypot, hypotl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -63,5 +63,5 @@ int ilogb(double x)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(ilogb, ilogbl);
|
__weak_reference(ilogb, ilogbl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,88 +0,0 @@
|
||||||
/*-*- 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"
|
|
||||||
#include "libc/tinymath/internal.h"
|
|
||||||
#include "libc/tinymath/ldshape.internal.h"
|
|
||||||
#if !(LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024)
|
|
||||||
|
|
||||||
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 log₂𝑥 exponent part of double.
|
|
||||||
*/
|
|
||||||
int ilogbl(long double x)
|
|
||||||
{
|
|
||||||
#if LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
|
|
||||||
// #pragma STDC FENV_ACCESS ON
|
|
||||||
union ldshape u = {x};
|
|
||||||
uint64_t m = u.i.m;
|
|
||||||
int e = u.i.se & 0x7fff;
|
|
||||||
|
|
||||||
if (!e) {
|
|
||||||
if (m == 0) {
|
|
||||||
FORCE_EVAL(0/0.0f);
|
|
||||||
return FP_ILOGB0;
|
|
||||||
}
|
|
||||||
/* subnormal x */
|
|
||||||
for (e = -0x3fff+1; m>>63 == 0; e--, m<<=1);
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
if (e == 0x7fff) {
|
|
||||||
FORCE_EVAL(0/0.0f);
|
|
||||||
return m<<1 ? FP_ILOGBNAN : INT_MAX;
|
|
||||||
}
|
|
||||||
return e - 0x3fff;
|
|
||||||
#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
|
|
||||||
// #pragma STDC FENV_ACCESS ON
|
|
||||||
union ldshape u = {x};
|
|
||||||
int e = u.i.se & 0x7fff;
|
|
||||||
|
|
||||||
if (!e) {
|
|
||||||
if (x == 0) {
|
|
||||||
FORCE_EVAL(0/0.0f);
|
|
||||||
return FP_ILOGB0;
|
|
||||||
}
|
|
||||||
/* subnormal x */
|
|
||||||
x *= 0x1p120;
|
|
||||||
return ilogbl(x) - 120;
|
|
||||||
}
|
|
||||||
if (e == 0x7fff) {
|
|
||||||
FORCE_EVAL(0/0.0f);
|
|
||||||
u.i.se = 0;
|
|
||||||
return u.f ? FP_ILOGBNAN : INT_MAX;
|
|
||||||
}
|
|
||||||
return e - 0x3fff;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* long double is long */
|
|
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/math.h"
|
#include "libc/math.h"
|
||||||
#include "libc/tinymath/kernel.internal.h"
|
#include "libc/tinymath/kernel.internal.h"
|
||||||
|
#if !(LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024)
|
||||||
|
|
||||||
asm(".ident\t\"\\n\\n\
|
asm(".ident\t\"\\n\\n\
|
||||||
FreeBSD libm (BSD-2 License)\\n\
|
FreeBSD libm (BSD-2 License)\\n\
|
||||||
|
@ -183,3 +184,5 @@ long double __tanl(long double x, long double y, int odd) {
|
||||||
#else
|
#else
|
||||||
#error "architecture unsupported"
|
#error "architecture unsupported"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif /* long double is long */
|
||||||
|
|
|
@ -142,5 +142,5 @@ double log(double x)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(log, logl);
|
__weak_reference(log, logl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -143,5 +143,5 @@ double log10(double x)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(log10, log10l);
|
__weak_reference(log10, log10l);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -161,5 +161,5 @@ double log1p(double x)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(log1p, log1pl);
|
__weak_reference(log1p, log1pl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -159,5 +159,5 @@ double log2(double x)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(log2, log2l);
|
__weak_reference(log2, log2l);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -23,3 +23,7 @@ double logb(double x) {
|
||||||
if (!x) return -1 / (x * x);
|
if (!x) return -1 / (x * x);
|
||||||
return ilogb(x);
|
return ilogb(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
|
__weak_reference(logb, logbl);
|
||||||
|
#endif
|
||||||
|
|
|
@ -45,8 +45,8 @@ __weak_reference(lrint, llrint);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(lrint, lrintl);
|
__weak_reference(lrint, lrintl);
|
||||||
#if __SIZEOF_LONG__ == __SIZEOF_LONG_LONG__
|
#if __SIZEOF_LONG__ == __SIZEOF_LONG_LONG__
|
||||||
__strong_reference(lrint, llrintl);
|
__weak_reference(lrint, llrintl);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -26,5 +26,5 @@ long lround(double x) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(lround, lroundl);
|
__weak_reference(lround, lroundl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -33,6 +33,9 @@ Copyright 2005-2014 Rich Felker, et. al.\"");
|
||||||
asm(".include \"libc/disclaimer.inc\"");
|
asm(".include \"libc/disclaimer.inc\"");
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns fractional part of 𝑥.
|
||||||
|
*/
|
||||||
double modf(double x, double *iptr)
|
double modf(double x, double *iptr)
|
||||||
{
|
{
|
||||||
union {double f; uint64_t i;} u = {x};
|
union {double f; uint64_t i;} u = {x};
|
||||||
|
@ -65,3 +68,7 @@ double modf(double x, double *iptr)
|
||||||
*iptr = u.f;
|
*iptr = u.f;
|
||||||
return x - u.f;
|
return x - u.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
|
__weak_reference(modf, modfl);
|
||||||
|
#endif
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
│ │
|
│ │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/math.h"
|
#include "libc/math.h"
|
||||||
|
#if !(LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024)
|
||||||
|
|
||||||
asm(".ident\t\"\\n\\n\
|
asm(".ident\t\"\\n\\n\
|
||||||
Musl libc (MIT License)\\n\
|
Musl libc (MIT License)\\n\
|
||||||
|
@ -33,20 +34,11 @@ Copyright 2005-2014 Rich Felker, et. al.\"");
|
||||||
asm(".include \"libc/disclaimer.inc\"");
|
asm(".include \"libc/disclaimer.inc\"");
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
|
||||||
long double modfl(long double x, long double *iptr)
|
|
||||||
{
|
|
||||||
double d;
|
|
||||||
long double r;
|
|
||||||
|
|
||||||
r = modf(x, &d);
|
|
||||||
*iptr = d;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
|
|
||||||
|
|
||||||
static const long double toint = 1/LDBL_EPSILON;
|
static const long double toint = 1/LDBL_EPSILON;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns fractional part of 𝑥.
|
||||||
|
*/
|
||||||
long double modfl(long double x, long double *iptr)
|
long double modfl(long double x, long double *iptr)
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
|
@ -90,6 +82,4 @@ long double modfl(long double x, long double *iptr)
|
||||||
return -y;
|
return -y;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#endif /* long double is long */
|
||||||
#error "architecture unsupported"
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -42,5 +42,5 @@ double nearbyint(double x) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(nearbyint, nearbyintl);
|
__weak_reference(nearbyint, nearbyintl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -65,5 +65,5 @@ double nextafter(double x, double y)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(nextafter, nextafterl);
|
__weak_reference(nextafter, nextafterl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -381,5 +381,5 @@ double pow(double x, double y)
|
||||||
|
|
||||||
__weak_reference(pow, __pow_finite);
|
__weak_reference(pow, __pow_finite);
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(pow, powl);
|
__weak_reference(pow, powl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -28,5 +28,5 @@ double remainder(double x, double y) {
|
||||||
|
|
||||||
__strong_reference(remainder, drem);
|
__strong_reference(remainder, drem);
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(remainder, remainderl);
|
__weak_reference(remainder, remainderl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -225,3 +225,7 @@ medium:
|
||||||
y[1] = ty[1];
|
y[1] = ty[1];
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
|
__weak_reference(__rem_pio2, __rem_pio2l);
|
||||||
|
#endif
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "libc/math.h"
|
#include "libc/math.h"
|
||||||
#include "libc/tinymath/kernel.internal.h"
|
#include "libc/tinymath/kernel.internal.h"
|
||||||
#include "libc/tinymath/ldshape.internal.h"
|
#include "libc/tinymath/ldshape.internal.h"
|
||||||
|
#if !(LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024)
|
||||||
|
|
||||||
asm(".ident\t\"\\n\\n\
|
asm(".ident\t\"\\n\\n\
|
||||||
FreeBSD libm (BSD-2 License)\\n\
|
FreeBSD libm (BSD-2 License)\\n\
|
||||||
|
@ -200,3 +201,5 @@ int __rem_pio2l(long double x, long double *y)
|
||||||
#else
|
#else
|
||||||
#error "architecture unsupported"
|
#error "architecture unsupported"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif /* long double is long */
|
||||||
|
|
|
@ -117,5 +117,5 @@ end:
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(remquo, remquol);
|
__weak_reference(remquo, remquol);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -66,5 +66,5 @@ double rint(double x)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(rint, rintl);
|
__weak_reference(rint, rintl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -92,5 +92,5 @@ double round(double x)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(round, roundl);
|
__weak_reference(round, roundl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -26,5 +26,5 @@ double scalbln(double x, long n) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(scalbln, scalblnl);
|
__weak_reference(scalbln, scalblnl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -26,5 +26,5 @@ double significand(double x) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(significand, significandl);
|
__weak_reference(significand, significandl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -123,5 +123,5 @@ double sin(double x)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(sin, sinl);
|
__weak_reference(sin, sinl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -114,5 +114,5 @@ void sincos(double x, double *sin, double *cos)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(sincos, sincosl);
|
__weak_reference(sincos, sincosl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -75,3 +75,7 @@ double sinh(double x)
|
||||||
t = __expo2(absx, 2*h);
|
t = __expo2(absx, 2*h);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
|
__weak_reference(sinh, sinhl);
|
||||||
|
#endif
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include "libc/intrin/likely.h"
|
#include "libc/intrin/likely.h"
|
||||||
#include "libc/math.h"
|
#include "libc/math.h"
|
||||||
#include "libc/tinymath/freebsd.internal.h"
|
#include "libc/tinymath/freebsd.internal.h"
|
||||||
|
#if !(LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024)
|
||||||
|
|
||||||
asm(".ident\t\"\\n\\n\
|
asm(".ident\t\"\\n\\n\
|
||||||
FreeBSD libm (BSD-2 License)\\n\
|
FreeBSD libm (BSD-2 License)\\n\
|
||||||
|
@ -154,3 +155,5 @@ sinhl(long double x)
|
||||||
/* |x| > o_threshold, sinh(x) overflow */
|
/* |x| > o_threshold, sinh(x) overflow */
|
||||||
return x*shuge;
|
return x*shuge;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* long double is long */
|
||||||
|
|
|
@ -222,5 +222,5 @@ double sqrt(double x)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(sqrt, sqrtl);
|
__weak_reference(sqrt, sqrtl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -115,5 +115,5 @@ double tan(double x)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
__strong_reference(tan, tanl);
|
__weak_reference(tan, tanl);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -76,3 +76,7 @@ double tanh(double x)
|
||||||
}
|
}
|
||||||
return sign ? -t : t;
|
return sign ? -t : t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||||
|
__weak_reference(tanh, tanhl);
|
||||||
|
#endif
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue