ref: c2c3ff71512cd26f452ff6f97a167393c0ccec9f
parent: 36232a98d2ebeb42a853493aafab51777a3f0081
author: Ori Bernstein <[email protected]>
date: Wed Oct 9 13:27:02 EDT 2013
Collect strings into a de-duplicating string table.
--- a/6/asm.h
+++ b/6/asm.h
@@ -181,8 +181,9 @@
};
/* entry points */
-void genblob(FILE *fd, Node *blob, Htab *globls);
-void genasm(FILE *fd, Func *fn, Htab *globls);
+void genblob(FILE *fd, Node *blob, Htab *globls, Htab *strtab);
+void genasm(FILE *fd, Func *fn, Htab *globls, Htab *strtab);
+void genstrings(FILE *fd, Htab *strtab);
void gen(Node *file, char *out);
/* location generation */
--- a/6/isel.c
+++ b/6/isel.c
@@ -34,9 +34,8 @@
/* forward decls */
Loc *selexpr(Isel *s, Node *n);
-static void writeblob(FILE *fd, Node *blob);
+static void writeblob(FILE *fd, Htab *strtab, Node *blob);
-
/* used to decide which operator is appropriate
* for implementing various conditional operators */
struct {
@@ -926,9 +925,10 @@
}
}
-static void writelit(FILE *fd, Node *v, size_t sz)
+static void writelit(FILE *fd, Htab *strtab, Node *v, size_t sz)
{
- char lbl[128];
+ char buf[128];
+ char *lbl;
char *intsz[] = {
[1] = ".byte",
[2] = ".short",
@@ -942,11 +942,16 @@
case Lbool: fprintf(fd, "\t.byte %d\n", v->lit.boolval); break;
case Lchr: fprintf(fd, "\t.long %d\n", v->lit.chrval); break;
case Lflt: fprintf(fd, "\t.double %f\n", v->lit.fltval); break;
- case Lstr: fprintf(fd, "\t.quad %s\n", genlblstr(lbl, 128));
- fprintf(fd, "\t.quad %zd\n", strlen(v->lit.strval));
- fprintf(fd, "%s:\n", lbl);
- writebytes(fd, v->lit.strval, strlen(v->lit.strval));
- break;
+ case Lstr:
+ if (hthas(strtab, v->lit.strval)) {
+ lbl = htget(strtab, v->lit.strval);
+ } else {
+ lbl = genlblstr(buf, sizeof buf);
+ htput(strtab, v->lit.strval, strdup(lbl));
+ }
+ fprintf(fd, "\t.quad %s\n", lbl);
+ fprintf(fd, "\t.quad %zd\n", strlen(v->lit.strval));
+ break;
case Lfunc:
die("Generating this shit ain't ready yet ");
break;
@@ -964,40 +969,40 @@
fprintf(fd, "\t.byte 0\n");
}
-static void writetup(FILE *fd, Node *n)
+static void writetup(FILE *fd, Htab *strtab, Node *n)
{
size_t i;
for (i = 0; i < n->expr.nargs; i++) {
- writeblob(fd, n->expr.args[i]);
+ writeblob(fd, strtab, n->expr.args[i]);
}
}
-static void writearr(FILE *fd, Node *n)
+static void writearr(FILE *fd, Htab *strtab, Node *n)
{
size_t i;
for (i = 0; i < n->expr.nargs; i++) {
- writeblob(fd, n->expr.args[i]);
+ writeblob(fd, strtab, n->expr.args[i]);
}
}
-static void writestruct(FILE *fd, Node *n)
+static void writestruct(FILE *fd, Htab *strtab, Node *n)
{
size_t i;
for (i = 0; i < n->expr.nargs; i++) {
- writeblob(fd, n->expr.args[i]);
+ writeblob(fd, strtab, n->expr.args[i]);
}
}
-static void writeblob(FILE *fd, Node *n)
+static void writeblob(FILE *fd, Htab *strtab, Node *n)
{
switch(exprop(n)) {
- case Otup: writetup(fd, n); break;
- case Oarr: writearr(fd, n); break;
- case Ostruct: writestruct(fd, n); break;
- case Olit: writelit(fd, n->expr.args[0], size(n)); break;
+ case Otup: writetup(fd, strtab, n); break;
+ case Oarr: writearr(fd, strtab, n); break;
+ case Ostruct: writestruct(fd, strtab, n); break;
+ case Olit: writelit(fd, strtab, n->expr.args[0], size(n)); break;
default:
die("Nonliteral initializer for global");
break;
@@ -1004,7 +1009,7 @@
}
}
-void genblob(FILE *fd, Node *blob, Htab *globls)
+void genblob(FILE *fd, Node *blob, Htab *globls, Htab *strtab)
{
char *lbl;
@@ -1016,7 +1021,7 @@
fprintf(fd, ".globl %s\n", lbl);
fprintf(fd, "%s:\n", lbl);
if (blob->decl.init)
- writeblob(fd, blob->decl.init);
+ writeblob(fd, strtab, blob->decl.init);
else
writepad(fd, size(blob));
}
@@ -1024,7 +1029,7 @@
/* genasm requires all nodes in 'nl' to map cleanly to operations that are
* natively supported, as promised in the output of reduce(). No 64-bit
* operations on x32, no structures, and so on. */
-void genasm(FILE *fd, Func *fn, Htab *globls)
+void genasm(FILE *fd, Func *fn, Htab *globls, Htab *strtab)
{
Isel is = {0,};
size_t i, j;
@@ -1062,4 +1067,16 @@
if (debugopt['i'])
writeasm(stdout, &is, fn);
writeasm(fd, &is, fn);
+}
+
+void genstrings(FILE *fd, Htab *strtab)
+{
+ void **k;
+ size_t i, nk;
+
+ k = htkeys(strtab, &nk);
+ for (i = 0; i < nk; i++) {
+ fprintf(fd, "%s:\n", (char*)htget(strtab, k[i]));
+ writebytes(fd, k[i], strlen(k[i]));
+ }
}
--- a/6/simp.c
+++ b/6/simp.c
@@ -1505,7 +1505,7 @@
void gen(Node *file, char *out)
{
- Htab *globls;
+ Htab *globls, *strtab;
Node *n, **blob;
Func **fn;
size_t nfn, nblob;
@@ -1546,11 +1546,13 @@
if (!fd)
die("Couldn't open fd %s", out);
+ strtab = mkht(strhash, streq);
fprintf(fd, ".data\n");
for (i = 0; i < nblob; i++)
- genblob(fd, blob[i], globls);
+ genblob(fd, blob[i], globls, strtab);
fprintf(fd, ".text\n");
for (i = 0; i < nfn; i++)
- genasm(fd, fn[i], globls);
+ genasm(fd, fn[i], globls, strtab);
+ genstrings(fd, strtab);
fclose(fd);
}