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
Justine Tunney 2020-12-05 12:20:41 -08:00
parent e44a0cf6f8
commit 8da931a7f6
298 changed files with 19493 additions and 11950 deletions

View File

@ -115,7 +115,6 @@ include third_party/dlmalloc/dlmalloc.mk # │
include libc/mem/mem.mk # │ include libc/mem/mem.mk # │
include libc/ohmyplus/ohmyplus.mk # │ include libc/ohmyplus/ohmyplus.mk # │
include libc/zipos/zipos.mk # │ include libc/zipos/zipos.mk # │
include third_party/dtoa/dtoa.mk # │
include third_party/gdtoa/gdtoa.mk # │ include third_party/gdtoa/gdtoa.mk # │
include libc/time/time.mk # │ include libc/time/time.mk # │
include libc/alg/alg.mk # │ include libc/alg/alg.mk # │
@ -140,6 +139,7 @@ include libc/dns/dns.mk # │
include libc/crypto/crypto.mk # │ include libc/crypto/crypto.mk # │
include net/http/http.mk #─┘ include net/http/http.mk #─┘
include third_party/chibicc/chibicc.mk include third_party/chibicc/chibicc.mk
include third_party/chibicc/test/test.mk
include third_party/lemon/lemon.mk include third_party/lemon/lemon.mk
include third_party/linenoise/linenoise.mk include third_party/linenoise/linenoise.mk
include third_party/editline/editline.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/emubin/emubin.mk
include tool/build/build.mk include tool/build/build.mk
include tool/calc/calc.mk include tool/calc/calc.mk
include tool/tags/tags.mk
include tool/decode/lib/decodelib.mk include tool/decode/lib/decodelib.mk
include tool/decode/decode.mk include tool/decode/decode.mk
include tool/hash/hash.mk include tool/hash/hash.mk
include tool/net/net.mk include tool/net/net.mk
include tool/viz/viz.mk include tool/viz/viz.mk
include tool/cc/cc.mk
include tool/tool.mk include tool/tool.mk
include test/libc/alg/test.mk include test/libc/alg/test.mk
include test/libc/tinymath/test.mk include test/libc/tinymath/test.mk
@ -278,7 +276,7 @@ COSMOPOLITAN_OBJECTS = \
LIBC_ZIPOS \ LIBC_ZIPOS \
THIRD_PARTY_COMPILER_RT \ THIRD_PARTY_COMPILER_RT \
THIRD_PARTY_DLMALLOC \ THIRD_PARTY_DLMALLOC \
THIRD_PARTY_DTOA \ THIRD_PARTY_GDTOA \
THIRD_PARTY_GETOPT \ THIRD_PARTY_GETOPT \
THIRD_PARTY_MUSL \ THIRD_PARTY_MUSL \
THIRD_PARTY_REGEX THIRD_PARTY_REGEX
@ -311,7 +309,7 @@ COSMOPOLITAN_HEADERS = \
LIBC_X \ LIBC_X \
LIBC_ZIPOS \ LIBC_ZIPOS \
THIRD_PARTY_DLMALLOC \ THIRD_PARTY_DLMALLOC \
THIRD_PARTY_DTOA \ THIRD_PARTY_GDTOA \
THIRD_PARTY_GETOPT \ THIRD_PARTY_GETOPT \
THIRD_PARTY_MUSL \ THIRD_PARTY_MUSL \
THIRD_PARTY_REGEX THIRD_PARTY_REGEX

View File

@ -53,7 +53,7 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0) #if !(__ASSEMBLER__ + __LINKER__ + 0)
void apmoff(void) noreturn; void apmoff(void) wontreturn;
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* APE_LIB_APM_H_ */ #endif /* APE_LIB_APM_H_ */

View File

