summaryrefslogtreecommitdiff
path: root/6/genp9.c
diff options
context:
space:
mode:
Diffstat (limited to '6/genp9.c')
-rw-r--r--6/genp9.c766
1 files changed, 383 insertions, 383 deletions
diff --git a/6/genp9.c b/6/genp9.c
index 0a83335..68e9d1b 100644
--- a/6/genp9.c
+++ b/6/genp9.c
@@ -29,334 +29,334 @@ static char *regnames[] = {
};
static char* modenames[] = {
- [ModeB] = "B",
- [ModeW] = "W",
- [ModeL] = "L",
- [ModeQ] = "Q",
- [ModeF] = "S",
- [ModeD] = "D"
+ [ModeB] = "B",
+ [ModeW] = "W",
+ [ModeL] = "L",
+ [ModeQ] = "Q",
+ [ModeF] = "S",
+ [ModeD] = "D"
};
static void locprint(FILE *fd, Loc *l, char spec);
static void initconsts(Htab *globls)
{
- Type *ty;
- Node *name;
- Node *dcl;
-
- tyintptr = mktype(Zloc, Tyuint64);
- tyword = mktype(Zloc, Tyuint);
- tyvoid = mktype(Zloc, Tyvoid);
-
- ty = mktyfunc(Zloc, NULL, 0, mktype(Zloc, Tyvoid));
- ty->type = Tycode;
- name = mknsname(Zloc, "_rt", "abort_oob");
- dcl = mkdecl(Zloc, name, ty);
- dcl->decl.isconst = 1;
- dcl->decl.isextern = 1;
- htput(globls, dcl, asmname(dcl));
-
- abortoob = mkexpr(Zloc, Ovar, name, NULL);
- abortoob->expr.type = ty;
- abortoob->expr.did = dcl->decl.did;
- abortoob->expr.isconst = 1;
+ Type *ty;
+ Node *name;
+ Node *dcl;
+
+ tyintptr = mktype(Zloc, Tyuint64);
+ tyword = mktype(Zloc, Tyuint);
+ tyvoid = mktype(Zloc, Tyvoid);
+
+ ty = mktyfunc(Zloc, NULL, 0, mktype(Zloc, Tyvoid));
+ ty->type = Tycode;
+ name = mknsname(Zloc, "_rt", "abort_oob");
+ dcl = mkdecl(Zloc, name, ty);
+ dcl->decl.isconst = 1;
+ dcl->decl.isextern = 1;
+ htput(globls, dcl, asmname(dcl));
+
+ abortoob = mkexpr(Zloc, Ovar, name, NULL);
+ abortoob->expr.type = ty;
+ abortoob->expr.did = dcl->decl.did;
+ abortoob->expr.isconst = 1;
}
static void printmem(FILE *fd, Loc *l, char spec)
{
- if (l->type == Locmem) {
- if (l->mem.constdisp)
- fprintf(fd, "%ld", l->mem.constdisp);
- } else if (l->mem.lbldisp) {
- fprintf(fd, "%s", l->mem.lbldisp);
- }
- if (!l->mem.base || l->mem.base->reg.colour == Rrip) {
- fprintf(fd, "+0(SB)");
- } else {
- fprintf(fd, "(");
- locprint(fd, l->mem.base, 'r');
- fprintf(fd, ")");
- }
- if (l->mem.idx) {
- fprintf(fd, "(");
- locprint(fd, l->mem.idx, 'r');
- fprintf(fd, "*%d", l->mem.scale);
- fprintf(fd, ")");
- }
+ if (l->type == Locmem) {
+ if (l->mem.constdisp)
+ fprintf(fd, "%ld", l->mem.constdisp);
+ } else if (l->mem.lbldisp) {
+ fprintf(fd, "%s", l->mem.lbldisp);
+ }
+ if (!l->mem.base || l->mem.base->reg.colour == Rrip) {
+ fprintf(fd, "+0(SB)");
+ } else {
+ fprintf(fd, "(");
+ locprint(fd, l->mem.base, 'r');
+ fprintf(fd, ")");
+ }
+ if (l->mem.idx) {
+ fprintf(fd, "(");
+ locprint(fd, l->mem.idx, 'r');
+ fprintf(fd, "*%d", l->mem.scale);
+ fprintf(fd, ")");
+ }
}
static void locprint(FILE *fd, Loc *l, char spec)
{
- spec = tolower(spec);
- assert(l->mode);
- switch (l->type) {
- case Loclitl:
- assert(spec == 'i' || spec == 'x' || spec == 'u');
- fprintf(fd, "$%s", l->lbl);
- break;
- case Loclbl:
- assert(spec == 'm' || spec == 'v' || spec == 'x');
- fprintf(fd, "%s", l->lbl);
- break;
- case Locreg:
- assert((spec == 'r' && isintmode(l->mode)) ||
- (spec == 'f' && isfloatmode(l->mode)) ||
- spec == 'v' ||
- spec == 'x' ||
- spec == 'u');
- if (l->reg.colour == Rnone)
- fprintf(fd, "%%P.%zd%s", l->reg.id, modenames[l->mode]);
- else
- fprintf(fd, "%s", regnames[l->reg.colour]);
- break;
- case Locmem:
- case Locmeml:
- assert(spec == 'm' || spec == 'v' || spec == 'x');
- printmem(fd, l, spec);
- break;
- case Loclit:
- assert(spec == 'i' || spec == 'x' || spec == 'u');
- fprintf(fd, "$%ld", l->lit);
- break;
- case Locnone:
- die("Bad location in locprint()");
- break;
- }
+ spec = tolower(spec);
+ assert(l->mode);
+ switch (l->type) {
+ case Loclitl:
+ assert(spec == 'i' || spec == 'x' || spec == 'u');
+ fprintf(fd, "$%s", l->lbl);
+ break;
+ case Loclbl:
+ assert(spec == 'm' || spec == 'v' || spec == 'x');
+ fprintf(fd, "%s", l->lbl);
+ break;
+ case Locreg:
+ assert((spec == 'r' && isintmode(l->mode)) ||
+ (spec == 'f' && isfloatmode(l->mode)) ||
+ spec == 'v' ||
+ spec == 'x' ||
+ spec == 'u');
+ if (l->reg.colour == Rnone)
+ fprintf(fd, "%%P.%zd%s", l->reg.id, modenames[l->mode]);
+ else
+ fprintf(fd, "%s", regnames[l->reg.colour]);
+ break;
+ case Locmem:
+ case Locmeml:
+ assert(spec == 'm' || spec == 'v' || spec == 'x');
+ printmem(fd, l, spec);
+ break;
+ case Loclit:
+ assert(spec == 'i' || spec == 'x' || spec == 'u');
+ fprintf(fd, "$%ld", l->lit);
+ break;
+ case Locnone:
+ die("Bad location in locprint()");
+ break;
+ }
}
static int issubreg(Loc *a, Loc *b)
{
- return rclass(a) == rclass(b) && a->mode != b->mode;
+ return rclass(a) == rclass(b) && a->mode != b->mode;
}
static void iprintf(FILE *fd, Insn *insn)
{
- char *p;
- int i;
- int idx;
-
- /* x64 has a quirk; it has no movzlq because mov zero extends. This
- * means that we need to do a movl when we really want a movzlq. Since
- * we don't know the name of the reg to use, we need to sub it in when
- * writing... */
- switch (insn->op) {
- case Imovzx:
- if (insn->args[0]->mode == ModeL && insn->args[1]->mode == ModeQ) {
- if (insn->args[1]->reg.colour) {
- insn->op = Imov;
- insn->args[1] = coreg(insn->args[1]->reg.colour, ModeL);
- }
- }
- break;
- case Imovs:
- if (insn->args[0]->reg.colour == Rnone || insn->args[1]->reg.colour == Rnone)
- break;
- /* moving a reg to itself is dumb. */
- if (insn->args[0]->reg.colour == insn->args[1]->reg.colour)
- return;
- break;
- case Imov:
- assert(!isfloatmode(insn->args[0]->mode));
- if (insn->args[0]->type != Locreg || insn->args[1]->type != Locreg)
- break;
- if (insn->args[0]->reg.colour == Rnone || insn->args[1]->reg.colour == Rnone)
- break;
- /* if one reg is a subreg of another, we can just use the right
- * mode to move between them. */
- if (issubreg(insn->args[0], insn->args[1]))
- insn->args[0] = coreg(insn->args[0]->reg.colour, insn->args[1]->mode);
- /* moving a reg to itself is dumb. */
- if (insn->args[0]->reg.colour == insn->args[1]->reg.colour)
- return;
- break;
- default:
- break;
- }
- p = insnfmt[insn->op];
- i = 0; /* NB: this is 1 based indexing */
- for (; *p; p++) {
- if (*p != '%') {
- fputc(*p, fd);
- continue;
- }
-
- /* %-formating */
- p++;
- idx = i;
+ char *p;
+ int i;
+ int idx;
+
+ /* x64 has a quirk; it has no movzlq because mov zero extends. This
+ * means that we need to do a movl when we really want a movzlq. Since
+ * we don't know the name of the reg to use, we need to sub it in when
+ * writing... */
+ switch (insn->op) {
+ case Imovzx:
+ if (insn->args[0]->mode == ModeL && insn->args[1]->mode == ModeQ) {
+ if (insn->args[1]->reg.colour) {
+ insn->op = Imov;
+ insn->args[1] = coreg(insn->args[1]->reg.colour, ModeL);
+ }
+ }
+ break;
+ case Imovs:
+ if (insn->args[0]->reg.colour == Rnone || insn->args[1]->reg.colour == Rnone)
+ break;
+ /* moving a reg to itself is dumb. */
+ if (insn->args[0]->reg.colour == insn->args[1]->reg.colour)
+ return;
+ break;
+ case Imov:
+ assert(!isfloatmode(insn->args[0]->mode));
+ if (insn->args[0]->type != Locreg || insn->args[1]->type != Locreg)
+ break;
+ if (insn->args[0]->reg.colour == Rnone || insn->args[1]->reg.colour == Rnone)
+ break;
+ /* if one reg is a subreg of another, we can just use the right
+ * mode to move between them. */
+ if (issubreg(insn->args[0], insn->args[1]))
+ insn->args[0] = coreg(insn->args[0]->reg.colour, insn->args[1]->mode);
+ /* moving a reg to itself is dumb. */
+ if (insn->args[0]->reg.colour == insn->args[1]->reg.colour)
+ return;
+ break;
+ default:
+ break;
+ }
+ p = insnfmt[insn->op];
+ i = 0; /* NB: this is 1 based indexing */
+ for (; *p; p++) {
+ if (*p != '%') {
+ fputc(*p, fd);
+ continue;
+ }
+
+ /* %-formating */
+ p++;
+ idx = i;
again:
- switch (*p) {
- case '\0':
- goto done; /* skip the final p++ */
- break;
- case 'R': /* int register */
- case 'F': /* float register */
- case 'M': /* memory */
- case 'I': /* imm */
- case 'V': /* reg/mem */
- case 'U': /* reg/imm */
- case 'X': /* reg/mem/imm */
- locprint(fd, insn->args[idx], *p);
- i++;
- break;
- case 'T':
- fputs(modenames[insn->args[idx]->mode], fd);
- break;
- default:
- /* the asm description uses 1-based indexing, so that 0
- * can be used as a sentinel. */
- if (!isdigit(*p))
- die("Invalid %%-specifier '%c'", *p);
- idx = strtol(p, &p, 10) - 1;
- goto again;
- break;
- }
- }
+ switch (*p) {
+ case '\0':
+ goto done; /* skip the final p++ */
+ break;
+ case 'R': /* int register */
+ case 'F': /* float register */
+ case 'M': /* memory */
+ case 'I': /* imm */
+ case 'V': /* reg/mem */
+ case 'U': /* reg/imm */
+ case 'X': /* reg/mem/imm */
+ locprint(fd, insn->args[idx], *p);
+ i++;
+ break;
+ case 'T':
+ fputs(modenames[insn->args[idx]->mode], fd);
+ break;
+ default:
+ /* the asm description uses 1-based indexing, so that 0
+ * can be used as a sentinel. */
+ if (!isdigit(*p))
+ die("Invalid %%-specifier '%c'", *p);
+ idx = strtol(p, &p, 10) - 1;
+ goto again;
+ break;
+ }
+ }
done:
- return;
+ return;
}
static size_t writebytes(FILE *fd, char *name, size_t off, char *p, size_t sz)
{
- size_t i, len;
-
- assert(sz != 0);
- for (i = 0; i < sz; i++) {
- len = min(sz - i, 8);
- if (i % 8 == 0)
- fprintf(fd, "DATA %s+%zd(SB)/%zd,$\"", name, off + i, len);
- if (p[i] == '"' || p[i] == '\\')
- fprintf(fd, "\\");
- if (isprint(p[i]))
- fprintf(fd, "%c", p[i]);
- else
- fprintf(fd, "\\%03o", (uint8_t)p[i] & 0xff);
- /* line wrapping for readability */
- if (i % 8 == 7 || i == sz - 1)
- fprintf(fd, "\"\n");
- }
-
- return sz;
+ size_t i, len;
+
+ assert(sz != 0);
+ for (i = 0; i < sz; i++) {
+ len = min(sz - i, 8);
+ if (i % 8 == 0)
+ fprintf(fd, "DATA %s+%zd(SB)/%zd,$\"", name, off + i, len);
+ if (p[i] == '"' || p[i] == '\\')
+ fprintf(fd, "\\");
+ if (isprint(p[i]))
+ fprintf(fd, "%c", p[i]);
+ else
+ fprintf(fd, "\\%03o", (uint8_t)p[i] & 0xff);
+ /* line wrapping for readability */
+ if (i % 8 == 7 || i == sz - 1)
+ fprintf(fd, "\"\n");
+ }
+
+ return sz;
}
static void genstrings(FILE *fd, Htab *strtab)
{
- void **k;
- char *lbl;
- Str *s;
- size_t i, nk;
-
- k = htkeys(strtab, &nk);
- for (i = 0; i < nk; i++) {
- s = k[i];
- lbl = htget(strtab, k[i]);
- if (s->len) {
- fprintf(fd, "GLOBL %s+0(SB),$%lld\n", lbl, (vlong)s->len);
- writebytes(fd, lbl, 0, s->buf, s->len);
- }
- }
+ void **k;
+ char *lbl;
+ Str *s;
+ size_t i, nk;
+
+ k = htkeys(strtab, &nk);
+ for (i = 0; i < nk; i++) {
+ s = k[i];
+ lbl = htget(strtab, k[i]);
+ if (s->len) {
+ fprintf(fd, "GLOBL %s+0(SB),$%lld\n", lbl, (vlong)s->len);
+ writebytes(fd, lbl, 0, s->buf, s->len);
+ }
+ }
}
static void writeasm(FILE *fd, Isel *s, Func *fn)
{
- size_t i, j;
- char *hidden;
-
- hidden = "";
- if (fn->isexport)
- hidden = "";
- /* we don't use the stack size directive: myrddin handles
- * the stack frobbing on its own */
- fprintf(fd, "TEXT %s%s+0(SB),$0\n", fn->name, hidden);
- for (j = 0; j < s->cfg->nbb; j++) {
- if (!s->bb[j])
- continue;
- for (i = 0; i < s->bb[j]->nlbls; i++)
- fprintf(fd, "%s:\n", s->bb[j]->lbls[i]);
- for (i = 0; i < s->bb[j]->ni; i++)
- iprintf(fd, s->bb[j]->il[i]);
- }
+ size_t i, j;
+ char *hidden;
+
+ hidden = "";
+ if (fn->isexport)
+ hidden = "";
+ /* we don't use the stack size directive: myrddin handles
+ * the stack frobbing on its own */
+ fprintf(fd, "TEXT %s%s+0(SB),$0\n", fn->name, hidden);
+ for (j = 0; j < s->cfg->nbb; j++) {
+ if (!s->bb[j])
+ continue;
+ for (i = 0; i < s->bb[j]->nlbls; i++)
+ fprintf(fd, "%s:\n", s->bb[j]->lbls[i]);
+ for (i = 0; i < s->bb[j]->ni; i++)
+ iprintf(fd, s->bb[j]->il[i]);
+ }
}
static size_t encodemin(FILE *fd, uint64_t val, size_t off, char *lbl)
{
- size_t i, shift, n;
- uint8_t b;
-
- if (val < 128) {
- fprintf(fd, "\tDATA %s+%zd(SB)/1,$%zd\n", lbl, off, val);
- return 1;
- }
-
- for (i = 1; i < 8; i++)
- if (val < 1ULL << (7*i))
- break;
-
- n = 0;
- shift = 8 - i;
- b = ~0 << (shift + 1);
- b |= val & ((1 << (8 - shift)) - 1);
- fprintf(fd, "\tDATA %s+%zd(SB)/1,$%u\n", lbl, off, b);
- val >>= shift;
- while (val != 0) {
- n++;
- fprintf(fd, "\tDATA %s+%zd(SB)/1,$%u\n", lbl, off+n, (uint)val & 0xff);
- val >>= 8;
- }
- return i;
+ size_t i, shift, n;
+ uint8_t b;
+
+ if (val < 128) {
+ fprintf(fd, "\tDATA %s+%zd(SB)/1,$%zd\n", lbl, off, val);
+ return 1;
+ }
+
+ for (i = 1; i < 8; i++)
+ if (val < 1ULL << (7*i))
+ break;
+
+ n = 0;
+ shift = 8 - i;
+ b = ~0 << (shift + 1);
+ b |= val & ((1 << (8 - shift)) - 1);
+ fprintf(fd, "\tDATA %s+%zd(SB)/1,$%u\n", lbl, off, b);
+ val >>= shift;
+ while (val != 0) {
+ n++;
+ fprintf(fd, "\tDATA %s+%zd(SB)/1,$%u\n", lbl, off+n, (uint)val & 0xff);
+ val >>= 8;
+ }
+ return i;
}
static size_t writeblob(FILE *fd, Blob *b, size_t off, char *lbl)
{
- size_t i, n;
-
- n = 0;
- if (!b)
- return 0;
- switch (b->type) {
- case Bti8:
- fprintf(fd, "DATA %s+%zd(SB)/1,$%zd\n", lbl, off+n, b->ival);
- n += 1;
- break;
- case Bti16:
- fprintf(fd, "DATA %s+%zd(SB)/2,$%zd\n", lbl, off+n, b->ival);
- n += 2;
- break;
- case Bti32:
- fprintf(fd, "DATA %s+%zd(SB)/4,$%zd\n", lbl, off+n, b->ival);
- n += 4;
- break;
- case Bti64:
- fprintf(fd, "DATA %s+%zd(SB)/8,$%lld\n", lbl, off+n, (vlong)b->ival);
- n += 8;
- break;
- case Btimin:
- n += encodemin(fd, b->ival, off+n, lbl);
- break;
- case Btref:
- if (b->ref.isextern || b->ref.str[0] == '.')
- 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<>+%zd(SB)\n",
- lbl, off+n, b->ref.str, b->ref.off);
- n += 8;
- break;
- case Btbytes:
- n += writebytes(fd, lbl, off+n, b->bytes.buf, b->bytes.len);
- break;
- case Btseq:
- for (i = 0; i < b->seq.nsub; i++)
- 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;
+ size_t i, n;
+
+ n = 0;
+ if (!b)
+ return 0;
+ switch (b->type) {
+ case Bti8:
+ fprintf(fd, "DATA %s+%zd(SB)/1,$%zd\n", lbl, off+n, b->ival);
+ n += 1;
+ break;
+ case Bti16:
+ fprintf(fd, "DATA %s+%zd(SB)/2,$%zd\n", lbl, off+n, b->ival);
+ n += 2;
+ break;
+ case Bti32:
+ fprintf(fd, "DATA %s+%zd(SB)/4,$%zd\n", lbl, off+n, b->ival);
+ n += 4;
+ break;
+ case Bti64:
+ fprintf(fd, "DATA %s+%zd(SB)/8,$%lld\n", lbl, off+n, (vlong)b->ival);
+ n += 8;
+ break;
+ case Btimin:
+ n += encodemin(fd, b->ival, off+n, lbl);
+ break;
+ case Btref:
+ if (b->ref.isextern || b->ref.str[0] == '.')
+ 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<>+%zd(SB)\n",
+ lbl, off+n, b->ref.str, b->ref.off);
+ n += 8;
+ break;
+ case Btbytes:
+ n += writebytes(fd, lbl, off+n, b->bytes.buf, b->bytes.len);
+ break;
+ case Btseq:
+ for (i = 0; i < b->seq.nsub; i++)
+ 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
@@ -364,116 +364,116 @@ static size_t writeblob(FILE *fd, Blob *b, size_t off, char *lbl)
* 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.envoff = fn->envoff;
- is.globls = globls;
- is.ret = fn->ret;
- is.cfg = fn->cfg;
- if (fn->hasenv)
- is.envp = locreg(ModeQ);
-
- selfunc(&is, fn, globls, strtab);
- if (debugopt['i'])
- writeasm(stdout, &is, fn);
- writeasm(fd, &is, fn);
+ Isel is = {0,};
+
+ is.reglocs = mkht(varhash, vareq);
+ is.stkoff = fn->stkoff;
+ is.envoff = fn->envoff;
+ is.globls = globls;
+ is.ret = fn->ret;
+ is.cfg = fn->cfg;
+ if (fn->hasenv)
+ is.envp = locreg(ModeQ);
+
+ 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;
- char lbl[1024];
-
- if (ty->type == Tyvar)
- return;
- b = tydescblob(ty);
- if (!b)
- return;
- if (b->isglobl) {
- fprintf(fd, "GLOBL %s%s+0(SB),$%zd\n", Symprefix, b->lbl, blobsz(b));
- bprintf(lbl, sizeof lbl, "%s%s", Symprefix, b->lbl);
- } else {
- fprintf(fd, "GLOBL %s%s<>+0(SB),$%zd\n", Symprefix, b->lbl, blobsz(b));
- bprintf(lbl, sizeof lbl, "%s%s<>", Symprefix, b->lbl);
- }
- writeblob(fd, b, 0, lbl);
+ Blob *b;
+ char lbl[1024];
+
+ if (ty->type == Tyvar)
+ return;
+ b = tydescblob(ty);
+ if (!b)
+ return;
+ if (b->isglobl) {
+ fprintf(fd, "GLOBL %s%s+0(SB),$%zd\n", Symprefix, b->lbl, blobsz(b));
+ bprintf(lbl, sizeof lbl, "%s%s", Symprefix, b->lbl);
+ } else {
+ fprintf(fd, "GLOBL %s%s<>+0(SB),$%zd\n", Symprefix, b->lbl, blobsz(b));
+ bprintf(lbl, sizeof lbl, "%s%s<>", Symprefix, b->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);
+ 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)
{
- Htab *globls, *strtab;
- Node *n, **blob;
- Func **fn;
- size_t nfn, nblob;
- size_t i;
- FILE *fd;
-
- /* ensure that all physical registers have a loc created before any
- * other locs, so that locmap[Physreg] maps to the Loc for the physreg
- * in question */
- for (i = 0; i < Nreg; i++)
- locphysreg(i);
-
- fn = NULL;
- nfn = 0;
- blob = NULL;
- nblob = 0;
- globls = mkht(varhash, vareq);
- initconsts(globls);
-
- /* We need to define all global variables before use */
- fillglobls(file->file.globls, globls);
-
- pushstab(file->file.globls);
- for (i = 0; i < file->file.nstmts; i++) {
- n = file->file.stmts[i];
- switch (n->type) {
- case Nuse: /* nothing to do */
- case Nimpl:
- break;
- case Ndecl:
- simpglobl(n, globls, &fn, &nfn, &blob, &nblob);
- break;
- default:
- die("Bad node %s in toplevel", nodestr[n->type]);
- break;
- }
- }
- popstab();
-
- fd = fopen(out, "w");
- if (!fd)
- die("Couldn't open fd %s", out);
-
- strtab = mkht(strlithash, strliteq);
- for (i = 0; i < nblob; i++)
- genblob(fd, blob[i], globls, strtab);
- for (i = 0; i < nfn; i++)
- genfunc(fd, fn[i], globls, strtab);
- for (i = 0; i < ntypes; i++)
- if (types[i]->isreflect && !types[i]->isimport)
- gentype(fd, types[i]);
- fprintf(fd, "\n");
- genstrings(fd, strtab);
-
- fclose(fd);
+ Htab *globls, *strtab;
+ Node *n, **blob;
+ Func **fn;
+ size_t nfn, nblob;
+ size_t i;
+ FILE *fd;
+
+ /* ensure that all physical registers have a loc created before any
+ * other locs, so that locmap[Physreg] maps to the Loc for the physreg
+ * in question */
+ for (i = 0; i < Nreg; i++)
+ locphysreg(i);
+
+ fn = NULL;
+ nfn = 0;
+ blob = NULL;
+ nblob = 0;
+ globls = mkht(varhash, vareq);
+ initconsts(globls);
+
+ /* We need to define all global variables before use */
+ fillglobls(file->file.globls, globls);
+
+ pushstab(file->file.globls);
+ for (i = 0; i < file->file.nstmts; i++) {
+ n = file->file.stmts[i];
+ switch (n->type) {
+ case Nuse: /* nothing to do */
+ case Nimpl:
+ break;
+ case Ndecl:
+ simpglobl(n, globls, &fn, &nfn, &blob, &nblob);
+ break;
+ default:
+ die("Bad node %s in toplevel", nodestr[n->type]);
+ break;
+ }
+ }
+ popstab();
+
+ fd = fopen(out, "w");
+ if (!fd)
+ die("Couldn't open fd %s", out);
+
+ strtab = mkht(strlithash, strliteq);
+ for (i = 0; i < nblob; i++)
+ genblob(fd, blob[i], globls, strtab);
+ for (i = 0; i < nfn; i++)
+ genfunc(fd, fn[i], globls, strtab);
+ for (i = 0; i < ntypes; i++)
+ if (types[i]->isreflect && !types[i]->isimport)
+ gentype(fd, types[i]);
+ fprintf(fd, "\n");
+ genstrings(fd, strtab);
+
+ fclose(fd);
}