ref: a16c4e637079bb3d7f1cb93ae9b2348d710c003f
parent: fa8e0920764f9f298d6b6ac9471c862aec024e01
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Jun 27 09:38:48 EDT 2015
Factor out blob generation. The logic for our type layout is common between platforms.
--- a/6/Makefile
+++ b/6/Makefile
@@ -1,5 +1,6 @@
INSTBIN=6m
OBJ= \
+ blob.o \
gen.o \
gengas.o \
genp9.o \
--- a/6/asm.h
+++ b/6/asm.h
@@ -68,6 +68,7 @@
Btref,
Btbytes,
Btseq,
+ Btpad,
} Blobtype;
struct Blob {
@@ -75,10 +76,12 @@
char *lbl; /* may be null */
char isglobl;
union {
+ uint64_t npad;
uint64_t ival;
struct {
char *str;
char isextern;
+ size_t off;
} ref;
struct {
size_t len;
@@ -238,7 +241,17 @@
void gen(Node *file, char *out);
void gengas(Node *file, char *out);
void genp9(Node *file, char *out);
+
+/* blob stuff */
+Blob *mkblobpad(size_t sz);
+Blob *mkblobi(Blobtype type, uint64_t ival);
+Blob *mkblobbytes(char *buf, size_t len);
+Blob *mkblobseq(Blob **sub, size_t nsub);
+Blob *mkblobref(char *lbl, size_t off, int isextern);
+void blobfree(Blob *b);
+
Blob *tydescblob(Type *t);
+Blob *litblob(Htab *globls, Htab *strtab, Node *n);
size_t blobsz(Blob *b);
/* location generation */
--- /dev/null
+++ b/6/blob.c
@@ -1,0 +1,272 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <inttypes.h>
+#include <ctype.h>
+#include <string.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "parse.h"
+#include "mi.h"
+#include "asm.h"
+#include "../config.h"
+
+static size_t blobrec(Blob *b, Htab *globls, Htab *strtab, Node *n);
+
+Blob *mkblobi(Blobtype type, uint64_t ival)
+{
+ Blob *b;
+
+ b = zalloc(sizeof(Blob));
+ b->type = type;
+ b->ival = ival;
+ return b;
+}
+
+Blob *mkblobpad(size_t sz)
+{
+ Blob *b;
+
+ b = zalloc(sizeof(Blob));
+ b->type = Btpad;
+ b->npad = sz;
+ return b;
+}
+
+Blob *mkblobbytes(char *buf, size_t len)
+{
+ Blob *b;
+
+ b = zalloc(sizeof(Blob));
+ b->type = Btbytes;
+ b->bytes.buf = buf;
+ b->bytes.len = len;
+ return b;
+}
+
+Blob *mkblobseq(Blob **sub, size_t nsub)
+{
+ Blob *b;
+
+ b = zalloc(sizeof(Blob));
+ b->type = Btseq;
+ b->seq.sub = sub;
+ b->seq.nsub = nsub;
+ return b;
+}
+
+Blob *mkblobref(char *lbl, size_t off, int isextern)
+{
+ Blob *b;
+
+ b = zalloc(sizeof(Blob));
+ b->type = Btref;
+ b->ref.str = strdup(lbl);
+ b->ref.isextern = isextern;
+ b->ref.off = off;
+ return b;
+}
+
+void blobfree(Blob *b)
+{
+ size_t i;
+
+ switch (b->type) {
+ case Btref:
+ free(b->lbl);
+ break;
+ case Btseq:
+ for (i = 0; i < b->seq.nsub; i++)
+ blobfree(b->seq.sub[i]);
+ break;
+ default:
+ break;
+ }
+ free(b);
+}
+
+static size_t getintlit(Node *n, char *failmsg)
+{
+ if (exprop(n) != Olit)
+ fatal(n, "%s", failmsg);
+ n = n->expr.args[0];
+ if (n->lit.littype != Lint)
+ fatal(n, "%s", failmsg);
+ return n->lit.intval;
+}
+
+void b(Blob *b, Blob *n)
+{
+ lappend(&b->seq.sub, &b->seq.nsub, n);
+}
+
+static size_t blobpad(Blob *seq, size_t sz)
+{
+ b(seq, mkblobpad(sz));
+ return sz;
+}
+
+static size_t bloblit(Blob *seq, Htab *strtab, Node *v, Type *ty)
+{
+ char buf[128];
+ char *lbl;
+ size_t sz;
+ Blobtype intsz[] = {
+ [1] = Bti8,
+ [2] = Bti16,
+ [4] = Bti32,
+ [8] = Bti64
+ };
+ union {
+ float fv;
+ double dv;
+ uint64_t qv;
+ uint32_t lv;
+ } u;
+
+ assert(v->type == Nlit);
+ sz = tysize(ty);
+ switch (v->lit.littype) {
+ case Lint: b(seq, mkblobi(intsz[sz], v->lit.intval)); break;
+ case Lbool: b(seq, mkblobi(Bti8, v->lit.boolval)); break;
+ case Lchr: b(seq, mkblobi(Bti32, v->lit.chrval)); break;
+ case Lflt:
+ if (tybase(v->lit.type)->type == Tyflt32) {
+ u.fv = v->lit.fltval;
+ b(seq, mkblobi(Bti32, u.lv));
+ } else if (tybase(v->lit.type)->type == Tyflt64) {
+ u.dv = v->lit.fltval;
+ b(seq, mkblobi(Bti64, u.qv));
+ }
+ break;
+ case Lstr:
+ if (hthas(strtab, &v->lit.strval)) {
+ lbl = htget(strtab, &v->lit.strval);
+ } else {
+ lbl = genlocallblstr(buf, sizeof buf);
+ htput(strtab, &v->lit.strval, strdup(lbl));
+ }
+ b(seq, mkblobref(lbl, 0, 0));
+ b(seq, mkblobi(Bti64, v->lit.strval.len));
+ break;
+ case Lfunc:
+ die("Generating this shit ain't ready yet ");
+ break;
+ case Llbl:
+ die("Can't generate literal labels, ffs. They're not data.");
+ break;
+ }
+ return sz;
+}
+
+static size_t blobslice(Blob *seq, Htab *globls, Htab *strtab, Node *n)
+{
+ Node *base, *lo, *hi;
+ ssize_t loval, hival, sz;
+ char *lbl;
+
+ base = n->expr.args[0];
+ lo = n->expr.args[1];
+ hi = n->expr.args[2];
+
+ /* by this point, all slicing operations should have had their bases
+ * pulled out, and we should have vars with their pseudo-decls in their
+ * place */
+ if (exprop(base) != Ovar || !base->expr.isconst)
+ fatal(base, "slice base is not a constant value");
+ loval = getintlit(lo, "lower bound in slice is not constant literal");
+ hival = getintlit(hi, "upper bound in slice is not constant literal");
+ sz = tysize(tybase(exprtype(base))->sub[0]);
+
+ lbl = htget(globls, base);
+ b(seq, mkblobref(lbl, loval*sz, 0));
+ b(seq, mkblobi(Bti64, (hival - loval)));
+ return 16;
+}
+
+static Node *structmemb(Node *n, char *dcl)
+{
+ size_t i;
+
+ for (i = 0; i < n->expr.nargs; i++)
+ if (!strcmp(namestr(n->expr.args[i]->expr.idx), dcl))
+ return n->expr.args[i];
+ return NULL;
+}
+
+static size_t blobstruct(Blob *seq, Htab *globls, Htab *strtab, Node *n)
+{
+ size_t i, sz, pad, end, ndcl;
+ Node **dcl, *m;
+ Type *t;
+
+ sz = 0;
+ t = tybase(exprtype(n));
+ assert(t->type == Tystruct);
+ dcl = t->sdecls;
+ ndcl = t->nmemb;
+
+ for (i = 0; i < ndcl; i++) {
+ pad = alignto(sz, decltype(dcl[i]));
+ m = structmemb(n, declname(dcl[i]));
+ sz += blobpad(seq, pad - sz);
+ if (m)
+ sz += blobrec(seq, globls, strtab, m);
+ else
+ sz += blobpad(seq, size(dcl[i]));
+ }
+ end = alignto(sz, t);
+ sz += blobpad(seq, end - sz);
+ return sz;
+}
+
+static size_t blobucon(Blob *seq, Htab *globls, Htab *strtab, Node *n)
+{
+ size_t sz;
+ Ucon *uc;
+
+ sz = 4;
+ uc = finducon(exprtype(n), n->expr.args[0]);
+ b(seq, mkblobi(Bti32, uc->id));
+ if (n->expr.nargs > 1)
+ sz += blobrec(seq, globls, strtab, n->expr.args[1]);
+ sz += blobpad(seq, size(n) - sz);
+ return sz;
+}
+
+
+static size_t blobrec(Blob *b, Htab *globls, Htab *strtab, Node *n)
+{
+ size_t i, sz;
+
+ switch(exprop(n)) {
+ case Oucon: sz = blobucon(b, globls, strtab, n); break;
+ case Oslice: sz = blobslice(b, globls, strtab, n); break;
+ case Ostruct: sz = blobstruct(b, globls, strtab, n); break;
+ case Olit: sz = bloblit(b, strtab, n->expr.args[0], exprtype(n)); break;
+ case Otup:
+ case Oarr:
+ sz = 0;
+ for (i = 0; i < n->expr.nargs; i++)
+ sz += blobrec(b, globls, strtab, n->expr.args[i]);
+ break;
+ default:
+ dump(n, stdout);
+ die("Nonliteral initializer for global");
+ break;
+ }
+ return sz;
+}
+
+Blob *litblob(Htab *globls, Htab *strtab, Node *n)
+{
+ Blob *b;
+
+ b = mkblobseq(NULL, 0);
+ blobrec(b, globls, strtab, n);
+ return b;
+}
--- a/6/gengas.c
+++ b/6/gengas.c
@@ -38,7 +38,6 @@
[ModeD] = "d"
};
-static size_t writeblob(FILE *fd, Htab *globls, Htab *strtab, Node *blob);
static void locprint(FILE *fd, Loc *l, char spec);
static void fillglobls(Stab *st, Htab *globls)
@@ -260,169 +259,6 @@
}
}
-static size_t writelit(FILE *fd, Htab *strtab, Node *v, Type *ty)
-{
- char buf[128];
- char *lbl;
- size_t sz;
- char *intsz[] = {
- [1] = ".byte",
- [2] = ".short",
- [4] = ".long",
- [8] = ".quad"
- };
- union {
- float fv;
- double dv;
- uint64_t qv;
- uint32_t lv;
- } u;
-
- assert(v->type == Nlit);
- sz = tysize(ty);
- switch (v->lit.littype) {
- case Lint: fprintf(fd, "\t%s %lld\n", intsz[sz], v->lit.intval); break;
- 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:
- if (tybase(v->lit.type)->type == Tyflt32) {
- u.fv = v->lit.fltval;
- fprintf(fd, "\t.long 0x%llx\n", (vlong)u.lv);
- } else if (tybase(v->lit.type)->type == Tyflt64) {
- u.dv = v->lit.fltval;
- fprintf(fd, "\t.quad 0x%llx\n", (vlong)u.qv);
- }
- break;
- case Lstr:
- if (hthas(strtab, &v->lit.strval)) {
- lbl = htget(strtab, &v->lit.strval);
- } else {
- lbl = genlocallblstr(buf, sizeof buf);
- htput(strtab, &v->lit.strval, strdup(lbl));
- }
- fprintf(fd, "\t.quad %s\n", lbl);
- fprintf(fd, "\t.quad %zd\n", v->lit.strval.len);
- break;
- case Lfunc:
- die("Generating this shit ain't ready yet ");
- break;
- case Llbl:
- die("Can't generate literal labels, ffs. They're not data.");
- break;
- }
- return sz;
-}
-
-static size_t writepad(FILE *fd, size_t sz)
-{
- assert((ssize_t)sz >= 0);
- if (sz > 0)
- fprintf(fd, "\t.fill %zd,1,0\n", sz);
- return sz;
-}
-
-static size_t getintlit(Node *n, char *failmsg)
-{
- if (exprop(n) != Olit)
- fatal(n, "%s", failmsg);
- n = n->expr.args[0];
- if (n->lit.littype != Lint)
- fatal(n, "%s", failmsg);
- return n->lit.intval;
-}
-
-static size_t writeucon(FILE *fd, Htab *globls, Htab *strtab, Node *n)
-{
- size_t sz;
- Ucon *uc;
-
- sz = 4;
- uc = finducon(exprtype(n), n->expr.args[0]);
- fprintf(fd, ".long %zd\n", uc->id);
- if (n->expr.nargs > 1)
- sz += writeblob(fd, globls, strtab, n->expr.args[1]);
- return writepad(fd, size(n) - sz);
-}
-
-static size_t writeslice(FILE *fd, Htab *globls, Htab *strtab, Node *n)
-{
- Node *base, *lo, *hi;
- ssize_t loval, hival, sz;
- char *lbl;
-
- base = n->expr.args[0];
- lo = n->expr.args[1];
- hi = n->expr.args[2];
-
- /* by this point, all slicing operations should have had their bases
- * pulled out, and we should have vars with their pseudo-decls in their
- * place */
- if (exprop(base) != Ovar || !base->expr.isconst)
- fatal(base, "slice base is not a constant value");
- loval = getintlit(lo, "lower bound in slice is not constant literal");
- hival = getintlit(hi, "upper bound in slice is not constant literal");
- sz = tysize(tybase(exprtype(base))->sub[0]);
-
- lbl = htget(globls, base);
- fprintf(fd, "\t.quad %s + (%zd*%zd)\n", lbl, loval, sz);
- fprintf(fd, "\t.quad %zd\n", (hival - loval));
- return size(n);
-}
-
-static size_t writestruct(FILE *fd, Htab *globls, Htab *strtab, Node *n)
-{
- Type *t;
- Node **dcl;
- int found;
- size_t i, j;
- size_t sz, pad, end;
- size_t ndcl;
-
- sz = 0;
- t = tybase(exprtype(n));
- assert(t->type == Tystruct);
- dcl = t->sdecls;
- ndcl = t->nmemb;
- for (i = 0; i < ndcl; i++) {
- pad = alignto(sz, decltype(dcl[i]));
- sz += writepad(fd, pad - sz);
- found = 0;
- for (j = 0; j < n->expr.nargs; j++)
- if (!strcmp(namestr(n->expr.args[j]->expr.idx), declname(dcl[i]))) {
- found = 1;
- sz += writeblob(fd, globls, strtab, n->expr.args[j]);
- }
- if (!found)
- sz += writepad(fd, size(dcl[i]));
- }
- end = alignto(sz, t);
- sz += writepad(fd, end - sz);
- return sz;
-}
-
-static size_t writeblob(FILE *fd, Htab *globls, Htab *strtab, Node *n)
-{
- size_t i, sz;
-
- switch(exprop(n)) {
- case Oucon: sz = writeucon(fd, globls, strtab, n); break;
- case Oslice: sz = writeslice(fd, globls, strtab, n); break;
- case Ostruct: sz = writestruct(fd, globls, strtab, n); break;
- case Olit: sz = writelit(fd, strtab, n->expr.args[0], exprtype(n)); break;
- case Otup:
- case Oarr:
- sz = 0;
- for (i = 0; i < n->expr.nargs; i++)
- sz += writeblob(fd, globls, strtab, n->expr.args[i]);
- break;
- default:
- dump(n, stdout);
- die("Nonliteral initializer for global");
- break;
- }
- return sz;
-}
-
void genstrings(FILE *fd, Htab *strtab)
{
void **k;
@@ -454,42 +290,6 @@
}
}
-void genblob(FILE *fd, Node *blob, Htab *globls, Htab *strtab)
-{
- char *lbl;
-
- /* lits and such also get wrapped in decls */
- assert(blob->type == Ndecl);
-
- lbl = htget(globls, blob);
- if (blob->decl.vis != Visintern)
- fprintf(fd, ".globl %s\n", lbl);
- fprintf(fd, "%s:\n", lbl);
- if (blob->decl.init)
- writeblob(fd, globls, strtab, blob->decl.init);
- else
- writepad(fd, size(blob));
-}
-
-/* genfunc 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 genfunc(FILE *fd, Func *fn, Htab *globls, Htab *strtab)
-{
- Isel is = {0,};
-
- is.reglocs = mkht(varhash, vareq);
- is.stkoff = fn->stkoff;
- is.globls = globls;
- is.ret = fn->ret;
- is.cfg = fn->cfg;
-
- selfunc(&is, fn, globls, strtab);
- if (debugopt['i'])
- writeasm(stdout, &is, fn);
- writeasm(fd, &is, fn);
-}
-
static void encodemin(FILE *fd, uint64_t val)
{
size_t i, shift;
@@ -514,7 +314,7 @@
}
}
-static void gentyblob(FILE *fd, Blob *b)
+static void writeblob(FILE *fd, Blob *b)
{
size_t i;
@@ -542,7 +342,7 @@
encodemin(fd, b->ival);
break;
case Btref:
- fprintf(fd, "\t.quad %s%s\n", b->ref.str, b->ref.isextern ? "g" : "");
+ fprintf(fd, "\t.quad %s%s + %zd\n", b->ref.str, b->ref.isextern ? "g" : "", b->ref.off);
break;
case Btbytes:
writebytes(fd, b->bytes.buf, b->bytes.len);
@@ -549,11 +349,36 @@
break;
case Btseq:
for (i = 0; i < b->seq.nsub; i++)
- gentyblob(fd, b->seq.sub[i]);
+ writeblob(fd, b->seq.sub[i]);
break;
+ case Btpad:
+ for (i = 0; i < b->npad; i++)
+ fprintf(fd, "\t.byte 0\n");
+ break;
+
}
}
+/* genfunc 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 genfunc(FILE *fd, Func *fn, Htab *globls, Htab *strtab)
+{
+ Isel is = {0,};
+
+ is.reglocs = mkht(varhash, vareq);
+ is.stkoff = fn->stkoff;
+ is.globls = globls;
+ is.ret = fn->ret;
+ is.cfg = fn->cfg;
+
+ selfunc(&is, fn, globls, strtab);
+ if (debugopt['i'])
+ writeasm(stdout, &is, fn);
+ writeasm(fd, &is, fn);
+}
+
+
void gentype(FILE *fd, Type *ty)
{
Blob *b;
@@ -561,7 +386,28 @@
if (ty->type == Tyvar)
return;
b = tydescblob(ty);
- gentyblob(fd, b);
+ writeblob(fd, b);
+ blobfree(b);
+}
+
+void genblob(FILE *fd, Node *blob, Htab *globls, Htab *strtab)
+{
+ char *lbl;
+ Blob *b;
+
+ /* lits and such also get wrapped in decls */
+ assert(blob->type == Ndecl);
+
+ lbl = htget(globls, blob);
+ if (blob->decl.vis != Visintern)
+ fprintf(fd, ".globl %s\n", lbl);
+ fprintf(fd, "%s:\n", lbl);
+ if (blob->decl.init)
+ b = litblob(globls, strtab, blob->decl.init);
+ else
+ b = mkblobpad(size(blob));
+ writeblob(fd, b);
+ blobfree(b);
}
void gengas(Node *file, char *out)
--- a/6/genp9.c
+++ b/6/genp9.c
@@ -37,7 +37,6 @@
[ModeD] = "D"
};
-static size_t writeblob(FILE *fd, char *name, size_t off, Htab *globls, Htab *strtab, Node *blob);
static void locprint(FILE *fd, Loc *l, char spec);
static void fillglobls(Stab *st, Htab *globls)
@@ -262,169 +261,6 @@
return sz;
}
-static size_t writelit(FILE *fd, char *name, size_t off, Htab *strtab, Node *v, Type *ty)
-{
- char buf[128];
- char *lbl;
- size_t sz;
- union {
- float fv;
- double dv;
- uint64_t qv;
- uint32_t lv;
- } u;
-
- assert(v->type == Nlit);
- sz = tysize(ty);
- switch (v->lit.littype) {
- case Lint:
- fprintf(fd, "DATA %s+%zd(SB)/%zd,$%lld\n", name, off, sz, v->lit.intval);
- break;
- case Lbool:
- fprintf(fd, "DATA %s+%zd(SB)/%zd,$%d\n", name, off, sz, v->lit.boolval);
- break;
- case Lchr:
- fprintf(fd, "DATA %s+%zd(SB)/%zd,$%d\n", name, off, sz, v->lit.chrval);
- break;
- case Lflt:
- if (tybase(v->lit.type)->type == Tyflt32) {
- u.fv = v->lit.fltval;
- fprintf(fd, "DATA %s+%zd(SB)/%zd, $0x%llx\n", name, off, sz, (vlong)u.lv);
- } else if (tybase(v->lit.type)->type == Tyflt64) {
- u.dv = v->lit.fltval;
- fprintf(fd, "DATA %s+%zd(SB)/%zd, $0x%llx\n", name, off, sz, (vlong)u.qv);
- }
- break;
- case Lstr:
- if (hthas(strtab, &v->lit.strval)) {
- lbl = htget(strtab, &v->lit.strval);
- } else {
- lbl = genlocallblstr(buf, sizeof buf);
- htput(strtab, &v->lit.strval, strdup(lbl));
- }
- if (v->lit.strval.len > 0)
- fprintf(fd, "DATA %s+%zd(SB)/8,$%s+0(SB)\n", name, off, lbl);
- else
- fprintf(fd, "DATA %s+%zd(SB)/8,$0\n", name, off);
- fprintf(fd, "DATA %s+%zd(SB)/8,$%zd\n", name, off+8, v->lit.strval.len);
- break;
- case Lfunc:
- die("Generating this shit ain't ready yet ");
- break;
- case Llbl:
- die("Can't generate literal labels, ffs. They're not data.");
- break;
- }
- return sz;
-}
-
-static size_t writepad(FILE *fd, char *name, size_t off, size_t sz)
-{
- size_t n;
-
- assert((ssize_t)sz >= 0);
- while (sz > 0) {
- n = min(sz, 8);
- fprintf(fd, "DATA %s+%zd(SB)/%zd,$0\n", name, off, n);
- sz -= n;
- }
- return sz;
-}
-
-static size_t getintlit(Node *n, char *failmsg)
-{
- if (exprop(n) != Olit)
- fatal(n, "%s", failmsg);
- n = n->expr.args[0];
- if (n->lit.littype != Lint)
- fatal(n, "%s", failmsg);
- return n->lit.intval;
-}
-
-static size_t writeslice(FILE *fd, char *name, size_t off, Htab *globls, Htab *strtab, Node *n)
-{
- Node *base, *lo, *hi;
- ssize_t loval, hival, sz;
- char *lbl;
-
- base = n->expr.args[0];
- lo = n->expr.args[1];
- hi = n->expr.args[2];
-
- /* by this point, all slicing operations should have had their bases
- * pulled out, and we should have vars with their pseudo-decls in their
- * place */
- if (exprop(base) != Ovar || !base->expr.isconst)
- fatal(base, "slice base is not a constant value");
- loval = getintlit(lo, "lower bound in slice is not constant literal");
- hival = getintlit(hi, "upper bound in slice is not constant literal");
- sz = tysize(tybase(exprtype(base))->sub[0]);
-
- lbl = htget(globls, base);
- fprintf(fd, "DATA %s+%zd(SB)/8,$%s+%zd(SB)\n", name, off, lbl, loval*sz);
- fprintf(fd, "DATA %s+%zd(SB)/8,$%zd\n", name, off + Ptrsz, (hival - loval));
- return size(n);
-}
-
-static size_t writestruct(FILE *fd, char *name, size_t off, Htab *globls, Htab *strtab, Node *n)
-{
- Type *t;
- Node **dcl;
- int found;
- size_t i, j;
- size_t pad, start, end;
- size_t ndcl;
-
- start = off;
- t = tybase(exprtype(n));
- assert(t->type == Tystruct);
- dcl = t->sdecls;
- ndcl = t->nmemb;
- for (i = 0; i < ndcl; i++) {
- pad = alignto(off, decltype(dcl[i]));
- off += writepad(fd, name, off, pad - off);
- found = 0;
- for (j = 0; j < n->expr.nargs; j++)
- if (!strcmp(namestr(n->expr.args[j]->expr.idx), declname(dcl[i]))) {
- found = 1;
- off += writeblob(fd, name, off, globls, strtab, n->expr.args[j]);
- }
- if (!found)
- off += writepad(fd, name, off, size(dcl[i]));
- }
- end = alignto(off, t);
- off += writepad(fd, name, off, end - off);
- return off - start;
-}
-
-static size_t writeblob(FILE *fd, char *name, size_t off, Htab *globls, Htab *strtab, Node *n)
-{
- size_t i, sz;
-
- switch(exprop(n)) {
- case Otup:
- case Oarr:
- sz = 0;
- for (i = 0; i < n->expr.nargs; i++)
- sz += writeblob(fd, name, off + sz, globls, strtab, n->expr.args[i]);
- break;
- case Ostruct:
- sz = writestruct(fd, name, off, globls, strtab, n);
- break;
- case Olit:
- sz = writelit(fd, name, off, strtab, n->expr.args[0], exprtype(n));
- break;
- case Oslice:
- sz = writeslice(fd, name, off, globls, strtab, n);
- break;
- default:
- dump(n, stdout);
- die("Nonliteral initializer for global");
- break;
- }
- return sz;
-}
-
static void genstrings(FILE *fd, Htab *strtab)
{
void **k;
@@ -464,40 +300,6 @@
}
}
-static void genblob(FILE *fd, Node *blob, Htab *globls, Htab *strtab)
-{
- char *lbl;
-
- /* lits and such also get wrapped in decls */
- assert(blob->type == Ndecl);
-
- lbl = htget(globls, blob);
- fprintf(fd, "GLOBL %s+0(SB),$%zd\n", lbl, size(blob));
- if (blob->decl.init)
- writeblob(fd, lbl, 0, globls, strtab, blob->decl.init);
- else
- writepad(fd, lbl, 0, size(blob));
-}
-
-/* genfunc 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. */
-static void genfunc(FILE *fd, Func *fn, Htab *globls, Htab *strtab)
-{
- Isel is = {0,};
-
- is.reglocs = mkht(varhash, vareq);
- is.stkoff = fn->stkoff;
- is.globls = globls;
- is.ret = fn->ret;
- is.cfg = fn->cfg;
-
- selfunc(&is, fn, globls, strtab);
- if (debugopt['i'])
- writeasm(stdout, &is, fn);
- writeasm(fd, &is, fn);
-}
-
static size_t encodemin(FILE *fd, uint64_t val, size_t off, char *lbl)
{
size_t i, shift, n;
@@ -526,7 +328,7 @@
return i;
}
-static size_t gentyblob(FILE *fd, Blob *b, size_t off, char *lbl)
+static size_t writeblob(FILE *fd, Blob *b, size_t off, char *lbl)
{
size_t i, n;
@@ -555,9 +357,11 @@
break;
case Btref:
if (b->ref.isextern)
- fprintf(fd, "DATA %s+%zd(SB)/8,$%s+0(SB)\n", lbl, off+n, b->ref.str);
+ fprintf(fd, "DATA %s+%zd(SB)/8,$%s+%zd(SB)\n",
+ lbl, off+n, b->ref.str, b->ref.off);
else
- fprintf(fd, "DATA %s+%zd(SB)/8,$%s<>+0(SB)\n", lbl, off+n, b->ref.str);
+ fprintf(fd, "DATA %s+%zd(SB)/8,$%s<>+%zd(SB)\n",
+ lbl, off+n, b->ref.str, b->ref.off);
n += 8;
break;
case Btbytes:
@@ -565,12 +369,35 @@
break;
case Btseq:
for (i = 0; i < b->seq.nsub; i++)
- n += gentyblob(fd, b->seq.sub[i], off+n, lbl);
+ n += writeblob(fd, b->seq.sub[i], off+n, lbl);
break;
+ case Btpad:
+ for (i = 0; i < b->npad; i++)
+ fprintf(fd, "DATA %s+%zd(SB)/1,$0\n", lbl, off+n+i);
+ n += b->npad;
+ break;
}
return n;
}
+/* genfunc 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. */
+static void genfunc(FILE *fd, Func *fn, Htab *globls, Htab *strtab)
+{
+ Isel is = {0,};
+ is.reglocs = mkht(varhash, vareq);
+ is.stkoff = fn->stkoff;
+ is.globls = globls;
+ is.ret = fn->ret;
+ is.cfg = fn->cfg;
+
+ selfunc(&is, fn, globls, strtab);
+ if (debugopt['i'])
+ writeasm(stdout, &is, fn);
+ writeasm(fd, &is, fn);
+}
+
static void gentype(FILE *fd, Type *ty)
{
Blob *b;
@@ -588,7 +415,24 @@
fprintf(fd, "GLOBL %s%s<>+0(SB),$%zd\n", Symprefix, b->lbl, blobsz(b));
snprintf(lbl, sizeof lbl, "%s%s<>", Symprefix, b->lbl);
}
- gentyblob(fd, b, 0, lbl);
+ writeblob(fd, b, 0, lbl);
+}
+
+static void genblob(FILE *fd, Node *blob, Htab *globls, Htab *strtab)
+{
+ char *lbl;
+ Blob *b;
+
+ /* lits and such also get wrapped in decls */
+ assert(blob->type == Ndecl);
+
+ lbl = htget(globls, blob);
+ fprintf(fd, "GLOBL %s+0(SB),$%zd\n", lbl, size(blob));
+ if (blob->decl.init)
+ b = litblob(globls, strtab, blob->decl.init);
+ else
+ b = mkblobpad(size(blob));
+ writeblob(fd, b, 0, lbl);
}
void genp9(Node *file, char *out)
--- a/6/typeinfo.c
+++ b/6/typeinfo.c
@@ -19,49 +19,6 @@
Blob *tydescsub(Type *ty);
-static Blob *mkblobi(Blobtype type, uint64_t ival)
-{
- Blob *b;
-
- b = zalloc(sizeof(Blob));
- b->type = type;
- b->ival = ival;
- return b;
-}
-
-static Blob *mkblobbytes(char *buf, size_t len)
-{
- Blob *b;
-
- b = zalloc(sizeof(Blob));
- b->type = Btbytes;
- b->bytes.len = len;
- b->bytes.buf = buf;
- return b;
-}
-
-static Blob *mkblobseq(Blob **sub, size_t nsub)
-{
- Blob *b;
-
- b = zalloc(sizeof(Blob));
- b->type = Btseq;
- b->seq.nsub = nsub;
- b->seq.sub = sub;
- return b;
-}
-
-static Blob *mkblobref(char *lbl, int isextern)
-{
- Blob *b;
-
- b = zalloc(sizeof(Blob));
- b->type = Btref;
- b->ref.str = strdup(lbl);
- b->ref.isextern = isextern;
- return b;
-}
-
size_t blobsz(Blob *b)
{
size_t n;
@@ -220,7 +177,7 @@
case Tyname:
i = snprintf(buf, sizeof buf, "%s", Symprefix);
tydescid(buf + i, sizeof buf - i, ty);
- lappend(&sub, &nsub, mkblobref(buf, ty->isimport || ty->vis == Visexport));
+ lappend(&sub, &nsub, mkblobref(buf, 0, ty->isimport || ty->vis == Visexport));
break;
}
b = mkblobseq(sub, nsub);