Skip to content

Commit

Permalink
self hosting
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewchambers committed Dec 1, 2015
1 parent 22f13ba commit a5b7b4a
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 9 deletions.
21 changes: 19 additions & 2 deletions src/cc/cc.h
Expand Up @@ -232,14 +232,19 @@ typedef enum {
NSIZEOF,
NIF,
NDECL,
NEXPRSTMT
NEXPRSTMT,
NBUILTIN
} Nodekind;

typedef struct {
int offset;
Node *n;
} InitMember;

typedef enum {
BUILTIN_VASTART
} Builtinkind;

struct Node {
/* type tag, one of the N* types */
Nodekind t;
Expand Down Expand Up @@ -371,6 +376,15 @@ struct Node {
struct {
CTy *type;
} Sizeof;
struct {
Builtinkind t;
union {
struct {
Node *valist;
Node *param;
} Vastart;
};
} Builtin;
};
};

Expand All @@ -393,8 +407,11 @@ struct Sym {
char *label;
} Global;
struct {
int isparam;
StkSlot *slot;
/* XXX make a Param sym type */
CTy *functy;
int paramidx;
int isparam;
} Local;
struct {
int64 v;
Expand Down
29 changes: 29 additions & 0 deletions src/cc/parse.c
Expand Up @@ -38,6 +38,7 @@ static Node *primaryexpr(void);
static Node *declorstmt(void);
static Node *decl(void);
static Node *declinit(CTy *);
static Node *vastart();
static void fbody(void);
static CTy *declspecs(int *);

Expand Down Expand Up @@ -729,6 +730,8 @@ fbody(void)
if(nt->name) {
sym = definesym(&curfunc->pos, SCAUTO, nt->name, nt->type, 0);
sym->Local.isparam = 1;
sym->Local.paramidx = i;
sym->Local.functy = curfunc->type;
vecappend(curfunc->Func.params, sym);
}
}
Expand Down Expand Up @@ -2274,6 +2277,8 @@ primaryexpr(void)

switch (tok->k) {
case TOKIDENT:
if(strcmp(tok->v, "__builtin_va_start") == 0)
return vastart();
sym = lookup(syms, tok->v);
if(!sym)
errorposf(&tok->pos, "undefined symbol %s", tok->v);
Expand Down Expand Up @@ -2327,3 +2332,27 @@ primaryexpr(void)
return 0;
}

static Node *
vastart()
{
Node *n, *valist, *param;

n = mknode(NBUILTIN, &tok->pos);
expect(TOKIDENT);
expect('(');
valist = assignexpr();
expect(',');
param = assignexpr();
expect(')');
n->type = cvoid;
n->Builtin.t = BUILTIN_VASTART;
n->Builtin.Vastart.param = param;
n->Builtin.Vastart.valist = valist;
if(param->t != NIDENT)
errorposf(&n->pos, "expected an identifer in va_start");
if(param->Ident.sym->k != SYMLOCAL
|| !param->Ident.sym->Local.isparam)
errorposf(&n->pos, "expected a parameter symbol in va_start");
return n;
}

39 changes: 38 additions & 1 deletion src/cmd/6c/emit.c
Expand Up @@ -74,7 +74,7 @@ calcslotoffsets(Node *f)
{
int i, tsz, curoffset;
StkSlot *s;

curoffset = 0;
for(i = 0; i < f->Func.stkslots->len; i++) {
s = vecget(f->Func.stkslots, i);
Expand All @@ -85,6 +85,8 @@ calcslotoffsets(Node *f)
if(curoffset % s->align)
curoffset = (curoffset - (curoffset % s->align) + s->align);
s->offset = -curoffset;
if(f->type->Func.isvararg)
s->offset -= 176;
}
if(curoffset % 16)
curoffset = (curoffset - (curoffset % 16) + 16);
Expand Down Expand Up @@ -121,6 +123,16 @@ func(Node *f, char *label, int isglobal)
out("%s:\n", label);
pushq("rbp");
outi("movq %%rsp, %%rbp\n");
if (f->type->Func.isvararg) {
stackoffset += 176;
outi("sub $176, %%rsp\n");
outi("movq %%rdi, (%%rsp)\n");
outi("movq %%rsi, 8(%%rsp)\n");
outi("movq %%rdx, 16(%%rsp)\n");
outi("movq %%rcx, 24(%%rsp)\n");
outi("movq %%r8, 32(%%rsp)\n");
outi("movq %%r9, 40(%%rsp)\n");
}
if (f->Func.localsz) {
outi("sub $%d, %%rsp\n", f->Func.localsz);
stackoffset += f->Func.localsz;
Expand Down Expand Up @@ -768,6 +780,22 @@ str(Node *n)
outi("movq (%%rax), %%rax\n", l);
}

static void
vastart(Node *n)
{
int argend;

expr(n->Builtin.Vastart.valist);
/* XXX currently only support int args */
argend = (n->Builtin.Vastart.param->Ident.sym->Local.paramidx + 1) * 8;
pushq("rcx");
outi("movl $%d, (%%rax)\n", argend);
outi("movl $%d, 4(%%rax)\n", 48 + 0 * 16);
outi("leaq %d(%%rbp), %%rcx\n", -176);
outi("movq %%rcx, 16(%%rax)\n");
popq("rcx");
}

static void
expr(Node *n)
{
Expand Down Expand Up @@ -814,6 +842,15 @@ expr(Node *n)
case NINCDEC:
incdec(n);
break;
case NBUILTIN:
switch(n->Builtin.t) {
case BUILTIN_VASTART:
vastart(n);
break;
default:
errorposf(&n->pos, "unimplemented builtin");
}
break;
default:
errorf("unimplemented emit expr %d\n", n->t);
}
Expand Down
7 changes: 1 addition & 6 deletions src/selfhost/stdarg.h
Expand Up @@ -8,12 +8,7 @@ typedef struct {

typedef __va_elem va_list[1];

#define va_start(X, Y) do { \
(X)[0].gp_offset = 0; \
(X)[0].fp_offset = 0; \
(X)[0].overflow_arg_area = 0; \
(X)[0].reg_save_area = 0;\
} while(0);
#define va_start(X, Y) __builtin_va_start((X), (Y))
#define va_end(X) (X)

int vfprintf(FILE *stream, const char *format, va_list ap);
Expand Down

0 comments on commit a5b7b4a

Please sign in to comment.