Add chibicc
This program popped up on Hacker News recently. It's the only modern compiler I've ever seen that doesn't have dependencies and is easily modified. So I added all of the missing GNU extensions I like to use which means it might be possible soon to build on non-Linux and have third party not vendor gcc binaries.main
parent
e44a0cf6f8
commit
8da931a7f6
8
Makefile
8
Makefile
|
@ -115,7 +115,6 @@ include third_party/dlmalloc/dlmalloc.mk # │
|
|||
include libc/mem/mem.mk # │
|
||||
include libc/ohmyplus/ohmyplus.mk # │
|
||||
include libc/zipos/zipos.mk # │
|
||||
include third_party/dtoa/dtoa.mk # │
|
||||
include third_party/gdtoa/gdtoa.mk # │
|
||||
include libc/time/time.mk # │
|
||||
include libc/alg/alg.mk # │
|
||||
|
@ -140,6 +139,7 @@ include libc/dns/dns.mk # │
|
|||
include libc/crypto/crypto.mk # │
|
||||
include net/http/http.mk #─┘
|
||||
include third_party/chibicc/chibicc.mk
|
||||
include third_party/chibicc/test/test.mk
|
||||
include third_party/lemon/lemon.mk
|
||||
include third_party/linenoise/linenoise.mk
|
||||
include third_party/editline/editline.mk
|
||||
|
@ -160,13 +160,11 @@ include tool/build/emucrt/emucrt.mk
|
|||
include tool/build/emubin/emubin.mk
|
||||
include tool/build/build.mk
|
||||
include tool/calc/calc.mk
|
||||
include tool/tags/tags.mk
|
||||
include tool/decode/lib/decodelib.mk
|
||||
include tool/decode/decode.mk
|
||||
include tool/hash/hash.mk
|
||||
include tool/net/net.mk
|
||||
include tool/viz/viz.mk
|
||||
include tool/cc/cc.mk
|
||||
include tool/tool.mk
|
||||
include test/libc/alg/test.mk
|
||||
include test/libc/tinymath/test.mk
|
||||
|
@ -278,7 +276,7 @@ COSMOPOLITAN_OBJECTS = \
|
|||
LIBC_ZIPOS \
|
||||
THIRD_PARTY_COMPILER_RT \
|
||||
THIRD_PARTY_DLMALLOC \
|
||||
THIRD_PARTY_DTOA \
|
||||
THIRD_PARTY_GDTOA \
|
||||
THIRD_PARTY_GETOPT \
|
||||
THIRD_PARTY_MUSL \
|
||||
THIRD_PARTY_REGEX
|
||||
|
@ -311,7 +309,7 @@ COSMOPOLITAN_HEADERS = \
|
|||
LIBC_X \
|
||||
LIBC_ZIPOS \
|
||||
THIRD_PARTY_DLMALLOC \
|
||||
THIRD_PARTY_DTOA \
|
||||
THIRD_PARTY_GDTOA \
|
||||
THIRD_PARTY_GETOPT \
|
||||
THIRD_PARTY_MUSL \
|
||||
THIRD_PARTY_REGEX
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
void apmoff(void) noreturn;
|
||||
void apmoff(void) wontreturn;
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* APE_LIB_APM_H_ */
|
||||
|
|
|
@ -197,7 +197,7 @@ struct IdtDescriptor {
|
|||
|
||||
struct thatispacked PageTable {
|
||||
uint64_t p[512];
|
||||
} aligned(PAGESIZE);
|
||||
} forcealign(PAGESIZE);
|
||||
|
||||
extern struct PageTable g_pml4t;
|
||||
extern struct GlobalDescriptorTable gdt;
|
||||
|
@ -211,7 +211,7 @@ extern struct SmapEntry e820map_xlm[XLM_E820_SIZE / sizeof(struct SmapEntry)];
|
|||
extern uint64_t g_ptsp;
|
||||
extern uint64_t g_ptsp_xlm;
|
||||
|
||||
void bootdr(char drive) noreturn;
|
||||
void bootdr(char drive) wontreturn;
|
||||
|
||||
void smapsort(struct SmapEntry *);
|
||||
uint64_t *__getpagetableentry(int64_t, unsigned, struct PageTable *,
|
||||
|
|
|
@ -138,7 +138,7 @@ CONFIG_CCFLAGS += \
|
|||
-fno-align-loops
|
||||
|
||||
TARGET_ARCH ?= \
|
||||
-march=k8-sse3
|
||||
-msse3
|
||||
|
||||
endif
|
||||
|
||||
|
|
|
@ -266,7 +266,7 @@ struct plm_audio_t {
|
|||
float D[1024];
|
||||
float V[1024];
|
||||
float U[32];
|
||||
} aligned(64);
|
||||
} forcealign(64);
|
||||
|
||||
typedef plm_audio_t plm_audio_t;
|
||||
|
||||
|
|
|
@ -77,12 +77,12 @@ struct plm_samples_t {
|
|||
double time;
|
||||
unsigned int count;
|
||||
#ifdef PLM_AUDIO_SEPARATE_CHANNELS
|
||||
float left[PLM_AUDIO_SAMPLES_PER_FRAME] aligned(32);
|
||||
float right[PLM_AUDIO_SAMPLES_PER_FRAME] aligned(32);
|
||||
float left[PLM_AUDIO_SAMPLES_PER_FRAME] forcealign(32);
|
||||
float right[PLM_AUDIO_SAMPLES_PER_FRAME] forcealign(32);
|
||||
#else
|
||||
float interleaved[PLM_AUDIO_SAMPLES_PER_FRAME * 2] aligned(32);
|
||||
float interleaved[PLM_AUDIO_SAMPLES_PER_FRAME * 2] forcealign(32);
|
||||
#endif
|
||||
} aligned(32);
|
||||
} forcealign(32);
|
||||
|
||||
typedef struct plm_samples_t plm_samples_t;
|
||||
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "third_party/dtoa/dtoa.h"
|
||||
#include "tool/viz/lib/knobs.h"
|
||||
|
||||
/**
|
||||
|
|
|
@ -611,8 +611,8 @@ static struct Pick PickBlockUnicodeAnsi(struct TtyRgb tl, struct TtyRgb tr,
|
|||
struct TtyRgb bl2 = GetQuant(bl);
|
||||
struct TtyRgb br2 = GetQuant(br);
|
||||
unsigned i, p1, p2;
|
||||
uint16_t picks1[96] aligned(32);
|
||||
uint16_t picks2[32] aligned(32);
|
||||
uint16_t picks1[96] forcealign(32);
|
||||
uint16_t picks2[32] forcealign(32);
|
||||
memset(picks1, 0x79, sizeof(picks1));
|
||||
memset(picks2, 0x79, sizeof(picks2));
|
||||
PickUnicode(picks1, tl, tr, bl, br, tl2, tr2, bl2, br2);
|
||||
|
@ -625,7 +625,7 @@ static struct Pick PickBlockUnicodeAnsi(struct TtyRgb tl, struct TtyRgb tr,
|
|||
static struct Pick PickBlockUnicodeTrue(struct TtyRgb tl, struct TtyRgb tr,
|
||||
struct TtyRgb bl, struct TtyRgb br) {
|
||||
unsigned i;
|
||||
uint16_t picks[96] aligned(32);
|
||||
uint16_t picks[96] forcealign(32);
|
||||
memset(picks, 0x79, sizeof(picks));
|
||||
PickUnicode(picks, tl, tr, bl, br, tl, tr, bl, br);
|
||||
i = windex(picks, 96);
|
||||
|
@ -648,8 +648,8 @@ static struct Pick PickBlockCp437Ansi(struct TtyRgb tl, struct TtyRgb tr,
|
|||
struct TtyRgb bl2 = GetQuant(bl);
|
||||
struct TtyRgb br2 = GetQuant(br);
|
||||
unsigned i, p1, p2;
|
||||
uint16_t picks1[32] aligned(32);
|
||||
uint16_t picks2[32] aligned(32);
|
||||
uint16_t picks1[32] forcealign(32);
|
||||
uint16_t picks2[32] forcealign(32);
|
||||
memset(picks1, 0x79, sizeof(picks1));
|
||||
memset(picks2, 0x79, sizeof(picks2));
|
||||
PickCp437(picks1, tl, tr, bl, br, tl2, tr2, bl2, br2);
|
||||
|
@ -662,7 +662,7 @@ static struct Pick PickBlockCp437Ansi(struct TtyRgb tl, struct TtyRgb tr,
|
|||
static struct Pick PickBlockCp437True(struct TtyRgb tl, struct TtyRgb tr,
|
||||
struct TtyRgb bl, struct TtyRgb br) {
|
||||
unsigned i;
|
||||
uint16_t picks[32] aligned(32);
|
||||
uint16_t picks[32] forcealign(32);
|
||||
memset(picks, 0x79, sizeof(picks));
|
||||
PickCp437(picks, tl, tr, bl, br, tl, tr, bl, br);
|
||||
return kPicksCp437[windex(picks, 32)];
|
||||
|
|
|
@ -42,7 +42,7 @@ FLAGS\n\
|
|||
int flags;
|
||||
bool force;
|
||||
|
||||
noreturn void PrintUsage(int rc, FILE *f) {
|
||||
wontreturn void PrintUsage(int rc, FILE *f) {
|
||||
fprintf(f, "%s%s%s", "Usage: ", program_invocation_name, USAGE);
|
||||
exit(rc);
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ EXAMPLES_DIRECTDEPS = \
|
|||
LIBC_ZIPOS \
|
||||
THIRD_PARTY_COMPILER_RT \
|
||||
THIRD_PARTY_DLMALLOC \
|
||||
THIRD_PARTY_DTOA \
|
||||
THIRD_PARTY_GDTOA \
|
||||
THIRD_PARTY_GETOPT \
|
||||
THIRD_PARTY_MUSL \
|
||||
THIRD_PARTY_STB \
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/time/time.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "third_party/dtoa/dtoa.h"
|
||||
#include "third_party/gdtoa/gdtoa.h"
|
||||
|
||||
/**
|
||||
* @fileoverview Measure CPU clock mystery constants.
|
||||
|
@ -52,15 +52,18 @@ long double GetSample(void) {
|
|||
|
||||
void MeasureNanosecondsPerAlwaysRunningTimerCycle(void) {
|
||||
int i;
|
||||
long double avg, samp;
|
||||
long double avg, samp, elapsed;
|
||||
start_ = now();
|
||||
for (i = 1, avg = 1.0L; !isdone_; ++i) {
|
||||
samp = GetSample();
|
||||
avg += (samp - avg) / i;
|
||||
dsleep(kInterval);
|
||||
printf("1c = %sns (last=%sns spent=%ss)\n", g_fmt(dtoabuf_[0], (double)avg),
|
||||
g_fmt(dtoabuf_[1], (double)samp),
|
||||
g_fmt(dtoabuf_[2], (double)(now() - start_)));
|
||||
elapsed = now() - start_;
|
||||
g_xfmt_p(dtoabuf_[0], &avg, 15, 32, 0);
|
||||
g_xfmt_p(dtoabuf_[1], &samp, 15, 32, 0);
|
||||
g_xfmt_p(dtoabuf_[2], &elapsed, 15, 32, 0);
|
||||
printf("1c = %sns (last=%sns spent=%ss)\n", dtoabuf_[0], dtoabuf_[1],
|
||||
dtoabuf_[2]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1774,7 +1774,7 @@ Press enter to continue without sound: ",
|
|||
for (;;) CPU::Op();
|
||||
}
|
||||
|
||||
noreturn void PrintUsage(int rc, FILE* f) {
|
||||
wontreturn void PrintUsage(int rc, FILE* f) {
|
||||
fprintf(f, "%s%s%s", "Usage: ", program_invocation_name, USAGE);
|
||||
exit(rc);
|
||||
}
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/bits/safemacros.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/time/time.h"
|
||||
#include "third_party/dtoa/dtoa.h"
|
||||
|
||||
char dtoabuf_[3][32];
|
||||
|
||||
static long double avg;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
long double t2, t1 = nowl();
|
||||
dsleep(0.3);
|
||||
for (;;) {
|
||||
t2 = nowl();
|
||||
printf("%s %s avg=%s\n", g_fmt(dtoabuf_[0], t2),
|
||||
g_fmt(dtoabuf_[1], t2 - t1), g_fmt(dtoabuf_[2], avg));
|
||||
t1 = t2;
|
||||
dsleep(0.3);
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -141,7 +141,7 @@
|
|||
#include "libc/sysv/consts/rlim.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/sysv/consts/w.h"
|
||||
#include "third_party/dtoa/dtoa.h"
|
||||
#include "third_party/gdtoa/gdtoa.h"
|
||||
#include "third_party/musl/passwd.h"
|
||||
|
||||
#undef CEOF
|
||||
|
@ -1602,7 +1602,7 @@ static inline void sigclearmask(void) {
|
|||
* just do a longjmp to the exception handler. The type of exception is
|
||||
* stored in the global variable "exception".
|
||||
*/
|
||||
noreturn static void exraise(int e) {
|
||||
wontreturn static void exraise(int e) {
|
||||
if (vforked) _exit(exitstatus);
|
||||
INTOFF;
|
||||
exception = e;
|
||||
|
@ -1617,7 +1617,7 @@ noreturn static void exraise(int e) {
|
|||
* are held using the INTOFF macro. (The test for iflag is just
|
||||
* defensive programming.)
|
||||
*/
|
||||
noreturn static void onint(void) {
|
||||
wontreturn static void onint(void) {
|
||||
intpending = 0;
|
||||
sigclearmask();
|
||||
if (!(rootshell && iflag)) {
|
||||
|
@ -1896,20 +1896,20 @@ printfesque(1) static void sh_warnx(const char *fmt, ...) {
|
|||
* is not NULL then error prints an error message using printf style
|
||||
* formatting. It then raises the error exception.
|
||||
*/
|
||||
noreturn static void exverror(int cond, const char *msg, va_list ap) {
|
||||
wontreturn static void exverror(int cond, const char *msg, va_list ap) {
|
||||
exvwarning(msg, ap);
|
||||
flushall();
|
||||
exraise(cond);
|
||||
}
|
||||
|
||||
noreturn static void exerror(int cond, const char *msg, ...) {
|
||||
wontreturn static void exerror(int cond, const char *msg, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
exverror(cond, msg, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
noreturn static void sh_error(const char *msg, ...) {
|
||||
wontreturn static void sh_error(const char *msg, ...) {
|
||||
va_list ap;
|
||||
exitstatus = 2;
|
||||
va_start(ap, msg);
|
||||
|
@ -1917,16 +1917,16 @@ noreturn static void sh_error(const char *msg, ...) {
|
|||
va_end(ap);
|
||||
}
|
||||
|
||||
noreturn static void badnum(const char *s) {
|
||||
wontreturn static void badnum(const char *s) {
|
||||
sh_error(illnum, s);
|
||||
}
|
||||
|
||||
noreturn static void synerror(const char *msg) {
|
||||
wontreturn static void synerror(const char *msg) {
|
||||
errlinno = plinno;
|
||||
sh_error("Syntax error: %s", msg);
|
||||
}
|
||||
|
||||
noreturn static void yyerror(const char *s) {
|
||||
wontreturn static void yyerror(const char *s) {
|
||||
sh_error("arithmetic expression: %s: \"%s\"", s, arith_startbuf);
|
||||
}
|
||||
|
||||
|
@ -1935,7 +1935,7 @@ noreturn static void yyerror(const char *s) {
|
|||
* argument is the token that is expected, or -1 if more than one type
|
||||
* of token can occur at this point.
|
||||
*/
|
||||
noreturn static void synexpect(int token) {
|
||||
wontreturn static void synexpect(int token) {
|
||||
char msg[64];
|
||||
if (token >= 0) {
|
||||
fmtstr(msg, 64, "%s unexpected (expecting %s)", tokname[lasttoken], tokname[token]);
|
||||
|
@ -1945,7 +1945,7 @@ noreturn static void synexpect(int token) {
|
|||
synerror(msg);
|
||||
}
|
||||
|
||||
noreturn static void varunset(const char *end, const char *var_, const char *umsg, int varflags) {
|
||||
wontreturn static void varunset(const char *end, const char *var_, const char *umsg, int varflags) {
|
||||
const char *msg;
|
||||
const char *tail;
|
||||
tail = nullstr;
|
||||
|
@ -2096,7 +2096,7 @@ static char *nodesavestr(s) char *s;
|
|||
return rtn;
|
||||
}
|
||||
|
||||
noreturn static void shellexec(char **, const char *, int);
|
||||
wontreturn static void shellexec(char **, const char *, int);
|
||||
static char **listvars(int, int, char ***);
|
||||
static char *argstr(char *p, int flag);
|
||||
static char *conv_escape(char *, int *);
|
||||
|
@ -3175,7 +3175,7 @@ out:
|
|||
return exitstatus;
|
||||
}
|
||||
|
||||
noreturn static void evaltreenr(union node *n, int flags) {
|
||||
wontreturn static void evaltreenr(union node *n, int flags) {
|
||||
evaltree(n, flags);
|
||||
abort();
|
||||
}
|
||||
|
@ -3876,7 +3876,7 @@ static int eprintlist(struct output *out, struct strlist *sp, int sep) {
|
|||
* Exec a program. Never returns. If you change this routine, you may
|
||||
* have to change the find_command routine as well.
|
||||
*/
|
||||
noreturn static void shellexec(char **argv, const char *path, int idx) {
|
||||
wontreturn static void shellexec(char **argv, const char *path, int idx) {
|
||||
char *cmdname;
|
||||
int e;
|
||||
char **envp;
|
||||
|
@ -9316,7 +9316,7 @@ static void setinteractive(int on) {
|
|||
/*
|
||||
* Called to exit the shell.
|
||||
*/
|
||||
noreturn static void exitshell(void) {
|
||||
wontreturn static void exitshell(void) {
|
||||
struct jmploc loc;
|
||||
char *p;
|
||||
savestatus = exitstatus;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
void __assert_fail(const char *, const char *, int) hidden noreturn relegated;
|
||||
void __assert_fail(const char *, const char *, int) hidden wontreturn relegated;
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define __ASSERT_FAIL(EXPR, FILE, LINE)
|
||||
|
|
|
@ -45,7 +45,7 @@ COSMOPOLITAN_C_START_
|
|||
|
||||
struct AtomicFlag {
|
||||
uint32_t __cacheline[16]; /* Intel V.O §9.4.6 */
|
||||
} aligned(64);
|
||||
} forcealign(64);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -7,9 +7,9 @@ typedef float __m256 _Vector_size(32) mayalias;
|
|||
typedef double __m256d _Vector_size(32) mayalias;
|
||||
typedef long long __m256i _Vector_size(32) mayalias;
|
||||
|
||||
typedef float __m256_u _Vector_size(32) aligned(1) mayalias;
|
||||
typedef double __m256d_u _Vector_size(32) aligned(1) mayalias;
|
||||
typedef long long __m256i_u _Vector_size(32) aligned(1) mayalias;
|
||||
typedef float __m256_u _Vector_size(32) forcealign(1) mayalias;
|
||||
typedef double __m256d_u _Vector_size(32) forcealign(1) mayalias;
|
||||
typedef long long __m256i_u _Vector_size(32) forcealign(1) mayalias;
|
||||
|
||||
typedef double __v4df _Vector_size(32);
|
||||
typedef float __v8sf _Vector_size(32);
|
||||
|
|
|
@ -16,12 +16,12 @@ typedef short __v8hi _Vector_size(16);
|
|||
typedef unsigned short __v8hu _Vector_size(16);
|
||||
|
||||
typedef double __v2df _Vector_size(16);
|
||||
typedef double __m128d _Vector_size(16) aligned(16);
|
||||
typedef double __m128d_u _Vector_size(16) aligned(1);
|
||||
typedef double __m128d _Vector_size(16) forcealign(16);
|
||||
typedef double __m128d_u _Vector_size(16) forcealign(1);
|
||||
|
||||
typedef long long __v2di _Vector_size(16);
|
||||
typedef long long __m128i _Vector_size(16) aligned(16);
|
||||
typedef long long __m128i_u _Vector_size(16) aligned(1);
|
||||
typedef long long __m128i _Vector_size(16) forcealign(16);
|
||||
typedef long long __m128i_u _Vector_size(16) forcealign(1);
|
||||
typedef unsigned long long __v2du _Vector_size(16);
|
||||
|
||||
struct thatispacked mayalias __usi128ma {
|
||||
|
|
|
@ -35,8 +35,8 @@
|
|||
typedef int __v4si _Vector_size(16);
|
||||
typedef unsigned int __v4su _Vector_size(16);
|
||||
typedef float __v4sf _Vector_size(16);
|
||||
typedef float __m128 _Vector_size(16) aligned(16) mayalias;
|
||||
typedef float __m128_u _Vector_size(16) aligned(1) mayalias;
|
||||
typedef float __m128 _Vector_size(16) forcealign(16) mayalias;
|
||||
typedef float __m128_u _Vector_size(16) forcealign(1) mayalias;
|
||||
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § it's a trap! » sse » simd ops ─╬─│┼
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
|
@ -33,12 +34,18 @@
|
|||
* function. The stat() function may be used to differentiate them.
|
||||
*/
|
||||
bool fileexists(const char *path) {
|
||||
/* TODO(jart): Use fast path on NT? */
|
||||
int rc, olderr;
|
||||
struct stat st;
|
||||
int olderr = errno;
|
||||
int rc = stat(path, &st);
|
||||
if (rc == -1 && (errno == ENOENT || errno == ENOTDIR)) {
|
||||
errno = olderr;
|
||||
uint16_t path16[PATH_MAX];
|
||||
if (!IsWindows()) {
|
||||
olderr = errno;
|
||||
rc = stat(path, &st);
|
||||
if (rc == -1 && (errno == ENOENT || errno == ENOTDIR)) {
|
||||
errno = olderr;
|
||||
}
|
||||
return rc != -1;
|
||||
} else {
|
||||
if (__mkntpath(path, path16) == -1) return -1;
|
||||
return GetFileAttributes(path16) != -1u;
|
||||
}
|
||||
return rc != -1;
|
||||
}
|
||||
|
|
|
@ -34,8 +34,8 @@
|
|||
textwindows int fstat$nt(int64_t handle, struct stat *st) {
|
||||
int filetype;
|
||||
uint64_t actualsize;
|
||||
struct NtByHandleFileInformation wst;
|
||||
struct NtFileCompressionInfo fci;
|
||||
struct NtByHandleFileInformation wst;
|
||||
if (GetFileInformationByHandle(handle, &wst)) {
|
||||
memset(st, 0, sizeof(*st));
|
||||
filetype = GetFileType(handle);
|
||||
|
|
|
@ -198,12 +198,12 @@ i32 tunefd$sysv(i32, i32, i32, i32) hidden;
|
|||
u32 fprot2nt(i32, i32) hidden;
|
||||
u32 prot2nt(i32, i32) privileged;
|
||||
void __restore_rt() hidden;
|
||||
void __sigenter$xnu(void *, i32, i32, void *, void *) hidden noreturn;
|
||||
void __sigenter$xnu(void *, i32, i32, void *, void *) hidden wontreturn;
|
||||
int utimensat$xnu(int, const char *, const struct timespec *, int) hidden;
|
||||
int nanosleep$xnu(const struct timespec *, struct timespec *) hidden;
|
||||
void stat2linux(void *) hidden;
|
||||
void xnutrampoline(void *, i32, i32, const struct __darwin_siginfo *,
|
||||
const struct __darwin_ucontext *) hidden noreturn;
|
||||
const struct __darwin_ucontext *) hidden wontreturn;
|
||||
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § syscalls » windows nt » veneers ─╬─│┼
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
* @asyncsignalsafe
|
||||
*/
|
||||
bool32 isatty(int fd) {
|
||||
char buf[sizeof(uint16_t) * 4] aligned(2);
|
||||
char buf[sizeof(uint16_t) * 4] forcealign(2);
|
||||
if (!IsWindows()) {
|
||||
return ioctl$sysv(fd, TIOCGWINSZ, &buf) != -1;
|
||||
} else {
|
||||
|
|
|
@ -14,7 +14,7 @@ struct sigaction { /* cosmo abi */
|
|||
void (*sa_restorer)(void);
|
||||
struct sigset sa_mask;
|
||||
int64_t __pad;
|
||||
} aligned(8);
|
||||
} forcealign(8);
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_H_ */
|
||||
|
|
|
@ -49,7 +49,7 @@ struct siginfo {
|
|||
};
|
||||
char __ignoreme[128 - 2 * sizeof(int32_t) - sizeof(int64_t)];
|
||||
};
|
||||
} aligned(8);
|
||||
} forcealign(8);
|
||||
|
||||
typedef struct siginfo siginfo_t;
|
||||
|
||||
|
|
|
@ -425,9 +425,9 @@ static void xnussefpustate2linux(struct FpuState *fs,
|
|||
memcpy(fs->st, &xnufs->__fpu_stmm0, (8 + 16) * sizeof(uint128_t));
|
||||
}
|
||||
|
||||
noreturn void xnutrampoline(void *fn, int infostyle, int sig,
|
||||
const struct __darwin_siginfo *xnuinfo,
|
||||
const struct __darwin_ucontext *xnuctx) {
|
||||
wontreturn void xnutrampoline(void *fn, int infostyle, int sig,
|
||||
const struct __darwin_siginfo *xnuinfo,
|
||||
const struct __darwin_ucontext *xnuctx) {
|
||||
/* note: this function impl can't access static memory */
|
||||
intptr_t ax;
|
||||
struct Goodies {
|
||||
|
|
|
@ -97,7 +97,7 @@ double RoundDecimalPlaces(double, double, double (*)(double));
|
|||
#endif
|
||||
|
||||
#ifndef __STRICT_ANSI__
|
||||
intmax_t __imaxabs(intmax_t) asm("imaxabs") libcesque pureconst;
|
||||
intmax_t __imaxabs(intmax_t) libcesque pureconst;
|
||||
#define imaxabs(x) __imaxabs(x)
|
||||
#endif /* !ANSI */
|
||||
|
||||
|
|
|
@ -20,6 +20,6 @@
|
|||
#include "libc/conv/conv.h"
|
||||
#include "libc/macros.h"
|
||||
|
||||
intmax_t imaxabs(intmax_t x) {
|
||||
intmax_t(imaxabs)(intmax_t x) {
|
||||
return ABS(x);
|
||||
}
|
||||
|
|
|
@ -18,16 +18,7 @@
|
|||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
.source __FILE__
|
||||
|
||||
/ Avoid dtoa needing .data section.
|
||||
.bss
|
||||
.align 4
|
||||
dtoa_divmax:
|
||||
.zero 4
|
||||
.endobj dtoa_divmax,globl
|
||||
.previous
|
||||
|
||||
.init.start 202,_init_dtoa_divmax
|
||||
movb $2,dtoa_divmax(%rip)
|
||||
.init.end 202,_init_dtoa_divmax
|
||||
__imaxabs:
|
||||
jmp imaxabs
|
||||
.endfn __imaxabs,globl
|
|
@ -37,10 +37,10 @@
|
|||
* @see strtoumax
|
||||
*/
|
||||
intmax_t strtoimax(const char *s, char **endptr, int base) {
|
||||
bool neg;
|
||||
uintmax_t x;
|
||||
intmax_t res;
|
||||
unsigned diglet, bits;
|
||||
bool neg, islong, isunsigned;
|
||||
|
||||
x = 0;
|
||||
bits = 0;
|
||||
|
@ -104,8 +104,6 @@ intmax_t strtoimax(const char *s, char **endptr, int base) {
|
|||
}
|
||||
}
|
||||
|
||||
if ((isunsigned = *s == 'u' || *s == 'U')) s++;
|
||||
if ((islong = *s == 'l' || *s == 'L')) s++;
|
||||
if (endptr) *endptr = s;
|
||||
|
||||
if (neg) {
|
||||
|
@ -114,13 +112,5 @@ intmax_t strtoimax(const char *s, char **endptr, int base) {
|
|||
res = x;
|
||||
}
|
||||
|
||||
if (isunsigned) {
|
||||
if (islong) {
|
||||
res = (uint64_t)res;
|
||||
} else {
|
||||
res = (uint32_t)res;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ COSMOPOLITAN_C_START_
|
|||
Performance (New Hardware) ~20 ns ~40 ns ~400 ns
|
||||
Performance (Old Hardware) ~400 ns ~40 ns ~400 ns */
|
||||
|
||||
typedef uint32_t aes_block_t _Vector_size(16) aligned(16);
|
||||
typedef uint32_t aes_block_t _Vector_size(16) forcealign(16);
|
||||
|
||||
struct Rijndael {
|
||||
union {
|
||||
|
@ -47,8 +47,8 @@ aes_block_t unrijndael(uint32_t, aes_block_t, const struct Rijndael *);
|
|||
│ cosmopolitan § cryptography » implementation details ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
extern const uint8_t kAesSbox[256] aligned(64);
|
||||
extern const uint8_t kAesSboxInverse[256] aligned(64);
|
||||
extern const uint8_t kAesSbox[256] forcealign(64);
|
||||
extern const uint8_t kAesSboxInverse[256] forcealign(64);
|
||||
|
||||
aes_block_t InvMixColumns(aes_block_t) hidden;
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#define COSMOPOLITAN_LIBC_FMT_PFLINK_H_
|
||||
#include "libc/dce.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
#ifndef __STRICT_ANSI__
|
||||
#if !defined(__STRICT_ANSI__) && !defined(__chibicc__)
|
||||
|
||||
/**
|
||||
* @fileoverview builtin+preprocessor+linker tricks for printf/scanf.
|
||||
|
@ -65,6 +65,19 @@
|
|||
#else
|
||||
#define PFLINK(FMT) FMT
|
||||
#define SFLINK(FMT) FMT
|
||||
asm(".pushsection .yoink\n\t"
|
||||
"nop\tntoa(%rip)\n\t"
|
||||
"nop\tftoa(%rip)\n\t"
|
||||
"nop\tkCp437(%rip)\n\t"
|
||||
"nop\tstrerror(%rip)\n\t"
|
||||
"nop\tstrnwidth(%rip)\n\t"
|
||||
"nop\tstrnwidth16(%rip)\n\t"
|
||||
"nop\twcsnwidth(%rip)\n\t"
|
||||
"nop\tmalloc(%rip)\n\t"
|
||||
"nop\tcalloc(%rip)\n\t"
|
||||
"nop\tfree_s(%rip)\n\t"
|
||||
"nop\t__grow(%rip)\n\t"
|
||||
".popsection");
|
||||
#endif /* __STRICT_ANSI__ */
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_FMT_PFLINK_H_ */
|
||||
|
|
|
@ -2,6 +2,14 @@
|
|||
#define __attribute__(x)
|
||||
#endif
|
||||
|
||||
#ifndef __cplusplus
|
||||
#define COSMOPOLITAN_C_START_
|
||||
#define COSMOPOLITAN_C_END_
|
||||
#define COSMOPOLITAN_CXX_START_
|
||||
#define COSMOPOLITAN_CXX_END_
|
||||
#define COSMOPOLITAN_CXX_USING_
|
||||
#endif
|
||||
|
||||
#if defined(__STRICT_ANSI__) && __STDC_VERSION__ + 0 < 201112
|
||||
#define asm __asm__
|
||||
#endif
|
||||
|
@ -67,18 +75,6 @@
|
|||
} while (0)
|
||||
#endif
|
||||
|
||||
#if defined(__STRICT_ANSI__) || \
|
||||
(!defined(__GNUC__) && !__has_builtin(constant_p) && \
|
||||
!defined(__builtin_constant_p))
|
||||
#define __builtin_constant_p(x) 0
|
||||
#endif
|
||||
|
||||
#if defined(__STRICT_ANSI__) || \
|
||||
(!defined(__GNUC__) && !__has_builtin(choose_expr) && \
|
||||
!defined(__builtin_choose_expr))
|
||||
#define __builtin_choose_expr(x, a, b) ((x) ? (long)(a) : (long)(b))
|
||||
#endif
|
||||
|
||||
#if __STDC_VERSION__ + 0 < 201112
|
||||
#define ____Static_assert(x, y) A##B
|
||||
#define ___Static_assert(x, y) ____Static_assert(x, y)
|
||||
|
@ -195,7 +191,7 @@ typedef int64_t intmax_t;
|
|||
typedef uint64_t uintmax_t;
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#ifndef __chibicc__
|
||||
#define va_list __builtin_va_list
|
||||
#define va_arg(ap, type) __builtin_va_arg(ap, type)
|
||||
#define va_copy(dest, src) __builtin_va_copy(dest, src)
|
||||
|
@ -230,11 +226,11 @@ typedef uint64_t uintmax_t;
|
|||
/**
|
||||
* Aligns automatic or static variable.
|
||||
*/
|
||||
#ifndef aligned
|
||||
#ifndef forcealign
|
||||
#ifndef __STRICT_ANSI__
|
||||
#define aligned(bytes) __attribute__((__aligned__(bytes)))
|
||||
#define forcealign(bytes) __attribute__((__aligned__(bytes)))
|
||||
#else
|
||||
#define aligned(bytes)
|
||||
#define forcealign(bytes)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -291,13 +287,13 @@ typedef uint64_t uintmax_t;
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef noreturn
|
||||
#ifndef wontreturn
|
||||
#if !defined(__STRICT_ANSI__) && \
|
||||
(__has_attribute(__noreturn__) || \
|
||||
(__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 208)
|
||||
#define noreturn __attribute__((__noreturn__))
|
||||
#define wontreturn __attribute__((__noreturn__))
|
||||
#else
|
||||
#define noreturn
|
||||
#define wontreturn
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -1067,13 +1063,5 @@ typedef uint64_t uintmax_t;
|
|||
STATIC_YOINK_SOURCE(__BASE_FILE__);
|
||||
#endif
|
||||
|
||||
#ifndef __cplusplus
|
||||
#define COSMOPOLITAN_CXX_START_
|
||||
#define COSMOPOLITAN_CXX_END_
|
||||
#define COSMOPOLITAN_CXX_USING_
|
||||
#define COSMOPOLITAN_C_START_
|
||||
#define COSMOPOLITAN_C_END_
|
||||
#endif
|
||||
|
||||
#define MACHINE_CODE_ANALYSIS_BEGIN_
|
||||
#define MACHINE_CODE_ANALYSIS_END_
|
||||
|
|
|
@ -1,50 +1,17 @@
|
|||
typedef struct {
|
||||
unsigned int gp_offset;
|
||||
unsigned int fp_offset;
|
||||
void *overflow_arg_area;
|
||||
void *reg_save_area;
|
||||
} __va_elem;
|
||||
|
||||
typedef __va_elem va_list[1];
|
||||
|
||||
#define va_start(ap, last) \
|
||||
do { \
|
||||
*(ap) = *(__va_elem *)__va_area__; \
|
||||
} while (0)
|
||||
|
||||
#define va_end(ap)
|
||||
|
||||
static inline void *__va_arg_mem(__va_elem *ap, int sz, int align) {
|
||||
void *p = ap->overflow_arg_area;
|
||||
if (align > 8) p = (void *)(((unsigned long)p + 15) / 16 * 16);
|
||||
ap->overflow_arg_area = (void *)(((unsigned long)p + sz + 7) / 8 * 8);
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline void *__va_arg_gp(__va_elem *ap, int sz, int align) {
|
||||
if (ap->gp_offset >= 48) return __va_arg_mem(ap, sz, align);
|
||||
void *r = ap->reg_save_area + ap->gp_offset;
|
||||
ap->gp_offset += 8;
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline void *__va_arg_fp(__va_elem *ap, int sz, int align) {
|
||||
if (ap->fp_offset >= 112) return __va_arg_mem(ap, sz, align);
|
||||
void *r = ap->reg_save_area + ap->fp_offset;
|
||||
ap->fp_offset += 8;
|
||||
return r;
|
||||
}
|
||||
|
||||
#define va_arg(ap, ty) \
|
||||
({ \
|
||||
int klass = __builtin_reg_class(ty); \
|
||||
*(ty *)(klass == 0 \
|
||||
? __va_arg_gp(ap, sizeof(ty), _Alignof(ty)) \
|
||||
: klass == 1 ? __va_arg_fp(ap, sizeof(ty), _Alignof(ty)) \
|
||||
: __va_arg_mem(ap, sizeof(ty), _Alignof(ty))); \
|
||||
})
|
||||
|
||||
#define va_copy(dest, src) ((dest)[0] = (src)[0])
|
||||
#include "libc/runtime/valist.h"
|
||||
|
||||
#define __GNUC_VA_LIST 1
|
||||
typedef va_list __gnuc_va_list;
|
||||
#define __gnuc_va_list va_list
|
||||
|
||||
#define va_end(AP)
|
||||
#define va_copy(DST, SRC) ((DST)[0] = (SRC)[0])
|
||||
#define va_start(AP, LAST) \
|
||||
do { \
|
||||
*(AP) = *(struct __va *)__va_area__; \
|
||||
} while (0)
|
||||
|
||||
#define va_arg(AP, TYPE) \
|
||||
(*(TYPE *)__va_arg(AP, sizeof(TYPE), _Alignof(TYPE), \
|
||||
__builtin_reg_class(TYPE)))
|
||||
|
||||
typedef struct __va va_list[1];
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#if defined(__x86_64__) && !defined(__STRICT_ANSI__)
|
||||
|
||||
typedef char __intrin_xmm_t _Vector_size(16) aligned(16) mayalias;
|
||||
typedef char __intrin_xmm_t _Vector_size(16) forcealign(16) mayalias;
|
||||
|
||||
#define INTRIN_SSEVEX_X_X_X_(PURE, ISA, OP, FLAGS, A, B, C) \
|
||||
do { \
|
||||
|
|
|
@ -5,12 +5,12 @@
|
|||
|
||||
#define PTHREAD_ONCE_INIT 0
|
||||
|
||||
#define PTHREAD_MUTEX_NORMAL 0
|
||||
#define PTHREAD_MUTEX_DEFAULT 0
|
||||
#define PTHREAD_MUTEX_RECURSIVE 1
|
||||
#define PTHREAD_MUTEX_NORMAL 0
|
||||
#define PTHREAD_MUTEX_DEFAULT 0
|
||||
#define PTHREAD_MUTEX_RECURSIVE 1
|
||||
#define PTHREAD_MUTEX_ERRORCHECK 2
|
||||
#define PTHREAD_MUTEX_STALLED 0
|
||||
#define PTHREAD_MUTEX_ROBUST 1
|
||||
#define PTHREAD_MUTEX_STALLED 0
|
||||
#define PTHREAD_MUTEX_ROBUST 1
|
||||
|
||||
/* clang-format off */
|
||||
#define PTHREAD_MUTEX_INITIALIZER {{{0}}}
|
||||
|
@ -65,7 +65,7 @@ typedef struct {
|
|||
} __u;
|
||||
} pthread_rwlock_t;
|
||||
|
||||
noreturn void pthread_exit(void *);
|
||||
wontreturn void pthread_exit(void *);
|
||||
pureconst pthread_t pthread_self(void);
|
||||
int pthread_create(pthread_t *, const pthread_attr_t *, void *(*)(void *),
|
||||
void *);
|
||||
|
|
|
@ -110,13 +110,13 @@
|
|||
#define PWSTR WCHAR*
|
||||
#define PZPWSTR PWSTR*
|
||||
#define PCZPWSTR CONST PWSTR*
|
||||
#define LPUWSTR WCHAR aligned(1)*
|
||||
#define PUWSTR WCHAR aligned(1)*
|
||||
#define LPUWSTR WCHAR forcealign(1)*
|
||||
#define PUWSTR WCHAR forcealign(1)*
|
||||
#define LPCWSTR CONST WCHAR*
|
||||
#define PCWSTR CONST WCHAR*
|
||||
#define PZPCWSTR PCWSTR*
|
||||
#define LPCUWSTR CONST WCHAR aligned(1)*
|
||||
#define PCUWSTR CONST WCHAR aligned(1)*
|
||||
#define LPCUWSTR CONST WCHAR forcealign(1)*
|
||||
#define PCUWSTR CONST WCHAR forcealign(1)*
|
||||
#define PCHAR CHAR*
|
||||
#define LPCH CHAR*
|
||||
#define PCH CHAR*
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
forceinline noreturn long LinuxExit(long rc) {
|
||||
forceinline wontreturn long LinuxExit(long rc) {
|
||||
asm volatile("syscall"
|
||||
: /* no outputs */
|
||||
: "a"(0xE7), "D"(rc)
|
||||
|
|
|
@ -147,7 +147,7 @@ static const char *__asan_describe_access_poison(int c) {
|
|||
}
|
||||
}
|
||||
|
||||
static noreturn void __asan_die(const char *msg, size_t size) {
|
||||
static wontreturn void __asan_die(const char *msg, size_t size) {
|
||||
write(STDERR_FILENO, msg, size);
|
||||
__die();
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ static char *__asan_report_start(char *p) {
|
|||
return stpcpy(p, ": ");
|
||||
}
|
||||
|
||||
static noreturn void __asan_report_deallocate_fault(void *addr, int c) {
|
||||
static wontreturn void __asan_report_deallocate_fault(void *addr, int c) {
|
||||
char *p, ibuf[21], buf[256];
|
||||
p = __asan_report_start(buf);
|
||||
p = stpcpy(p, __asan_dscribe_free_poison(c));
|
||||
|
@ -175,8 +175,8 @@ static noreturn void __asan_report_deallocate_fault(void *addr, int c) {
|
|||
__asan_die(buf, p - buf);
|
||||
}
|
||||
|
||||
static noreturn void __asan_report_memory_fault(uint8_t *addr, int size,
|
||||
const char *kind) {
|
||||
static wontreturn void __asan_report_memory_fault(uint8_t *addr, int size,
|
||||
const char *kind) {
|
||||
char *p, ibuf[21], buf[256];
|
||||
p = __asan_report_start(buf);
|
||||
p = stpcpy(p, __asan_describe_access_poison(*(char *)SHADOW((intptr_t)addr)));
|
||||
|
|
|
@ -8,23 +8,23 @@ COSMOPOLITAN_C_START_
|
|||
│ cosmopolitan § logging » berkeley logger ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
void err(int, const char *, ...) printfesque(2) noreturn;
|
||||
void errx(int, const char *, ...) printfesque(2) noreturn;
|
||||
void verr(int, const char *, va_list) paramsnonnull((3)) noreturn;
|
||||
void verrx(int, const char *, va_list) paramsnonnull((3)) noreturn;
|
||||
void err(int, const char *, ...) printfesque(2) wontreturn;
|
||||
void errx(int, const char *, ...) printfesque(2) wontreturn;
|
||||
void verr(int, const char *, va_list) paramsnonnull((3)) wontreturn;
|
||||
void verrx(int, const char *, va_list) paramsnonnull((3)) wontreturn;
|
||||
void vwarn(const char *, va_list) paramsnonnull((2));
|
||||
void vwarnx(const char *, va_list) paramsnonnull((2));
|
||||
void warn(const char *, ...) printfesque(1);
|
||||
void warnx(const char *, ...) printfesque(1);
|
||||
|
||||
#define err(EVAL, FMT, ...) (err)(EVAL, PFLINK(FMT), ##__VA_ARGS__)
|
||||
#define err(EVAL, FMT, ...) (err)(EVAL, PFLINK(FMT), ##__VA_ARGS__)
|
||||
#define errx(EVAL, FMT, ...) (errx)(EVAL, PFLINK(FMT), ##__VA_ARGS__)
|
||||
#define verr(EVAL, FMT, VA) (verr)(EVAL, PFLINK(FMT), VA)
|
||||
#define verr(EVAL, FMT, VA) (verr)(EVAL, PFLINK(FMT), VA)
|
||||
#define verrx(EVAL, FMT, VA) (verrx)(EVAL, PFLINK(FMT), VA)
|
||||
#define vwarn(FMT, VA) (vwarn)(PFLINK(FMT), VA)
|
||||
#define vwarnx(FMT, VA) (vwarnx)(PFLINK(FMT), VA)
|
||||
#define warn(FMT, ...) (warn)(PFLINK(FMT), ##__VA_ARGS__)
|
||||
#define warnx(FMT, ...) (warn)(PFLINK(FMT), ##__VA_ARGS__)
|
||||
#define vwarn(FMT, VA) (vwarn)(PFLINK(FMT), VA)
|
||||
#define vwarnx(FMT, VA) (vwarnx)(PFLINK(FMT), VA)
|
||||
#define warn(FMT, ...) (warn)(PFLINK(FMT), ##__VA_ARGS__)
|
||||
#define warnx(FMT, ...) (warn)(PFLINK(FMT), ##__VA_ARGS__)
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -84,15 +84,15 @@ COSMOPOLITAN_C_START_
|
|||
|
||||
void __check_fail(const char *, const char *, uint64_t, const char *, uint64_t,
|
||||
const char *, const char *, int, const char *,
|
||||
...) relegated noreturn;
|
||||
...) relegated wontreturn;
|
||||
|
||||
void __check_fail_eq(uint64_t, uint64_t) relegated noreturn;
|
||||
void __check_fail_ne(uint64_t, uint64_t) relegated noreturn;
|
||||
void __check_fail_le(uint64_t, uint64_t) relegated noreturn;
|
||||
void __check_fail_lt(uint64_t, uint64_t) relegated noreturn;
|
||||
void __check_fail_ge(uint64_t, uint64_t) relegated noreturn;
|
||||
void __check_fail_gt(uint64_t, uint64_t) relegated noreturn;
|
||||
void __check_fail_aligned(unsigned, uint64_t) relegated noreturn;
|
||||
void __check_fail_eq(uint64_t, uint64_t) relegated wontreturn;
|
||||
void __check_fail_ne(uint64_t, uint64_t) relegated wontreturn;
|
||||
void __check_fail_le(uint64_t, uint64_t) relegated wontreturn;
|
||||
void __check_fail_lt(uint64_t, uint64_t) relegated wontreturn;
|
||||
void __check_fail_ge(uint64_t, uint64_t) relegated wontreturn;
|
||||
void __check_fail_gt(uint64_t, uint64_t) relegated wontreturn;
|
||||
void __check_fail_aligned(unsigned, uint64_t) relegated wontreturn;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
/**
|
||||
* Aborts process after printing details on its current state.
|
||||
*/
|
||||
relegated noreturn void __die(void) {
|
||||
relegated wontreturn void __die(void) {
|
||||
static bool once;
|
||||
if (!once) {
|
||||
once = true;
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/log/bsd.h"
|
||||
|
||||
noreturn void(err)(int eval, const char *fmt, ...) {
|
||||
wontreturn void(err)(int eval, const char *fmt, ...) {
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
(verr)(eval, fmt, va);
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/log/bsd.h"
|
||||
|
||||
noreturn void(errx)(int eval, const char *fmt, ...) {
|
||||
wontreturn void(errx)(int eval, const char *fmt, ...) {
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
(verrx)(eval, fmt, va);
|
||||
|
|
|
@ -33,10 +33,10 @@ typedef struct FILE FILE;
|
|||
|
||||
extern FILE *g_logfile;
|
||||
|
||||
void perror(const char *) relegated; /* print the last system error */
|
||||
void __die(void) relegated noreturn; /* print backtrace and abort() */
|
||||
void meminfo(int); /* shows malloc statistics &c. */
|
||||
void memsummary(int); /* light version of same thing */
|
||||
void perror(const char *) relegated; /* print the last system error */
|
||||
void __die(void) relegated wontreturn; /* print backtrace and abort() */
|
||||
void meminfo(int); /* shows malloc statistics &c. */
|
||||
void memsummary(int); /* light version of same thing */
|
||||
uint16_t getttycols(uint16_t);
|
||||
int getttysize(int, struct winsize *) paramsnonnull();
|
||||
bool isterminalinarticulate(void) nosideeffect;
|
||||
|
@ -218,8 +218,8 @@ void fverbosef(ARGS, ...) asm("flogf") ATTR relegated libcesque;
|
|||
void vfverbosef(ARGS, va_list) asm("vflogf") ATTRV relegated libcesque;
|
||||
void fdebugf(ARGS, ...) asm("flogf") ATTR relegated libcesque;
|
||||
void vfdebugf(ARGS, va_list) asm("vflogf") ATTRV relegated libcesque;
|
||||
void ffatalf(ARGS, ...) asm("flogf") ATTR relegated noreturn libcesque;
|
||||
void vffatalf(ARGS, va_list) asm("vflogf") ATTRV relegated noreturn libcesque;
|
||||
void ffatalf(ARGS, ...) asm("flogf") ATTR relegated wontreturn libcesque;
|
||||
void vffatalf(ARGS, va_list) asm("vflogf") ATTRV relegated wontreturn libcesque;
|
||||
#undef ARGS
|
||||
#undef ATTR
|
||||
#undef ATTRV
|
||||
|
|
|
@ -51,17 +51,17 @@ STATIC_YOINK("stoa");
|
|||
|
||||
struct siginfo;
|
||||
|
||||
static const char kGregOrder[17] aligned(1) = {
|
||||
static const char kGregOrder[17] forcealign(1) = {
|
||||
13, 11, 8, 14, 12, 9, 10, 15, 16, 0, 1, 2, 3, 4, 5, 6, 7,
|
||||
};
|
||||
|
||||
static const char kGregNames[17][4] aligned(1) = {
|
||||
static const char kGregNames[17][4] forcealign(1) = {
|
||||
"R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15", "RDI",
|
||||
"RSI", "RBP", "RBX", "RDX", "RAX", "RCX", "RSP", "RIP",
|
||||
};
|
||||
|
||||
static const char kGodHatesFlags[12] aligned(1) = "CVPRAKZSTIDO";
|
||||
static const char kCrashSigNames[8][5] aligned(1) = {
|
||||
static const char kGodHatesFlags[12] forcealign(1) = "CVPRAKZSTIDO";
|
||||
static const char kCrashSigNames[8][5] forcealign(1) = {
|
||||
"QUIT", "FPE", "ILL", "SEGV", "TRAP", "ABRT", "BUS"};
|
||||
|
||||
int kCrashSigs[8];
|
||||
|
|
|
@ -98,13 +98,13 @@ struct UbsanShiftOutOfBoundsData {
|
|||
};
|
||||
|
||||
void __ubsan_abort(const struct UbsanSourceLocation *,
|
||||
const char *) relegated hidden noreturn;
|
||||
const char *) relegated hidden wontreturn;
|
||||
void __ubsan_handle_type_mismatch(struct UbsanTypeMismatchInfo *,
|
||||
uintptr_t) relegated hidden noreturn;
|
||||
uintptr_t) relegated hidden wontreturn;
|
||||
void ___ubsan_handle_type_mismatch_v1(struct UbsanTypeMismatchInfoClang *,
|
||||
uintptr_t) relegated hidden noreturn;
|
||||
uintptr_t) relegated hidden wontreturn;
|
||||
void __ubsan_handle_float_cast_overflow(void *,
|
||||
void *) relegated hidden noreturn;
|
||||
void *) relegated hidden wontreturn;
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_UBSAN_H_ */
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
noreturn void(verr)(int eval, const char *fmt, va_list va) {
|
||||
wontreturn void(verr)(int eval, const char *fmt, va_list va) {
|
||||
fprintf(stderr, "%s: %s%s%s[%m]: ", program_invocation_name, RED2, "ERROR",
|
||||
RESET);
|
||||
if (fmt) (vfprintf)(stderr, fmt, va);
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
noreturn void(verrx)(int eval, const char *fmt, va_list va) {
|
||||
wontreturn void(verrx)(int eval, const char *fmt, va_list va) {
|
||||
fprintf(stderr, "%s: %s%s%s: ", program_invocation_name, RED2, "ERROR",
|
||||
RESET);
|
||||
if (fmt) (vfprintf)(stderr, fmt, va);
|
||||
|
|
|
@ -22,9 +22,11 @@ int bsfl(long);
|
|||
int bsfll(long long);
|
||||
int bsfmax(uintmax_t);
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define bsf(u) __builtin_ctz(u)
|
||||
#define bsfl(u) __builtin_ctzl(u)
|
||||
#define bsfll(u) __builtin_ctzll(u)
|
||||
#endif
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -22,9 +22,11 @@ int bsrl(long);
|
|||
int bsrll(long long);
|
||||
int bsrmax(uintmax_t);
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define bsr(u) ((sizeof(int) * 8 - 1) ^ __builtin_clz(u))
|
||||
#define bsrl(u) ((sizeof(long) * 8 - 1) ^ __builtin_clzl(u))
|
||||
#define bsrll(u) ((sizeof(long long) * 8 - 1) ^ __builtin_clzll(u))
|
||||
#endif
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -36,32 +36,32 @@ cescapec:
|
|||
movzbl %cl,%ecx
|
||||
jmp *cescapectab(,%rcx,8)
|
||||
.Lanchorpoint:
|
||||
.LBEL: mov $'a,%ah
|
||||
.LBEL: mov $'a',%ah
|
||||
ret
|
||||
.LBS: mov $'b,%ah
|
||||
.LBS: mov $'b',%ah
|
||||
ret
|
||||
.LHT: mov $'t,%ah
|
||||
.LHT: mov $'t',%ah
|
||||
ret
|
||||
.LLF: mov $'n,%ah
|
||||
.LLF: mov $'n',%ah
|
||||
ret
|
||||
.LVT: mov $'v,%ah
|
||||
.LVT: mov $'v',%ah
|
||||
ret
|
||||
.LFF: mov $'f,%ah
|
||||
.LFF: mov $'f',%ah
|
||||
ret
|
||||
.LCR: mov $'r,%ah
|
||||
.LCR: mov $'r',%ah
|
||||
ret
|
||||
.LDQ: mov $'\",%ah
|
||||
.LDQ: mov $'\"',%ah
|
||||
ret
|
||||
.LSQ: mov $'\',%ah
|
||||
.LSQ: mov $'\'',%ah
|
||||
ret
|
||||
.LBSL: mov $'\\,%ah
|
||||
.LBSL: mov $'\\',%ah
|
||||
ret
|
||||
#ifdef __STRICT_ANSI__
|
||||
.LQM: mov $'?,%ah
|
||||
.LQM: mov $'?',%ah
|
||||
ret
|
||||
.LESC:
|
||||
#elif defined(__GNUC__)
|
||||
.LESC: mov $'e,%ah
|
||||
.LESC: mov $'e',%ah
|
||||
ret
|
||||
.LQM:
|
||||
#endif
|
||||
|
|
|
@ -17,17 +17,9 @@
|
|||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "tool/tags/keywords.inc"
|
||||
#include "tool/tags/tags.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/nexgen32e/nexgen32e.h"
|
||||
|
||||
/**
|
||||
* Returns small number for HTTP header, or -1 if not found.
|
||||
*/
|
||||
int GetKeyword(const char *str, size_t len) {
|
||||
const struct KeywordSlot *slot;
|
||||
if ((slot = LookupKeyword(str, len))) {
|
||||
return slot->code;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
bool ctz(double x, double y) {
|
||||
return __builtin_islessgreater(x, y);
|
||||
}
|
|
@ -41,7 +41,7 @@ ffs: .leafprologue
|
|||
bsf %edi,%eax
|
||||
or $-1,%edx
|
||||
cmovz %edx,%eax
|
||||
add $1,%eax
|
||||
inc %eax
|
||||
.leafepilogue
|
||||
.endfn ffs,globl
|
||||
.source __FILE__
|
||||
|
|
|
@ -41,7 +41,7 @@ ffsl: .leafprologue
|
|||
bsf %rdi,%rax
|
||||
or $-1,%edx
|
||||
cmovz %edx,%eax
|
||||
add $1,%eax
|
||||
inc %eax
|
||||
.leafepilogue
|
||||
.endfn ffsl,globl
|
||||
.alias ffsl,ffsll
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
|
||||
/ Half size of level 3 cache in bytes.
|
||||
.initbss 202,_init_kHalfCache3
|
||||
kHalfCache3:
|
||||
.quad 0
|
||||
.endobj kHalfCache3,globl
|
||||
.previous
|
||||
|
||||
.init.start 202,_init_kHalfCache3
|
||||
cmpl $3,kCpuids(%rip)
|
||||
jbe 3f
|
||||
xor %r8d,%r8d
|
||||
mov $4,%r8d
|
||||
1: mov %r8d,%eax
|
||||
mov %r8d,%ecx
|
||||
push %rbx
|
||||
cpuid
|
||||
mov %ebx,%r9d
|
||||
pop %rbx
|
||||
test $31,%al
|
||||
je 3f
|
||||
cmp $99,%al
|
||||
jne 2f
|
||||
mov %r9d,%eax
|
||||
mov %r9d,%edx
|
||||
inc %ecx
|
||||
shr $12,%r9d
|
||||
shr $22,%eax
|
||||
and $0x0fff,%edx
|
||||
and $0x03ff,%r9d
|
||||
inc %eax
|
||||
inc %edx
|
||||
imul %edx,%eax
|
||||
imul %ecx,%eax
|
||||
lea 1(%r9),%ecx
|
||||
imul %ecx,%eax
|
||||
jmp 4f
|
||||
2: inc %r8d
|
||||
jmp 1b
|
||||
3: mov $0x00400000,%eax
|
||||
4: shr %eax
|
||||
stosq
|
||||
.init.end 202,_init_kHalfCache3
|
||||
.source __FILE__
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
/ Loads XMM registers from buffer.
|
||||
/
|
||||
/ @param %rdi points to &(aligned(16) uint8_t[256])[128]
|
||||
/ @param %rdi points to &(forcealign(16) uint8_t[256])[128]
|
||||
/ @note modern cpus have out-of-order execution engines
|
||||
loadxmm:.leafprologue
|
||||
movaps -0x80(%rdi),%xmm0
|
||||
|
|
|
@ -112,7 +112,7 @@ MemCpy: .leafprologue
|
|||
.L1: mov (%rsi),%cl
|
||||
mov %cl,(%rdi)
|
||||
jmp .L0
|
||||
.Lerms: cmp $4*1024*1024,%rdx # TODO: getcachesize()
|
||||
.Lerms: cmp kHalfCache3(%rip),%rdx
|
||||
ja .Lnts
|
||||
push %rdi
|
||||
push %rsi
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
/ Stores XMM registers to buffer.
|
||||
/
|
||||
/ @param %rdi points to &(aligned(16) uint8_t[256])[128]
|
||||
/ @param %rdi points to &(forcealign(16) uint8_t[256])[128]
|
||||
/ @note modern cpus have out-of-order execution engines
|
||||
savexmm:.leafprologue
|
||||
movaps %xmm0,-0x80(%rdi)
|
||||
|
|
|
@ -28,6 +28,21 @@
|
|||
/ @return rax is pointer to substring or NULL
|
||||
/ @asyncsignalsafe
|
||||
strstr$sse42:
|
||||
.strstr .Lequalordered
|
||||
.leafprologue
|
||||
mov %rdi,%rax
|
||||
xor %ecx,%ecx
|
||||
0: mov $-16,%rdx
|
||||
1: add $16,%rdx
|
||||
movaps (%rsi,%rdx),%xmm0
|
||||
2: add %rcx,%rax
|
||||
lea (%rax,%rdx),%rdi
|
||||
pcmpistri $.Lequalordered,(%rdi),%xmm0
|
||||
3: ja 2b # !CF (no match) && !ZF (need NUL-term)
|
||||
jnc 4f # !CF (no match) && ZF (NUL-terminator)
|
||||
jno 0b # !OF ← CF && CX!=0 (matched at offset)
|
||||
jns 1b # !SF ← NUL ∉ XMM1 (need to match more)
|
||||
jmp 5f # youtu.be/nVk1DjMtLWs
|
||||
4: xor %eax,%eax
|
||||
5: .leafepilogue
|
||||
.endfn strstr$sse42,globl,hidden
|
||||
.source __FILE__
|
||||
|
|
|
@ -33,7 +33,7 @@ bool32 WriteFile(int64_t hFile, const void *lpBuffer,
|
|||
struct NtOverlapped *opt_lpOverlapped);
|
||||
bool32 TerminateProcess(int64_t hProcess, uint32_t uExitCode);
|
||||
int64_t GetCurrentProcess(void) pureconst;
|
||||
void ExitProcess(uint32_t uExitCode) noreturn;
|
||||
void ExitProcess(uint32_t uExitCode) wontreturn;
|
||||
uint32_t GetLastError(void) nosideeffect;
|
||||
bool32 CloseHandle(int64_t hObject) nothrow nocallback;
|
||||
intptr_t GetStdHandle(int64_t nStdHandle) nosideeffect;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
struct NtM128A {
|
||||
uint64_t Low;
|
||||
int64_t High;
|
||||
} aligned(16);
|
||||
} forcealign(16);
|
||||
|
||||
struct NtXmmSaveArea32 {
|
||||
uint16_t ControlWord;
|
||||
|
@ -53,7 +53,7 @@ struct NtContext {
|
|||
uint64_t LastBranchFromRip;
|
||||
uint64_t LastExceptionToRip;
|
||||
uint64_t LastExceptionFromRip;
|
||||
} aligned(16);
|
||||
} forcealign(16);
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_CONTEXT_H_ */
|
||||
|
|
|
@ -37,7 +37,7 @@ int64_t CreateThread(struct NtSecurityAttributes *lpThreadAttributes,
|
|||
void *lpParameter, uint32_t dwCreationFlags,
|
||||
uint32_t *opt_lpThreadId);
|
||||
|
||||
void ExitThread(uint32_t dwExitCode) noreturn;
|
||||
void ExitThread(uint32_t dwExitCode) wontreturn;
|
||||
int64_t GetCurrentThread(void);
|
||||
uint32_t GetCurrentThreadId(void);
|
||||
uint64_t SetThreadAffinityMask(int64_t hThread, uintptr_t dwThreadAffinityMask);
|
||||
|
|
|
@ -25,7 +25,7 @@ COSMOPOLITAN_C_START_
|
|||
/**
|
||||
* Same as longjmp() but runs gc() / defer() destructors.
|
||||
*/
|
||||
void gclongjmp(jmp_buf, int) nothrow noreturn paramsnonnull();
|
||||
void gclongjmp(jmp_buf, int) nothrow wontreturn paramsnonnull();
|
||||
|
||||
/**
|
||||
* Calls FN(ARG) when function returns.
|
||||
|
|
|
@ -19,10 +19,10 @@ extern hidden void *g_stacktop;
|
|||
void _init(void) hidden;
|
||||
void _piro(int) hidden;
|
||||
void *__cxa_finalize(void *) hidden;
|
||||
void _executive(int, char **, char **, long (*)[2]) hidden noreturn;
|
||||
void __stack_chk_fail(void) noreturn relegated;
|
||||
void __stack_chk_fail_local(void) noreturn relegated hidden;
|
||||
void _jmpstack(void *, void *, ...) hidden noreturn;
|
||||
void _executive(int, char **, char **, long (*)[2]) hidden wontreturn;
|
||||
void __stack_chk_fail(void) wontreturn relegated;
|
||||
void __stack_chk_fail_local(void) wontreturn relegated hidden;
|
||||
void _jmpstack(void *, void *, ...) hidden wontreturn;
|
||||
long _setstack(void *, void *, ...) hidden;
|
||||
int GetDosArgv(const char16_t *, char *, size_t, char **, size_t) hidden;
|
||||
Elf64_Ehdr *MapElfRead(const char *, struct MappedFile *) hidden;
|
||||
|
|
|
@ -29,7 +29,7 @@ STATIC_YOINK("_init_onntconsoleevent");
|
|||
|
||||
static struct InterruptibleCall *g_interruptiblecall;
|
||||
|
||||
noreturn static void interruptcall(int sig) {
|
||||
wontreturn static void interruptcall(int sig) {
|
||||
longjmp(g_interruptiblecall->jb, 1);
|
||||
unreachable;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
static privileged void __print$nt(const void *data, size_t len) {
|
||||
int64_t hand;
|
||||
uint32_t wrote;
|
||||
char xmm[256] aligned(16);
|
||||
char xmm[256] forcealign(16);
|
||||
savexmm(&xmm[128]);
|
||||
hand = __imp_GetStdHandle(kNtStdErrorHandle);
|
||||
__imp_WriteFile(hand, data, len, &wrote, NULL);
|
||||
|
|
|
@ -6,45 +6,45 @@ COSMOPOLITAN_C_START_
|
|||
│ cosmopolitan § runtime ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
typedef long jmp_buf[8] aligned(CACHELINE);
|
||||
typedef long jmp_buf[8] forcealign(CACHELINE);
|
||||
|
||||
extern int g_argc; /* CRT */
|
||||
extern char **g_argv; /* CRT */
|
||||
extern char **environ; /* CRT */
|
||||
extern unsigned long *g_auxv; /* CRT */
|
||||
extern char *program_invocation_name; /* RII */
|
||||
extern char *program_invocation_short_name; /* RII */
|
||||
extern uint64_t g_syscount; /* RII */
|
||||
extern const uint64_t kStartTsc; /* RII */
|
||||
extern const char kTmpPath[]; /* RII */
|
||||
extern const char kNtSystemDirectory[]; /* RII */
|
||||
extern const char kNtWindowsDirectory[]; /* RII */
|
||||
extern unsigned char _base[] aligned(PAGESIZE); /* αpε */
|
||||
extern unsigned char _ehead[] aligned(PAGESIZE); /* αpε */
|
||||
extern unsigned char _etext[] aligned(PAGESIZE); /* αpε */
|
||||
extern unsigned char _edata[] aligned(PAGESIZE); /* αpε */
|
||||
extern unsigned char _end[] aligned(PAGESIZE); /* αpε */
|
||||
extern unsigned char _ereal; /* αpε */
|
||||
extern unsigned char __privileged_start; /* αpε */
|
||||
extern unsigned char __test_start; /* αpε */
|
||||
extern unsigned char __ro; /* αpε */
|
||||
extern unsigned char *__relo_start[]; /* αpε */
|
||||
extern unsigned char *__relo_end[]; /* αpε */
|
||||
extern uint8_t __zip_start[]; /* αpε */
|
||||
extern uint8_t __zip_end[]; /* αpε */
|
||||
extern int g_argc; /* CRT */
|
||||
extern char **g_argv; /* CRT */
|
||||
extern char **environ; /* CRT */
|
||||
extern unsigned long *g_auxv; /* CRT */
|
||||
extern char *program_invocation_name; /* RII */
|
||||
extern char *program_invocation_short_name; /* RII */
|
||||
extern uint64_t g_syscount; /* RII */
|
||||
extern const uint64_t kStartTsc; /* RII */
|
||||
extern const char kTmpPath[]; /* RII */
|
||||
extern const char kNtSystemDirectory[]; /* RII */
|
||||
extern const char kNtWindowsDirectory[]; /* RII */
|
||||
extern unsigned char _base[] forcealign(PAGESIZE); /* αpε */
|
||||
extern unsigned char _ehead[] forcealign(PAGESIZE); /* αpε */
|
||||
extern unsigned char _etext[] forcealign(PAGESIZE); /* αpε */
|
||||
extern unsigned char _edata[] forcealign(PAGESIZE); /* αpε */
|
||||
extern unsigned char _end[] forcealign(PAGESIZE); /* αpε */
|
||||
extern unsigned char _ereal; /* αpε */
|
||||
extern unsigned char __privileged_start; /* αpε */
|
||||
extern unsigned char __test_start; /* αpε */
|
||||
extern unsigned char __ro; /* αpε */
|
||||
extern unsigned char *__relo_start[]; /* αpε */
|
||||
extern unsigned char *__relo_end[]; /* αpε */
|
||||
extern uint8_t __zip_start[]; /* αpε */
|
||||
extern uint8_t __zip_end[]; /* αpε */
|
||||
|
||||
long missingno();
|
||||
void mcount(void);
|
||||
unsigned long getauxval(unsigned long);
|
||||
void *mapanon(size_t) vallocesque attributeallocsize((1));
|
||||
int setjmp(jmp_buf) libcesque returnstwice paramsnonnull();
|
||||
void longjmp(jmp_buf, int) libcesque noreturn paramsnonnull();
|
||||
void exit(int) noreturn;
|
||||
void _exit(int) libcesque noreturn;
|
||||
void _Exit(int) libcesque noreturn;
|
||||
void abort(void) noreturn noinstrument;
|
||||
void panic(void) noreturn noinstrument privileged;
|
||||
void triplf(void) noreturn noinstrument privileged;
|
||||
void longjmp(jmp_buf, int) libcesque wontreturn paramsnonnull();
|
||||
void exit(int) wontreturn;
|
||||
void _exit(int) libcesque wontreturn;
|
||||
void _Exit(int) libcesque wontreturn;
|
||||
void abort(void) wontreturn noinstrument;
|
||||
void panic(void) wontreturn noinstrument privileged;
|
||||
void triplf(void) wontreturn noinstrument privileged;
|
||||
int __cxa_atexit(void *, void *, void *) libcesque;
|
||||
int atfork(void *, void *) libcesque;
|
||||
int atexit(void (*)(void)) libcesque;
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/runtime/valist.h"
|
||||
|
||||
static void *__va_arg_mem(struct __va *ap, unsigned long sz, unsigned align) {
|
||||
void *r = ap->overflow_arg_area;
|
||||
if (align > 8) r = (void *)(((unsigned long)r + 15) / 16 * 16);
|
||||
ap->overflow_arg_area = (void *)(((unsigned long)r + sz + 7) / 8 * 8);
|
||||
return r;
|
||||
}
|
||||
|
||||
void *__va_arg(struct __va *ap, unsigned long sz, unsigned align, unsigned k) {
|
||||
void *r;
|
||||
switch (k) {
|
||||
case 0:
|
||||
if (ap->gp_offset < 48) {
|
||||
r = (char *)ap->reg_save_area + ap->gp_offset;
|
||||
ap->gp_offset += 8;
|
||||
return r;
|
||||
} else {
|
||||
return __va_arg_mem(ap, sz, align);
|
||||
}
|
||||
case 1:
|
||||
if (ap->fp_offset < 112) {
|
||||
r = (char *)ap->reg_save_area + ap->fp_offset;
|
||||
ap->fp_offset += 8;
|
||||
return r;
|
||||
} else {
|
||||
return __va_arg_mem(ap, sz, align);
|
||||
}
|
||||
default:
|
||||
return __va_arg_mem(ap, sz, align);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_RUNTIME_VALIST_H_
|
||||
#define COSMOPOLITAN_LIBC_RUNTIME_VALIST_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct __va {
|
||||
unsigned int gp_offset;
|
||||
unsigned int fp_offset;
|
||||
void *overflow_arg_area;
|
||||
void *reg_save_area;
|
||||
};
|
||||
|
||||
void *__va_arg(struct __va *, unsigned long, unsigned, unsigned);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_RUNTIME_VALIST_H_ */
|
|
@ -119,7 +119,7 @@ static textwindows char *AllocateMemory(void *addr, size_t size, int64_t *h) {
|
|||
kNtNumaNoPreferredNode);
|
||||
}
|
||||
|
||||
static textwindows noreturn void WinMainNew(void) {
|
||||
static textwindows wontreturn void WinMainNew(void) {
|
||||
int64_t h;
|
||||
size_t size;
|
||||
int i, count;
|
||||
|
|
|
@ -24,7 +24,7 @@ STATIC_YOINK("_init_g_stderr");
|
|||
|
||||
FILE *stderr;
|
||||
hidden FILE g_stderr;
|
||||
hidden unsigned char g_stderr_buf[BUFSIZ] aligned(PAGESIZE);
|
||||
hidden unsigned char g_stderr_buf[BUFSIZ] forcealign(PAGESIZE);
|
||||
|
||||
static textstartup void _init_g_stderr2() {
|
||||
_fflushregister(stderr);
|
||||
|
|
|
@ -24,7 +24,7 @@ STATIC_YOINK("_init_g_stdin");
|
|||
|
||||
FILE *stdin;
|
||||
hidden FILE g_stdin;
|
||||
hidden unsigned char g_stdin_buf[BUFSIZ] aligned(PAGESIZE);
|
||||
hidden unsigned char g_stdin_buf[BUFSIZ] forcealign(PAGESIZE);
|
||||
|
||||
static textstartup void g_stdin_init() {
|
||||
_fflushregister(stdin);
|
||||
|
|
|
@ -27,7 +27,7 @@ STATIC_YOINK("_init_g_stdout");
|
|||
|
||||
FILE *stdout;
|
||||
hidden FILE g_stdout;
|
||||
hidden unsigned char g_stdout_buf[BUFSIZ] aligned(PAGESIZE);
|
||||
hidden unsigned char g_stdout_buf[BUFSIZ] forcealign(PAGESIZE);
|
||||
|
||||
static textstartup void _init_g_stdout2() {
|
||||
struct FILE *sf;
|
||||
|
|
|
@ -19,4 +19,6 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/stdio/temp.h"
|
||||
|
||||
int mkstemp(char *template) { return mkostempsm(template, 0, 0, 0600); }
|
||||
int mkstemp(char *template) {
|
||||
return mkostempsm(template, 0, 0, 0600);
|
||||
}
|
||||
|
|
|
@ -19,14 +19,16 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/str/str.h"
|
||||
|
||||
#undef char
|
||||
#undef endswith
|
||||
#undef strlen
|
||||
#undef strnlen
|
||||
|
||||
#define char char16_t
|
||||
#define endswith endswith16
|
||||
#define strlen strlen16
|
||||
#define strnlen strnlen16
|
||||
|
||||
#include "libc/str/endswith.c"
|
||||
/**
|
||||
* Returns true if s has suffix.
|
||||
*
|
||||
* @param s is a NUL-terminated string
|
||||
* @param suffix is also NUL-terminated
|
||||
*/
|
||||
bool endswith16(const char16_t *s, const char16_t *suffix) {
|
||||
size_t n, m;
|
||||
n = strlen16(s);
|
||||
m = strlen16(suffix);
|
||||
if (m > n) return false;
|
||||
return memcmp(s + n - m, suffix, m * sizeof(char16_t)) == 0;
|
||||
}
|
||||
|
|
|
@ -19,14 +19,16 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/str/str.h"
|
||||
|
||||
#undef char
|
||||
#undef startswith
|
||||
#undef strlen
|
||||
#undef strncmp
|
||||
|
||||
#define char char16_t
|
||||
#define startswith startswith16
|
||||
#define strlen strlen16
|
||||
#define strncmp strncmp16
|
||||
|
||||
#include "libc/str/startswith.c"
|
||||
/**
|
||||
* Returns true if s has prefix.
|
||||
*
|
||||
* @param s is a NUL-terminated string
|
||||
* @param prefix is also NUL-terminated
|
||||
*/
|
||||
bool startswith16(const char16_t *s, const char16_t *prefix) {
|
||||
for (;;) {
|
||||
if (!*prefix) return true;
|
||||
if (!*s) return false;
|
||||
if (*s++ != *prefix++) return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -238,8 +238,8 @@ char *strsignal(int) returnsnonnull libcesque;
|
|||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
|
||||
char *_strncpy(char *, const char *, size_t) asm("strncpy") memcpyesque;
|
||||
#define strncpy(DEST, SRC, N) _strncpy(DEST, SRC, N) /* pacify bad warning */
|
||||
char *__strncpy(char *, const char *, size_t) memcpyesque;
|
||||
#define strncpy(DEST, SRC, N) __strncpy(DEST, SRC, N) /* pacify bad warning */
|
||||
|
||||
#define explicit_bzero(STR, BYTES) \
|
||||
do { \
|
||||
|
@ -318,7 +318,7 @@ char *_strncpy(char *, const char *, size_t) asm("strncpy") memcpyesque;
|
|||
size_t SiZe = (SIZE); \
|
||||
size_t Rcx; \
|
||||
asm("rep movsb" \
|
||||
: "=D"(Rdi), "=S"(Rsi), "=D"(Rcx), "=m"(*(char(*)[SiZe])(Dest)) \
|
||||
: "=D"(Rdi), "=S"(Rsi), "=c"(Rcx), "=m"(*(char(*)[SiZe])(Dest)) \
|
||||
: "0"(Dest), "1"(Src), "2"(SiZe), "m"(*(const char(*)[SiZe])(Src)) \
|
||||
: "cc"); \
|
||||
Rdi; \
|
||||
|
@ -351,9 +351,6 @@ char *_strncpy(char *, const char *, size_t) asm("strncpy") memcpyesque;
|
|||
|
||||
#endif /* hosted/sse2/unbloat */
|
||||
|
||||
size_t _strlen(const char *s) asm("strlen") strlenesque;
|
||||
void *_memchr(const void *, int, size_t) asm("memchr") strlenesque;
|
||||
|
||||
#endif /* __GNUC__ && !__STRICT_ANSI__ */
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
|
||||
__strncpy:
|
||||
jmp strncpy
|
||||
.endfn __strncpy,globl
|
|
@ -24,7 +24,7 @@
|
|||
* Returns pointer to first byte matching any in accept, or NULL.
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
char *(strpbrk)(const char *s, const char *accept) {
|
||||
char *strpbrk(const char *s, const char *accept) {
|
||||
size_t i;
|
||||
if (accept[0]) {
|
||||
if (!accept[1]) {
|
||||
|
|
|
@ -20,10 +20,22 @@
|
|||
#include "libc/nexgen32e/hascharacter.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
#undef strpbrk
|
||||
#define char char16_t
|
||||
#define HasCharacter HasCharacter16
|
||||
#define strpbrk strpbrk16
|
||||
#define strchr(x, y) strchr16(x, y)
|
||||
|
||||
#include "libc/str/strpbrk.c"
|
||||
/**
|
||||
* Returns pointer to first byte matching any in accept, or NULL.
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
char16_t *strpbrk16(const char16_t *s, const char16_t *accept) {
|
||||
size_t i;
|
||||
if (accept[0]) {
|
||||
if (!accept[1]) {
|
||||
return strchr16(s, accept[0]);
|
||||
} else {
|
||||
for (i = 0; s[i]; ++i) {
|
||||
if (HasCharacter16(s[i], accept)) {
|
||||
return (/*unconst*/ char16_t *)&s[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
* @see strcspn(), strtok_r()
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
size_t(strspn)(const char *s, const char *accept) {
|
||||
size_t strspn(const char *s, const char *accept) {
|
||||
size_t i;
|
||||
for (i = 0; s[i]; ++i) {
|
||||
if (!HasCharacter(s[i], accept)) {
|
||||
|
|
|
@ -20,9 +20,19 @@
|
|||
#include "libc/nexgen32e/hascharacter.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
#undef strspn
|
||||
#define char char16_t
|
||||
#define HasCharacter HasCharacter16
|
||||
#define strspn strspn16
|
||||
|
||||
#include "libc/str/strspn.c"
|
||||
/**
|
||||
* Returns prefix length, consisting of chars in accept.
|
||||
*
|
||||
* @param accept is nul-terminated character set
|
||||
* @see strcspn(), strtok_r()
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
size_t strspn16(const char16_t *s, const char16_t *accept) {
|
||||
size_t i;
|
||||
for (i = 0; s[i]; ++i) {
|
||||
if (!HasCharacter16(s[i], accept)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/alg/alg.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/str/internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
@ -32,22 +31,26 @@
|
|||
* @asyncsignalsafe
|
||||
* @see memmem()
|
||||
*/
|
||||
char *(strstr)(const char *haystack, const char *needle) {
|
||||
char *strstr(const char *haystack, const char *needle) {
|
||||
size_t i;
|
||||
if (needle[0]) {
|
||||
if (needle[1]) {
|
||||
if (!((intptr_t)needle & 0xf) && X86_HAVE(SSE4_2)) {
|
||||
return strstr$sse42(haystack, needle);
|
||||
} else {
|
||||
size_t needlelen;
|
||||
alignas(16) char needle2[64];
|
||||
needlelen = strlen(needle);
|
||||
if (needlelen < 64 && X86_HAVE(SSE4_2)) {
|
||||
memcpy(needle2, needle, (needlelen + 1) * sizeof(char));
|
||||
return strstr$sse42(haystack, needle2);
|
||||
} else {
|
||||
return tinystrstr(haystack, needle);
|
||||
for (;;) {
|
||||
#if 0 /* todo: fix me */
|
||||
if (!((uintptr_t)haystack & 15) && X86_HAVE(SSE4_2) &&
|
||||
(((uintptr_t)needle + strlen(needle)) & 0xfff) <= 0xff0) {
|
||||
return strstr$sse42(haystack, needle);
|
||||
}
|
||||
#endif
|
||||
for (i = 0;;) {
|
||||
if (!needle[i]) return haystack;
|
||||
if (!haystack[i]) break;
|
||||
if (needle[i] != haystack[i]) break;
|
||||
++i;
|
||||
}
|
||||
if (!*haystack++) break;
|
||||
}
|
||||
return NULL;
|
||||
} else {
|
||||
return strchr(haystack, needle[0]);
|
||||
}
|
||||
|
|
|
@ -19,14 +19,16 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/str/str.h"
|
||||
|
||||
#undef char
|
||||
#undef endswith
|
||||
#undef strlen
|
||||
#undef strnlen
|
||||
|
||||
#define char wchar_t
|
||||
#define endswith wcsendswith
|
||||
#define strlen wcslen
|
||||
#define strnlen wcsnlen
|
||||
|
||||
#include "libc/str/endswith.c"
|
||||
/**
|
||||
* Returns true if s has suffix.
|
||||
*
|
||||
* @param s is a NUL-terminated string
|
||||
* @param suffix is also NUL-terminated
|
||||
*/
|
||||
bool wcsendswith(const wchar_t *s, const wchar_t *suffix) {
|
||||
size_t n, m;
|
||||
n = wcslen(s);
|
||||
m = wcslen(suffix);
|
||||
if (m > n) return false;
|
||||
return memcmp(s + n - m, suffix, m * sizeof(wchar_t)) == 0;
|
||||
}
|
||||
|
|
|
@ -20,10 +20,22 @@
|
|||
#include "libc/nexgen32e/hascharacter.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
#undef strpbrk
|
||||
#define char wchar_t
|
||||
#define HasCharacter HasCharacterWide
|
||||
#define strpbrk wcspbrk
|
||||
#define strchr(x, y) wcschr(x, y)
|
||||
|
||||
#include "libc/str/strpbrk.c"
|
||||
/**
|
||||
* Returns pointer to first byte matching any in accept, or NULL.
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
wchar_t *wcspbrk(const wchar_t *s, const wchar_t *accept) {
|
||||
size_t i;
|
||||
if (accept[0]) {
|
||||
if (!accept[1]) {
|
||||
return wcschr(s, accept[0]);
|
||||
} else {
|
||||
for (i = 0; s[i]; ++i) {
|
||||
if (HasCharacterWide(s[i], accept)) {
|
||||
return (/*unconst*/ wchar_t *)&s[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -20,9 +20,19 @@
|
|||
#include "libc/nexgen32e/hascharacter.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
#undef strspn
|
||||
#define char wchar_t
|
||||
#define HasCharacter HasCharacterWide
|
||||
#define strspn wcsspn
|
||||
|
||||
#include "libc/str/strspn.c"
|
||||
/**
|
||||
* Returns prefix length, consisting of chars in accept.
|
||||
*
|
||||
* @param accept is nul-terminated character set
|
||||
* @see strcspn(), strtok_r()
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
size_t wcsspn(const wchar_t *s, const wchar_t *accept) {
|
||||
size_t i;
|
||||
for (i = 0; s[i]; ++i) {
|
||||
if (!HasCharacterWide(s[i], accept)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
|
|
@ -19,14 +19,16 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/str/str.h"
|
||||
|
||||
#undef char
|
||||
#undef startswith
|
||||
#undef strlen
|
||||
#undef strncmp
|
||||
|
||||
#define char wchar_t
|
||||
#define startswith wcsstartswith
|
||||
#define strlen wcslen
|
||||
#define strncmp wcsncmp
|
||||
|
||||
#include "libc/str/startswith.c"
|
||||
/**
|
||||
* Returns true if s has prefix.
|
||||
*
|
||||
* @param s is a NUL-terminated string
|
||||
* @param prefix is also NUL-terminated
|
||||
*/
|
||||
bool wcsstartswith(const wchar_t *s, const wchar_t *prefix) {
|
||||
for (;;) {
|
||||
if (!*prefix) return true;
|
||||
if (!*s) return false;
|
||||
if (*s++ != *prefix++) return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
#include "libc/sysv/consts/mlock.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
double g_avx2_juiceup_doubles_[4] aligned(32);
|
||||
unsigned long long g_avx2_juiceup_quadwords_[4] aligned(32);
|
||||
double g_avx2_juiceup_doubles_[4] forcealign(32);
|
||||
unsigned long long g_avx2_juiceup_quadwords_[4] forcealign(32);
|
||||
|
||||
void testlib_benchwarmup(void) {
|
||||
/* get mathematical parts of cpu juiced up */
|
||||
|
|
|
@ -20,11 +20,12 @@
|
|||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "third_party/dtoa/dtoa.h"
|
||||
#include "third_party/gdtoa/gdtoa.h"
|
||||
|
||||
testonly char *testlib_formatfloat(long double x) {
|
||||
char dtoabuf[32];
|
||||
char buf[32];
|
||||
char *str = malloc(256);
|
||||
sprintf(str, "%Lf (%s)", x, g_fmt(dtoabuf, x));
|
||||
g_xfmt_p(buf, &x, 15, sizeof(buf), 0);
|
||||
sprintf(str, "%Lf (%s)", x, buf);
|
||||
return str;
|
||||
}
|
||||
|
|
|
@ -350,7 +350,7 @@ void testlib_runfixtures(testfn_t *, testfn_t *, const struct TestFixture *,
|
|||
const struct TestFixture *);
|
||||
int testlib_countfixtures(const struct TestFixture *,
|
||||
const struct TestFixture *);
|
||||
void testlib_abort(void) noreturn relegated;
|
||||
void testlib_abort(void) wontreturn relegated;
|
||||
bool testlib_strequals(size_t, const void *, const void *) nosideeffect;
|
||||
bool testlib_strnequals(size_t, const void *, const void *,
|
||||
size_t) nosideeffect;
|
||||
|
|
|
@ -99,7 +99,7 @@ LIBC_TESTLIB_A_DIRECTDEPS = \
|
|||
LIBC_UNICODE \
|
||||
LIBC_X \
|
||||
LIBC_ZIPOS \
|
||||
THIRD_PARTY_DTOA
|
||||
THIRD_PARTY_GDTOA
|
||||
|
||||
LIBC_TESTLIB_A_DEPS := \
|
||||
$(call uniq,$(foreach x,$(LIBC_TESTLIB_A_DIRECTDEPS),$($(x))))
|
||||
|
|
|
@ -35,7 +35,7 @@ void testlib_finish(void) {
|
|||
}
|
||||
}
|
||||
|
||||
noreturn void testlib_abort(void) {
|
||||
wontreturn void testlib_abort(void) {
|
||||
testlib_finish();
|
||||
exit(MIN(255, g_testlib_failed));
|
||||
unreachable;
|
||||
|
|
|
@ -28,8 +28,8 @@ int xwrite(int, const void *, uint64_t);
|
|||
│ cosmopolitan § eXtended apis » memory ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
void xdie(void) noreturn;
|
||||
char *xdtoa(double) _XMAL;
|
||||
void xdie(void) wontreturn;
|
||||
char *xdtoa(long double) _XMAL;
|
||||
char *xasprintf(const char *, ...) printfesque(1) paramsnonnull((1)) _XMAL;
|
||||
char *xvasprintf(const char *, va_list) _XPNN _XMAL;
|
||||
char *xgetline(struct FILE *) _XPNN mallocesque;
|
||||
|
|
|
@ -43,7 +43,7 @@ LIBC_X_A_DIRECTDEPS = \
|
|||
LIBC_STR \
|
||||
LIBC_STUBS \
|
||||
LIBC_SYSV \
|
||||
THIRD_PARTY_DTOA
|
||||
THIRD_PARTY_GDTOA
|
||||
|
||||
LIBC_X_A_DEPS := \
|
||||
$(call uniq,$(foreach x,$(LIBC_X_A_DIRECTDEPS),$($(x))))
|
||||
|
|
|
@ -19,14 +19,15 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "third_party/dtoa/dtoa.h"
|
||||
#include "third_party/gdtoa/gdtoa.h"
|
||||
|
||||
/**
|
||||
* Converts double to string w/ high-accuracy the easy way.
|
||||
*
|
||||
* @see gc(), free()
|
||||
* @return string that needs to be free'd
|
||||
*/
|
||||
char *xdtoa(double d) {
|
||||
char buf[32];
|
||||
return xstrdup(g_fmt(buf, d));
|
||||
char *xdtoa(long double d) {
|
||||
char *p = xmalloc(32);
|
||||
g_xfmt_p(p, &d, 16, 32, 2);
|
||||
return p;
|
||||
}
|
||||
|
|
|
@ -1,88 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/core/core.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/time/time.h"
|
||||
#include "tool/viz/lib/formatstringtable-testlib.h"
|
||||
|
||||
TEST(dct, test) {
|
||||
float M[8][8] /* clang-format off */ = {
|
||||
{.509804, .513725, .094118, .219608, .027451, .294118, .172549, .658824},
|
||||
{.019608, .070588, .196078, .015686, .172549, .458824, .713725, .294118},
|
||||
{.380392, .341176, .235294, .737255, .741176, .968627, .607843, .12549},
|
||||
{.560784, .843137, .639216, .929412, .756863, .113725, .643137, .435294},
|
||||
{.878431, .576471, .737255, .356863, .8, .878431, .682353, .866667},
|
||||
{.780392, .070588, .866667, .607843, .792157, .47451, .427451, .043137},
|
||||
{.133333, .976471, .698039, .662745, .035294, .207843, .831373, .627451},
|
||||
{.313725, .580392, .858824, .631373, .784314, .972549, .27451, .94902},
|
||||
} /* clang-format on */;
|
||||
dctjpeg(M);
|
||||
EXPECT_FLTMATRIXEQ(5, rint, 8, 8, M, "\n\
|
||||
32.86666 -1.46274 -1.4456 -.43895 -1.17255 .19084 .05736 .01672\n\
|
||||
-9.41551 -2.72135 3.7228 5.47448 .74604 .91144 -1.22542 -.41829\n\
|
||||
-6.32875 -4.21755 4.42546 -3.86307 -1.93691 -2.1173 1.00377 -1.0752\n\
|
||||
-2.58232 3.67887 5.65331 -.25753 .89732 1.09837 .93163 .61133\n\
|
||||
4.23922 1.36747 3.29469 -1.63407 2.78039 -3.0021 .7602 -.21367\n\
|
||||
-.11643 3.93022 .80678 -3.70514 .13347 .54381 -2.15087 -.52343\n\
|
||||
.64248 1.19093 -2.94494 2.66037 1.6624 .04414 .99807 .00514\n\
|
||||
.61622 -.76318 .75918 .41939 -.38075 -.30623 .09867 -.19237");
|
||||
}
|
||||
|
||||
/* TEST(dct, test2) { */
|
||||
/* float M[8][8] /\* clang-format off *\/ = { */
|
||||
/* {.5,.5,.5,.5,.5,.5,.5,.5}, */
|
||||
/* {.5,.5,.5,.5,.5,.5,.5,.5}, */
|
||||
/* {.5,.5,.5,.5,.5,.5,.5,.5}, */
|
||||
/* {.5,.5,.5,.5,.5,.5,.5,.5}, */
|
||||
/* {.5,.5,.5,.5,.5,.5,.5,.5}, */
|
||||
/* {.5,.5,.5,.5,.5,.5,.5,.5}, */
|
||||
/* {.5,.5,.5,.5,.5,.5,.5,.5}, */
|
||||
/* {.5,.5,.5,.5,.5,.5,.5,.5}, */
|
||||
/* } /\* clang-format on *\/; */
|
||||
/* dctjpeg(M); */
|
||||
/* EXPECT_FLTMATRIXEQ(5, rint, 8, 8, M, "\n\ */
|
||||
/* 32.86666 -1.46274 -1.4456 -.43895 -1.17255 .19084 .05736 .01672\n\ */
|
||||
/* -9.41551 -2.72135 3.7228 5.47448 .74604 .91144 -1.22542 -.41829\n\ */
|
||||
/* -6.32875 -4.21755 4.42546 -3.86307 -1.93691 -2.1173 1.00377 -1.0752\n\ */
|
||||
/* -2.58232 3.67887 5.65331 -.25753 .89732 1.09837 .93163 .61133\n\ */
|
||||
/* 4.23922 1.36747 3.29469 -1.63407 2.78039 -3.0021 .7602 -.21367\n\ */
|
||||
/* -.11643 3.93022 .80678 -3.70514 .13347 .54381 -2.15087 -.52343\n\ */
|
||||
/* .64248 1.19093 -2.94494 2.66037 1.6624 .04414 .99807 .00514\n\ */
|
||||
/* .61622 -.76318 .75918 .41939 -.38075 -.30623 .09867 -.19237"); */
|
||||
/* } */
|
||||
|
||||
BENCH(dct, bench) {
|
||||
float M[8][8] /* clang-format off */ = {
|
||||
{.101961, .486275, .082353, .082353, .937255, .321569, .14902, .270588},
|
||||
{.384314, .062745, .152941, .003922, .921569, .015686, .247059, 0},
|
||||
{.760784, .023529, .411765, .443137, .862745, .85098, .435294, .631373},
|
||||
{.309804, .141176, .54902, .984314, .478431, .6, .364706, .643137},
|
||||
{.780392, .811765, .458824, .964706, .439216, .941176, .321569, .313725},
|
||||
{.596078, .207843, .133333, .345098, .278431, .192157, .52549, .627451},
|
||||
{.952941, .090196, .290196, .717647, .686275, .713725, .54902, .411765},
|
||||
{.109804, .121569, .403922, .27451, .470588, .007843, .168627, .105882},
|
||||
} /* clang-format on */;
|
||||
void *data = tgc(tmalloc(sizeof(M)));
|
||||
EZBENCH2("dct", memcpy(data, M, sizeof(M)), EXPROPRIATE(dctjpeg(data)));
|
||||
}
|
|
@ -29,18 +29,18 @@ TEST(GetChromaticAdaptationMatrix, testSuperiorIlluminationBannedInCalifornia) {
|
|||
double M[3][3];
|
||||
GetChromaticAdaptationMatrix(M, kIlluminantD65, kIlluminantA);
|
||||
EXPECT_DBLMATRIXEQ(5, rint, 3, 3, M, "\n\
|
||||
1.21646 .11099 -.15493\n\
|
||||
.15333 .91523 -.056\n\
|
||||
-.02395 .0359 .31475");
|
||||
1.2165 .11099 -.15493\n\
|
||||
.15333 .91523 -.055995\n\
|
||||
-.023947 .035898 .31475");
|
||||
}
|
||||
|
||||
TEST(GetChromaticAdaptationMatrix, testD65ToD50_soWeCanCieLab) {
|
||||
double M[3][3];
|
||||
GetChromaticAdaptationMatrix(M, kIlluminantD65, kIlluminantD50);
|
||||
EXPECT_DBLMATRIXEQ(6, rint, 3, 3, M, "\n\
|
||||
1.047811 .022887 -.050127\n\
|
||||
.029542 .990484 -.017049\n\
|
||||
-.009234 .015044 .752132");
|
||||
1.04781 .0228866 -.050127\n\
|
||||
.0295424 .990484 -.0170491\n\
|
||||
-.00923449 .0150436 .752132");
|
||||
}
|
||||
|
||||
BENCH(GetChromaticAdaptationMatrix, bench) {
|
||||
|
|
|
@ -28,9 +28,9 @@ TEST(inv3, test) {
|
|||
double M[3][3];
|
||||
inv3(M, kBradford, det3(kBradford));
|
||||
EXPECT_DBLMATRIXEQ(7, rint, 3, 3, M, "\n\
|
||||
.9869929 -.1470543 .1599627\n\
|
||||
.4323053 .5183603 .0492912\n\
|
||||
-.0085287 .0400428 .9684867");
|
||||
.9869929 -.1470543 .1599627\n\
|
||||
.4323053 .5183603 .04929123\n\
|
||||
-.008528665 .04004282 .9684867");
|
||||
}
|
||||
|
||||
BENCH(inv3, bench) {
|
||||
|
|
|
@ -31,7 +31,7 @@ unsigned windex$k8(short *, size_t) hidden;
|
|||
unsigned windex$avx2(short *, size_t) hidden;
|
||||
unsigned windex$sse4(short *, size_t) hidden;
|
||||
|
||||
const short kW[64] aligned(32) = {
|
||||
const short kW[64] forcealign(32) = {
|
||||
8281, 3883, 1365, 1786, 9006, 3681, 5563, 8013, 5787, 9063, 2923,
|
||||
3564, 6122, 32, 1436, 0741, 7957, 9219, 1320, 2083, 1904, 8905,
|
||||
2465, 9122, 9563, 1290, 4474, 3988, 9920, 8325, 1088, 2915, 33,
|
||||
|
@ -40,13 +40,13 @@ const short kW[64] aligned(32) = {
|
|||
1730, 2041, 7707, 5096, 6876, 1324, 1242, 5283, 0x7fff,
|
||||
};
|
||||
|
||||
const short kW2[32] aligned(32) = {
|
||||
const short kW2[32] forcealign(32) = {
|
||||
8281, 1, 1365, 1786, 9006, 3681, 5563, 8013, 5787, 9063, 2923,
|
||||
3564, 6122, 32, 1436, 0741, 7957, 9219, 1320, 2083, 1904, 8905,
|
||||
2465, 9122, 9563, 1290, 4474, 3988, 9920, 8325, 1088, 2915,
|
||||
};
|
||||
|
||||
const short kW3[64] aligned(32) = {
|
||||
const short kW3[64] forcealign(32) = {
|
||||
8281, 0x7fff, 1365, 1786, 9006, 3681, 5563, 8013, 5787, 9063, 2923,
|
||||
3564, 6122, 32, 1436, 0741, 7957, 9219, 1320, 2083, 1904, 8905,
|
||||
2465, 9122, 9563, 1290, 4474, 3988, 9920, 8325, 1088, 2915, 33,
|
||||
|
@ -64,7 +64,7 @@ const short kW3[64] aligned(32) = {
|
|||
})
|
||||
|
||||
TEST(windex, testRealWorldPicks) {
|
||||
const short kPicks[96] aligned(32) = {
|
||||
const short kPicks[96] forcealign(32) = {
|
||||
103, 85, 145, 146, 121, 103, 145, 187, 146, 189,
|
||||
121, 103, 139, 121, 63, 105, 105, 147, 60, 103,
|
||||
103, 146, 121, 103, 139, 121, 139, 121, 157, 139,
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue