diff options
| author | Xavier Del Campo Romero <xavi92@disroot.org> | 2026-10-01 01:04:30 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi92@disroot.org> | 2026-10-11 00:14:35 +0200 |
| commit | 4ce39e4fc1de9536de7dedfe91b6dee38dec76ae (patch) | |
| tree | f9820f96b8eab624430c3700f32a2878a7036ee2 /src/prc1/cgen/qbe/call.c | |
| parent | 9140988be4e5bb028b7140aca1a67af1370c72a7 (diff) | |
| download | prc-4ce39e4fc1de9536de7dedfe91b6dee38dec76ae.tar.gz | |
WIP sym + cgen
Diffstat (limited to 'src/prc1/cgen/qbe/call.c')
| -rw-r--r-- | src/prc1/cgen/qbe/call.c | 163 |
1 files changed, 163 insertions, 0 deletions
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 <stdio.h> + +#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; +} |
