aboutsummaryrefslogtreecommitdiff
path: root/src/prc1/cgen/qbe/call.c
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi92@disroot.org>2026-10-01 01:04:30 +0200
committerXavier Del Campo Romero <xavi92@disroot.org>2026-10-11 00:14:35 +0200
commit4ce39e4fc1de9536de7dedfe91b6dee38dec76ae (patch)
treef9820f96b8eab624430c3700f32a2878a7036ee2 /src/prc1/cgen/qbe/call.c
parent9140988be4e5bb028b7140aca1a67af1370c72a7 (diff)
downloadprc-4ce39e4fc1de9536de7dedfe91b6dee38dec76ae.tar.gz
WIP sym + cgen
Diffstat (limited to 'src/prc1/cgen/qbe/call.c')
-rw-r--r--src/prc1/cgen/qbe/call.c163
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;
+}