Browse Source
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
298 changed files with 19484 additions and 11941 deletions
@ -1,34 +0,0 @@
@@ -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; |
||||
} |
@ -1,50 +1,17 @@
@@ -1,50 +1,17 @@
|
||||
typedef struct { |
||||
unsigned int gp_offset; |
||||
unsigned int fp_offset; |
||||
void *overflow_arg_area; |
||||
void *reg_save_area; |
||||
} __va_elem; |
||||
#include "libc/runtime/valist.h" |
||||
|
||||
typedef __va_elem va_list[1]; |
||||
#define __GNUC_VA_LIST 1 |
||||
#define __gnuc_va_list va_list |
||||
|
||||
#define va_start(ap, last) \ |
||||
do { \ |
||||
*(ap) = *(__va_elem *)__va_area__; \ |
||||
#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_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, TYPE) \ |
||||
(*(TYPE *)__va_arg(AP, sizeof(TYPE), _Alignof(TYPE), \ |
||||
__builtin_reg_class(TYPE))) |
||||
|
||||
#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 |
||||
typedef va_list __gnuc_va_list; |
||||
typedef struct __va va_list[1]; |
||||
|