aboutsummaryrefslogtreecommitdiff
path: root/src/prc1/from.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/prc1/from.c')
-rw-r--r--src/prc1/from.c150
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;