From 4ce39e4fc1de9536de7dedfe91b6dee38dec76ae Mon Sep 17 00:00:00 2001 From: Xavier Del Campo Romero Date: Thu, 1 Oct 2026 01:04:30 +0200 Subject: WIP sym + cgen --- src/prc1/cgen/CMakeLists.txt | 12 +++ src/prc1/cgen/call.c | 8 ++ src/prc1/cgen/fn.c | 8 ++ src/prc1/cgen/free.c | 8 ++ src/prc1/cgen/gl.c | 8 ++ src/prc1/cgen/global.c | 32 +++++++ src/prc1/cgen/param.c | 15 ++++ src/prc1/cgen/print.c | 8 ++ src/prc1/cgen/prv.h | 23 +++++ src/prc1/cgen/qbe/CMakeLists.txt | 10 +++ src/prc1/cgen/qbe/call.c | 163 ++++++++++++++++++++++++++++++++++ src/prc1/cgen/qbe/fn.c | 94 ++++++++++++++++++++ src/prc1/cgen/qbe/free.c | 7 ++ src/prc1/cgen/qbe/gl.c | 16 ++++ src/prc1/cgen/qbe/print.c | 95 ++++++++++++++++++++ src/prc1/cgen/qbe/qbe.c | 187 +++++++++++++++++++++++++++++++++++++++ src/prc1/cgen/qbe/qbe.h | 26 ++++++ src/prc1/cgen/qbe/set.c | 11 +++ src/prc1/cgen/qbe/ws.c | 23 +++++ src/prc1/cgen/set.c | 8 ++ src/prc1/cgen/ws.c | 8 ++ 21 files changed, 770 insertions(+) create mode 100644 src/prc1/cgen/CMakeLists.txt create mode 100644 src/prc1/cgen/call.c create mode 100644 src/prc1/cgen/fn.c create mode 100644 src/prc1/cgen/free.c create mode 100644 src/prc1/cgen/gl.c create mode 100644 src/prc1/cgen/global.c create mode 100644 src/prc1/cgen/param.c create mode 100644 src/prc1/cgen/print.c create mode 100644 src/prc1/cgen/prv.h create mode 100644 src/prc1/cgen/qbe/CMakeLists.txt create mode 100644 src/prc1/cgen/qbe/call.c create mode 100644 src/prc1/cgen/qbe/fn.c create mode 100644 src/prc1/cgen/qbe/free.c create mode 100644 src/prc1/cgen/qbe/gl.c create mode 100644 src/prc1/cgen/qbe/print.c create mode 100644 src/prc1/cgen/qbe/qbe.c create mode 100644 src/prc1/cgen/qbe/qbe.h create mode 100644 src/prc1/cgen/qbe/set.c create mode 100644 src/prc1/cgen/qbe/ws.c create mode 100644 src/prc1/cgen/set.c create mode 100644 src/prc1/cgen/ws.c (limited to 'src/prc1/cgen') diff --git a/src/prc1/cgen/CMakeLists.txt b/src/prc1/cgen/CMakeLists.txt new file mode 100644 index 0000000..77aa786 --- /dev/null +++ b/src/prc1/cgen/CMakeLists.txt @@ -0,0 +1,12 @@ +add_subdirectory(qbe) +target_sources(prc1 PRIVATE + call.c + fn.c + free.c + gl.c + global.c + param.c + print.c + set.c + ws.c +) diff --git a/src/prc1/cgen/call.c b/src/prc1/cgen/call.c new file mode 100644 index 0000000..dc3545b --- /dev/null +++ b/src/prc1/cgen/call.c @@ -0,0 +1,8 @@ +#include "call.h" +#include "cgen.h" +#include "cgen/prv.h" + +int call_cgen(const struct call *m, struct cgen *c) +{ + return c->drv->call(m, c); +} diff --git a/src/prc1/cgen/fn.c b/src/prc1/cgen/fn.c new file mode 100644 index 0000000..0a79a1d --- /dev/null +++ b/src/prc1/cgen/fn.c @@ -0,0 +1,8 @@ +#include "cgen.h" +#include "cgen/prv.h" +#include "fn.h" + +int fn_cgen(const struct fn *fn, struct cgen *c) +{ + return c->drv->fn(fn, c); +} diff --git a/src/prc1/cgen/free.c b/src/prc1/cgen/free.c new file mode 100644 index 0000000..a7b88bb --- /dev/null +++ b/src/prc1/cgen/free.c @@ -0,0 +1,8 @@ +#include "cgen.h" +#include "cgen/prv.h" + +void cgen_free(struct cgen *c) +{ + if (c->drv) + c->drv->free(c->p); +} diff --git a/src/prc1/cgen/gl.c b/src/prc1/cgen/gl.c new file mode 100644 index 0000000..8b436b8 --- /dev/null +++ b/src/prc1/cgen/gl.c @@ -0,0 +1,8 @@ +#include "cgen.h" +#include "cgen/prv.h" +#include "gl.h" + +int gl_cgen(const struct storage *gl, struct cgen *c) +{ + return c->drv->gl(gl, c); +} diff --git a/src/prc1/cgen/global.c b/src/prc1/cgen/global.c new file mode 100644 index 0000000..6371b96 --- /dev/null +++ b/src/prc1/cgen/global.c @@ -0,0 +1,32 @@ +#include "cgen.h" +#include + +int cgen_global(const struct fn *fn, const struct stentry *e) +{ + const struct storage *ws = fn->ws, *gl = fn->gl; + const struct pr *pr = fn->pr; + const struct param *ret = pr->ret; + const char *name = e->tk->s; + + /* A variable is only global if it is defined inside the global + * variables section ("gl"), or if it is not listed on the working + * storage section ("ws"), as a function parameter or a return value. */ + + if (gl) + for (size_t i = 0; i < gl->nentries; i++) + if (!strcmp(gl->entries[i].tk->s, name)) + return 1; + + if (cgen_param(fn, e) || (ret && !strcmp(ret->tk->s, name))) + return 0; + else if (ws) + for (size_t i = 0; i < ws->nentries; i++) + if (!strcmp(ws->entries[i].tk->s, name)) + return 0; + + for (const struct tmp *t = fn->tmps; t; t = t->next) + if (!strcmp(t->tk.s, name)) + return 0; + + return 1; +} diff --git a/src/prc1/cgen/param.c b/src/prc1/cgen/param.c new file mode 100644 index 0000000..e31f1f1 --- /dev/null +++ b/src/prc1/cgen/param.c @@ -0,0 +1,15 @@ +#include "cgen.h" +#include +#include + +int cgen_param(const struct fn *fn, const struct stentry *e) +{ + const struct pr *pr = fn->pr; + const char *name = e->tk->s; + + for (size_t i = 0; i < pr->nparams; i++) + if (!strcmp(pr->params[i].tk->s, name)) + return 1; + + return 0; +} diff --git a/src/prc1/cgen/print.c b/src/prc1/cgen/print.c new file mode 100644 index 0000000..32c01f3 --- /dev/null +++ b/src/prc1/cgen/print.c @@ -0,0 +1,8 @@ +#include "cgen.h" +#include "cgen/prv.h" +#include "print.h" + +int print_cgen(const struct print *p, struct cgen *c, const char *f) +{ + return c->drv->print(p, c, f); +} diff --git a/src/prc1/cgen/prv.h b/src/prc1/cgen/prv.h new file mode 100644 index 0000000..dc99404 --- /dev/null +++ b/src/prc1/cgen/prv.h @@ -0,0 +1,23 @@ +#ifndef CGEN_PRV_H +#define CGEN_PRV_H + +#include "cgen.h" +#include "call.h" +#include "print.h" +#include "set.h" +#include "storage.h" + +struct cgen_drv +{ + int (*print)(const struct print *, struct cgen *, const char *); + int (*gl)(const struct storage *, struct cgen *); + int (*ws)(const struct storage *, struct cgen *); + int (*call)(const struct call *, struct cgen *); + int (*set)(const struct set *, struct cgen *); + int (*fn)(const struct fn *, struct cgen *); + void (*free)(struct cgen_prv *); +}; + +int cgen_qbe(const struct ast *ast, struct cgen *c); + +#endif diff --git a/src/prc1/cgen/qbe/CMakeLists.txt b/src/prc1/cgen/qbe/CMakeLists.txt new file mode 100644 index 0000000..5d0bd63 --- /dev/null +++ b/src/prc1/cgen/qbe/CMakeLists.txt @@ -0,0 +1,10 @@ +target_sources(prc1 PRIVATE + call.c + free.c + fn.c + gl.c + print.c + set.c + qbe.c + ws.c +) diff --git a/src/prc1/cgen/qbe/call.c b/src/prc1/cgen/qbe/call.c new file mode 100644 index 0000000..0f49d76 --- /dev/null +++ b/src/prc1/cgen/qbe/call.c @@ -0,0 +1,163 @@ +#include "call.h" +#include "cgen.h" +#include "cgen/prv.h" +#include "qbe.h" +#include + +#if 0 +static int gettmp(char *tmp, size_t n) +{ + size_t j; + + for (j = 0; j < n; j++) + { + char c = tmp[j]; + + if (!c) + return tmp[j] = 'a'; + else if (c != 'z') + return ++(tmp[j]); + } + + return EOF; +} + +static int param_lit(const struct lit *lit, struct cgen *c) +{ + printf("l $%s", lit->name); + return 0; +} + +static int param_id(const struct stentry *e, struct cgen *c, char *tmp, + size_t n) +{ + const char *name = e->tk->s; + const struct type *t = e->t; + + printf("%s ", cgen_sz(t->sz)); + + if (cgen_global(c->fn, e)) + printf("$%s", name); + else if (cgen_abity(t)) + { + if (gettmp(tmp, n) == EOF) + return -1; + + printf("%%%s", tmp); + } + else + printf("%%%s_", name); + + return 0; +} + +static int param_c(const struct type *t, struct cgen *cg) +{ + const union c *c = &t->u.c; + + /* TODO: adapt type to expected param size */ + fputs("l ", stdout); + + if (t->sign) + printf("%lld", c->v); + else + printf("%llu", c->uv); + + return 0; +} + +static int param_num(const struct callparam *cp, struct cgen *c) +{ + const union callv *u = &cp->u; + + /* TODO: adapt type to expected param size */ + fputs("w ", stdout); + + if (cp->sign) + printf("%lld", u->v); + else + printf("%llu", u->uv); + + return 0; +} + +static int param_load(const struct call *m, struct cgen *c) +{ + char tmp[sizeof "abcdefghijklmnopqrstuvwxyz"] = {0}; + + for (size_t i = 0; i < m->nparams; i++) + { + const struct callparam *cp = &m->params[i]; + const struct stentry *e = cp->entry; + + if (!e || cgen_global(c->fn, e) || !cgen_abity(e->t)) + continue; + else if (gettmp(tmp, sizeof tmp - 1) == EOF) + { + fprintf(stderr, "%s: exhausted temporaries\n", __func__); + return -1; + } + + printf("%%%s =%s load%s %%%s_\n", tmp, cgen_sz(e->t->sz), + cgen_load(e->t), e->tk->s); + } + + return 0; +} + +int call_cgen(const struct call *m, struct cgen *c) +{ + char tmps[sizeof "abcdefghijklmnopqrstuvwxyz"] = {0}; + const struct stentry *ret = m->ret; + const char *tmp; + size_t sz; + + if (param_load(m, c)) + return -1; + else if (ret) + { + tmp = cgen_tmp((sz = ret->t->sz)); + printf("%%%s =%s ", tmp, cgen_sz(sz)); + } + + printf("call $%s(", m->tk->s); + + for (size_t i = 0; i < m->nparams; i++) + { + const struct callparam *cp = &m->params[i]; + int var = m->pr->variadic; + + if (cp->lit) + param_lit(cp->lit, c); + else if (cp->entry) + param_id(cp->entry, c, tmps, sizeof tmps - 1); + else if (cp->t) + param_c(cp->t, c); + else + param_num(cp, c); + + if (var && i + 1 == var - 1) + fputs(", ...", stdout); + + if (i + 1 < m->nparams) + fputs(", ", stdout); + } + + puts(")"); + + if (ret) + { + printf("store%s %%%s, ", cgen_sz(sz), tmp); + cgen_printvar(c->fn, ret); + putchar('\n'); + } + + return 0; +} +#endif + +int qbe_call(const struct call *m, struct cgen *c) +{ + fprintf(stderr, "%s: TODO\n", __func__); + return -1; +} diff --git a/src/prc1/cgen/qbe/fn.c b/src/prc1/cgen/qbe/fn.c new file mode 100644 index 0000000..61b0bf0 --- /dev/null +++ b/src/prc1/cgen/qbe/fn.c @@ -0,0 +1,94 @@ +#include "cgen.h" +#include "fn.h" +#include "gl.h" +#include "stmt.h" +#include "qbe.h" +#include "ws.h" +#include + +int qbe_fn(const struct fn *fn, struct cgen *c) +{ + const struct pr *pr = fn->pr; + const struct param *ret = pr->ret; + const struct type *rt = NULL; + const char *s = NULL; + struct fn_cgen fnc = {0}; + + c->fnc = &fnc; + + if (fn->gl && gl_cgen(fn->gl, c)) + return -1; + + switch (fn->linkage) + { + case STATIC: + printf("function "); + break; + case EXTERNAL: + printf("export function "); + break; + } + + if (ret) + { + rt = ret->entry->t; + s = ret->entry->tk->s; + printf("%s ", cgen_abity(ret->entry->t)); + } + + printf("$%s(", fn->tk->s); + + for (size_t i = 0; i < pr->nparams; i++) + { + const struct param *p = &pr->params[i]; + + printf(" %s", cgen_abity(p->entry->t)); + printf(" %%__param_%s ", p->tk->s); + + if (i + 1 < pr->nparams) + fputs(", ", stdout); + } + + puts(") {\n@start"); + + for (size_t i = 0; i < pr->nparams; i++) + { + const struct param *p = &pr->params[i]; + const struct type *t = p->entry->t; + const char *s = p->tk->s; + + printf("%%%s_ =l alloc%zu %zu\n", s, t->align, t->sz); + printf("store%s %%__param_%s, %%%s_\n", cgen_sz(t->sz), s, s); + } + + if (ret) + printf("%%%s_ =l alloc%zu %zu\n", s, rt->align, rt->sz); + + if (fn->ws && ws_cgen(fn->ws, c)) + return -1; + + for (const struct tmp *tmp = fn->tmps; tmp; tmp = tmp->next) + { + const struct stentry *e = &tmp->e; + const struct type *t = tmp->e.t; + + printf("%%%s_ =l alloc%zu %zu\n", e->tk->s, t->align, t->sz); + } + + for (size_t i = 0; i < fn->nstmts; i++) + if (stmt_cgen(&fn->stmts[i], c)) + return -1; + + if (ret) + { + const char *t = cgen_tmp(rt->sz); + + printf("%%%s =%s load%s %%%s_\n", t, cgen_sz(rt->sz), cgen_load(rt), s); + printf("ret %%%s", t); + } + else + fputs("ret", stdout); + + puts("\n}"); + return 0; +} diff --git a/src/prc1/cgen/qbe/free.c b/src/prc1/cgen/qbe/free.c new file mode 100644 index 0000000..c05e72d --- /dev/null +++ b/src/prc1/cgen/qbe/free.c @@ -0,0 +1,7 @@ +#include "cgen.h" +#include "cgen/prv.h" +#include "qbe.h" + +void qbe_free(struct cgen_prv *p) +{ +} diff --git a/src/prc1/cgen/qbe/gl.c b/src/prc1/cgen/qbe/gl.c new file mode 100644 index 0000000..61e9d7a --- /dev/null +++ b/src/prc1/cgen/qbe/gl.c @@ -0,0 +1,16 @@ +#include "cgen.h" +#include "qbe.h" +#include +#include + +int qbe_gl(const struct storage *gl, struct cgen *c) +{ + for (size_t i = 0; i < gl->nentries; i++) + { + const struct stentry *e = &gl->entries[i]; + + printf("export data $%s = { z %zu }\n", e->tk->s, e->t->sz); + } + + return 0; +} diff --git a/src/prc1/cgen/qbe/print.c b/src/prc1/cgen/qbe/print.c new file mode 100644 index 0000000..2890eb8 --- /dev/null +++ b/src/prc1/cgen/qbe/print.c @@ -0,0 +1,95 @@ +#include "cgen.h" +#include "cgen/prv.h" +#include "print.h" +#include "qbe.h" +#include + +static int cg_str(const struct prisym *s, struct cgen *c, const char *f) +{ + fprintf(stderr, "%s: TODO\n", __func__); + return -1; +} + +static int cg_ptr(const struct prisym *s, struct cgen *c, const char *f) +{ + const char *tmpf = cgen_tmp2(c), *tmpv = cgen_tmp2(c), + *name = s->s->tk->s; + + if (!tmpf || !tmpv) + return -1; + + printf("%%%s =l loadl ", tmpv); + + if (cgen_global(c->fn, s->u.e)) + printf("$%s", name); + else + printf("%%%s_", name); + + fputc('\n', stdout); + printf("%%%s =l loadl $%s\n", tmpf, f); + printf("call $fprintf(w %%%s, l $____fmtlx, ..., l %%%s)\n", tmpf, tmpv); + return 0; +} + +static int cg_num(const struct prisym *s, struct cgen *c, const char *f) +{ + fprintf(stderr, "%s: TODO\n", __func__); + return -1; +} + +static int cg_nam(const struct prisym *ps, struct cgen *c, const char *f) +{ + const char *tmpf = cgen_tmp2(c), *name = ps->u.name; + + if (!tmpf) + return -1; + + printf("%%%s =l loadl $%s\n", tmpf, f); + printf("call $fprintf(w %%%s, l $____fmtlx, ..., l $%s)\n", tmpf, name); + return 0; +} + +static int cg_lit(const struct prisym *s, struct cgen *c, const char *f) +{ + const struct lit *l = s->u.lit; + const char *tmp; + + if (!l) + { + fprintf(stderr, "%s: unexpected null literal\n", __func__); + return -1; + } + + /* TODO: ask target for sizeof (void *) */ + tmp = cgen_tmp(sizeof (void *)); + printf("%%%s =l loadl $%s\n", tmp, f); + printf("call $fputs(l $%s, w %%%s)\n", l->name, tmp); + return 0; +} + +int qbe_print(const struct print *pr, struct cgen *c, const char *f) +{ + for (size_t i = 0; i < pr->nsyms; i++) + { + const struct prisym *ps = &pr->syms[i]; + static int (*fn[])(const struct prisym *, struct cgen *, const char *) = + { + [PRS_LIT] = cg_lit, + [PRS_STR] = cg_str, + [PRS_NAM] = cg_nam, + [PRS_PTR] = cg_ptr, + [PRS_NUM] = cg_num + }; + + if (fn[ps->type](ps, c, f)) + return -1; + } + + if (!pr->skipln) + { + printf("%%v =l loadl $%s\n", f); + puts("call $fputc(l 10 , w %v)"); + } + + return 0; +} diff --git a/src/prc1/cgen/qbe/qbe.c b/src/prc1/cgen/qbe/qbe.c new file mode 100644 index 0000000..c27bad6 --- /dev/null +++ b/src/prc1/cgen/qbe/qbe.c @@ -0,0 +1,187 @@ +#include "cgen.h" +#include "cgen/prv.h" +#include "fn.h" +#include "lex.h" +#include "lit.h" +#include "parse.h" +#include "qbe.h" +#include "storage.h" +#include +#include +#include + +const char *cgen_sz(const size_t sz) +{ + switch (sz) + { + case 1: + return "b"; + case 2: + return "h"; + case 4: + return "w"; + case 8: + return "l"; + default: + break; + } + + return NULL; +} + +const char *cgen_tmp2(struct cgen *c) +{ + struct fn_cgen *fnc = c->fnc; + + for (size_t i = 0; i < sizeof fnc->tmp - 1; i++) + { + char *s = &fnc->tmp[i]; + + if (!*s) + *s = 'a'; + else if (*s >= 'z') + *s = 'A'; + else if (*s >= 'Z') + continue; + else + (*s)++; + + return s; + } + + fprintf(stderr, "%s: ran out of temporaries\n", __func__); + return NULL; +} + +const char *cgen_tmp(const size_t sz) +{ + switch (sz) + { + case 1: + return "vb"; + case 2: + return "vh"; + case 4: + return "vw"; + case 8: + return "vl"; + default: + break; + } + + return "v"; +} + +const char *cgen_type(const struct type *t) +{ + switch (t->sz) + { + case 1: + return t->sign ? "b" : "ub"; + case 2: + return t->sign ? "h" : "uh"; + case 4: + return t->sign ? "w" : "uw"; + case 8: + return t->sign ? "l" : "ul"; + + default: + break; + } + + return NULL; +} + +const char *cgen_abity(const struct type *t) +{ + switch (t->sz) + { + case 1: + return t->sign ? "b" : "ub"; + case 2: + return t->sign ? "h" : "uh"; + case 4: + return "w"; + case 8: + return "l"; + + default: + break; + } + + return NULL; +} + +const char *cgen_load(const struct type *t) +{ + switch (t->sz) + { + case 1: + return t->sign ? "sb" : "ub"; + case 2: + return t->sign ? "sh" : "uh"; + case 4: + return t->sign ? "sw" : "uw"; + case 8: + return "l"; + + default: + break; + } + + return NULL; +} + +void cgen_printvar(const struct fn *fn, const struct stentry *e) +{ + const char *name = e->tk->s; + + if (cgen_global(fn, e)) + printf("$%s", name); + else + printf("%%%s_", name); +} + +static void pushfmt(const char *type, const char *fmt) +{ + printf("data $____fmt%s = { b \"%s\" , b 0 }\n", type, fmt); +} + +int cgen_qbe(const struct ast *ast, struct cgen *c) +{ + static const struct cgen_drv drv = + { + .print = qbe_print, + .call = qbe_call, + .free = qbe_free, + .set = qbe_set, + .gl = qbe_gl, + .ws = qbe_ws, + .fn = qbe_fn + }; + + c->drv = &drv; + /* generate literals to use with printf(3) */ + pushfmt("b", "%hhd"); + pushfmt("h", "%hd"); + pushfmt("w", "%d"); + pushfmt("l", "%ld"); + pushfmt("ub", "%hhu"); + pushfmt("uh", "%hu"); + pushfmt("uw", "%u"); + pushfmt("ul", "%lu"); + pushfmt("bx", "%#hhx"); + pushfmt("hx", "%#hx"); + pushfmt("wx", "%#x"); + pushfmt("lx", "%#lx"); + + for (const struct lit *l = ast->lits; l; l = l->next) + if (lit_cgen(l)) + return-1; + + for (size_t i = 0; i < ast->nfns; i++) + if (fn_cgen((c->fn = &ast->fns[i]), c)) + return -1; + + return 0; +} diff --git a/src/prc1/cgen/qbe/qbe.h b/src/prc1/cgen/qbe/qbe.h new file mode 100644 index 0000000..b0e66f1 --- /dev/null +++ b/src/prc1/cgen/qbe/qbe.h @@ -0,0 +1,26 @@ +#ifndef QBE_H +#define QBE_H + +#include "call.h" +#include "cgen.h" +#include "print.h" +#include "set.h" +#include "storage.h" +#include + +const char *cgen_sz(const size_t sz); +const char *cgen_tmp(const size_t sz); +const char *cgen_tmp2(struct cgen *c); +const char *cgen_type(const struct type *t); +const char *cgen_abity(const struct type *t); +const char *cgen_load(const struct type *t); +int qbe_print(const struct print *m, struct cgen *c, const char *f); +void cgen_printvar(const struct fn *fn, const struct stentry *e); +int qbe_call(const struct call *m, struct cgen *c); +int qbe_set(const struct set *m, struct cgen *c); +int qbe_gl(const struct storage *gl, struct cgen *c); +int qbe_ws(const struct storage *s, struct cgen *c); +int qbe_fn(const struct fn *fn, struct cgen *c); +void qbe_free(struct cgen_prv *p); + +#endif diff --git a/src/prc1/cgen/qbe/set.c b/src/prc1/cgen/qbe/set.c new file mode 100644 index 0000000..5dad08f --- /dev/null +++ b/src/prc1/cgen/qbe/set.c @@ -0,0 +1,11 @@ +#include "call.h" +#include "cgen.h" +#include "cgen/prv.h" +#include "qbe.h" +#include + +int qbe_set(const struct set *s, struct cgen *c) +{ + fprintf(stderr, "%s: TODO\n", __func__); + return -1; +} diff --git a/src/prc1/cgen/qbe/ws.c b/src/prc1/cgen/qbe/ws.c new file mode 100644 index 0000000..4f4a6df --- /dev/null +++ b/src/prc1/cgen/qbe/ws.c @@ -0,0 +1,23 @@ +#include "cgen.h" +#include "storage.h" +#include "type.h" +#include "qbe.h" +#include +#include + +static int wspush(const struct stentry *e, struct cgen *c) +{ + const struct type *t = e->t; + + printf("%%%s_ =l alloc%zu %zu\n", e->tk->s, t->align, t->sz); + return 0; +} + +int qbe_ws(const struct storage *s, struct cgen *c) +{ + for (size_t i = 0; i < s->nentries; i++) + if (wspush(&s->entries[i], c)) + return -1; + + return 0; +} diff --git a/src/prc1/cgen/set.c b/src/prc1/cgen/set.c new file mode 100644 index 0000000..07e654e --- /dev/null +++ b/src/prc1/cgen/set.c @@ -0,0 +1,8 @@ +#include "cgen.h" +#include "cgen/prv.h" +#include "set.h" + +int set_cgen(const struct set *s, struct cgen *c) +{ + return c->drv->set(s, c); +} diff --git a/src/prc1/cgen/ws.c b/src/prc1/cgen/ws.c new file mode 100644 index 0000000..a836e21 --- /dev/null +++ b/src/prc1/cgen/ws.c @@ -0,0 +1,8 @@ +#include "cgen.h" +#include "cgen/prv.h" +#include "ws.h" + +int ws_cgen(const struct storage *s, struct cgen *c) +{ + return c->drv->ws(s, c); +} -- cgit v1.2.3