diff options
author | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2016-02-15 14:22:22 -0500 |
---|---|---|
committer | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2016-02-15 16:34:16 -0500 |
commit | 16e430935db1f928452767af23ea1a1c6d000299 (patch) | |
tree | ec7e317757d60eca82a292cca147c0f46b9b7cf8 | |
parent | 916555cb10110f6c748e70cb5337752432a325b8 (diff) | |
download | roux-16e430935db1f928452767af23ea1a1c6d000299.tar.gz |
collect and emit fp constants
-rw-r--r-- | lisc/emit.c | 63 | ||||
-rw-r--r-- | lisc/isel.c | 6 | ||||
-rw-r--r-- | lisc/lisc.h | 5 | ||||
-rw-r--r-- | lisc/main.c | 2 |
4 files changed, 71 insertions, 5 deletions
diff --git a/lisc/emit.c b/lisc/emit.c index 3b916c4..aaac1b3 100644 --- a/lisc/emit.c +++ b/lisc/emit.c @@ -552,3 +552,66 @@ emitdat(Dat *d, FILE *f) break; } } + +typedef struct FBits FBits; + +struct FBits { + int64_t bits; + int wide; + FBits *link; +}; + +static FBits *stash; + +int +stashfp(int64_t n, int w) +{ + FBits **pb, *b; + int i; + + /* does a dumb de-dup of fp constants + * this should be the linker's job */ + for (pb=&stash, i=0; (b=*pb); pb=&b->link, i++) + if (n == b->bits && w == b->wide) + return i; + b = emalloc(sizeof *b); + b->bits = n; + b->wide = w; + b->link = 0; + *pb = b; + return i; +} + +void +emitfin(FILE *f) +{ + FBits *b; + int i; + + if (!stash) + return; + fprintf(f, "/* floating point constants */\n"); + fprintf(f, ".data\n.align 8\n"); + for (b=stash, i=0; b; b=b->link, i++) + if (b->wide) + fprintf(f, + ".Lfp%d:\n" + "\t.quad %"PRId64 + " /* %f */\n", + i, b->bits, + *(double *)&b->bits + ); + for (b=stash, i=0; b; b=b->link, i++) + if (!b->wide) + fprintf(f, + ".Lfp%d:\n" + "\t.long %"PRId64 + " /* %lf */\n", + i, b->bits & 0xffffffff, + *(float *)&b->bits + ); + while ((b=stash)) { + stash = b->link; + free(b); + } +} diff --git a/lisc/isel.c b/lisc/isel.c index 578eec7..d5ccdd7 100644 --- a/lisc/isel.c +++ b/lisc/isel.c @@ -114,7 +114,7 @@ fixarg(Ref *r, int k, int phi, Fn *fn) { Addr a; Ref r0, r1; - int s; + int s, n; r1 = r0 = *r; s = rslot(r0, fn); @@ -127,8 +127,8 @@ fixarg(Ref *r, int k, int phi, Fn *fn) vgrow(&fn->mem, ++fn->nmem); memset(&a, 0, sizeof a); a.offset.type = CAddr; - sprintf(a.offset.label, ".fp%d", r0.val); - fn->con[r0.val].emit = 1; + n = stashfp(fn->con[r0.val].bits.i, KWIDE(k)); + sprintf(a.offset.label, ".Lfp%d", n); fn->mem[fn->nmem-1] = a; } else if (!phi && rtype(r0) == RCon && noimm(r0, fn)) { diff --git a/lisc/lisc.h b/lisc/lisc.h index 05c1977..e857fcf 100644 --- a/lisc/lisc.h +++ b/lisc/lisc.h @@ -386,8 +386,7 @@ struct Con { double d; float s; } bits; - char flt; /* 1 for single precision, 2 for double */ - char emit; + char flt; /* for printing, see parse.c */ }; typedef struct Addr Addr; @@ -511,3 +510,5 @@ void rega(Fn *); /* emit.c */ void emitfn(Fn *, FILE *); void emitdat(Dat *, FILE *); +int stashfp(int64_t, int); +void emitfin(FILE *); diff --git a/lisc/main.c b/lisc/main.c index a393a69..25165ff 100644 --- a/lisc/main.c +++ b/lisc/main.c @@ -114,6 +114,8 @@ main(int ac, char *av[]) } parse(inf, data, func); + if (!dbg) + emitfin(stdout); fclose(inf); exit(0); |