Enhance chibicc
parent
8da931a7f6
commit
9df2cef4c4
|
@ -104,7 +104,7 @@ CONFIG_COPTS += \
|
|||
-ftrapv
|
||||
|
||||
TARGET_ARCH ?= \
|
||||
-march=k8-sse3
|
||||
-msse3
|
||||
|
||||
OVERRIDE_CCFLAGS += \
|
||||
-fno-pie
|
||||
|
@ -177,6 +177,6 @@ ifeq ($(MODE), ansi)
|
|||
CONFIG_CFLAGS += -std=c11
|
||||
#CONFIG_CPPFLAGS += -ansi
|
||||
CONFIG_CXXFLAGS += -std=c++11
|
||||
TARGET_ARCH ?= -march=k8-sse3
|
||||
TARGET_ARCH ?= -msse3
|
||||
|
||||
endif
|
||||
|
|
|
@ -22,6 +22,11 @@ set -e
|
|||
SPECIAL_TEXT=$(
|
||||
$1 --version |
|
||||
sed -n '
|
||||
/chibicc/ {
|
||||
i\
|
||||
chibicc
|
||||
q
|
||||
}
|
||||
/Free Software/ {
|
||||
i\
|
||||
gcc
|
||||
|
|
|
@ -229,12 +229,12 @@ unsigned long hamming(unsigned long, unsigned long) pureconst;
|
|||
* @see Intel Six-Thousand Page Manual Manual V.3A §8.2.3.1
|
||||
* @see atomic_load()
|
||||
*/
|
||||
#define atomic_store(MEM, VAL) \
|
||||
({ \
|
||||
autotype(VAL) Val = (VAL); \
|
||||
typeof(&Val) Mem = (MEM); \
|
||||
asm("mov%z1\t%1,%0" : "=m,m"(*Mem) : "i,r"(Val)); \
|
||||
Val; \
|
||||
#define atomic_store(MEM, VAL) \
|
||||
({ \
|
||||
autotype(VAL) Val = (VAL); \
|
||||
typeof(&Val) Mem = (MEM); \
|
||||
asm("mov%z1\t%1,%0" : "=m"(*Mem) : "r"(Val)); \
|
||||
Val; \
|
||||
})
|
||||
|
||||
#define bts(MEM, BIT) __BitOp("bts", BIT, MEM) /** bit test and set */
|
||||
|
|
|
@ -39,9 +39,6 @@ $(LIBC_BITS_A).pkg: \
|
|||
$(LIBC_BITS_A_OBJS) \
|
||||
$(foreach x,$(LIBC_BITS_A_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
#o/$(MODE)/libc/bits/bsf.o: CC = clang-10
|
||||
#o/$(MODE)/libc/bits/bsf.o: CC = /opt/cross9cc/bin/x86_64-linux-musl-cc
|
||||
|
||||
LIBC_BITS_LIBS = $(foreach x,$(LIBC_BITS_ARTIFACTS),$($(x)))
|
||||
LIBC_BITS_SRCS = $(foreach x,$(LIBC_BITS_ARTIFACTS),$($(x)_SRCS))
|
||||
LIBC_BITS_HDRS = $(foreach x,$(LIBC_BITS_ARTIFACTS),$($(x)_HDRS))
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_FMT_BING_H_
|
||||
#define COSMOPOLITAN_LIBC_FMT_BING_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
#ifndef __cplusplus
|
||||
|
||||
int bing(int, int) nosideeffect;
|
||||
int unbing(int) nosideeffect;
|
||||
|
@ -9,8 +8,6 @@ void *unbingbuf(void *, size_t, const char16_t *, int);
|
|||
void *unbingstr(const char16_t *) paramsnonnull() mallocesque;
|
||||
void *unhexbuf(void *, size_t, const char *);
|
||||
void *unhexstr(const char *) mallocesque;
|
||||
short *bingblit(int ys, int xs, unsigned char[ys][xs], int, int);
|
||||
|
||||
#endif /* __cplusplus */
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_FMT_BING_H_ */
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#define COSMOPOLITAN_LIBC_FMT_PFLINK_H_
|
||||
#include "libc/dce.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
#if !defined(__STRICT_ANSI__) && !defined(__chibicc__)
|
||||
#ifndef __STRICT_ANSI__
|
||||
|
||||
/**
|
||||
* @fileoverview builtin+preprocessor+linker tricks for printf/scanf.
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#define COSMOPOLITAN_CXX_USING_
|
||||
#endif
|
||||
|
||||
#if defined(__STRICT_ANSI__) && __STDC_VERSION__ + 0 < 201112
|
||||
#ifdef __STRICT_ANSI__
|
||||
#define asm __asm__
|
||||
#endif
|
||||
|
||||
|
@ -773,8 +773,9 @@ typedef uint64_t uintmax_t;
|
|||
*/
|
||||
#if __cplusplus + 0 >= 201103L
|
||||
#define autotype(x) auto
|
||||
#elif (__has_builtin(auto_type) || defined(__llvm__) || \
|
||||
(__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 409)
|
||||
#elif ((__has_builtin(auto_type) || defined(__llvm__) || \
|
||||
(__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 409) && \
|
||||
!defined(__chibicc__))
|
||||
#define autotype(x) __auto_type
|
||||
#else
|
||||
#define autotype(x) typeof(x)
|
||||
|
|
|
@ -7,7 +7,7 @@ COSMOPOLITAN_C_START_
|
|||
|
||||
void palignr(void *, const void *, const void *, unsigned long);
|
||||
|
||||
#ifndef __STRICT_ANSI__
|
||||
#if !defined(__STRICT_ANSI__) && !defined(__chibicc__)
|
||||
__intrin_xmm_t __palignrs(__intrin_xmm_t, __intrin_xmm_t);
|
||||
#define palignr(C, B, A, I) \
|
||||
do { \
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "libc/intrin/pand.h"
|
||||
|
||||
/**
|
||||
* Nands 128-bit integers.
|
||||
* Ands 128-bit integers.
|
||||
*
|
||||
* @param 𝑎 [w/o] receives result
|
||||
* @param 𝑏 [r/o] supplies first input vector
|
||||
|
|
|
@ -59,10 +59,7 @@ cescapec:
|
|||
#ifdef __STRICT_ANSI__
|
||||
.LQM: mov $'?',%ah
|
||||
ret
|
||||
.LESC:
|
||||
#elif defined(__GNUC__)
|
||||
.LESC: mov $'e',%ah
|
||||
ret
|
||||
#else
|
||||
.LQM:
|
||||
#endif
|
||||
1: mov %edi,%eax
|
||||
|
@ -91,9 +88,7 @@ cescapectab.ro:
|
|||
.byte 1,.LVT-.Lanchorpoint
|
||||
.byte 1,.LFF-.Lanchorpoint
|
||||
.byte 1,.LCR-.Lanchorpoint
|
||||
.byte 0x1b-'\r-1,1b-.Lanchorpoint
|
||||
.byte 1,.LESC-.Lanchorpoint
|
||||
.byte '\"-0x1b-1,1b-.Lanchorpoint
|
||||
.byte '\"-'\r-1,1b-.Lanchorpoint
|
||||
.byte 1,.LDQ-.Lanchorpoint
|
||||
.byte '\'-'\"-1,1b-.Lanchorpoint
|
||||
.byte 1,.LSQ-.Lanchorpoint
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_STR_STRCMP8TO16I_H_
|
||||
#define COSMOPOLITAN_LIBC_STR_STRCMP8TO16I_H_
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/str/oldutf16.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/str/tpdecode.internal.h"
|
||||
|
@ -12,9 +13,12 @@ forceinline int strcmp8to16i(const char *s1, const char16_t *s2, size_t n,
|
|||
int res = 0;
|
||||
if (n) {
|
||||
do {
|
||||
unsigned i, j;
|
||||
wint_t wc1, wc2;
|
||||
s1 += abs(tpdecode(s1, &wc1));
|
||||
s2 += abs(getutf16(s2, &wc2));
|
||||
i = tpdecode(s1, &wc1);
|
||||
j = getutf16(s2, &wc2);
|
||||
s1 += ABS(i);
|
||||
s2 += ABS(j);
|
||||
if ((res = xlat(wc1) - xlat(wc2)) || !wc1) break;
|
||||
} while (n == -1ul || --n);
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
#include "libc/x/x.h"
|
||||
#include "tool/viz/lib/formatstringtable-testlib.h"
|
||||
|
||||
short *bingblit(int ys, int xs, unsigned char[ys][xs], int, int);
|
||||
|
||||
TEST(magikarp, testConvolve) {
|
||||
signed char K[8] = {-1, -3, 3, 17, 17, 3, -3, -1};
|
||||
EXPECT_BINEQ(
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
#include "libc/x/x.h"
|
||||
#include "tool/viz/lib/formatstringtable-testlib.h"
|
||||
|
||||
short *bingblit(int ys, int xs, unsigned char[ys][xs], int, int);
|
||||
|
||||
void *AbsoluteDifference(int yn, int xn, unsigned char C[yn][xn], int ays,
|
||||
int axs, const unsigned char A[ays][axs], int bys,
|
||||
int bxs, const unsigned char B[bys][bxs]) {
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/sysv/consts/ok.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
|
@ -29,7 +29,9 @@ textstartup static void init(void) {
|
|||
}
|
||||
const void *const ctors[] initarray = {init};
|
||||
|
||||
TEST(access, readDirectory) { ASSERT_EQ(0, access("test/libc/", F_OK)); }
|
||||
TEST(access, readDirectory) {
|
||||
ASSERT_EQ(0, access("test/libc/", F_OK));
|
||||
}
|
||||
|
||||
TEST(access, readThisCode) {
|
||||
ASSERT_EQ(0, access("test/libc/access_test.c", R_OK));
|
||||
|
|
|
@ -26,6 +26,7 @@ TEST(cescapec, test) {
|
|||
EXPECT_EQ('\\' | 'r' << 8, cescapec('\r'));
|
||||
EXPECT_EQ('\\' | 'n' << 8, cescapec('\n'));
|
||||
EXPECT_EQ('\\' | '0' << 8 | '0' << 16 | '0' << 24, cescapec(0));
|
||||
EXPECT_EQ('\\' | '0' << 8 | '3' << 16 | '3' << 24, cescapec('\e'));
|
||||
EXPECT_EQ('\\' | '1' << 8 | '7' << 16 | '7' << 24, cescapec(0x7F));
|
||||
EXPECT_EQ('\\' | '3' << 8 | '7' << 16 | '7' << 24, cescapec(0xFF));
|
||||
EXPECT_EQ('\\' | '3' << 8 | '7' << 16 | '7' << 24, cescapec(0xFFFF));
|
||||
|
|
|
@ -17,13 +17,14 @@
|
|||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/time/time.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
TEST(clock_gettime, testClockRealtime) {
|
||||
|
@ -31,5 +32,5 @@ TEST(clock_gettime, testClockRealtime) {
|
|||
struct timespec ts;
|
||||
EXPECT_NE(-1, gettimeofday(&tv, NULL));
|
||||
EXPECT_NE(-1, clock_gettime(CLOCK_REALTIME, &ts));
|
||||
EXPECT_LT((unsigned)abs(ts.tv_sec - tv.tv_sec), 5u);
|
||||
EXPECT_LT((unsigned)ABS(ts.tv_sec - tv.tv_sec), 5u);
|
||||
}
|
||||
|
|
|
@ -6,21 +6,30 @@ which is great, considering it's a 220kb αcτµαlly pδrταblε εxεcµταb
|
|||
|
||||
local enhancements
|
||||
|
||||
- support __asm__
|
||||
- support dce
|
||||
- support gnu asm
|
||||
- support __int128
|
||||
- support _Static_assert
|
||||
- support __vector_size__
|
||||
- support __builtin_memcpy
|
||||
- support __builtin_add_overflow, etc.
|
||||
- support __builtin_memcpy, strlen, strpbrk, etc.
|
||||
- support __builtin_constant_p, __builtin_likely, etc.
|
||||
- support __builtin_isunordered, __builtin_islessgreater, etc.
|
||||
- support __builtin_ctz, __builtin_bswap, __builtin_popcount, etc.
|
||||
- support __constructor__, __destructor__, __section__, __cold__, etc.
|
||||
- support __constructor__, __section__, __cold__, -ffunction-sections, etc.
|
||||
- support building -x assembler-with-cpp a.k.a. .S files
|
||||
- support profiling w/ -mcount / -mfentry / -mnop-mcount
|
||||
- improve error messages to trace macro expansions
|
||||
- reduce #lines of generated assembly by a third
|
||||
- reduce #bytes of generated binary by a third
|
||||
|
||||
local bug fixes
|
||||
|
||||
- allow casted values to be lvalues
|
||||
- permit parentheses around string-initializer
|
||||
- fix 64-bit bug in generated code for struct bitfields
|
||||
- fix bug where last statement in statement expression couldn't have label
|
||||
- print_tokens (chibicc -E) now works in the case of adjacent string literals
|
||||
|
||||
local changes
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ static void DecodeAsmConstraints(AsmOperand *op) {
|
|||
switch ((c = op->str[i++])) {
|
||||
case '\0':
|
||||
case ',': // alternative group
|
||||
return;
|
||||
return; // todo: read combos
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
|
@ -180,13 +180,17 @@ static bool IsLvalue(AsmOperand *op) {
|
|||
}
|
||||
}
|
||||
|
||||
static bool CanUseReg(Node *n) {
|
||||
return is_integer(n->ty) || n->ty->kind == TY_PTR;
|
||||
static bool CanUseReg(Node **n) {
|
||||
if ((*n)->ty->kind == TY_ARRAY) {
|
||||
*n = new_cast(*n, pointer_to((*n)->ty->base));
|
||||
return true;
|
||||
}
|
||||
return is_integer((*n)->ty) || (*n)->ty->kind == TY_PTR;
|
||||
}
|
||||
|
||||
static bool CanUseXmm(Node *n) {
|
||||
return n->ty->kind == TY_FLOAT || n->ty->kind == TY_DOUBLE ||
|
||||
n->ty->kind == TY_PTR ||
|
||||
return n->ty->vector_size == 16 || n->ty->kind == TY_FLOAT ||
|
||||
n->ty->kind == TY_DOUBLE || n->ty->kind == TY_PTR ||
|
||||
(n->ty->kind == TY_ARRAY && n->ty->size == 16);
|
||||
}
|
||||
|
||||
|
@ -201,7 +205,7 @@ static int PickAsmReferenceType(AsmOperand *op, AsmOperand *ref) {
|
|||
case kAsmMem:
|
||||
error_tok(op->tok, "bad reference");
|
||||
case kAsmReg:
|
||||
if (!CanUseReg(op->node)) {
|
||||
if (!CanUseReg(&op->node)) {
|
||||
error_tok(op->tok, "expected integral expression");
|
||||
}
|
||||
op->regmask = 0;
|
||||
|
@ -235,7 +239,7 @@ static int PickAsmOperandType(Asm *a, AsmOperand *op) {
|
|||
if ((op->type & kAsmFpu) && op->node->ty->kind == TY_LDOUBLE) return kAsmFpu;
|
||||
if ((op->type & kAsmXmm) && CanUseXmm(op->node)) return kAsmXmm;
|
||||
if ((op->type & kAsmMmx) && CanUseMmx(op->node)) return kAsmMmx;
|
||||
if ((op->type & kAsmReg) && CanUseReg(op->node)) return kAsmReg;
|
||||
if ((op->type & kAsmReg) && CanUseReg(&op->node)) return kAsmReg;
|
||||
if (op->type & kAsmFlag) return kAsmFlag;
|
||||
if (op->type & kAsmRaw) return kAsmRaw;
|
||||
error_tok(op->tok, "constraint mismatch");
|
||||
|
@ -245,7 +249,7 @@ static Token *ParseAsmOperand(Asm *a, AsmOperand *op, Token *tok) {
|
|||
int i;
|
||||
op->tok = tok;
|
||||
op->str = ConsumeStringLiteral(&tok, tok);
|
||||
tok = skip(tok, "(");
|
||||
tok = skip(tok, '(');
|
||||
op->node = expr(&tok, tok);
|
||||
add_type(op->node);
|
||||
DecodeAsmConstraints(op);
|
||||
|
@ -255,7 +259,7 @@ static Token *ParseAsmOperand(Asm *a, AsmOperand *op, Token *tok) {
|
|||
} else {
|
||||
op->type = PickAsmOperandType(a, op);
|
||||
}
|
||||
return skip(tok, ")");
|
||||
return skip(tok, ')');
|
||||
}
|
||||
|
||||
static Token *ParseAsmOperands(Asm *a, Token *tok) {
|
||||
|
@ -267,7 +271,7 @@ static Token *ParseAsmOperands(Asm *a, Token *tok) {
|
|||
tok = ParseAsmOperand(a, &a->ops[a->n], tok);
|
||||
++a->n;
|
||||
if (!EQUAL(tok, ",")) break;
|
||||
tok = skip(tok, ",");
|
||||
tok = skip(tok, ',');
|
||||
}
|
||||
return tok;
|
||||
}
|
||||
|
@ -315,10 +319,6 @@ static void PickAsmRegisters(Asm *a) {
|
|||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < a->n; ++i) {
|
||||
assert(!a->ops[i].regmask);
|
||||
assert(!a->ops[i].x87mask);
|
||||
}
|
||||
}
|
||||
|
||||
static void MarkUsedAsmOperands(Asm *a) {
|
||||
|
@ -378,11 +378,13 @@ static Token *ParseAsmClobbers(Asm *a, Token *tok) {
|
|||
i = s[3] - '0';
|
||||
i &= 7;
|
||||
a->x87clob |= 1 << i;
|
||||
} else if (!strcmp(s, "memory")) {
|
||||
/* do nothing */
|
||||
} else {
|
||||
error_tok(stok, "unknown clobber register");
|
||||
}
|
||||
if (!EQUAL(tok, ",")) break;
|
||||
tok = skip(tok, ",");
|
||||
tok = skip(tok, ',');
|
||||
}
|
||||
return tok;
|
||||
}
|
||||
|
@ -402,25 +404,25 @@ Asm *asm_stmt(Token **rest, Token *tok) {
|
|||
Asm *a = calloc(1, sizeof(Asm));
|
||||
tok = tok->next;
|
||||
while (EQUAL(tok, "volatile") || EQUAL(tok, "inline")) tok = tok->next;
|
||||
tok = skip(tok, "(");
|
||||
tok = skip(tok, '(');
|
||||
a->tok = tok;
|
||||
a->str = ConsumeStringLiteral(&tok, tok);
|
||||
if (!EQUAL(tok, ")")) {
|
||||
a->isgnu = true;
|
||||
tok = skip(tok, ":");
|
||||
tok = skip(tok, ':');
|
||||
tok = ParseAsmOperands(a, tok);
|
||||
if (!EQUAL(tok, ")")) {
|
||||
tok = skip(tok, ":");
|
||||
tok = skip(tok, ':');
|
||||
tok = ParseAsmOperands(a, tok);
|
||||
if (!EQUAL(tok, ")")) {
|
||||
tok = skip(tok, ":");
|
||||
tok = skip(tok, ':');
|
||||
tok = ParseAsmClobbers(a, tok);
|
||||
}
|
||||
}
|
||||
}
|
||||
PickAsmRegisters(a);
|
||||
MarkUsedAsmOperands(a);
|
||||
*rest = skip(tok, ")");
|
||||
*rest = skip(tok, ')');
|
||||
return a;
|
||||
}
|
||||
|
||||
|
@ -541,24 +543,26 @@ static char *HandleAsmSpecifier(Asm *a, char *p) {
|
|||
|
||||
static void EmitAsmText(Asm *a) {
|
||||
char c, *p;
|
||||
if (a->isgnu) {
|
||||
flushln();
|
||||
fprintf(output_stream, "\t");
|
||||
for (p = a->str;;) {
|
||||
switch ((c = *p++)) {
|
||||
case '\0':
|
||||
fputc('\n', output_stream);
|
||||
return;
|
||||
case '%':
|
||||
p = HandleAsmSpecifier(a, p);
|
||||
break;
|
||||
default:
|
||||
fputc(c, output_stream);
|
||||
break;
|
||||
if (*a->str) {
|
||||
if (a->isgnu) {
|
||||
flushln();
|
||||
fprintf(output_stream, "\t");
|
||||
for (p = a->str;;) {
|
||||
switch ((c = *p++)) {
|
||||
case '\0':
|
||||
fputc('\n', output_stream);
|
||||
return;
|
||||
case '%':
|
||||
p = HandleAsmSpecifier(a, p);
|
||||
break;
|
||||
default:
|
||||
fputc(c, output_stream);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
println("\t%s", a->str);
|
||||
}
|
||||
} else {
|
||||
println("\t%s", a->str);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -668,9 +672,9 @@ static void StoreAsmOutputs(Asm *a) {
|
|||
println("\tset%s\t(%%rax)", a->ops[i].str + a->ops[i].predicate);
|
||||
break;
|
||||
case kAsmReg:
|
||||
z = bsr(a->ops[i].node->ty->size);
|
||||
if (a->ops[i].reg) {
|
||||
gen_addr(a->ops[i].node);
|
||||
z = bsr(a->ops[i].node->ty->size);
|
||||
if (z > 3) error_tok(a->tok, "bad asm out size");
|
||||
println("\tmov\t%%%s,(%%rax)", kGreg[z][a->ops[i].reg]);
|
||||
} else {
|
||||
|
@ -678,7 +682,7 @@ static void StoreAsmOutputs(Asm *a) {
|
|||
push();
|
||||
pop("%rbx");
|
||||
gen_addr(a->ops[i].node);
|
||||
println("\tmov\t%%rbx,(%%rax)");
|
||||
println("\tmov\t%%%s,(%%rax)", kGreg[z][3]);
|
||||
println("\tpop\t%%rbx");
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -150,8 +150,9 @@ static int getTypeId(Type *ty) {
|
|||
return F64;
|
||||
case TY_LDOUBLE:
|
||||
return F80;
|
||||
default:
|
||||
return U64;
|
||||
}
|
||||
return U64;
|
||||
}
|
||||
|
||||
void gen_cast(Type *from, Type *to) {
|
||||
|
|
|
@ -16,15 +16,21 @@ typedef enum {
|
|||
FILE_DSO,
|
||||
} FileType;
|
||||
|
||||
bool opt_fcommon = true;
|
||||
bool opt_fpic;
|
||||
bool opt_verbose;
|
||||
bool opt_mpopcnt;
|
||||
bool opt_common = true;
|
||||
bool opt_data_sections;
|
||||
bool opt_fentry;
|
||||
bool opt_function_sections;
|
||||
bool opt_no_builtin;
|
||||
bool opt_nop_mcount;
|
||||
bool opt_pg;
|
||||
bool opt_mfentry;
|
||||
bool opt_mnop_mcount;
|
||||
bool opt_mrecord_mcount;
|
||||
bool opt_pic;
|
||||
bool opt_popcnt;
|
||||
bool opt_record_mcount;
|
||||
bool opt_sse3;
|
||||
bool opt_sse4;
|
||||
bool opt_verbose;
|
||||
|
||||
static bool opt_A;
|
||||
static bool opt_E;
|
||||
static bool opt_M;
|
||||
static bool opt_MD;
|
||||
|
@ -56,6 +62,14 @@ static void usage(int status) {
|
|||
exit(status);
|
||||
}
|
||||
|
||||
static void version(void) {
|
||||
printf("\
|
||||
chibicc (cosmopolitan) 9.0.0\n\
|
||||
copyright 2019 rui ueyama\n\
|
||||
copyright 2020 justine alexandra roberts tunney\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static bool take_arg(char *arg) {
|
||||
char *x[] = {"-o", "-I", "-idirafter", "-include",
|
||||
"-x", "-MF", "-MT", "-Xlinker"};
|
||||
|
@ -130,231 +144,171 @@ static void PrintMemoryUsage(void) {
|
|||
fprintf(stderr, "allocated %,ld bytes of memory\n", mi.arena);
|
||||
}
|
||||
|
||||
static void strarray_push_comma(StringArray *a, char *s) {
|
||||
char *p;
|
||||
for (; *s++ == ','; s = p) {
|
||||
p = strchrnul(s, ',');
|
||||
strarray_push(a, strndup(s, p - s));
|
||||
}
|
||||
}
|
||||
|
||||
static void parse_args(int argc, char **argv) {
|
||||
// Make sure that all command line options that take an argument
|
||||
// have an argument.
|
||||
for (int i = 1; i < argc; i++)
|
||||
if (take_arg(argv[i]))
|
||||
if (!argv[++i]) usage(1);
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (take_arg(argv[i])) {
|
||||
if (!argv[++i]) {
|
||||
usage(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
StringArray idirafter = {};
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (!strcmp(argv[i], "-###")) {
|
||||
opt_hash_hash_hash = true;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-cc1")) {
|
||||
} else if (!strcmp(argv[i], "-cc1")) {
|
||||
opt_cc1 = true;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "--help")) usage(0);
|
||||
if (!strcmp(argv[i], "-v")) {
|
||||
} else if (!strcmp(argv[i], "--help")) {
|
||||
usage(0);
|
||||
} else if (!strcmp(argv[i], "--version")) {
|
||||
version();
|
||||
} else if (!strcmp(argv[i], "-v")) {
|
||||
opt_verbose = true;
|
||||
atexit(PrintMemoryUsage);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-o")) {
|
||||
} else if (!strcmp(argv[i], "-o")) {
|
||||
opt_o = argv[++i];
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(argv[i], "-o", 2)) {
|
||||
} else if (startswith(argv[i], "-o")) {
|
||||
opt_o = argv[i] + 2;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-S")) {
|
||||
} else if (!strcmp(argv[i], "-S")) {
|
||||
opt_S = true;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-fcommon")) {
|
||||
opt_fcommon = true;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-fno-common")) {
|
||||
opt_fcommon = false;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-c")) {
|
||||
} else if (!strcmp(argv[i], "-fcommon")) {
|
||||
opt_common = true;
|
||||
} else if (!strcmp(argv[i], "-fno-common")) {
|
||||
opt_common = false;
|
||||
} else if (!strcmp(argv[i], "-fno-builtin")) {
|
||||
opt_no_builtin = true;
|
||||
} else if (!strcmp(argv[i], "-c")) {
|
||||
opt_c = true;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-E")) {
|
||||
} else if (!strcmp(argv[i], "-E")) {
|
||||
opt_E = true;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(argv[i], "-I", 2)) {
|
||||
} else if (!strcmp(argv[i], "-A")) {
|
||||
opt_A = true;
|
||||
} else if (!strcmp(argv[i], "-I")) {
|
||||
strarray_push(&include_paths, argv[++i]);
|
||||
} else if (startswith(argv[i], "-I")) {
|
||||
strarray_push(&include_paths, argv[i] + 2);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-D")) {
|
||||
} else if (!strcmp(argv[i], "-iquote")) {
|
||||
strarray_push(&include_paths, argv[++i]);
|
||||
} else if (startswith(argv[i], "-iquote")) {
|
||||
strarray_push(&include_paths, argv[i] + strlen("-iquote"));
|
||||
} else if (!strcmp(argv[i], "-isystem")) {
|
||||
strarray_push(&include_paths, argv[++i]);
|
||||
} else if (startswith(argv[i], "-isystem")) {
|
||||
strarray_push(&include_paths, argv[i] + strlen("-isystem"));
|
||||
} else if (!strcmp(argv[i], "-D")) {
|
||||
define(argv[++i]);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(argv[i], "-D", 2)) {
|
||||
} else if (startswith(argv[i], "-D")) {
|
||||
define(argv[i] + 2);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-U")) {
|
||||
} else if (!strcmp(argv[i], "-U")) {
|
||||
undef_macro(argv[++i]);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(argv[i], "-U", 2)) {
|
||||
} else if (!strncmp(argv[i], "-U", 2)) {
|
||||
undef_macro(argv[i] + 2);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-include")) {
|
||||
} else if (!strcmp(argv[i], "-include")) {
|
||||
strarray_push(&opt_include, argv[++i]);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-x")) {
|
||||
} else if (!strcmp(argv[i], "-x")) {
|
||||
opt_x = parse_opt_x(argv[++i]);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(argv[i], "-x", 2)) {
|
||||
} else if (!strncmp(argv[i], "-x", 2)) {
|
||||
opt_x = parse_opt_x(argv[i] + 2);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(argv[i], "-l", 2) || !strncmp(argv[i], "-Wl,", 4)) {
|
||||
strarray_push(&input_paths, argv[i]);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-Xassembler")) {
|
||||
} else if (startswith(argv[i], "-Wa")) {
|
||||
strarray_push_comma(&as_extra_args, argv[i]);
|
||||
} else if (startswith(argv[i], "-Wl")) {
|
||||
strarray_push_comma(&ld_extra_args, argv[i]);
|
||||
} else if (!strcmp(argv[i], "-Xassembler")) {
|
||||
strarray_push(&as_extra_args, argv[++i]);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-Xlinker")) {
|
||||
} else if (!strcmp(argv[i], "-Xlinker")) {
|
||||
strarray_push(&ld_extra_args, argv[++i]);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-s")) {
|
||||
} else if (!strncmp(argv[i], "-l", 2) || !strncmp(argv[i], "-Wl,", 4)) {
|
||||
strarray_push(&input_paths, argv[i]);
|
||||
} else if (!strcmp(argv[i], "-s")) {
|
||||
strarray_push(&ld_extra_args, "-s");
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-M")) {
|
||||
} else if (!strcmp(argv[i], "-M")) {
|
||||
opt_M = true;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-MF")) {
|
||||
} else if (!strcmp(argv[i], "-MF")) {
|
||||
opt_MF = argv[++i];
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-MP")) {
|
||||
} else if (!strcmp(argv[i], "-MP")) {
|
||||
opt_MP = true;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-MT")) {
|
||||
if (opt_MT == NULL)
|
||||
} else if (!strcmp(argv[i], "-MT")) {
|
||||
if (!opt_MT) {
|
||||
opt_MT = argv[++i];
|
||||
else
|
||||
} else {
|
||||
opt_MT = xasprintf("%s %s", opt_MT, argv[++i]);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-MD")) {
|
||||
}
|
||||
} else if (!strcmp(argv[i], "-MD")) {
|
||||
opt_MD = true;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-MQ")) {
|
||||
if (opt_MT == NULL)
|
||||
} else if (!strcmp(argv[i], "-MQ")) {
|
||||
if (!opt_MT) {
|
||||
opt_MT = quote_makefile(argv[++i]);
|
||||
else
|
||||
} else {
|
||||
opt_MT = xasprintf("%s %s", opt_MT, quote_makefile(argv[++i]));
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-MMD")) {
|
||||
}
|
||||
} else if (!strcmp(argv[i], "-MMD")) {
|
||||
opt_MD = opt_MMD = true;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-fpie") || !strcmp(argv[i], "-fpic") ||
|
||||
!strcmp(argv[i], "-fPIC")) {
|
||||
opt_fpic = true;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-pg")) {
|
||||
} else if (!strcmp(argv[i], "-fpie") || !strcmp(argv[i], "-fpic") ||
|
||||
!strcmp(argv[i], "-fPIC")) {
|
||||
opt_pic = true;
|
||||
} else if (!strcmp(argv[i], "-pg")) {
|
||||
opt_pg = true;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-mfentry")) {
|
||||
opt_mfentry = true;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-mrecord-mcount")) {
|
||||
opt_mrecord_mcount = true;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-mnop-mcount")) {
|
||||
opt_mnop_mcount = true;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-mpopcnt")) {
|
||||
opt_mpopcnt = true;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-cc1-input")) {
|
||||
} else if (!strcmp(argv[i], "-mfentry")) {
|
||||
opt_fentry = true;
|
||||
} else if (!strcmp(argv[i], "-ffunction-sections")) {
|
||||
opt_function_sections = true;
|
||||
} else if (!strcmp(argv[i], "-fdata-sections")) {
|
||||
opt_data_sections = true;
|
||||
} else if (!strcmp(argv[i], "-mrecord-mcount")) {
|
||||
opt_record_mcount = true;
|
||||
} else if (!strcmp(argv[i], "-mnop-mcount")) {
|
||||
opt_nop_mcount = true;
|
||||
} else if (!strcmp(argv[i], "-msse3")) {
|
||||
opt_sse3 = true;
|
||||
} else if (!strcmp(argv[i], "-msse4") || !strcmp(argv[i], "-msse4.2") ||
|
||||
!strcmp(argv[i], "-msse4.1")) {
|
||||
opt_sse4 = true;
|
||||
} else if (!strcmp(argv[i], "-mpopcnt")) {
|
||||
opt_popcnt = true;
|
||||
} else if (!strcmp(argv[i], "-cc1-input")) {
|
||||
base_file = argv[++i];
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-cc1-output")) {
|
||||
} else if (!strcmp(argv[i], "-cc1-output")) {
|
||||
output_file = argv[++i];
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-idirafter")) {
|
||||
} else if (!strcmp(argv[i], "-idirafter")) {
|
||||
strarray_push(&idirafter, argv[i++]);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-static")) {
|
||||
} else if (!strcmp(argv[i], "-static")) {
|
||||
opt_static = true;
|
||||
strarray_push(&ld_extra_args, "-static");
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-shared")) {
|
||||
fprintf(stderr, "error: -shared not supported\n");
|
||||
exit(1);
|
||||
}
|
||||
if (!strcmp(argv[i], "-L")) {
|
||||
} else if (!strcmp(argv[i], "-shared")) {
|
||||
error("-shared not supported");
|
||||
} else if (!strcmp(argv[i], "-L")) {
|
||||
strarray_push(&ld_extra_args, "-L");
|
||||
strarray_push(&ld_extra_args, argv[++i]);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(argv[i], "-L", 2)) {
|
||||
} else if (startswith(argv[i], "-L")) {
|
||||
strarray_push(&ld_extra_args, "-L");
|
||||
strarray_push(&ld_extra_args, argv[i] + 2);
|
||||
continue;
|
||||
} else {
|
||||
if (argv[i][0] == '-' && argv[i][1]) {
|
||||
/* compiler should not whine about the flags race */
|
||||
if (opt_verbose) {
|
||||
fprintf(stderr, "unknown argument: %s\n", argv[i]);
|
||||
}
|
||||
} else {
|
||||
strarray_push(&input_paths, argv[i]);
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
if (!strcmp(argv[i], "-hashmap-test")) {
|
||||
hashmap_test();
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
// These options are ignored for now.
|
||||
if (startswith(argv[i], "-O") || startswith(argv[i], "-W") ||
|
||||
startswith(argv[i], "-g") || startswith(argv[i], "-std=") ||
|
||||
startswith(argv[i], "-fno-") || startswith(argv[i], "-mno-") ||
|
||||
startswith(argv[i], "-fsanitize") ||
|
||||
startswith(argv[i], "-fdebug-prefix-map") ||
|
||||
!strcmp(argv[i], "-fwrapv") || !strcmp(argv[i], "-nostdlib") ||
|
||||
!strcmp(argv[i], "-nostdinc") || !strcmp(argv[i], "-ffreestanding") ||
|
||||
!strcmp(argv[i], "-fstrict-aliasing") ||
|
||||
!strcmp(argv[i], "-fstrict-overflow") ||
|
||||
!strcmp(argv[i], "-frecord-gcc-switches") ||
|
||||
!strcmp(argv[i], "-fsignaling-nans") ||
|
||||
!strcmp(argv[i], "-frounding-math") ||
|
||||
!strcmp(argv[i], "-fcx-limited-range") ||
|
||||
!strcmp(argv[i], "-fmodulo-sched") ||
|
||||
!strcmp(argv[i], "-fmerge-constants") ||
|
||||
!strcmp(argv[i], "-fmerge-all-constants") ||
|
||||
!strcmp(argv[i], "-fno-builtin") ||
|
||||
!strcmp(argv[i], "-fno-omit-frame-pointer") ||
|
||||
!strcmp(argv[i], "-fno-stack-protector") ||
|
||||
!strcmp(argv[i], "-fno-strict-aliasing") || !strcmp(argv[i], "-m64") ||
|
||||
!strcmp(argv[i], "-mno-red-zone") || !strcmp(argv[i], "-w")) {
|
||||
continue;
|
||||
}
|
||||
if (argv[i][0] == '-' && argv[i][1] != '\0')
|
||||
error("unknown argument: %s", argv[i]);
|
||||
strarray_push(&input_paths, argv[i]);
|
||||
}
|
||||
for (int i = 0; i < idirafter.len; i++)
|
||||
for (int i = 0; i < idirafter.len; i++) {
|
||||
strarray_push(&include_paths, idirafter.data[i]);
|
||||
if (input_paths.len == 0) error("no input files");
|
||||
}
|
||||
if (!input_paths.len) {
|
||||
error("no input files");
|
||||
}
|
||||
// -E implies that the input is the C macro language.
|
||||
if (opt_E) opt_x = FILE_C;
|
||||
}
|
||||
|
@ -439,13 +393,36 @@ static void run_cc1(int argc, char **argv, char *input, char *output) {
|
|||
run_subprocess(args);
|
||||
}
|
||||
|
||||
static void print_token(FILE *out, Token *tok) {
|
||||
switch (tok->kind) {
|
||||
case TK_STR:
|
||||
switch (tok->ty->base->size) {
|
||||
case 1:
|
||||
fprintf(out, "%`'.*s", tok->ty->array_len - 1, tok->str);
|
||||
break;
|
||||
case 2:
|
||||
fprintf(out, "%`'.*hs", tok->ty->array_len - 1, tok->str);
|
||||
break;
|
||||
case 4:
|
||||
fprintf(out, "%`'.*ls", tok->ty->array_len - 1, tok->str);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(out, "%.*s", tok->len, tok->loc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void print_tokens(Token *tok) {
|
||||
FILE *out = open_file(opt_o ? opt_o : "-");
|
||||
int line = 1;
|
||||
for (; tok->kind != TK_EOF; tok = tok->next) {
|
||||
if (line > 1 && tok->at_bol) fprintf(out, "\n");
|
||||
if (tok->has_space && !tok->at_bol) fprintf(out, " ");
|
||||
fprintf(out, "%.*s", tok->len, tok->loc);
|
||||
print_token(out, tok);
|
||||
line++;
|
||||
}
|
||||
fprintf(out, "\n");
|
||||
|
@ -547,7 +524,10 @@ static void cc1(void) {
|
|||
return;
|
||||
}
|
||||
Obj *prog = parse(tok);
|
||||
// Traverse the AST to emit assembly.
|
||||
if (opt_A) {
|
||||
print_ast(stdout, prog);
|
||||
return;
|
||||
}
|
||||
FILE *out = open_file(output_file);
|
||||
codegen(prog, out);
|
||||
fclose(out);
|
||||
|
@ -582,7 +562,7 @@ static void run_linker(StringArray *inputs, char *output) {
|
|||
strarray_push(&arr, "elf_x86_64");
|
||||
strarray_push(&arr, "-z");
|
||||
strarray_push(&arr, "max-page-size=0x1000");
|
||||
strarray_push(&arr, "-mnostdlib");
|
||||
strarray_push(&arr, "-nostdlib");
|
||||
strarray_push(&arr, "--gc-sections");
|
||||
strarray_push(&arr, "--build-id=none");
|
||||
strarray_push(&arr, "--no-dynamic-linker");
|
||||
|
@ -611,8 +591,9 @@ int main(int argc, char **argv) {
|
|||
cc1();
|
||||
return 0;
|
||||
}
|
||||
if (input_paths.len > 1 && opt_o && (opt_c || opt_S | opt_E))
|
||||
if (input_paths.len > 1 && opt_o && (opt_c || opt_S | opt_E)) {
|
||||
error("cannot specify '-o' with '-c,' '-S' or '-E' with multiple files");
|
||||
}
|
||||
StringArray ld_args = {};
|
||||
for (int i = 0; i < input_paths.len; i++) {
|
||||
char *input = input_paths.data[i];
|
||||
|
@ -650,7 +631,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
continue;
|
||||
}
|
||||
assert(type == FILE_C);
|
||||
assert(type == FILE_C || type == FILE_ASM_CPP);
|
||||
// Just preprocess
|
||||
if (opt_E || opt_M) {
|
||||
run_cc1(argc, argv, input, NULL);
|
||||
|
|
|
@ -114,7 +114,7 @@ void warn_tok(Token *, char *, ...)
|
|||
|
||||
File **get_input_files(void);
|
||||
File *new_file(char *, int, char *);
|
||||
Token *skip(Token *, char *);
|
||||
Token *skip(Token *, char);
|
||||
Token *tokenize(File *);
|
||||
Token *tokenize_file(char *);
|
||||
Token *tokenize_string_literal(Token *, Type *);
|
||||
|
@ -269,10 +269,10 @@ typedef enum {
|
|||
ND_MUL, // *
|
||||
ND_DIV, // /
|
||||
ND_NEG, // unary -
|
||||
ND_MOD, // %
|
||||
ND_BITAND, // &
|
||||
ND_BITOR, // |
|
||||
ND_BITXOR, // ^
|
||||
ND_REM, // %
|
||||
ND_BINAND, // &
|
||||
ND_BINOR, // |
|
||||
ND_BINXOR, // ^
|
||||
ND_SHL, // <<
|
||||
ND_SHR, // >>
|
||||
ND_EQ, // ==
|
||||
|
@ -329,61 +329,44 @@ struct Node {
|
|||
Node *inc;
|
||||
// Block or statement expression
|
||||
Node *body;
|
||||
union {
|
||||
struct {
|
||||
// Function call
|
||||
Type *func_ty;
|
||||
Node *args;
|
||||
bool pass_by_stack;
|
||||
Obj *ret_buffer;
|
||||
};
|
||||
struct {
|
||||
// Switch
|
||||
Node *case_next;
|
||||
Node *default_case;
|
||||
// Goto or labeled statement, or labels-as-values
|
||||
char *label;
|
||||
char *unique_label;
|
||||
Node *goto_next;
|
||||
// "break" and "continue" labels
|
||||
char *brk_label;
|
||||
char *cont_label;
|
||||
// Case
|
||||
long begin;
|
||||
long end;
|
||||
};
|
||||
struct {
|
||||
// Struct member access
|
||||
Member *member;
|
||||
};
|
||||
struct {
|
||||
// Assembly
|
||||
Asm *azm;
|
||||
};
|
||||
struct {
|
||||
// Atomic compare-and-swap
|
||||
Node *cas_addr;
|
||||
Node *cas_old;
|
||||
Node *cas_new;
|
||||
};
|
||||
struct {
|
||||
// Atomic op= operators
|
||||
Obj *atomic_addr;
|
||||
Node *atomic_expr;
|
||||
};
|
||||
struct {
|
||||
// Variable
|
||||
Obj *var;
|
||||
};
|
||||
struct {
|
||||
// Numeric literal
|
||||
int64_t val;
|
||||
long double fval;
|
||||
};
|
||||
struct {
|
||||
FpClassify *fpc;
|
||||
};
|
||||
};
|
||||
// Function call
|
||||
Type *func_ty;
|
||||
Node *args;
|
||||
Obj *ret_buffer;
|
||||
bool pass_by_stack;
|
||||
bool realign_stack;
|
||||
// Switch
|
||||
Node *case_next;
|
||||
Node *default_case;
|
||||
// Goto or labeled statement, or labels-as-values
|
||||
char *label;
|
||||
char *unique_label;
|
||||
Node *goto_next;
|
||||
// "break" and "continue" labels
|
||||
char *brk_label;
|
||||
char *cont_label;
|
||||
// Case
|
||||
long begin;
|
||||
long end;
|
||||
// Struct member access
|
||||
Member *member;
|
||||
// Assembly
|
||||
Asm *azm;
|
||||
// Atomic compare-and-swap
|
||||
Node *cas_addr;
|
||||
Node *cas_old;
|
||||
Node *cas_new;
|
||||
// Atomic op= operators
|
||||
Obj *atomic_addr;
|
||||
Node *atomic_expr;
|
||||
// Variable
|
||||
Obj *var;
|
||||
// Arithmetic
|
||||
Node *overflow;
|
||||
// Numeric literal
|
||||
int64_t val;
|
||||
long double fval;
|
||||
FpClassify *fpc;
|
||||
};
|
||||
|
||||
Node *expr(Token **, Token *);
|
||||
|
@ -396,6 +379,12 @@ int64_t const_expr(Token **, Token *);
|
|||
int64_t eval(Node *);
|
||||
int64_t eval2(Node *, char ***);
|
||||
|
||||
//
|
||||
// debug.c
|
||||
//
|
||||
|
||||
void print_ast(FILE *, Obj *);
|
||||
|
||||
//
|
||||
// type.c
|
||||
//
|
||||
|
@ -560,15 +549,20 @@ void hashmap_test(void);
|
|||
//
|
||||
|
||||
extern StringArray include_paths;
|
||||
extern bool opt_fcommon;
|
||||
extern bool opt_fpic;
|
||||
extern bool opt_verbose;
|
||||
extern bool opt_mpopcnt;
|
||||
extern char *base_file;
|
||||
extern bool opt_common;
|
||||
extern bool opt_data_sections;
|
||||
extern bool opt_fentry;
|
||||
extern bool opt_function_sections;
|
||||
extern bool opt_no_builtin;
|
||||
extern bool opt_nop_mcount;
|
||||
extern bool opt_pg;
|
||||
extern bool opt_mfentry;
|
||||
extern bool opt_mnop_mcount;
|
||||
extern bool opt_mrecord_mcount;
|
||||
extern bool opt_pic;
|
||||
extern bool opt_popcnt;
|
||||
extern bool opt_record_mcount;
|
||||
extern bool opt_sse3;
|
||||
extern bool opt_sse4;
|
||||
extern bool opt_verbose;
|
||||
extern char *base_file;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -55,6 +55,7 @@ THIRD_PARTY_CHIBICC_A_DIRECTDEPS = \
|
|||
LIBC_TIME \
|
||||
LIBC_UNICODE \
|
||||
LIBC_X \
|
||||
THIRD_PARTY_COMPILER_RT \
|
||||
THIRD_PARTY_DLMALLOC \
|
||||
THIRD_PARTY_GDTOA
|
||||
|
||||
|
@ -73,10 +74,10 @@ $(THIRD_PARTY_CHIBICC_A).pkg: \
|
|||
o/$(MODE)/third_party/chibicc/chibicc.com.dbg: \
|
||||
$(THIRD_PARTY_CHIBICC_A_DEPS) \
|
||||
$(THIRD_PARTY_CHIBICC_A) \
|
||||
o/$(MODE)/third_party/chibicc/chibicc.o \
|
||||
$(THIRD_PARTY_CHIBICC_A).pkg \
|
||||
$(APE) \
|
||||
$(CRT) \
|
||||
$(APE)
|
||||
o/$(MODE)/third_party/chibicc/chibicc.o \
|
||||
$(THIRD_PARTY_CHIBICC_A).pkg
|
||||
@$(APELINK)
|
||||
|
||||
o/$(MODE)/third_party/chibicc/chibicc2.com.dbg: \
|
||||
|
@ -93,16 +94,16 @@ o/$(MODE)/third_party/chibicc/chibicc.o: \
|
|||
-DAPE=\"o/$(MODE)/ape/ape.o\" \
|
||||
-DLDS=\"o/$(MODE)/ape/ape.lds\"
|
||||
|
||||
o/$(MODE)/third_party/chibicc/chibicc.chibicc.s: \
|
||||
o/$(MODE)/third_party/chibicc/chibicc.chibicc.o: \
|
||||
CHIBICC_FLAGS += \
|
||||
-DCRT=\"$(CRT)\" \
|
||||
-DAPE=\"o/$(MODE)/ape/ape.o\" \
|
||||
-DLDS=\"o/$(MODE)/ape/ape.lds\"
|
||||
|
||||
o/$(MODE)/%.chibicc.s: %.c o/$(MODE)/third_party/chibicc/chibicc.com.dbg
|
||||
@ACTION=CHIBICC TARGET=$@ build/do $(CHIBICC) $(CHIBICC_FLAGS) -S -o $@ $<
|
||||
o/$(MODE)/%.chibicc2.s: %.c o/$(MODE)/third_party/chibicc/chibicc2.com.dbg
|
||||
@ACTION=CHIBICC2 TARGET=$@ build/do $(CHIBICC2) $(CHIBICC_FLAGS) -S -o $@ $<
|
||||
o/$(MODE)/%.chibicc.o: %.c o/$(MODE)/third_party/chibicc/chibicc.com.dbg
|
||||
@ACTION=CHIBICC TARGET=$@ build/do $(CHIBICC) $(CHIBICC_FLAGS) -c -o $@ $<
|
||||
o/$(MODE)/%.chibicc2.o: %.c o/$(MODE)/third_party/chibicc/chibicc2.com.dbg
|
||||
@ACTION=CHIBICC2 TARGET=$@ build/do $(CHIBICC2) $(CHIBICC_FLAGS) -c -o $@ $<
|
||||
|
||||
THIRD_PARTY_CHIBICC_LIBS = $(foreach x,$(THIRD_PARTY_CHIBICC_ARTIFACTS),$($(x)))
|
||||
THIRD_PARTY_CHIBICC_SRCS = $(foreach x,$(THIRD_PARTY_CHIBICC_ARTIFACTS),$($(x)_SRCS))
|
||||
|
@ -115,5 +116,4 @@ $(THIRD_PARTY_CHIBICC_OBJS): $(BUILD_FILES) third_party/chibicc/chibicc.mk
|
|||
o/$(MODE)/third_party/chibicc: \
|
||||
o/$(MODE)/third_party/chibicc/test \
|
||||
$(THIRD_PARTY_CHIBICC_BINS) \
|
||||
$(THIRD_PARTY_CHIBICC_CHECKS) \
|
||||
$(THIRD_PARTY_CHIBICC_A_SRCS:%.c=o/$(MODE)/%.chibicc.s)
|
||||
$(THIRD_PARTY_CHIBICC_CHECKS)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|