diff options
Diffstat (limited to 'src/prc1/from.c')
| -rw-r--r-- | src/prc1/from.c | 150 |
1 files changed, 13 insertions, 137 deletions
diff --git a/src/prc1/from.c b/src/prc1/from.c index 83f9b71..8561b8f 100644 --- a/src/prc1/from.c +++ b/src/prc1/from.c @@ -1,11 +1,11 @@ #include "from.h" -#include "cgen.h" #include "dbg.h" #include "fn.h" #include "errloc.h" #include "stmt.h" #include "storage.h" #include "tmp.h" +#include "triplet.h" #include "type.h" #include <errno.h> #include <stddef.h> @@ -17,133 +17,6 @@ void from_free(struct from *fr) { } -static int loadvar(const struct from_it *st, struct cgen *c) -{ - const struct stentry *e = st->u.e; - size_t sz = e->t->sz; - const char *tmp = cgen_tmp(sz); - - printf("%%%s =%s load%s ", tmp, cgen_sz(sz), cgen_load(e->t)); - cgen_printvar(c->fn, e); - putchar('\n'); - return 0; -} - -/* TODO: de-duplicate function */ -static unsigned long long tonum(const char *s) -{ - unsigned long long v; - char *end; - - errno = 0; - v = strtoull(s, &end, 0); - - if (*s == '-' || errno || *end) - return strtoll(s, NULL, 0); - - return v; -} - -static int loadval(const struct from *fr, struct cgen *c) -{ - const struct stentry *dst = fr->var; - const struct from_it *st = &fr->start; - unsigned long long v = tonum(st->u.tk->s); - - printf("store%s %llu, ", cgen_sz(dst->t->sz), v); - cgen_printvar(c->fn, dst); - putchar('\n'); - return 0; -} - -static int endvar(const struct from *fr, struct cgen *c) -{ - fprintf(stderr, "%s: TODO\n", __func__); - return -1; -} - -static int endval(const struct from *fr, struct cgen *c) -{ - const struct stentry *src = fr->var; - size_t sz = src->t->sz; - const char *tmp = cgen_tmp(sz); - const struct from_it *end = &fr->end; - const struct tk *tk = end->u.tk; - int neg = *tk->s == '-'; - size_t bl = fr->block_i; - - printf("%%%s =%s load%s ", tmp, cgen_sz(sz), cgen_load(src->t)); - cgen_printvar(c->fn, src); - putchar('\n'); - printf("%%%s =%s c", tmp, cgen_sz(sz)); - fputs(neg ? "sge" : "uge", stdout); - printf("%s ", cgen_sz(sz)); - printf("%%%s, %s\n", tmp, tk->s); - printf("jnz %%%s, @__end%zu, @__blockbody%zu\n", tmp, bl, bl); - printf("@__blockbody%zu\n", bl); - return 0; -} - -static int from_var(const struct from *fr, struct cgen *c) -{ - const struct from_it *st = &fr->start; - - switch (st->type) - { - case FR_VAR: - if (loadvar(st, c)) - return -1; - break; - - case FR_VAL: - if (loadval(fr, c)) - return -1; - break; - } - - printf("@__block%zu\n", fr->block_i); - - switch (fr->end.type) - { - case FR_VAR: - if (endvar(fr, c)) - return -1; - break; - - case FR_VAL: - if (endval(fr, c)) - return -1; - break; - } - - return 0; -} - -int from_cgen(const struct from *fr, struct cgen *c) -{ - return from_var(fr, c); -} - -static int from_end(const struct stmt *s, struct cgen *c) -{ - const struct from *fr = &s->u.from; - const struct stentry *src = fr->var; - const struct type *t = src->t; - size_t sz = t->sz; - const char *tmp = cgen_tmp(sz); - const struct fn *fn = c->fn; - - printf("%%%s =%s load%s ", tmp, cgen_sz(sz), cgen_load(t)); - cgen_printvar(fn, src); - putchar('\n'); - printf("%%%s =%s add %%%s, 1\n", tmp, cgen_sz(sz), tmp); - printf("store%s %%%s, ", cgen_sz(sz), tmp); - cgen_printvar(fn, src); - putchar('\n'); - printf("jmp @__block%zu\n", fr->block_i); - return 0; -} - static int checksym(const struct fn *fn, const struct tk *tk, struct from_it *fr) { @@ -241,7 +114,8 @@ static int finalize(struct prv *p, struct fn *fn, struct from *fr) return 0; } -static const struct type *valtype(const struct fn *fn, const struct tk *tk) +static const struct type *valtype(const struct fn *fn, const char *tr, + const struct tk *tk) { char *end; @@ -254,20 +128,21 @@ static const struct type *valtype(const struct fn *fn, const struct tk *tk) strtoll(tk->s, &end, 0); if (errno || *end) - return type_find(fn, "ulong"); + return type_find(fn, tr, "ulong"); - return type_find(fn, "long"); + return type_find(fn, tr, "long"); } - return type_find(fn, "word"); + return type_find(fn, tr, "word"); } -static const struct type *ittype(const struct fn *fn, const struct from_it *it) +static const struct type *ittype(const struct fn *fn, const char *tr, + const struct from_it *it) { switch (it->type) { case FR_VAL: - return valtype(fn, it->u.tk); + return valtype(fn, tr, it->u.tk); case FR_VAR: return it->u.e->t; } @@ -277,9 +152,9 @@ static const struct type *ittype(const struct fn *fn, const struct from_it *it) } static const struct type *gettype(const struct fn *fn, - const struct from_it *a, const struct from_it *b) + const char *tr, const struct from_it *a, const struct from_it *b) { - const struct type *ta = ittype(fn, a), *tb = ittype(fn, b); + const struct type *ta = ittype(fn, tr, a), *tb = ittype(fn, tr, b); return ta->sz > tb->sz ? ta : tb; } @@ -287,13 +162,14 @@ static const struct type *gettype(const struct fn *fn, int from(const struct lex *l, struct prv *p) { const struct tk *start = p->stk + 1, *end = p->stk + 3; + const char *tr = triplet(p); struct fn *fn = fn_cur(p); struct from fr = {0}; const struct type *t; if (check(fn, start, &fr.start) || check(fn, end, &fr.end) - || !(t = gettype(fn, &fr.start, &fr.end)) + || !(t = gettype(fn, tr, &fr.start, &fr.end)) || !(fr.var = tmp_create(fn, t))) return -1; |
