#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; }