ref: 5683fabf488d8e1a8e6beeff31e732cf8dcf590b
parent: 90b5bcd21e3920cc6ab27bb32df81aed5cb26e9f
author: Ori Bernstein <[email protected]>
date: Sun Jun 17 14:09:44 EDT 2012
Add in support for writing out strings.
--- a/8/asm.h
+++ b/8/asm.h
@@ -42,12 +42,6 @@
Nmode,
} Mode;
-struct Blob {
- char *name; /* mangled asm name */
- void *data;
- size_t ndata;
-};
-
struct Loc {
LocType type;
Mode mode;
@@ -162,6 +156,7 @@
};
/* entry points */
+void genblob(FILE *fd, Node *blob, Htab *globls);
void genasm(FILE *fd, Func *fn, Htab *globls);
void gen(Node *file, char *out);
@@ -169,6 +164,8 @@
extern size_t maxregid;
extern Loc **locmap; /* mapping from reg id => Loc * */
+char *genlblstr(char *buf, size_t sz);
+Node *genlbl(void);
Loc *loclbl(Node *lbl);
Loc *locstrlbl(char *lbl);
Loc *locreg(Mode m);
--- a/8/isel.c
+++ b/8/isel.c
@@ -517,6 +517,8 @@
break;
case Olit: /* fall through */
+ r = loc(s, n);
+ break;
case Ovar:
r = loc(s, n);
break;
@@ -711,6 +713,55 @@
as->lbls = memdup(bb->lbls, bb->nlbls*sizeof(char*));
as->nlbls = bb->nlbls;
return as;
+}
+
+void writeblob(FILE *fd, char *p, size_t sz)
+{
+ size_t i;
+
+ for (i = 0; i < sz; i++) {
+ if (i % 60 == 0)
+ fprintf(fd, "\t.string \"");
+ if (isprint(p[i]))
+ fprintf(fd, "%c", p[i]);
+ else
+ fprintf(fd, "\\%x", p[i]);
+ if (i % 60 == 59 || i == sz - 1)
+ fprintf(fd, "\"\n");
+ }
+}
+
+void writelit(FILE *fd, Node *v)
+{
+ char lbl[128];
+ switch (v->lit.littype) {
+ case Lbool: fprintf(fd, "\t.long %d\n", v->lit.boolval); break;
+ case Lchr: fprintf(fd, "\t.byte %d\n", v->lit.chrval); break;
+ case Lint: fprintf(fd, "\t.long %lld\n", v->lit.intval); break;
+ case Lflt: fprintf(fd, "\t.double %f\n", v->lit.fltval); break;
+ case Lstr: fprintf(fd, "\t.long $%s\n", genlblstr(lbl, 128));
+ fprintf(fd, "\t.long %zd\n", strlen(v->lit.strval));
+ writeblob(fd, v->lit.strval, strlen(v->lit.strval));
+ break;
+ case Larray:
+ case Lfunc:
+ die("Generating this shit ain't ready yet ");
+ }
+}
+
+void genblob(FILE *fd, Node *blob, Htab *globls)
+{
+ char *lbl;
+
+ /* lits and such also get wrapped in decls */
+ assert(blob->type == Ndecl);
+ assert(blob->decl.init != NULL);
+
+ lbl = htget(globls, blob);
+ fprintf(fd, "%s:\n", lbl);
+ if (exprop(blob->decl.init) != Olit)
+ die("Nonliteral initializer for global");
+ writelit(fd, blob->decl.init->expr.args[0]);
}
/* genasm requires all nodes in 'nl' to map cleanly to operations that are
--- a/8/locs.c
+++ b/8/locs.c
@@ -53,6 +53,22 @@
[Rebp] = {Rebp},
};
+
+char *genlblstr(char *buf, size_t sz)
+{
+ static int nextlbl;
+ snprintf(buf, 128, ".L%d", nextlbl++);
+ return buf;
+}
+
+Node *genlbl(void)
+{
+ char buf[128];
+
+ genlblstr(buf, 128);
+ return mklbl(-1, buf);
+}
+
Loc *locstrlbl(char *lbl)
{
Loc *l;
--- a/8/reduce.c
+++ b/8/reduce.c
@@ -37,10 +37,12 @@
size_t nqueue;
/* location handling */
+ Node **blobs;
+ size_t nblobs;
size_t stksz;
size_t argsz;
- Htab *locs;
Htab *globls;
+ Htab *locs;
Node *ret;
};
@@ -172,19 +174,9 @@
t = n->expr.type;
else
t = n->decl.type;
-
return tysize(t);
}
-static Node *genlbl(void)
-{
- char buf[128];
- static int nextlbl;
-
- snprintf(buf, 128, ".L%d", nextlbl++);
- return mklbl(-1, buf);
-}
-
static Node *temp(Simp *simp, Node *e)
{
char buf[128];
@@ -277,6 +269,21 @@
}
}
+static Node *bloblit(Simp *s, Node *lit)
+{
+ Node *n, *t, *r;
+ char lbl[128];
+
+ n = mkname(lit->line, genlblstr(lbl, 128));
+ t = mkdecl(lit->line, n, lit->expr.type);
+ r = mkexpr(lit->line, Ovar, t, NULL);
+ t->decl.init = lit;
+ r->expr.did = t->decl.did;
+ htput(s->globls, t, strdup(lbl));
+ lappend(&s->blobs, &s->nblobs, t);
+ return r;
+}
+
static size_t offsetof(Node *aggr, Node *memb)
{
Type *ty;
@@ -519,7 +526,20 @@
t = mkexpr(n->line, Ostor, r, v, NULL);
lappend(&s->incqueue, &s->nqueue, t);
break;
- case Olit: case Ovar:
+ case Olit:
+ switch (args[0]->lit.littype) {
+ case Lchr: case Lbool: case Lint: case Lflt:
+ r = n;
+ break;
+ case Lstr: case Larray:
+ r = bloblit(s, n);
+ break;
+ case Lfunc:
+ die("Func lits not handled yet");
+ break;
+ }
+ break;
+ case Ovar:
r = n;
break;
case Oret:
@@ -694,20 +714,6 @@
return fn;
}
-void blobdump(Blob *b, FILE *fd)
-{
- size_t i;
- char *p;
-
- p = b->data;
- for (i = 0; i < b->ndata; i++)
- if (isprint(p[i]))
- fprintf(fd, "%c", p[i]);
- else
- fprintf(fd, "\\%x", p[i]);
- fprintf(fd, "\n");
-}
-
void fillglobls(Stab *st, Htab *globls)
{
void **k;
@@ -739,13 +745,20 @@
name = asmname(dcl->decl.name);
s.locs = mkht(dclhash, dcleq);
s.globls = globls;
+ s.blobs = *blob;
+ s.nblobs = *nblob;
if (isconstfn(dcl)) {
f = lowerfn(&s, name, dcl->decl.init);
lappend(fn, nfn, f);
} else {
- die("We don't lower globls yet...");
+ if (dcl->decl.init && exprop(dcl->decl.init) == Olit)
+ lappend(blob, nblob, dcl);
+ else
+ die("We don't lower globls with nonlit inits yet...");
}
+ *blob = s.blobs;
+ *nblob = s.nblobs;
free(name);
}
@@ -789,6 +802,8 @@
}
}
+ for (i = 0; i < nblob; i++)
+ genblob(fd, blob[i], globls);
for (i = 0; i < nfn; i++)
genasm(fd, fn[i], globls);
fclose(fd);