commit 92be2fdd177503e315ae433b30bdc1c0c21faf38
parent 837c46ca813da15d57cf65273da03de9ccbe548c
Author: Quentin Carbonneaux <quentin.carbonneaux@yale.edu>
Date: Thu, 30 Jul 2015 21:32:43 -0400
start improving constants support
Diffstat:
3 files changed, 83 insertions(+), 9 deletions(-)
diff --git a/lisc/emit.c b/lisc/emit.c
@@ -4,6 +4,8 @@
static void
eref(Ref r, Fn *fn, FILE *f)
{
+ Const *c;
+
switch (rtype(r)) {
case RSym:
assert(fn->sym[r.val].type == SReg);
@@ -13,7 +15,19 @@ eref(Ref r, Fn *fn, FILE *f)
fprintf(f, "-%d(%%rbp)", 8 * r.val);
break;
case RConst:
- fprintf(f, "$%d", (int)r.val);
+ c = &fn->cst[r.val];
+ switch (c->type) {
+ case CAddr:
+ fprintf(f, "$%s", c->label);
+ if (c->val)
+ fprintf(f, "%+"PRIi64, c->val);
+ break;
+ case CNum:
+ fprintf(f, "$%"PRId64, c->val);
+ break;
+ default:
+ diag("emitref: invalid constant");
+ }
break;
default:
diag("emitref: invalid reference");
diff --git a/lisc/lisc.h b/lisc/lisc.h
@@ -1,5 +1,5 @@
#include <assert.h>
-#include <stdint.h>
+#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -13,6 +13,7 @@ typedef struct Ins Ins;
typedef struct Phi Phi;
typedef struct Blk Blk;
typedef struct Sym Sym;
+typedef struct Const Const;
typedef struct Fn Fn;
enum {
@@ -158,9 +159,20 @@ struct Sym {
int hint;
};
+struct Const {
+ enum {
+ CUndef,
+ CNum,
+ CAddr,
+ } type;
+ char label[NString];
+ int64_t val;
+};
+
struct Fn {
Blk *start;
Sym *sym;
+ Const *cst;
int ntmp;
int nblk;
Blk **rpo;
diff --git a/lisc/parse.c b/lisc/parse.c
@@ -7,6 +7,7 @@
enum {
NSym = 256,
+ NCst = 256,
};
Ins insb[NIns], *curi;
@@ -48,6 +49,7 @@ typedef enum {
TNum,
TVar,
TLbl,
+ TAddr,
TEq,
TComma,
TLParen,
@@ -60,7 +62,7 @@ typedef enum {
static FILE *inf;
static Token thead;
static struct {
- long long num;
+ int64_t num;
char *str;
} tokval;
static int lnum;
@@ -83,7 +85,9 @@ static Sym sym[NSym] = {
[R14] = { .type = SReg, .name = "r14" },
[R15] = { .type = SReg, .name = "r15" },
};
+static Const cst[NCst];
static int ntmp;
+static int ncst;
static Phi **plink;
static Blk *bmap[NBlk+1];
static Blk *curb;
@@ -167,6 +171,10 @@ lex()
t = TLbl;
c = fgetc(inf);
goto Alpha;
+ case '$':
+ t = TAddr;
+ c = fgetc(inf);
+ goto Alpha;
case '#':
while (fgetc(inf) != '\n')
;
@@ -267,14 +275,38 @@ varref(char *v)
static Ref
parseref()
{
+ int64_t val;
+ char *label;
+ int i, ty;
+
switch (next()) {
case TVar:
return varref(tokval.str);
case TNum:
- if (tokval.num > NRef || tokval.num < 0)
- /* todo, use constants table */
- abort();
- return CONST(tokval.num);
+ ty = CNum;
+ val = tokval.num;
+ label = "";
+ for (i=0; i<ncst; i++)
+ if (cst[i].type == CNum)
+ if (cst[i].val == val)
+ return CONST(i);
+ goto New;
+ case TAddr:
+ ty = CAddr;
+ val = 0;
+ label = tokval.str;
+ for (i=0; i<ncst; i++)
+ if (cst[i].type == CAddr)
+ if (strcmp(cst[i].label, label) == 0)
+ return CONST(i);
+ New:
+ if (i >= NCst)
+ err("too many constants");
+ cst[i].type = ty;
+ cst[i].val = val;
+ strcpy(cst[i].label, label);
+ ncst++;
+ return CONST(i);
default:
return R;
}
@@ -477,6 +509,7 @@ parsefn(FILE *f)
for (i=Tmp0; i<NSym; i++)
sym[i] = (Sym){.type = SUndef};
ntmp = Tmp0;
+ ncst = 0;
curi = insb;
curb = 0;
lnum = 1;
@@ -493,6 +526,8 @@ parsefn(FILE *f)
err("last block misses jump");
fn->sym = alloc(ntmp * sizeof sym[0]);
memcpy(fn->sym, sym, ntmp * sizeof sym[0]);
+ fn->cst = alloc(ncst * sizeof cst[0]);
+ memcpy(fn->cst, cst, ncst * sizeof cst[0]);
fn->ntmp = ntmp;
fn->nblk = nblk;
fn->rpo = 0;
@@ -512,12 +547,25 @@ printref(Ref r, Fn *fn, FILE *f)
fprintf(f, "%s", fn->sym[r.val].name);
break;
case SUndef:
- fprintf(f, "???");
+ diag("printref: invalid symbol");
break;
}
break;
case RConst:
- fprintf(f, "%d", r.val);
+ switch (fn->cst[r.val].type) {
+ case CAddr:
+ fprintf(f, "$%s", fn->cst[r.val].label);
+ if (!fn->cst[r.val].val)
+ break;
+ if (fn->cst[r.val].val > 0)
+ fprintf(f, "+");
+ case CNum:
+ fprintf(f, "%"PRId64, fn->cst[r.val].val);
+ break;
+ case CUndef:
+ diag("printref: invalid constant");
+ break;
+ }
break;
case RSlot:
fprintf(f, "$%d", r.val);