@ -197,7 +197,7 @@ struct IdtDescriptor {
struct thatispacked PageTable { struct thatispacked PageTable {
uint64_t p[512]; uint64_t p[512];
} aligned(PAGESIZE); } forcealign(PAGESIZE);
extern struct PageTable g_pml4t; extern struct PageTable g_pml4t;
extern struct GlobalDescriptorTable gdt; 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;
extern uint64_t g_ptsp_xlm; extern uint64_t g_ptsp_xlm;
void bootdr(char drive) noreturn; void bootdr(char drive) wontreturn;
void smapsort(struct SmapEntry *); void smapsort(struct SmapEntry *);
uint64_t *__getpagetableentry(int64_t, unsigned, struct PageTable *, uint64_t *__getpagetableentry(int64_t, unsigned, struct PageTable *,

View File

@ -138,7 +138,7 @@ CONFIG_CCFLAGS += \
-fno-align-loops -fno-align-loops
TARGET_ARCH ?= \ TARGET_ARCH ?= \
-march=k8-sse3 -msse3
endif endif

View File

@ -266,7 +266,7 @@ struct plm_audio_t {
float D[1024]; float D[1024];
float V[1024]; float V[1024];
float U[32]; float U[32];
} aligned(64); } forcealign(64);
typedef plm_audio_t plm_audio_t; typedef plm_audio_t plm_audio_t;

View File

@ -77,12 +77,12 @@ struct plm_samples_t {
double time; double time;
unsigned int count; unsigned int count;
#ifdef PLM_AUDIO_SEPARATE_CHANNELS #ifdef PLM_AUDIO_SEPARATE_CHANNELS
float left[PLM_AUDIO_SAMPLES_PER_FRAME] aligned(32); float left[PLM_AUDIO_SAMPLES_PER_FRAME] forcealign(32);
float right[PLM_AUDIO_SAMPLES_PER_FRAME] aligned(32); float right[PLM_AUDIO_SAMPLES_PER_FRAME] forcealign(32);
#else #else
float interleaved[PLM_AUDIO_SAMPLES_PER_FRAME * 2] aligned(32); float interleaved[PLM_AUDIO_SAMPLES_PER_FRAME * 2] forcealign(32);
#endif #endif
} aligned(32); } forcealign(32);
typedef struct plm_samples_t plm_samples_t; typedef struct plm_samples_t plm_samples_t;

View File

@ -33,7 +33,6 @@
#include "libc/str/str.h" #include "libc/str/str.h"
#include "libc/testlib/testlib.h" #include "libc/testlib/testlib.h"
#include "libc/x/x.h" #include "libc/x/x.h"
#include "third_party/dtoa/dtoa.h"
#include "tool/viz/lib/knobs.h" #include "tool/viz/lib/knobs.h"
/** /**

View File

@ -611,8 +611,8 @@ static struct Pick PickBlockUnicodeAnsi(struct TtyRgb tl, struct TtyRgb tr,
struct TtyRgb bl2 = GetQuant(bl); struct TtyRgb bl2 = GetQuant(bl);
struct TtyRgb br2 = GetQuant(br); struct TtyRgb br2 = GetQuant(br);
unsigned i, p1, p2; unsigned i, p1, p2;
uint16_t picks1[96] aligned(32); uint16_t picks1[96] forcealign(32);
uint16_t picks2[32] aligned(32); uint16_t picks2[32] forcealign(32);
memset(picks1, 0x79, sizeof(picks1)); memset(picks1, 0x79, sizeof(picks1));
memset(picks2, 0x79, sizeof(picks2)); memset(picks2, 0x79, sizeof(picks2));
PickUnicode(picks1, tl, tr, bl, br, tl2, tr2, bl2, br2); 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, static struct Pick PickBlockUnicodeTrue(struct TtyRgb tl, struct TtyRgb tr,
struct TtyRgb bl, struct TtyRgb br) { struct TtyRgb bl, struct TtyRgb br) {
unsigned i; unsigned i;
uint16_t picks[96] aligned(32); uint16_t picks[96] forcealign(32);
memset(picks, 0x79, sizeof(picks)); memset(picks, 0x79, sizeof(picks));
PickUnicode(picks, tl, tr, bl, br, tl, tr, bl, br); PickUnicode(picks, tl, tr, bl, br, tl, tr, bl, br);
i = windex(picks, 96); 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 bl2 = GetQuant(bl);
struct TtyRgb br2 = GetQuant(br); struct TtyRgb br2 = GetQuant(br);
unsigned i, p1, p2; unsigned i, p1, p2;
uint16_t picks1[32] aligned(32); uint16_t picks1[32] forcealign(32);
uint16_t picks2[32] aligned(32); uint16_t picks2[32] forcealign(32);
memset(picks1, 0x79, sizeof(picks1)); memset(picks1, 0x79, sizeof(picks1));
memset(picks2, 0x79, sizeof(picks2)); memset(picks2, 0x79, sizeof(picks2));
PickCp437(picks1, tl, tr, bl, br, tl2, tr2, bl2, br2); 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, static struct Pick PickBlockCp437True(struct TtyRgb tl, struct TtyRgb tr,
struct TtyRgb bl, struct TtyRgb br) { struct TtyRgb bl, struct TtyRgb br) {
unsigned i; unsigned i;
uint16_t picks[32] aligned(32); uint16_t picks[32] forcealign(32);
memset(picks, 0x79, sizeof(picks)); memset(picks, 0x79, sizeof(picks));
PickCp437(picks, tl, tr, bl, br, tl, tr, bl, br); PickCp437(picks, tl, tr, bl, br, tl, tr, bl, br);
return kPicksCp437[windex(picks, 32)]; return kPicksCp437[windex(picks, 32)];

View File

@ -42,7 +42,7 @@ FLAGS\n\
int flags; int flags;
bool force; 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); fprintf(f, "%s%s%s", "Usage: ", program_invocation_name, USAGE);
exit(rc); exit(rc);
} }

View File

@ -72,7 +72,7 @@ EXAMPLES_DIRECTDEPS = \
LIBC_ZIPOS \ LIBC_ZIPOS \
THIRD_PARTY_COMPILER_RT \ THIRD_PARTY_COMPILER_RT \
THIRD_PARTY_DLMALLOC \ THIRD_PARTY_DLMALLOC \
THIRD_PARTY_DTOA \ THIRD_PARTY_GDTOA \
THIRD_PARTY_GETOPT \ THIRD_PARTY_GETOPT \
THIRD_PARTY_MUSL \ THIRD_PARTY_MUSL \
THIRD_PARTY_STB \ THIRD_PARTY_STB \

View File

@ -18,7 +18,7 @@
#include "libc/sysv/consts/sig.h" #include "libc/sysv/consts/sig.h"
#include "libc/time/time.h" #include "libc/time/time.h"
#include "libc/x/x.h" #include "libc/x/x.h"
#include "third_party/dtoa/dtoa.h" #include "third_party/gdtoa/gdtoa.h"
/** /**
* @fileoverview Measure CPU clock mystery constants. * @fileoverview Measure CPU clock mystery constants.
@ -52,15 +52,18 @@ long double GetSample(void) {
void MeasureNanosecondsPerAlwaysRunningTimerCycle(void) { void MeasureNanosecondsPerAlwaysRunningTimerCycle(void) {
int i; int i;
long double avg, samp; long double avg, samp, elapsed;
start_ = now(); start_ = now();
for (i = 1, avg = 1.0L; !isdone_; ++i) { for (i = 1, avg = 1.0L; !isdone_; ++i) {
samp = GetSample(); samp = GetSample();
avg += (samp - avg) / i; avg += (samp - avg) / i;
dsleep(kInterval); dsleep(kInterval);
printf("1c = %sns (last=%sns spent=%ss)\n", g_fmt(dtoabuf_[0], (double)avg), elapsed = now() - start_;
g_fmt(dtoabuf_[1], (double)samp), g_xfmt_p(dtoabuf_[0], &avg, 15, 32, 0);
g_fmt(dtoabuf_[2], (double)(now() - start_))); 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]);
} }
} }

View File

@ -1774,7 +1774,7 @@ Press enter to continue without sound: ",
for (;;) CPU::Op(); 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); fprintf(f, "%s%s%s", "Usage: ", program_invocation_name, USAGE);
exit(rc); exit(rc);
} }

View File

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

View File

@ -141,7 +141,7 @@
#include "libc/sysv/consts/rlim.h" #include "libc/sysv/consts/rlim.h"
#include "libc/sysv/consts/sig.h" #include "libc/sysv/consts/sig.h"
#include "libc/sysv/consts/w.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" #include "third_party/musl/passwd.h"
#undef CEOF #undef CEOF
@ -1602,7 +1602,7 @@ static inline void sigclearmask(void) {
* just do a longjmp to the exception handler. The type of exception is * just do a longjmp to the exception handler. The type of exception is
* stored in the global variable "exception". * stored in the global variable "exception".
*/ */
noreturn static void exraise(int e) { wontreturn static void exraise(int e) {
if (vforked) _exit(exitstatus); if (vforked) _exit(exitstatus);
INTOFF; INTOFF;
exception = e; exception = e;
@ -1617,7 +1617,7 @@ noreturn static void exraise(int e) {
* are held using the INTOFF macro. (The test for iflag is just * are held using the INTOFF macro. (The test for iflag is just
* defensive programming.) * defensive programming.)
*/ */
noreturn static void onint(void) { wontreturn static void onint(void) {
intpending = 0; intpending = 0;
sigclearmask(); sigclearmask();
if (!(rootshell && iflag)) { 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 * is not NULL then error prints an error message using printf style
* formatting. It then raises the error exception. * 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); exvwarning(msg, ap);
flushall(); flushall();
exraise(cond); exraise(cond);
} }
noreturn static void exerror(int cond, const char *msg, ...) { wontreturn static void exerror(int cond, const char *msg, ...) {
va_list ap; va_list ap;
va_start(ap, msg); va_start(ap, msg);
exverror(cond, msg, ap); exverror(cond, msg, ap);
va_end(ap); va_end(ap);
} }
noreturn static void sh_error(const char *msg, ...) { wontreturn static void sh_error(const char *msg, ...) {
va_list ap; va_list ap;
exitstatus = 2; exitstatus = 2;
va_start(ap, msg); va_start(ap, msg);
@ -1917,16 +1917,16 @@ noreturn static void sh_error(const char *msg, ...) {
va_end(ap); va_end(ap);
} }
noreturn static void badnum(const char *s) { wontreturn static void badnum(const char *s) {
sh_error(illnum, s); sh_error(illnum, s);
} }
noreturn static void synerror(const char *msg) { wontreturn static void synerror(const char *msg) {
errlinno = plinno; errlinno = plinno;
sh_error("Syntax error: %s", msg); 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); 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 * argument is the token that is expected, or -1 if more than one type
* of token can occur at this point. * of token can occur at this point.
*/ */
noreturn static void synexpect(int token) { wontreturn static void synexpect(int token) {
char msg[64]; char msg[64];
if (token >= 0) { if (token >= 0) {
fmtstr(msg, 64, "%s unexpected (expecting %s)", tokname[lasttoken], tokname[token]); fmtstr(msg, 64, "%s unexpected (expecting %s)", tokname[lasttoken], tokname[token]);
@ -1945,7 +1945,7 @@ noreturn static void synexpect(int token) {
synerror(msg); 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 *msg;
const char *tail; const char *tail;
tail = nullstr; tail = nullstr;
@ -2096,7 +2096,7 @@ static char *nodesavestr(s) char *s;
return rtn; 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 **listvars(int, int, char ***);
static char *argstr(char *p, int flag); static char *argstr(char *p, int flag);
static char *conv_escape(char *, int *); static char *conv_escape(char *, int *);
@ -3175,7 +3175,7 @@ out:
return exitstatus; return exitstatus;
} }
noreturn static void evaltreenr(union node *n, int flags) { wontreturn static void evaltreenr(union node *n, int flags) {
evaltree(n, flags); evaltree(n, flags);
abort(); 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 * Exec a program. Never returns. If you change this routine, you may
* have to change the find_command routine as well. * 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; char *cmdname;
int e; int e;
char **envp; char **envp;
@ -9316,7 +9316,7 @@ static void setinteractive(int on) {
/* /*
* Called to exit the shell. * Called to exit the shell.
*/ */
noreturn static void exitshell(void) { wontreturn static void exitshell(void) {
struct jmploc loc; struct jmploc loc;
char *p; char *p;
savestatus = exitstatus; savestatus = exitstatus;

View File

@ -3,7 +3,7 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0) #if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_ 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 #ifdef NDEBUG
#define __ASSERT_FAIL(EXPR, FILE, LINE) #define __ASSERT_FAIL(EXPR, FILE, LINE)

View File

@ -45,7 +45,7 @@ COSMOPOLITAN_C_START_
struct AtomicFlag { struct AtomicFlag {
uint32_t __cacheline[16]; /* Intel V.O §9.4.6 */ uint32_t __cacheline[16]; /* Intel V.O §9.4.6 */
} aligned(64); } forcealign(64);
COSMOPOLITAN_C_END_ COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View File

@ -7,9 +7,9 @@ typedef float __m256 _Vector_size(32) mayalias;
typedef double __m256d _Vector_size(32) mayalias; typedef double __m256d _Vector_size(32) mayalias;
typedef long long __m256i _Vector_size(32) mayalias; typedef long long __m256i _Vector_size(32) mayalias;
typedef float __m256_u _Vector_size(32) aligned(1) mayalias; typedef float __m256_u _Vector_size(32) forcealign(1) mayalias;
typedef double __m256d_u _Vector_size(32) aligned(1) mayalias; typedef double __m256d_u _Vector_size(32) forcealign(1) mayalias;
typedef long long __m256i_u _Vector_size(32) aligned(1) mayalias; typedef long long __m256i_u _Vector_size(32) forcealign(1) mayalias;
typedef double __v4df _Vector_size(32); typedef double __v4df _Vector_size(32);
typedef float __v8sf _Vector_size(32); typedef float __v8sf _Vector_size(32);

View File

@ -16,12 +16,12 @@ typedef short __v8hi _Vector_size(16);
typedef unsigned short __v8hu _Vector_size(16); typedef unsigned short __v8hu _Vector_size(16);
typedef double __v2df _Vector_size(16); typedef double __v2df _Vector_size(16);
typedef double __m128d _Vector_size(16) aligned(16); typedef double __m128d _Vector_size(16) forcealign(16);
typedef double __m128d_u _Vector_size(16) aligned(1); typedef double __m128d_u _Vector_size(16) forcealign(1);
typedef long long __v2di _Vector_size(16); typedef long long __v2di _Vector_size(16);
typedef long long __m128i _Vector_size(16) aligned(16); typedef long long __m128i _Vector_size(16) forcealign(16);
typedef long long __m128i_u _Vector_size(16) aligned(1); typedef long long __m128i_u _Vector_size(16) forcealign(1);
typedef unsigned long long __v2du _Vector_size(16); typedef unsigned long long __v2du _Vector_size(16);
struct thatispacked mayalias __usi128ma { struct thatispacked mayalias __usi128ma {

View File

@ -35,8 +35,8 @@
typedef int __v4si _Vector_size(16); typedef int __v4si _Vector_size(16);
typedef unsigned int __v4su _Vector_size(16); typedef unsigned int __v4su _Vector_size(16);
typedef float __v4sf _Vector_size(16); typedef float __v4sf _Vector_size(16);
typedef float __m128 _Vector_size(16) aligned(16) mayalias; typedef float __m128 _Vector_size(16) forcealign(16) mayalias;
typedef float __m128_u _Vector_size(16) aligned(1) mayalias; typedef float __m128_u _Vector_size(16) forcealign(1) mayalias;
/*───────────────────────────────────────────────────────────────────────────│─╗ /*───────────────────────────────────────────────────────────────────────────│─╗
cosmopolitan § it's a trap! » sse » simd ops cosmopolitan § it's a trap! » sse » simd ops

View File

@ -18,6 +18,7 @@
02110-1301 USA 02110-1301 USA
*/ */
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/struct/stat.h" #include "libc/calls/struct/stat.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/errno.h" #include "libc/errno.h"
@ -33,12 +34,18 @@
* function. The stat() function may be used to differentiate them. * function. The stat() function may be used to differentiate them.
*/ */
bool fileexists(const char *path) { bool fileexists(const char *path) {
/* TODO(jart): Use fast path on NT? */ int rc, olderr;
struct stat st; struct stat st;
int olderr = errno; uint16_t path16[PATH_MAX];
int rc = stat(path, &st); if (!IsWindows()) {
if (rc == -1 && (errno == ENOENT || errno == ENOTDIR)) { olderr = errno;
errno = olderr; 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;
} }

View File

@ -34,8 +34,8 @@
textwindows int fstat$nt(int64_t handle, struct stat *st) { textwindows int fstat$nt(int64_t handle, struct stat *st) {
int filetype; int filetype;
uint64_t actualsize; uint64_t actualsize;
struct NtByHandleFileInformation wst;
struct NtFileCompressionInfo fci; struct NtFileCompressionInfo fci;
struct NtByHandleFileInformation wst;
if (GetFileInformationByHandle(handle, &wst)) { if (GetFileInformationByHandle(handle, &wst)) {
memset(st, 0, sizeof(*st)); memset(st, 0, sizeof(*st));
filetype = GetFileType(handle); filetype = GetFileType(handle);

View File

@ -198,12 +198,12 @@ i32 tunefd$sysv(i32, i32, i32, i32) hidden;
u32 fprot2nt(i32, i32) hidden; u32 fprot2nt(i32, i32) hidden;
u32 prot2nt(i32, i32) privileged; u32 prot2nt(i32, i32) privileged;
void __restore_rt() hidden; 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 utimensat$xnu(int, const char *, const struct timespec *, int) hidden;
int nanosleep$xnu(const struct timespec *, struct timespec *) hidden; int nanosleep$xnu(const struct timespec *, struct timespec *) hidden;
void stat2linux(void *) hidden; void stat2linux(void *) hidden;
void xnutrampoline(void *, i32, i32, const struct __darwin_siginfo *, 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 cosmopolitan § syscalls » windows nt » veneers

View File

@ -27,7 +27,7 @@
* @asyncsignalsafe * @asyncsignalsafe
*/ */
bool32 isatty(int fd) { bool32 isatty(int fd) {
char buf[sizeof(uint16_t) * 4] aligned(2); char buf[sizeof(uint16_t) * 4] forcealign(2);
if (!IsWindows()) { if (!IsWindows()) {
return ioctl$sysv(fd, TIOCGWINSZ, &buf) != -1; return ioctl$sysv(fd, TIOCGWINSZ, &buf) != -1;
} else { } else {

View File

@ -14,7 +14,7 @@ struct sigaction { /* cosmo abi */
void (*sa_restorer)(void); void (*sa_restorer)(void);
struct sigset sa_mask; struct sigset sa_mask;
int64_t __pad; int64_t __pad;
} aligned(8); } forcealign(8);
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_H_ */ #endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_H_ */

View File

@ -49,7 +49,7 @@ struct siginfo {
}; };
char __ignoreme[128 - 2 * sizeof(int32_t) - sizeof(int64_t)]; char __ignoreme[128 - 2 * sizeof(int32_t) - sizeof(int64_t)];
}; };
} aligned(8); } forcealign(8);
typedef struct siginfo siginfo_t; typedef struct siginfo siginfo_t;

View File

@ -425,9 +425,9 @@ static void xnussefpustate2linux(struct FpuState *fs,
memcpy(fs->st, &xnufs->__fpu_stmm0, (8 + 16) * sizeof(uint128_t)); memcpy(fs->st, &xnufs->__fpu_stmm0, (8 + 16) * sizeof(uint128_t));
} }
noreturn void xnutrampoline(void *fn, int infostyle, int sig, wontreturn void xnutrampoline(void *fn, int infostyle, int sig,
const struct __darwin_siginfo *xnuinfo, const struct __darwin_siginfo *xnuinfo,
const struct __darwin_ucontext *xnuctx) { const struct __darwin_ucontext *xnuctx) {
/* note: this function impl can't access static memory */ /* note: this function impl can't access static memory */
intptr_t ax; intptr_t ax;
struct Goodies { struct Goodies {

View File

@ -97,7 +97,7 @@ double RoundDecimalPlaces(double, double, double (*)(double));
#endif #endif
#ifndef __STRICT_ANSI__ #ifndef __STRICT_ANSI__
intmax_t __imaxabs(intmax_t) asm("imaxabs") libcesque pureconst; intmax_t __imaxabs(intmax_t) libcesque pureconst;
#define imaxabs(x) __imaxabs(x) #define imaxabs(x) __imaxabs(x)
#endif /* !ANSI */ #endif /* !ANSI */

View File

@ -20,6 +20,6 @@
#include "libc/conv/conv.h" #include "libc/conv/conv.h"
#include "libc/macros.h" #include "libc/macros.h"
intmax_t imaxabs(intmax_t x) { intmax_t(imaxabs)(intmax_t x) {
return ABS(x); return ABS(x);
} }

View File

@ -18,16 +18,7 @@
02110-1301 USA 02110-1301 USA
*/ */
#include "libc/macros.h" #include "libc/macros.h"
.source __FILE__
/ Avoid dtoa needing .data section. __imaxabs:
.bss jmp imaxabs
.align 4 .endfn __imaxabs,globl
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

View File

@ -37,10 +37,10 @@
* @see strtoumax * @see strtoumax
*/ */
intmax_t strtoimax(const char *s, char **endptr, int base) { intmax_t strtoimax(const char *s, char **endptr, int base) {
bool neg;
uintmax_t x; uintmax_t x;
intmax_t res; intmax_t res;
unsigned diglet, bits; unsigned diglet, bits;
bool neg, islong, isunsigned;
x = 0; x = 0;
bits = 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 (endptr) *endptr = s;
if (neg) { if (neg) {
@ -114,13 +112,5 @@ intmax_t strtoimax(const char *s, char **endptr, int base) {
res = x; res = x;
} }
if (isunsigned) {
if (islong) {
res = (uint64_t)res;
} else {
res = (uint32_t)res;
}
}
return res; return res;
} }

View File

@ -28,7 +28,7 @@ COSMOPOLITAN_C_START_
Performance (New Hardware) ~20 ns ~40 ns ~400 ns Performance (New Hardware) ~20 ns ~40 ns ~400 ns
Performance (Old Hardware) ~400 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 { struct Rijndael {
union { union {
@ -47,8 +47,8 @@ aes_block_t unrijndael(uint32_t, aes_block_t, const struct Rijndael *);
cosmopolitan § cryptography » implementation details cosmopolitan § cryptography » implementation details
*/ */
extern const uint8_t kAesSbox[256] aligned(64); extern const uint8_t kAesSbox[256] forcealign(64);
extern const uint8_t kAesSboxInverse[256] aligned(64); extern const uint8_t kAesSboxInverse[256] forcealign(64);
aes_block_t InvMixColumns(aes_block_t) hidden; aes_block_t InvMixColumns(aes_block_t) hidden;

View File

@ -2,7 +2,7 @@
#define COSMOPOLITAN_LIBC_FMT_PFLINK_H_ #define COSMOPOLITAN_LIBC_FMT_PFLINK_H_
#include "libc/dce.h" #include "libc/dce.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0) #if !(__ASSEMBLER__ + __LINKER__ + 0)
#ifndef __STRICT_ANSI__ #if !defined(__STRICT_ANSI__) && !defined(__chibicc__)
/** /**
* @fileoverview builtin+preprocessor+linker tricks for printf/scanf. * @fileoverview builtin+preprocessor+linker tricks for printf/scanf.
@ -65,6 +65,19 @@
#else #else
#define PFLINK(FMT) FMT #define PFLINK(FMT) FMT
#define SFLINK(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 /* __STRICT_ANSI__ */
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_FMT_PFLINK_H_ */ #endif /* COSMOPOLITAN_LIBC_FMT_PFLINK_H_ */

View File

@ -2,6 +2,14 @@
#define __attribute__(x) #define __attribute__(x)
#endif #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 #if defined(__STRICT_ANSI__) && __STDC_VERSION__ + 0 < 201112
#define asm __asm__ #define asm __asm__
#endif #endif
@ -67,18 +75,6 @@
} while (0) } while (0)
#endif #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 #if __STDC_VERSION__ + 0 < 201112
#define ____Static_assert(x, y) A##B #define ____Static_assert(x, y) A##B
#define ___Static_assert(x, y) ____Static_assert(x, y) #define ___Static_assert(x, y) ____Static_assert(x, y)
@ -195,7 +191,7 @@ typedef int64_t intmax_t;
typedef uint64_t uintmax_t; typedef uint64_t uintmax_t;
#endif #endif
#ifdef __GNUC__ #ifndef __chibicc__
#define va_list __builtin_va_list #define va_list __builtin_va_list
#define va_arg(ap, type) __builtin_va_arg(ap, type) #define va_arg(ap, type) __builtin_va_arg(ap, type)
#define va_copy(dest, src) __builtin_va_copy(dest, src) #define va_copy(dest, src) __builtin_va_copy(dest, src)
@ -230,11 +226,11 @@ typedef uint64_t uintmax_t;
/** /**
* Aligns automatic or static variable. * Aligns automatic or static variable.
*/ */
#ifndef aligned #ifndef forcealign
#ifndef __STRICT_ANSI__ #ifndef __STRICT_ANSI__
#define aligned(bytes) __attribute__((__aligned__(bytes))) #define forcealign(bytes) __attribute__((__aligned__(bytes)))
#else #else
#define aligned(bytes) #define forcealign(bytes)
#endif #endif
#endif #endif
@ -291,13 +287,13 @@ typedef uint64_t uintmax_t;
#endif #endif
#endif #endif
#ifndef noreturn #ifndef wontreturn
#if !defined(__STRICT_ANSI__) && \ #if !defined(__STRICT_ANSI__) && \
(__has_attribute(__noreturn__) || \ (__has_attribute(__noreturn__) || \
(__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 208) (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 208)
#define noreturn __attribute__((__noreturn__)) #define wontreturn __attribute__((__noreturn__))
#else #else
#define noreturn #define wontreturn
#endif #endif
#endif #endif
@ -1067,13 +1063,5 @@ typedef uint64_t uintmax_t;
STATIC_YOINK_SOURCE(__BASE_FILE__); STATIC_YOINK_SOURCE(__BASE_FILE__);
#endif #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_BEGIN_
#define MACHINE_CODE_ANALYSIS_END_ #define MACHINE_CODE_ANALYSIS_END_

View File

@ -1,50 +1,17 @@
typedef struct { #include "libc/runtime/valist.h"
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])
#define __GNUC_VA_LIST 1 #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];

View File

@ -9,7 +9,7 @@
#if defined(__x86_64__) && !defined(__STRICT_ANSI__) #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) \ #define INTRIN_SSEVEX_X_X_X_(PURE, ISA, OP, FLAGS, A, B, C) \
do { \ do { \

View File

@ -5,12 +5,12 @@
#define PTHREAD_ONCE_INIT 0 #define PTHREAD_ONCE_INIT 0
#define PTHREAD_MUTEX_NORMAL 0 #define PTHREAD_MUTEX_NORMAL 0
#define PTHREAD_MUTEX_DEFAULT 0 #define PTHREAD_MUTEX_DEFAULT 0
#define PTHREAD_MUTEX_RECURSIVE 1 #define PTHREAD_MUTEX_RECURSIVE 1
#define PTHREAD_MUTEX_ERRORCHECK 2 #define PTHREAD_MUTEX_ERRORCHECK 2
#define PTHREAD_MUTEX_STALLED 0 #define PTHREAD_MUTEX_STALLED 0
#define PTHREAD_MUTEX_ROBUST 1 #define PTHREAD_MUTEX_ROBUST 1
/* clang-format off */ /* clang-format off */
#define PTHREAD_MUTEX_INITIALIZER {{{0}}} #define PTHREAD_MUTEX_INITIALIZER {{{0}}}
@ -65,7 +65,7 @@ typedef struct {
} __u; } __u;
} pthread_rwlock_t; } pthread_rwlock_t;
noreturn void pthread_exit(void *); wontreturn void pthread_exit(void *);
pureconst pthread_t pthread_self(void); pureconst pthread_t pthread_self(void);
int pthread_create(pthread_t *, const pthread_attr_t *, void *(*)(void *), int pthread_create(pthread_t *, const pthread_attr_t *, void *(*)(void *),
void *); void *);

View File

@ -110,13 +110,13 @@
#define PWSTR WCHAR* #define PWSTR WCHAR*
#define PZPWSTR PWSTR* #define PZPWSTR PWSTR*
#define PCZPWSTR CONST PWSTR* #define PCZPWSTR CONST PWSTR*
#define LPUWSTR WCHAR aligned(1)* #define LPUWSTR WCHAR forcealign(1)*
#define PUWSTR WCHAR aligned(1)* #define PUWSTR WCHAR forcealign(1)*
#define LPCWSTR CONST WCHAR* #define LPCWSTR CONST WCHAR*
#define PCWSTR CONST WCHAR* #define PCWSTR CONST WCHAR*
#define PZPCWSTR PCWSTR* #define PZPCWSTR PCWSTR*
#define LPCUWSTR CONST WCHAR aligned(1)* #define LPCUWSTR CONST WCHAR forcealign(1)*
#define PCUWSTR CONST WCHAR aligned(1)* #define PCUWSTR CONST WCHAR forcealign(1)*
#define PCHAR CHAR* #define PCHAR CHAR*
#define LPCH CHAR* #define LPCH CHAR*
#define PCH CHAR* #define PCH CHAR*

View File

@ -3,7 +3,7 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0) #if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_ COSMOPOLITAN_C_START_
forceinline noreturn long LinuxExit(long rc) { forceinline wontreturn long LinuxExit(long rc) {
asm volatile("syscall" asm volatile("syscall"
: /* no outputs */ : /* no outputs */
: "a"(0xE7), "D"(rc) : "a"(0xE7), "D"(rc)

View File

@ -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); write(STDERR_FILENO, msg, size);
__die(); __die();
} }
@ -163,7 +163,7 @@ static char *__asan_report_start(char *p) {
return stpcpy(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]; char *p, ibuf[21], buf[256];
p = __asan_report_start(buf); p = __asan_report_start(buf);
p = stpcpy(p, __asan_dscribe_free_poison(c)); 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); __asan_die(buf, p - buf);
} }
static noreturn void __asan_report_memory_fault(uint8_t *addr, int size, static wontreturn void __asan_report_memory_fault(uint8_t *addr, int size,
const char *kind) { const char *kind) {
char *p, ibuf[21], buf[256]; char *p, ibuf[21], buf[256];
p = __asan_report_start(buf); p = __asan_report_start(buf);
p = stpcpy(p, __asan_describe_access_poison(*(char *)SHADOW((intptr_t)addr))); p = stpcpy(p, __asan_describe_access_poison(*(char *)SHADOW((intptr_t)addr)));

View File

@ -8,23 +8,23 @@ COSMOPOLITAN_C_START_
cosmopolitan § logging » berkeley logger cosmopolitan § logging » berkeley logger
*/ */
void err(int, const char *, ...) printfesque(2) noreturn; void err(int, const char *, ...) printfesque(2) wontreturn;
void errx(int, const char *, ...) printfesque(2) noreturn; void errx(int, const char *, ...) printfesque(2) wontreturn;
void verr(int, const char *, va_list) paramsnonnull((3)) noreturn; void verr(int, const char *, va_list) paramsnonnull((3)) wontreturn;
void verrx(int, const char *, va_list) paramsnonnull((3)) noreturn; void verrx(int, const char *, va_list) paramsnonnull((3)) wontreturn;
void vwarn(const char *, va_list) paramsnonnull((2)); void vwarn(const char *, va_list) paramsnonnull((2));
void vwarnx(const char *, va_list) paramsnonnull((2)); void vwarnx(const char *, va_list) paramsnonnull((2));
void warn(const char *, ...) printfesque(1); void warn(const char *, ...) printfesque(1);
void warnx(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 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 verrx(EVAL, FMT, VA) (verrx)(EVAL, PFLINK(FMT), VA)
#define vwarn(FMT, VA) (vwarn)(PFLINK(FMT), VA) #define vwarn(FMT, VA) (vwarn)(PFLINK(FMT), VA)
#define vwarnx(FMT, VA) (vwarnx)(PFLINK(FMT), VA) #define vwarnx(FMT, VA) (vwarnx)(PFLINK(FMT), VA)
#define warn(FMT, ...) (warn)(PFLINK(FMT), ##__VA_ARGS__) #define warn(FMT, ...) (warn)(PFLINK(FMT), ##__VA_ARGS__)
#define warnx(FMT, ...) (warn)(PFLINK(FMT), ##__VA_ARGS__) #define warnx(FMT, ...) (warn)(PFLINK(FMT), ##__VA_ARGS__)
COSMOPOLITAN_C_END_ COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View File

@ -84,15 +84,15 @@ COSMOPOLITAN_C_START_
void __check_fail(const char *, const char *, uint64_t, const char *, uint64_t, void __check_fail(const char *, const char *, uint64_t, const char *, uint64_t,
const char *, const char *, int, const char *, const char *, const char *, int, const char *,
...) relegated noreturn; ...) relegated wontreturn;
void __check_fail_eq(uint64_t, uint64_t) relegated noreturn; void __check_fail_eq(uint64_t, uint64_t) relegated wontreturn;
void __check_fail_ne(uint64_t, uint64_t) relegated noreturn; void __check_fail_ne(uint64_t, uint64_t) relegated wontreturn;
void __check_fail_le(uint64_t, uint64_t) relegated noreturn; void __check_fail_le(uint64_t, uint64_t) relegated wontreturn;
void __check_fail_lt(uint64_t, uint64_t) relegated noreturn; void __check_fail_lt(uint64_t, uint64_t) relegated wontreturn;
void __check_fail_ge(uint64_t, uint64_t) relegated noreturn; void __check_fail_ge(uint64_t, uint64_t) relegated wontreturn;
void __check_fail_gt(uint64_t, uint64_t) relegated noreturn; void __check_fail_gt(uint64_t, uint64_t) relegated wontreturn;
void __check_fail_aligned(unsigned, uint64_t) relegated noreturn; void __check_fail_aligned(unsigned, uint64_t) relegated wontreturn;
COSMOPOLITAN_C_END_ COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View File

@ -28,7 +28,7 @@
/** /**
* Aborts process after printing details on its current state. * Aborts process after printing details on its current state.
*/ */
relegated noreturn void __die(void) { relegated wontreturn void __die(void) {
static bool once; static bool once;
if (!once) { if (!once) {
once = true; once = true;

View File

@ -19,7 +19,7 @@
*/ */
#include "libc/log/bsd.h" #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_list va;
va_start(va, fmt); va_start(va, fmt);
(verr)(eval, fmt, va); (verr)(eval, fmt, va);

View File

@ -19,7 +19,7 @@
*/ */
#include "libc/log/bsd.h" #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_list va;
va_start(va, fmt); va_start(va, fmt);
(verrx)(eval, fmt, va); (verrx)(eval, fmt, va);

View File

@ -33,10 +33,10 @@ typedef struct FILE FILE;
extern FILE *g_logfile; extern FILE *g_logfile;
void perror(const char *) relegated; /* print the last system error */ void perror(const char *) relegated; /* print the last system error */
void __die(void) relegated noreturn; /* print backtrace and abort() */ void __die(void) relegated wontreturn; /* print backtrace and abort() */
void meminfo(int); /* shows malloc statistics &c. */ void meminfo(int); /* shows malloc statistics &c. */
void memsummary(int); /* light version of same thing */ void memsummary(int); /* light version of same thing */
uint16_t getttycols(uint16_t); uint16_t getttycols(uint16_t);
int getttysize(int, struct winsize *) paramsnonnull(); int getttysize(int, struct winsize *) paramsnonnull();
bool isterminalinarticulate(void) nosideeffect; 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 vfverbosef(ARGS, va_list) asm("vflogf") ATTRV relegated libcesque;
void fdebugf(ARGS, ...) asm("flogf") ATTR relegated libcesque; void fdebugf(ARGS, ...) asm("flogf") ATTR relegated libcesque;
void vfdebugf(ARGS, va_list) asm("vflogf") ATTRV relegated libcesque; void vfdebugf(ARGS, va_list) asm("vflogf") ATTRV relegated libcesque;
void ffatalf(ARGS, ...) asm("flogf") ATTR relegated noreturn libcesque; void ffatalf(ARGS, ...) asm("flogf") ATTR relegated wontreturn libcesque;
void vffatalf(ARGS, va_list) asm("vflogf") ATTRV relegated noreturn libcesque; void vffatalf(ARGS, va_list) asm("vflogf") ATTRV relegated wontreturn libcesque;
#undef ARGS #undef ARGS
#undef ATTR #undef ATTR
#undef ATTRV #undef ATTRV

View File

@ -51,17 +51,17 @@ STATIC_YOINK("stoa");
struct siginfo; 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, 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", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15", "RDI",
"RSI", "RBP", "RBX", "RDX", "RAX", "RCX", "RSP", "RIP", "RSI", "RBP", "RBX", "RDX", "RAX", "RCX", "RSP", "RIP",
}; };
static const char kGodHatesFlags[12] aligned(1) = "CVPRAKZSTIDO"; static const char kGodHatesFlags[12] forcealign(1) = "CVPRAKZSTIDO";
static const char kCrashSigNames[8][5] aligned(1) = { static const char kCrashSigNames[8][5] forcealign(1) = {
"QUIT", "FPE", "ILL", "SEGV", "TRAP", "ABRT", "BUS"}; "QUIT", "FPE", "ILL", "SEGV", "TRAP", "ABRT", "BUS"};
int kCrashSigs[8]; int kCrashSigs[8];

View File

@ -98,13 +98,13 @@ struct UbsanShiftOutOfBoundsData {
}; };
void __ubsan_abort(const struct UbsanSourceLocation *, void __ubsan_abort(const struct UbsanSourceLocation *,
const char *) relegated hidden noreturn; const char *) relegated hidden wontreturn;
void __ubsan_handle_type_mismatch(struct UbsanTypeMismatchInfo *, 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 *, 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 __ubsan_handle_float_cast_overflow(void *,
void *) relegated hidden noreturn; void *) relegated hidden wontreturn;
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_UBSAN_H_ */ #endif /* COSMOPOLITAN_LIBC_UBSAN_H_ */

View File

@ -23,7 +23,7 @@
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.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", fprintf(stderr, "%s: %s%s%s[%m]: ", program_invocation_name, RED2, "ERROR",
RESET); RESET);
if (fmt) (vfprintf)(stderr, fmt, va); if (fmt) (vfprintf)(stderr, fmt, va);

View File

@ -23,7 +23,7 @@
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.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", fprintf(stderr, "%s: %s%s%s: ", program_invocation_name, RED2, "ERROR",
RESET); RESET);
if (fmt) (vfprintf)(stderr, fmt, va); if (fmt) (vfprintf)(stderr, fmt, va);

View File

@ -22,9 +22,11 @@ int bsfl(long);
int bsfll(long long); int bsfll(long long);
int bsfmax(uintmax_t); int bsfmax(uintmax_t);
#ifdef __GNUC__
#define bsf(u) __builtin_ctz(u) #define bsf(u) __builtin_ctz(u)
#define bsfl(u) __builtin_ctzl(u) #define bsfl(u) __builtin_ctzl(u)
#define bsfll(u) __builtin_ctzll(u) #define bsfll(u) __builtin_ctzll(u)
#endif
COSMOPOLITAN_C_END_ COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View File

@ -22,9 +22,11 @@ int bsrl(long);
int bsrll(long long); int bsrll(long long);
int bsrmax(uintmax_t); int bsrmax(uintmax_t);
#ifdef __GNUC__
#define bsr(u) ((sizeof(int) * 8 - 1) ^ __builtin_clz(u)) #define bsr(u) ((sizeof(int) * 8 - 1) ^ __builtin_clz(u))
#define bsrl(u) ((sizeof(long) * 8 - 1) ^ __builtin_clzl(u)) #define bsrl(u) ((sizeof(long) * 8 - 1) ^ __builtin_clzl(u))
#define bsrll(u) ((sizeof(long long) * 8 - 1) ^ __builtin_clzll(u)) #define bsrll(u) ((sizeof(long long) * 8 - 1) ^ __builtin_clzll(u))
#endif
COSMOPOLITAN_C_END_ COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View File

@ -36,32 +36,32 @@ cescapec:
movzbl %cl,%ecx movzbl %cl,%ecx
jmp *cescapectab(,%rcx,8) jmp *cescapectab(,%rcx,8)
.Lanchorpoint: .Lanchorpoint:
.LBEL: mov $'a,%ah .LBEL: mov $'a',%ah
ret ret
.LBS: mov $'b,%ah .LBS: mov $'b',%ah
ret ret
.LHT: mov $'t,%ah .LHT: mov $'t',%ah
ret ret
.LLF: mov $'n,%ah .LLF: mov $'n',%ah
ret ret
.LVT: mov $'v,%ah .LVT: mov $'v',%ah
ret ret
.LFF: mov $'f,%ah .LFF: mov $'f',%ah
ret ret
.LCR: mov $'r,%ah .LCR: mov $'r',%ah
ret ret
.LDQ: mov $'\",%ah .LDQ: mov $'\"',%ah
ret ret
.LSQ: mov $'\',%ah .LSQ: mov $'\'',%ah
ret ret
.LBSL: mov $'\\,%ah .LBSL: mov $'\\',%ah
ret ret
#ifdef __STRICT_ANSI__ #ifdef __STRICT_ANSI__
.LQM: mov $'?,%ah .LQM: mov $'?',%ah
ret ret
.LESC: .LESC:
#elif defined(__GNUC__) #elif defined(__GNUC__)
.LESC: mov $'e,%ah .LESC: mov $'e',%ah
ret ret
.LQM: .LQM:
#endif #endif

View File

@ -17,17 +17,9 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA 02110-1301 USA
*/ */
#include "tool/tags/keywords.inc" #include "libc/math.h"
#include "tool/tags/tags.h" #include "libc/nexgen32e/nexgen32e.h"
/** bool ctz(double x, double y) {
* Returns small number for HTTP header, or -1 if not found. return __builtin_islessgreater(x, y);
*/
int GetKeyword(const char *str, size_t len) {
const struct KeywordSlot *slot;
if ((slot = LookupKeyword(str, len))) {
return slot->code;
} else {
return -1;
}
} }

View File

@ -41,7 +41,7 @@ ffs: .leafprologue
bsf %edi,%eax bsf %edi,%eax
or $-1,%edx or $-1,%edx
cmovz %edx,%eax cmovz %edx,%eax
add $1,%eax inc %eax
.leafepilogue .leafepilogue
.endfn ffs,globl .endfn ffs,globl
.source __FILE__ .source __FILE__

View File

@ -41,7 +41,7 @@ ffsl: .leafprologue
bsf %rdi,%rax bsf %rdi,%rax
or $-1,%edx or $-1,%edx
cmovz %edx,%eax cmovz %edx,%eax
add $1,%eax inc %eax
.leafepilogue .leafepilogue
.endfn ffsl,globl .endfn ffsl,globl
.alias ffsl,ffsll .alias ffsl,ffsll

View File

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

View File

@ -22,7 +22,7 @@
/ Loads XMM registers from buffer. / 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 / @note modern cpus have out-of-order execution engines
loadxmm:.leafprologue loadxmm:.leafprologue
movaps -0x80(%rdi),%xmm0 movaps -0x80(%rdi),%xmm0

View File

@ -112,7 +112,7 @@ MemCpy: .leafprologue
.L1: mov (%rsi),%cl .L1: mov (%rsi),%cl
mov %cl,(%rdi) mov %cl,(%rdi)
jmp .L0 jmp .L0
.Lerms: cmp $4*1024*1024,%rdx # TODO: getcachesize() .Lerms: cmp kHalfCache3(%rip),%rdx
ja .Lnts ja .Lnts
push %rdi push %rdi
push %rsi push %rsi

View File

@ -22,7 +22,7 @@
/ Stores XMM registers to buffer. / 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 / @note modern cpus have out-of-order execution engines
savexmm:.leafprologue savexmm:.leafprologue
movaps %xmm0,-0x80(%rdi) movaps %xmm0,-0x80(%rdi)

View File

@ -28,6 +28,21 @@
/ @return rax is pointer to substring or NULL / @return rax is pointer to substring or NULL
/ @asyncsignalsafe / @asyncsignalsafe
strstr$sse42: 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 .endfn strstr$sse42,globl,hidden
.source __FILE__ .source __FILE__

View File

@ -33,7 +33,7 @@ bool32 WriteFile(int64_t hFile, const void *lpBuffer,
struct NtOverlapped *opt_lpOverlapped); struct NtOverlapped *opt_lpOverlapped);
bool32 TerminateProcess(int64_t hProcess, uint32_t uExitCode); bool32 TerminateProcess(int64_t hProcess, uint32_t uExitCode);
int64_t GetCurrentProcess(void) pureconst; int64_t GetCurrentProcess(void) pureconst;
void ExitProcess(uint32_t uExitCode) noreturn; void ExitProcess(uint32_t uExitCode) wontreturn;
uint32_t GetLastError(void) nosideeffect; uint32_t GetLastError(void) nosideeffect;
bool32 CloseHandle(int64_t hObject) nothrow nocallback; bool32 CloseHandle(int64_t hObject) nothrow nocallback;
intptr_t GetStdHandle(int64_t nStdHandle) nosideeffect; intptr_t GetStdHandle(int64_t nStdHandle) nosideeffect;

View File

@ -5,7 +5,7 @@
struct NtM128A { struct NtM128A {
uint64_t Low; uint64_t Low;
int64_t High; int64_t High;
} aligned(16); } forcealign(16);
struct NtXmmSaveArea32 { struct NtXmmSaveArea32 {
uint16_t ControlWord; uint16_t ControlWord;
@ -53,7 +53,7 @@ struct NtContext {
uint64_t LastBranchFromRip; uint64_t LastBranchFromRip;
uint64_t LastExceptionToRip; uint64_t LastExceptionToRip;
uint64_t LastExceptionFromRip; uint64_t LastExceptionFromRip;
} aligned(16); } forcealign(16);
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_CONTEXT_H_ */ #endif /* COSMOPOLITAN_LIBC_NT_STRUCT_CONTEXT_H_ */

View File

@ -37,7 +37,7 @@ int64_t CreateThread(struct NtSecurityAttributes *lpThreadAttributes,
void *lpParameter, uint32_t dwCreationFlags, void *lpParameter, uint32_t dwCreationFlags,
uint32_t *opt_lpThreadId); uint32_t *opt_lpThreadId);
void ExitThread(uint32_t dwExitCode) noreturn; void ExitThread(uint32_t dwExitCode) wontreturn;
int64_t GetCurrentThread(void); int64_t GetCurrentThread(void);
uint32_t GetCurrentThreadId(void); uint32_t GetCurrentThreadId(void);
uint64_t SetThreadAffinityMask(int64_t hThread, uintptr_t dwThreadAffinityMask); uint64_t SetThreadAffinityMask(int64_t hThread, uintptr_t dwThreadAffinityMask);

View File

@ -25,7 +25,7 @@ COSMOPOLITAN_C_START_
/** /**
* Same as longjmp() but runs gc() / defer() destructors. * 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. * Calls FN(ARG) when function returns.

View File

@ -19,10 +19,10 @@ extern hidden void *g_stacktop;
void _init(void) hidden; void _init(void) hidden;
void _piro(int) hidden; void _piro(int) hidden;
void *__cxa_finalize(void *) hidden; void *__cxa_finalize(void *) hidden;
void _executive(int, char **, char **, long (*)[2]) hidden noreturn; void _executive(int, char **, char **, long (*)[2]) hidden wontreturn;
void __stack_chk_fail(void) noreturn relegated; void __stack_chk_fail(void) wontreturn relegated;
void __stack_chk_fail_local(void) noreturn relegated hidden; void __stack_chk_fail_local(void) wontreturn relegated hidden;
void _jmpstack(void *, void *, ...) hidden noreturn; void _jmpstack(void *, void *, ...) hidden wontreturn;
long _setstack(void *, void *, ...) hidden; long _setstack(void *, void *, ...) hidden;
int GetDosArgv(const char16_t *, char *, size_t, char **, size_t) hidden; int GetDosArgv(const char16_t *, char *, size_t, char **, size_t) hidden;
Elf64_Ehdr *MapElfRead(const char *, struct MappedFile *) hidden; Elf64_Ehdr *MapElfRead(const char *, struct MappedFile *) hidden;

View File

@ -29,7 +29,7 @@ STATIC_YOINK("_init_onntconsoleevent");
static struct InterruptibleCall *g_interruptiblecall; static struct InterruptibleCall *g_interruptiblecall;
noreturn static void interruptcall(int sig) { wontreturn static void interruptcall(int sig) {
longjmp(g_interruptiblecall->jb, 1); longjmp(g_interruptiblecall->jb, 1);
unreachable; unreachable;
} }

View File

@ -32,7 +32,7 @@
static privileged void __print$nt(const void *data, size_t len) { static privileged void __print$nt(const void *data, size_t len) {
int64_t hand; int64_t hand;
uint32_t wrote; uint32_t wrote;
char xmm[256] aligned(16); char xmm[256] forcealign(16);
savexmm(&xmm[128]); savexmm(&xmm[128]);
hand = __imp_GetStdHandle(kNtStdErrorHandle); hand = __imp_GetStdHandle(kNtStdErrorHandle);
__imp_WriteFile(hand, data, len, &wrote, NULL); __imp_WriteFile(hand, data, len, &wrote, NULL);

View File

@ -6,45 +6,45 @@ COSMOPOLITAN_C_START_
cosmopolitan § runtime cosmopolitan § runtime
*/ */
typedef long jmp_buf[8] aligned(CACHELINE); typedef long jmp_buf[8] forcealign(CACHELINE);
extern int g_argc; /* CRT */ extern int g_argc; /* CRT */
extern char **g_argv; /* CRT */ extern char **g_argv; /* CRT */
extern char **environ; /* CRT */ extern char **environ; /* CRT */
extern unsigned long *g_auxv; /* CRT */ extern unsigned long *g_auxv; /* CRT */
extern char *program_invocation_name; /* RII */ extern char *program_invocation_name; /* RII */
extern char *program_invocation_short_name; /* RII */ extern char *program_invocation_short_name; /* RII */
extern uint64_t g_syscount; /* RII */ extern uint64_t g_syscount; /* RII */
extern const uint64_t kStartTsc; /* RII */ extern const uint64_t kStartTsc; /* RII */
extern const char kTmpPath[]; /* RII */ extern const char kTmpPath[]; /* RII */
extern const char kNtSystemDirectory[]; /* RII */ extern const char kNtSystemDirectory[]; /* RII */
extern const char kNtWindowsDirectory[]; /* RII */ extern const char kNtWindowsDirectory[]; /* RII */
extern unsigned char _base[] aligned(PAGESIZE); /* αpε */ extern unsigned char _base[] forcealign(PAGESIZE); /* αpε */
extern unsigned char _ehead[] aligned(PAGESIZE); /* αpε */ extern unsigned char _ehead[] forcealign(PAGESIZE); /* αpε */
extern unsigned char _etext[] aligned(PAGESIZE); /* αpε */ extern unsigned char _etext[] forcealign(PAGESIZE); /* αpε */
extern unsigned char _edata[] aligned(PAGESIZE); /* αpε */ extern unsigned char _edata[] forcealign(PAGESIZE); /* αpε */
extern unsigned char _end[] aligned(PAGESIZE); /* αpε */ extern unsigned char _end[] forcealign(PAGESIZE); /* αpε */
extern unsigned char _ereal; /* αpε */ extern unsigned char _ereal; /* αpε */
extern unsigned char __privileged_start; /* αpε */ extern unsigned char __privileged_start; /* αpε */
extern unsigned char __test_start; /* αpε */ extern unsigned char __test_start; /* αpε */
extern unsigned char __ro; /* αpε */ extern unsigned char __ro; /* αpε */
extern unsigned char *__relo_start[]; /* αpε */ extern unsigned char *__relo_start[]; /* αpε */
extern unsigned char *__relo_end[]; /* αpε */ extern unsigned char *__relo_end[]; /* αpε */
extern uint8_t __zip_start[]; /* αpε */ extern uint8_t __zip_start[]; /* αpε */
extern uint8_t __zip_end[]; /* αpε */ extern uint8_t __zip_end[]; /* αpε */
long missingno(); long missingno();
void mcount(void); void mcount(void);
unsigned long getauxval(unsigned long); unsigned long getauxval(unsigned long);
void *mapanon(size_t) vallocesque attributeallocsize((1)); void *mapanon(size_t) vallocesque attributeallocsize((1));
int setjmp(jmp_buf) libcesque returnstwice paramsnonnull(); int setjmp(jmp_buf) libcesque returnstwice paramsnonnull();
void longjmp(jmp_buf, int) libcesque noreturn paramsnonnull(); void longjmp(jmp_buf, int) libcesque wontreturn paramsnonnull();
void exit(int) noreturn; void exit(int) wontreturn;
void _exit(int) libcesque noreturn; void _exit(int) libcesque wontreturn;
void _Exit(int) libcesque noreturn; void _Exit(int) libcesque wontreturn;
void abort(void) noreturn noinstrument; void abort(void) wontreturn noinstrument;
void panic(void) noreturn noinstrument privileged; void panic(void) wontreturn noinstrument privileged;
void triplf(void) noreturn noinstrument privileged; void triplf(void) wontreturn noinstrument privileged;
int __cxa_atexit(void *, void *, void *) libcesque; int __cxa_atexit(void *, void *, void *) libcesque;
int atfork(void *, void *) libcesque; int atfork(void *, void *) libcesque;
int atexit(void (*)(void)) libcesque; int atexit(void (*)(void)) libcesque;

View File

@ -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);
}
}

View File

@ -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_ */

View File

@ -119,7 +119,7 @@ static textwindows char *AllocateMemory(void *addr, size_t size, int64_t *h) {
kNtNumaNoPreferredNode); kNtNumaNoPreferredNode);
} }
static textwindows noreturn void WinMainNew(void) { static textwindows wontreturn void WinMainNew(void) {
int64_t h; int64_t h;
size_t size; size_t size;
int i, count; int i, count;

View File

@ -24,7 +24,7 @@ STATIC_YOINK("_init_g_stderr");
FILE *stderr; FILE *stderr;
hidden FILE g_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() { static textstartup void _init_g_stderr2() {
_fflushregister(stderr); _fflushregister(stderr);

View File

@ -24,7 +24,7 @@ STATIC_YOINK("_init_g_stdin");
FILE *stdin; FILE *stdin;
hidden FILE g_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() { static textstartup void g_stdin_init() {
_fflushregister(stdin); _fflushregister(stdin);

View File

@ -27,7 +27,7 @@ STATIC_YOINK("_init_g_stdout");
FILE *stdout; FILE *stdout;
hidden FILE g_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() { static textstartup void _init_g_stdout2() {
struct FILE *sf; struct FILE *sf;

View File

@ -19,4 +19,6 @@
*/ */
#include "libc/stdio/temp.h" #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);
}

View File

@ -19,14 +19,16 @@
*/ */
#include "libc/str/str.h" #include "libc/str/str.h"
#undef char /**
#undef endswith * Returns true if s has suffix.
#undef strlen *
#undef strnlen * @param s is a NUL-terminated string
* @param suffix is also NUL-terminated
#define char char16_t */
#define endswith endswith16 bool endswith16(const char16_t *s, const char16_t *suffix) {
#define strlen strlen16 size_t n, m;
#define strnlen strnlen16 n = strlen16(s);
m = strlen16(suffix);
#include "libc/str/endswith.c" if (m > n) return false;
return memcmp(s + n - m, suffix, m * sizeof(char16_t)) == 0;
}

View File

@ -19,14 +19,16 @@
*/ */
#include "libc/str/str.h" #include "libc/str/str.h"
#undef char /**
#undef startswith * Returns true if s has prefix.
#undef strlen *
#undef strncmp * @param s is a NUL-terminated string
* @param prefix is also NUL-terminated
#define char char16_t */
#define startswith startswith16 bool startswith16(const char16_t *s, const char16_t *prefix) {
#define strlen strlen16 for (;;) {
#define strncmp strncmp16 if (!*prefix) return true;
if (!*s) return false;
#include "libc/str/startswith.c" if (*s++ != *prefix++) return false;
}
}

View File

@ -238,8 +238,8 @@ char *strsignal(int) returnsnonnull libcesque;
*/ */
#if defined(__GNUC__) && !defined(__STRICT_ANSI__) #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
char *_strncpy(char *, const char *, size_t) asm("strncpy") memcpyesque; char *__strncpy(char *, const char *, size_t) memcpyesque;
#define strncpy(DEST, SRC, N) _strncpy(DEST, SRC, N) /* pacify bad warning */ #define strncpy(DEST, SRC, N) __strncpy(DEST, SRC, N) /* pacify bad warning */
#define explicit_bzero(STR, BYTES) \ #define explicit_bzero(STR, BYTES) \
do { \ do { \
@ -318,7 +318,7 @@ char *_strncpy(char *, const char *, size_t) asm("strncpy") memcpyesque;
size_t SiZe = (SIZE); \ size_t SiZe = (SIZE); \
size_t Rcx; \ size_t Rcx; \
asm("rep movsb" \ 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)) \ : "0"(Dest), "1"(Src), "2"(SiZe), "m"(*(const char(*)[SiZe])(Src)) \
: "cc"); \ : "cc"); \
Rdi; \ Rdi; \
@ -351,9 +351,6 @@ char *_strncpy(char *, const char *, size_t) asm("strncpy") memcpyesque;
#endif /* hosted/sse2/unbloat */ #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__ */ #endif /* __GNUC__ && !__STRICT_ANSI__ */
COSMOPOLITAN_C_END_ COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View File

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

View File

@ -24,7 +24,7 @@
* Returns pointer to first byte matching any in accept, or NULL. * Returns pointer to first byte matching any in accept, or NULL.
* @asyncsignalsafe * @asyncsignalsafe
*/ */
char *(strpbrk)(const char *s, const char *accept) { char *strpbrk(const char *s, const char *accept) {
size_t i; size_t i;
if (accept[0]) { if (accept[0]) {
if (!accept[1]) { if (!accept[1]) {

View File

@ -20,10 +20,22 @@
#include "libc/nexgen32e/hascharacter.internal.h" #include "libc/nexgen32e/hascharacter.internal.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#undef strpbrk /**
#define char char16_t * Returns pointer to first byte matching any in accept, or NULL.
#define HasCharacter HasCharacter16 * @asyncsignalsafe
#define strpbrk strpbrk16 */
#define strchr(x, y) strchr16(x, y) char16_t *strpbrk16(const char16_t *s, const char16_t *accept) {
size_t i;
#include "libc/str/strpbrk.c" 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;
}

View File

@ -27,7 +27,7 @@
* @see strcspn(), strtok_r() * @see strcspn(), strtok_r()
* @asyncsignalsafe * @asyncsignalsafe
*/ */
size_t(strspn)(const char *s, const char *accept) { size_t strspn(const char *s, const char *accept) {
size_t i; size_t i;
for (i = 0; s[i]; ++i) { for (i = 0; s[i]; ++i) {
if (!HasCharacter(s[i], accept)) { if (!HasCharacter(s[i], accept)) {

View File

@ -20,9 +20,19 @@
#include "libc/nexgen32e/hascharacter.internal.h" #include "libc/nexgen32e/hascharacter.internal.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#undef strspn /**
#define char char16_t * Returns prefix length, consisting of chars in accept.
#define HasCharacter HasCharacter16 *
#define strspn strspn16 * @param accept is nul-terminated character set
* @see strcspn(), strtok_r()
#include "libc/str/strspn.c" * @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;
}

View File

@ -18,7 +18,6 @@
02110-1301 USA 02110-1301 USA
*/ */
#include "libc/alg/alg.h" #include "libc/alg/alg.h"
#include "libc/dce.h"
#include "libc/nexgen32e/x86feature.h" #include "libc/nexgen32e/x86feature.h"
#include "libc/str/internal.h" #include "libc/str/internal.h"
#include "libc/str/str.h" #include "libc/str/str.h"
@ -32,22 +31,26 @@
* @asyncsignalsafe * @asyncsignalsafe
* @see memmem() * @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[0]) {
if (needle[1]) { if (needle[1]) {
if (!((intptr_t)needle & 0xf) && X86_HAVE(SSE4_2)) { for (;;) {
return strstr$sse42(haystack, needle); #if 0 /* todo: fix me */
} else { if (!((uintptr_t)haystack & 15) && X86_HAVE(SSE4_2) &&
size_t needlelen; (((uintptr_t)needle + strlen(needle)) & 0xfff) <= 0xff0) {
alignas(16) char needle2[64]; return strstr$sse42(haystack, needle);
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);
} }
#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 { } else {
return strchr(haystack, needle[0]); return strchr(haystack, needle[0]);
} }

View File

@ -19,14 +19,16 @@
*/ */
#include "libc/str/str.h" #include "libc/str/str.h"
#undef char /**
#undef endswith * Returns true if s has suffix.
#undef strlen *
#undef strnlen * @param s is a NUL-terminated string
* @param suffix is also NUL-terminated
#define char wchar_t */
#define endswith wcsendswith bool wcsendswith(const wchar_t *s, const wchar_t *suffix) {
#define strlen wcslen size_t n, m;
#define strnlen wcsnlen n = wcslen(s);
m = wcslen(suffix);
#include "libc/str/endswith.c" if (m > n) return false;
return memcmp(s + n - m, suffix, m * sizeof(wchar_t)) == 0;
}

View File

@ -20,10 +20,22 @@
#include "libc/nexgen32e/hascharacter.internal.h" #include "libc/nexgen32e/hascharacter.internal.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#undef strpbrk /**
#define char wchar_t * Returns pointer to first byte matching any in accept, or NULL.
#define HasCharacter HasCharacterWide * @asyncsignalsafe
#define strpbrk wcspbrk */
#define strchr(x, y) wcschr(x, y) wchar_t *wcspbrk(const wchar_t *s, const wchar_t *accept) {
size_t i;
#include "libc/str/strpbrk.c" 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;
}

View File

@ -20,9 +20,19 @@
#include "libc/nexgen32e/hascharacter.internal.h" #include "libc/nexgen32e/hascharacter.internal.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#undef strspn /**
#define char wchar_t * Returns prefix length, consisting of chars in accept.
#define HasCharacter HasCharacterWide *
#define strspn wcsspn * @param accept is nul-terminated character set
* @see strcspn(), strtok_r()
#include "libc/str/strspn.c" * @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;
}

View File

@ -19,14 +19,16 @@
*/ */
#include "libc/str/str.h" #include "libc/str/str.h"
#undef char /**
#undef startswith * Returns true if s has prefix.
#undef strlen *
#undef strncmp * @param s is a NUL-terminated string
* @param prefix is also NUL-terminated
#define char wchar_t */
#define startswith wcsstartswith bool wcsstartswith(const wchar_t *s, const wchar_t *prefix) {
#define strlen wcslen for (;;) {
#define strncmp wcsncmp if (!*prefix) return true;
if (!*s) return false;
#include "libc/str/startswith.c" if (*s++ != *prefix++) return false;
}
}

View File

@ -25,8 +25,8 @@
#include "libc/sysv/consts/mlock.h" #include "libc/sysv/consts/mlock.h"
#include "libc/testlib/testlib.h" #include "libc/testlib/testlib.h"
double g_avx2_juiceup_doubles_[4] aligned(32); double g_avx2_juiceup_doubles_[4] forcealign(32);
unsigned long long g_avx2_juiceup_quadwords_[4] aligned(32); unsigned long long g_avx2_juiceup_quadwords_[4] forcealign(32);
void testlib_benchwarmup(void) { void testlib_benchwarmup(void) {
/* get mathematical parts of cpu juiced up */ /* get mathematical parts of cpu juiced up */

View File

@ -20,11 +20,12 @@
#include "libc/fmt/fmt.h" #include "libc/fmt/fmt.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/testlib/testlib.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) { testonly char *testlib_formatfloat(long double x) {
char dtoabuf[32]; char buf[32];
char *str = malloc(256); 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; return str;
} }

View File

@ -350,7 +350,7 @@ void testlib_runfixtures(testfn_t *, testfn_t *, const struct TestFixture *,
const struct TestFixture *); const struct TestFixture *);
int testlib_countfixtures(const struct TestFixture *, int testlib_countfixtures(const struct TestFixture *,
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_strequals(size_t, const void *, const void *) nosideeffect;
bool testlib_strnequals(size_t, const void *, const void *, bool testlib_strnequals(size_t, const void *, const void *,
size_t) nosideeffect; size_t) nosideeffect;

View File

@ -99,7 +99,7 @@ LIBC_TESTLIB_A_DIRECTDEPS = \
LIBC_UNICODE \ LIBC_UNICODE \
LIBC_X \ LIBC_X \
LIBC_ZIPOS \ LIBC_ZIPOS \
THIRD_PARTY_DTOA THIRD_PARTY_GDTOA
LIBC_TESTLIB_A_DEPS := \ LIBC_TESTLIB_A_DEPS := \
$(call uniq,$(foreach x,$(LIBC_TESTLIB_A_DIRECTDEPS),$($(x)))) $(call uniq,$(foreach x,$(LIBC_TESTLIB_A_DIRECTDEPS),$($(x))))

View File

@ -35,7 +35,7 @@ void testlib_finish(void) {
} }
} }
noreturn void testlib_abort(void) { wontreturn void testlib_abort(void) {
testlib_finish(); testlib_finish();
exit(MIN(255, g_testlib_failed)); exit(MIN(255, g_testlib_failed));
unreachable; unreachable;

View File

@ -28,8 +28,8 @@ int xwrite(int, const void *, uint64_t);
cosmopolitan § eXtended apis » memory cosmopolitan § eXtended apis » memory
*/ */
void xdie(void) noreturn; void xdie(void) wontreturn;
char *xdtoa(double) _XMAL; char *xdtoa(long double) _XMAL;
char *xasprintf(const char *, ...) printfesque(1) paramsnonnull((1)) _XMAL; char *xasprintf(const char *, ...) printfesque(1) paramsnonnull((1)) _XMAL;
char *xvasprintf(const char *, va_list) _XPNN _XMAL; char *xvasprintf(const char *, va_list) _XPNN _XMAL;
char *xgetline(struct FILE *) _XPNN mallocesque; char *xgetline(struct FILE *) _XPNN mallocesque;

View File

@ -43,7 +43,7 @@ LIBC_X_A_DIRECTDEPS = \
LIBC_STR \ LIBC_STR \
LIBC_STUBS \ LIBC_STUBS \
LIBC_SYSV \ LIBC_SYSV \
THIRD_PARTY_DTOA THIRD_PARTY_GDTOA
LIBC_X_A_DEPS := \ LIBC_X_A_DEPS := \
$(call uniq,$(foreach x,$(LIBC_X_A_DIRECTDEPS),$($(x)))) $(call uniq,$(foreach x,$(LIBC_X_A_DIRECTDEPS),$($(x))))

View File

@ -19,14 +19,15 @@
*/ */
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/x/x.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. * 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 *xdtoa(long double d) {
char buf[32]; char *p = xmalloc(32);
return xstrdup(g_fmt(buf, d)); g_xfmt_p(p, &d, 16, 32, 2);
return p;
} }

View File

@ -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)));
}

View File

@ -29,18 +29,18 @@ TEST(GetChromaticAdaptationMatrix, testSuperiorIlluminationBannedInCalifornia) {
double M[3][3]; double M[3][3];
GetChromaticAdaptationMatrix(M, kIlluminantD65, kIlluminantA); GetChromaticAdaptationMatrix(M, kIlluminantD65, kIlluminantA);
EXPECT_DBLMATRIXEQ(5, rint, 3, 3, M, "\n\ EXPECT_DBLMATRIXEQ(5, rint, 3, 3, M, "\n\
1.21646 .11099 -.15493\n\ 1.2165 .11099 -.15493\n\
.15333 .91523 -.056\n\ .15333 .91523 -.055995\n\
-.02395 .0359 .31475"); -.023947 .035898 .31475");
} }
TEST(GetChromaticAdaptationMatrix, testD65ToD50_soWeCanCieLab) { TEST(GetChromaticAdaptationMatrix, testD65ToD50_soWeCanCieLab) {
double M[3][3]; double M[3][3];
GetChromaticAdaptationMatrix(M, kIlluminantD65, kIlluminantD50); GetChromaticAdaptationMatrix(M, kIlluminantD65, kIlluminantD50);
EXPECT_DBLMATRIXEQ(6, rint, 3, 3, M, "\n\ EXPECT_DBLMATRIXEQ(6, rint, 3, 3, M, "\n\
1.047811 .022887 -.050127\n\ 1.04781 .0228866 -.050127\n\
.029542 .990484 -.017049\n\ .0295424 .990484 -.0170491\n\
-.009234 .015044 .752132"); -.00923449 .0150436 .752132");
} }
BENCH(GetChromaticAdaptationMatrix, bench) { BENCH(GetChromaticAdaptationMatrix, bench) {

View File

@ -28,9 +28,9 @@ TEST(inv3, test) {
double M[3][3]; double M[3][3];
inv3(M, kBradford, det3(kBradford)); inv3(M, kBradford, det3(kBradford));
EXPECT_DBLMATRIXEQ(7, rint, 3, 3, M, "\n\ EXPECT_DBLMATRIXEQ(7, rint, 3, 3, M, "\n\
.9869929 -.1470543 .1599627\n\ .9869929 -.1470543 .1599627\n\
.4323053 .5183603 .0492912\n\ .4323053 .5183603 .04929123\n\
-.0085287 .0400428 .9684867"); -.008528665 .04004282 .9684867");
} }
BENCH(inv3, bench) { BENCH(inv3, bench) {

View File

@ -31,7 +31,7 @@ unsigned windex$k8(short *, size_t) hidden;
unsigned windex$avx2(short *, size_t) hidden; unsigned windex$avx2(short *, size_t) hidden;
unsigned windex$sse4(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, 8281, 3883, 1365, 1786, 9006, 3681, 5563, 8013, 5787, 9063, 2923,
3564, 6122, 32, 1436, 0741, 7957, 9219, 1320, 2083, 1904, 8905, 3564, 6122, 32, 1436, 0741, 7957, 9219, 1320, 2083, 1904, 8905,
2465, 9122, 9563, 1290, 4474, 3988, 9920, 8325, 1088, 2915, 33, 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, 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, 8281, 1, 1365, 1786, 9006, 3681, 5563, 8013, 5787, 9063, 2923,
3564, 6122, 32, 1436, 0741, 7957, 9219, 1320, 2083, 1904, 8905, 3564, 6122, 32, 1436, 0741, 7957, 9219, 1320, 2083, 1904, 8905,
2465, 9122, 9563, 1290, 4474, 3988, 9920, 8325, 1088, 2915, 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, 8281, 0x7fff, 1365, 1786, 9006, 3681, 5563, 8013, 5787, 9063, 2923,
3564, 6122, 32, 1436, 0741, 7957, 9219, 1320, 2083, 1904, 8905, 3564, 6122, 32, 1436, 0741, 7957, 9219, 1320, 2083, 1904, 8905,
2465, 9122, 9563, 1290, 4474, 3988, 9920, 8325, 1088, 2915, 33, 2465, 9122, 9563, 1290, 4474, 3988, 9920, 8325, 1088, 2915, 33,
@ -64,7 +64,7 @@ const short kW3[64] aligned(32) = {
}) })
TEST(windex, testRealWorldPicks) { 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, 103, 85, 145, 146, 121, 103, 145, 187, 146, 189,
121, 103, 139, 121, 63, 105, 105, 147, 60, 103, 121, 103, 139, 121, 63, 105, 105, 147, 60, 103,
103, 146, 121, 103, 139, 121, 139, 121, 157, 139, 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