shithub: mc

Download patch

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);