commit 16e430935db1f928452767af23ea1a1c6d000299
parent 916555cb10110f6c748e70cb5337752432a325b8
Author: Quentin Carbonneaux <quentin.carbonneaux@yale.edu>
Date: Mon, 15 Feb 2016 14:22:22 -0500
collect and emit fp constants
Diffstat:
4 files changed, 71 insertions(+), 5 deletions(-)
diff --git 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
@@ -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
@@ -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
@@ -114,6 +114,8 @@ main(int ac, char *av[])
}
parse(inf, data, func);
+ if (!dbg)
+ emitfin(stdout);
fclose(inf);
exit(0);