diff options
Diffstat (limited to 'src/prc1/cgen/qbe/print.c')
| -rw-r--r-- | src/prc1/cgen/qbe/print.c | 95 |
1 files changed, 95 insertions, 0 deletions
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 <stdio.h> + +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; +} |
