mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-30 06:20:28 +00:00
Make it possible to compile redbean with chibicc
This cuts build latency down from 5 seconds to 500 milliseconds.
This commit is contained in:
parent
552525cbdd
commit
6ff46ca373
50 changed files with 898 additions and 824 deletions
40
third_party/chibicc/as.c
vendored
40
third_party/chibicc/as.c
vendored
|
@ -1752,6 +1752,14 @@ static void OnSize(struct As *a, struct Slice s) {
|
|||
a->symbols.p[i].size = GetInt(a);
|
||||
}
|
||||
|
||||
static void OnEqu(struct As *a, struct Slice s) {
|
||||
int i, j;
|
||||
i = GetSymbol(a, a->things.p[a->i++].i);
|
||||
ConsumeComma(a);
|
||||
a->symbols.p[i].offset = GetInt(a);
|
||||
a->symbols.p[i].section = SHN_ABS;
|
||||
}
|
||||
|
||||
static void OnComm(struct As *a, struct Slice s) {
|
||||
int i;
|
||||
i = GetSymbol(a, a->things.p[a->i++].i);
|
||||
|
@ -2132,12 +2140,24 @@ static void EmitRexOpModrm(struct As *a, long op, int reg, int modrm, int disp,
|
|||
EmitOpModrm(a, op, reg, modrm, disp, skew);
|
||||
}
|
||||
|
||||
static void OnLea(struct As *a, struct Slice s) {
|
||||
static void OnLoad(struct As *a, struct Slice s, int op) {
|
||||
int modrm, reg, disp;
|
||||
modrm = ParseModrm(a, &disp);
|
||||
ConsumeComma(a);
|
||||
reg = GetRegisterReg(a);
|
||||
EmitRexOpModrm(a, 0x8D, reg, modrm, disp, 0);
|
||||
EmitRexOpModrm(a, op, reg, modrm, disp, 0);
|
||||
}
|
||||
|
||||
static void OnLea(struct As *a, struct Slice s) {
|
||||
return OnLoad(a, s, 0x8D);
|
||||
}
|
||||
|
||||
static void OnLar(struct As *a, struct Slice s) {
|
||||
return OnLoad(a, s, 0x0f02);
|
||||
}
|
||||
|
||||
static void OnLsl(struct As *a, struct Slice s) {
|
||||
return OnLoad(a, s, 0x0f03);
|
||||
}
|
||||
|
||||
static void OnMov(struct As *a, struct Slice s) {
|
||||
|
@ -2593,6 +2613,12 @@ static void OnPush(struct As *a, struct Slice s) {
|
|||
}
|
||||
}
|
||||
|
||||
static void OnRdpid(struct As *a, struct Slice s) {
|
||||
int modrm, disp;
|
||||
EmitVarword(a, 0xf30fc7);
|
||||
EmitByte(a, 0370 | GetRegisterReg(a));
|
||||
}
|
||||
|
||||
static void OnPop(struct As *a, struct Slice s) {
|
||||
int modrm, disp;
|
||||
modrm = RemoveRexw(ParseModrm(a, &disp));
|
||||
|
@ -2901,6 +2927,7 @@ static void OnMinsd(struct As *a, struct Slice s) { OpSse(a, 0xF20F5D); }
|
|||
static void OnMinss(struct As *a, struct Slice s) { OpSse(a, 0xF30F5D); }
|
||||
static void OnMovmskpd(struct As *a, struct Slice s) { OpSse(a, 0x660F50); }
|
||||
static void OnMovmskps(struct As *a, struct Slice s) { OpSse(a, 0x0F50); }
|
||||
static void OnMovntdq(struct As *a, struct Slice s) { OpMovntdq(a); }
|
||||
static void OnMovsb(struct As *a, struct Slice s) { EmitByte(a, 0xA4); }
|
||||
static void OnMovsl(struct As *a, struct Slice s) { EmitByte(a, 0xA5); }
|
||||
static void OnMovsq(struct As *a, struct Slice s) { EmitVarword(a, 0x48A5); }
|
||||
|
@ -3013,12 +3040,13 @@ static void OnPunpcklbw(struct As *a, struct Slice s) { OpSse(a, 0x660F60); }
|
|||
static void OnPunpckldq(struct As *a, struct Slice s) { OpSse(a, 0x660F62); }
|
||||
static void OnPunpcklqdq(struct As *a, struct Slice s) { OpSse(a, 0x660F6C); }
|
||||
static void OnPunpcklwd(struct As *a, struct Slice s) { OpSse(a, 0x660F61); }
|
||||
static void OnMovntdq(struct As *a, struct Slice s) { OpMovntdq(a); }
|
||||
static void OnPxor(struct As *a, struct Slice s) { OpSse(a, 0x660FEF); }
|
||||
static void OnRcl(struct As *a, struct Slice s) { OpBsu(a, s, 2); }
|
||||
static void OnRcpps(struct As *a, struct Slice s) { OpSse(a, 0x0F53); }
|
||||
static void OnRcpss(struct As *a, struct Slice s) { OpSse(a, 0xF30F53); }
|
||||
static void OnRcr(struct As *a, struct Slice s) { OpBsu(a, s, 3); }
|
||||
static void OnRdtsc(struct As *a, struct Slice s) { EmitVarword(a, 0x0f31); }
|
||||
static void OnRdtscp(struct As *a, struct Slice s) { EmitVarword(a, 0x0f01f9); }
|
||||
static void OnRol(struct As *a, struct Slice s) { OpBsu(a, s, 0); }
|
||||
static void OnRor(struct As *a, struct Slice s) { OpBsu(a, s, 1); }
|
||||
static void OnRoundsd(struct As *a, struct Slice s) { OpSseIb(a, 0x660F3A0B); }
|
||||
|
@ -3088,6 +3116,7 @@ static const struct Directive8 {
|
|||
{".comm", OnComm}, //
|
||||
{".data", OnData}, //
|
||||
{".double", OnDouble}, //
|
||||
{".equ", OnEqu}, //
|
||||
{".err", OnErr}, //
|
||||
{".error", OnError}, //
|
||||
{".file", OnFile}, //
|
||||
|
@ -3329,12 +3358,14 @@ static const struct Directive8 {
|
|||
{"jpo", OnJnp}, //
|
||||
{"js", OnJs}, //
|
||||
{"jz", OnJz}, //
|
||||
{"lar", OnLar}, //
|
||||
{"lea", OnLea}, //
|
||||
{"leave", OnLeave}, //
|
||||
{"lodsb", OnLodsb}, //
|
||||
{"lodsl", OnLodsl}, //
|
||||
{"lodsq", OnLodsq}, //
|
||||
{"lodsw", OnLodsw}, //
|
||||
{"lsl", OnLsl}, //
|
||||
{"maxpd", OnMaxpd}, //
|
||||
{"maxps", OnMaxps}, //
|
||||
{"maxsd", OnMaxsd}, //
|
||||
|
@ -3507,6 +3538,9 @@ static const struct Directive8 {
|
|||
{"rcrl", OnRcr}, //
|
||||
{"rcrq", OnRcr}, //
|
||||
{"rcrw", OnRcr}, //
|
||||
{"rdpid", OnRdpid}, //
|
||||
{"rdtsc", OnRdtsc}, //
|
||||
{"rdtscp", OnRdtscp}, //
|
||||
{"ret", OnRet}, //
|
||||
{"rol", OnRol}, //
|
||||
{"rolb", OnRol}, //
|
||||
|
|
12
third_party/chibicc/cast.c
vendored
12
third_party/chibicc/cast.c
vendored
|
@ -39,12 +39,12 @@
|
|||
"\taddsd\t%xmm0,%xmm0\n" \
|
||||
"2:"
|
||||
|
||||
#define u64f80 \
|
||||
PUSHPOPRAX("fildq\t(%rsp)\n" \
|
||||
"\ttest\t%rax,%rax\n" \
|
||||
"\tjns\t1f\n" \
|
||||
"\tmov\t$0x5f800000,(%rsp)\n" \
|
||||
"\tfadds\t(%rsp)\n" \
|
||||
#define u64f80 \
|
||||
PUSHPOPRAX("fildq\t(%rsp)\n" \
|
||||
"\ttest\t%rax,%rax\n" \
|
||||
"\tjns\t1f\n" \
|
||||
"\tmovq\t$0x5f800000,(%rsp)\n" \
|
||||
"\tfadds\t(%rsp)\n" \
|
||||
"1:")
|
||||
|
||||
#define i32i8 "movsbl\t%al,%eax"
|
||||
|
|
2
third_party/chibicc/chibicc.mk
vendored
2
third_party/chibicc/chibicc.mk
vendored
|
@ -134,6 +134,8 @@ o/$(MODE)/third_party/chibicc/chibicc.o: \
|
|||
o/$(MODE)/third_party/chibicc/chibicc.chibicc.o: \
|
||||
CHIBICC_FLAGS += $(THIRD_PARTY_CHIBICC_DEFINES)
|
||||
|
||||
o/$(MODE)/%.chibicc.o: %.s o/$(MODE)/third_party/chibicc/chibicc.com.dbg
|
||||
@$(COMPILE) -ACHIBICC -T$@ $(CHIBICC) $(CHIBICC_FLAGS) -c -o $@ $<
|
||||
o/$(MODE)/%.chibicc.o: %.c o/$(MODE)/third_party/chibicc/chibicc.com.dbg
|
||||
@$(COMPILE) -ACHIBICC -T$@ $(CHIBICC) $(CHIBICC_FLAGS) -c -o $@ $<
|
||||
o/$(MODE)/%.chibicc2.o: %.c o/$(MODE)/third_party/chibicc/chibicc2.com.dbg
|
||||
|
|
4
third_party/chibicc/codegen.c
vendored
4
third_party/chibicc/codegen.c
vendored
|
@ -192,9 +192,9 @@ void print_loc(int64_t file, int64_t line) {
|
|||
if (file != lastfile || line != lastline) {
|
||||
locbuf = malloc(2 + 4 + 1 + 20 + 1 + 20 + 1);
|
||||
p = stpcpy(locbuf, "\t.loc\t");
|
||||
p += int64toarray_radix10(file, p);
|
||||
p = FormatInt64(p, file);
|
||||
*p++ = ' ';
|
||||
int64toarray_radix10(line, p);
|
||||
FormatInt64(p, line);
|
||||
emitlin(locbuf);
|
||||
free(locbuf);
|
||||
lastfile = file;
|
||||
|
|
35
third_party/chibicc/parse.c
vendored
35
third_party/chibicc/parse.c
vendored
|
@ -19,6 +19,7 @@
|
|||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nexgen32e/ffs.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
@ -352,7 +353,10 @@ static Obj *new_string_literal(char *p, Type *ty) {
|
|||
}
|
||||
|
||||
static char *get_ident(Token *tok) {
|
||||
if (tok->kind != TK_IDENT) error_tok(tok, "expected an identifier");
|
||||
if (tok->kind != TK_IDENT) {
|
||||
__die();
|
||||
error_tok(tok, "expected an identifier");
|
||||
}
|
||||
return strndup(tok->loc, tok->len);
|
||||
}
|
||||
|
||||
|
@ -1088,6 +1092,10 @@ static Type *enum_specifier(Token **rest, Token *tok) {
|
|||
int val = 0;
|
||||
while (!consume_end(rest, tok)) {
|
||||
if (i++ > 0) tok = skip(tok, ',');
|
||||
if (tok->kind == TK_JAVADOWN) {
|
||||
current_javadown = tok;
|
||||
tok = tok->next;
|
||||
}
|
||||
char *name = get_ident(tok);
|
||||
tok = tok->next;
|
||||
if (EQUAL(tok, "=")) val = const_expr(&tok, tok->next);
|
||||
|
@ -1282,6 +1290,10 @@ static void array_designator(Token **rest, Token *tok, Type *ty, int *begin,
|
|||
static Member *struct_designator(Token **rest, Token *tok, Type *ty) {
|
||||
Token *start = tok;
|
||||
tok = skip(tok, '.');
|
||||
if (tok->kind == TK_JAVADOWN) {
|
||||
current_javadown = tok;
|
||||
tok = tok->next;
|
||||
}
|
||||
if (tok->kind != TK_IDENT) error_tok(tok, "expected a field designator");
|
||||
for (Member *mem = ty->members; mem; mem = mem->next) {
|
||||
// Anonymous struct member
|
||||
|
@ -2775,6 +2787,10 @@ static void struct_members(Token **rest, Token *tok, Type *ty) {
|
|||
// Regular struct members
|
||||
while (!CONSUME(&tok, tok, ";")) {
|
||||
if (!first) tok = skip(tok, ',');
|
||||
if (tok->kind == TK_JAVADOWN) {
|
||||
current_javadown = tok;
|
||||
tok = tok->next;
|
||||
}
|
||||
first = false;
|
||||
Member *mem = calloc(1, sizeof(Member));
|
||||
mem->ty = declarator(&tok, tok, basety);
|
||||
|
@ -2833,6 +2849,10 @@ static Type *struct_union_decl(Token **rest, Token *tok) {
|
|||
ty->name = tag;
|
||||
tok = skip(tok, '{');
|
||||
// Construct a struct object.
|
||||
if (tok->kind == TK_JAVADOWN) {
|
||||
current_javadown = tok;
|
||||
tok = tok->next;
|
||||
}
|
||||
struct_members(&tok, tok, ty);
|
||||
*rest = attribute_list(tok, ty, type_attributes);
|
||||
if (tag) {
|
||||
|
@ -3510,7 +3530,9 @@ static Node *primary(Token **rest, Token *tok) {
|
|||
static Token *parse_typedef(Token *tok, Type *basety) {
|
||||
bool first = true;
|
||||
while (!CONSUME(&tok, tok, ";")) {
|
||||
if (!first) tok = skip(tok, ',');
|
||||
if (!first) {
|
||||
tok = skip(tok, ',');
|
||||
}
|
||||
first = false;
|
||||
Type *ty = declarator(&tok, tok, basety);
|
||||
if (!ty->name) error_tok(ty->name_pos, "typedef name omitted");
|
||||
|
@ -3648,11 +3670,18 @@ static Token *function(Token *tok, Type *basety, VarAttr *attr) {
|
|||
|
||||
static Token *global_variable(Token *tok, Type *basety, VarAttr *attr) {
|
||||
bool first = true;
|
||||
bool isjavadown = tok->kind == TK_JAVADOWN;
|
||||
while (!CONSUME(&tok, tok, ";")) {
|
||||
if (!first) tok = skip(tok, ',');
|
||||
first = false;
|
||||
Type *ty = declarator(&tok, tok, basety);
|
||||
if (!ty->name) error_tok(ty->name_pos, "variable name omitted");
|
||||
if (!ty->name) {
|
||||
if (isjavadown) {
|
||||
return tok;
|
||||
} else {
|
||||
error_tok(ty->name_pos, "variable name omitted");
|
||||
}
|
||||
}
|
||||
Obj *var = new_gvar(get_ident(ty->name), ty);
|
||||
if (!var->tok) var->tok = ty->name;
|
||||
var->javadown = current_javadown;
|
||||
|
|
11
third_party/chibicc/preprocess.c
vendored
11
third_party/chibicc/preprocess.c
vendored
|
@ -284,7 +284,9 @@ static long eval_const_expr(Token **rest, Token *tok) {
|
|||
convert_pp_tokens(expr);
|
||||
Token *rest2;
|
||||
long val = const_expr(&rest2, expr);
|
||||
if (rest2->kind != TK_EOF) error_tok(rest2, "extra token");
|
||||
if (rest2->kind != TK_EOF && rest2->kind != TK_JAVADOWN) {
|
||||
error_tok(rest2, "extra token");
|
||||
}
|
||||
__arena_pop();
|
||||
return val;
|
||||
}
|
||||
|
@ -324,7 +326,12 @@ static MacroParam *read_macro_params(Token **rest, Token *tok,
|
|||
*rest = skip(tok->next, ')');
|
||||
return head.next;
|
||||
}
|
||||
if (tok->kind != TK_IDENT) error_tok(tok, "expected an identifier");
|
||||
if (tok->kind == TK_JAVADOWN) {
|
||||
tok = tok->next;
|
||||
}
|
||||
if (tok->kind != TK_IDENT) {
|
||||
error_tok(tok, "expected an identifier");
|
||||
}
|
||||
if (EQUAL(tok->next, "...")) {
|
||||
*va_args_name = strndup(tok->loc, tok->len);
|
||||
*rest = skip(tok->next->next, ')');
|
||||
|
|
4
third_party/chibicc/tokenize.c
vendored
4
third_party/chibicc/tokenize.c
vendored
|
@ -97,10 +97,12 @@ bool consume(Token **rest, Token *tok, char *str, size_t n) {
|
|||
|
||||
// Ensure that the current token is `op`.
|
||||
Token *skip(Token *tok, char op) {
|
||||
while (tok->kind == TK_JAVADOWN) {
|
||||
tok = tok->next;
|
||||
}
|
||||
if (tok->len == 1 && *tok->loc == op) {
|
||||
return tok->next;
|
||||
} else {
|
||||
// __die();
|
||||
error_tok(tok, "expected '%c'", op);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue