ref: 3bbb5e43836cd3ea0df46d6adea3dbedd678785f
parent: 079536dfac30da7db118b8184ec04f0afdd4d461
author: Ori Bernstein <[email protected]>
date: Thu Dec 25 08:46:56 EST 2014
Fix a few more bad asm issues on plan9. Mostly to do with insn naming and symbol visibility.
--- a/6/asm.h
+++ b/6/asm.h
@@ -198,10 +198,11 @@
/* options */
extern int extracheck;
+extern Asmsyntax asmsyntax;
void simpglobl(Node *dcl, Htab *globls, Func ***fn, size_t *nfn, Node ***blob, size_t *nblob);
void selfunc(Isel *is, Func *fn, Htab *globls, Htab *strtab);
-void gen(Asmsyntax syn, Node *file, char *out);
+void gen(Node *file, char *out);
void gengas(Node *file, char *out);
void genp9(Node *file, char *out);
@@ -209,7 +210,8 @@
extern size_t maxregid;
extern Loc **locmap; /* mapping from reg id => Loc * */
-char *genlblstr(char *buf, size_t sz);
+char *gendatalbl(char *buf, size_t sz);
+char *genjmplbl(char *buf, size_t sz);
Node *genlbl(Srcloc loc);
Loc *loclbl(Node *lbl);
Loc *locstrlbl(char *lbl);
@@ -221,7 +223,7 @@
Loc *locmemls(char *disp, Loc *base, Loc *idx, int scale, Mode mode);
Loc *loclit(long val, Mode m);
Loc *loclitl(char *lbl);
-char *asmname(Node *n);
+char *asmname(Node *dcl);
Loc *coreg(Reg r, Mode m);
int isfloatmode(Mode m);
int isintmode(Mode m);
--- a/6/gen.c
+++ b/6/gen.c
@@ -14,9 +14,70 @@
#include "asm.h"
#include "../config.h"
-void gen(Asmsyntax syn, Node *file, char *out)
+
+static int islocal(Node *dcl)
{
- switch (syn) {
+ if (dcl->decl.vis != Visintern)
+ return 0;
+ if (dcl->decl.isimport || dcl->decl.isextern)
+ return 0;
+ return 1;
+}
+
+static int nextlbl;
+char *gendatalbl(char *buf, size_t sz)
+{
+ if (asmsyntax == Plan9)
+ snprintf(buf, 128, ".L%d<>", nextlbl++);
+ else
+ snprintf(buf, 128, ".L%d", nextlbl++);
+ return buf;
+}
+
+char *genjmplbl(char *buf, size_t sz)
+{
+ snprintf(buf, 128, ".L%d", nextlbl++);
+ return buf;
+}
+
+
+/*
+ * For x86, the assembly names are generated as follows:
+ * local symbols: .name
+ * un-namespaced symbols: <symprefix>name
+ * namespaced symbols: <symprefix>namespace$name
+ * local symbols on plan9 have the file-unique suffix '<>' appended
+ */
+char *asmname(Node *dcl)
+{
+ char buf[1024];
+ char *vis, *pf, *ns, *name, *sep;
+ Node *n;
+
+ n = dcl->decl.name;
+ pf = Symprefix;
+ ns = n->name.ns;
+ name = n->name.name;
+ vis = "";
+ sep = "";
+ if (asmsyntax == Plan9)
+ if (islocal(dcl))
+ vis = "<>";
+ if (!ns || !ns[0])
+ ns = "";
+ else
+ sep = "$";
+ if (name[0] == '.')
+ pf = "";
+
+ snprintf(buf, sizeof buf, "%s%s%s%s%s", pf, ns, sep, name, vis);
+ return strdup(buf);
+}
+
+
+void gen(Node *file, char *out)
+{
+ switch (asmsyntax) {
case Plan9: genp9(file, out); break;
case Gnugas: gengas(file, out); break;
default: die("unknown target"); break;
--- a/6/gengas.c
+++ b/6/gengas.c
@@ -48,7 +48,7 @@
k = htkeys(st->dcl, &nk);
for (i = 0; i < nk; i++) {
s = htget(st->dcl, k[i]);
- htput(globls, s, asmname(s->decl.name));
+ htput(globls, s, asmname(s));
}
free(k);
@@ -75,7 +75,7 @@
dcl = mkdecl(Zloc, name, ty);
dcl->decl.isconst = 1;
dcl->decl.isextern = 1;
- htput(globls, dcl, asmname(dcl->decl.name));
+ htput(globls, dcl, asmname(dcl));
abortoob = mkexpr(Zloc, Ovar, name, NULL);
abortoob->expr.type = ty;
@@ -293,7 +293,7 @@
if (hthas(strtab, &v->lit.strval)) {
lbl = htget(strtab, &v->lit.strval);
} else {
- lbl = genlblstr(buf, sizeof buf);
+ lbl = gendatalbl(buf, sizeof buf);
htput(strtab, &v->lit.strval, strdup(lbl));
}
fprintf(fd, "\t.quad %s\n", lbl);
--- a/6/genp9.c
+++ b/6/genp9.c
@@ -49,7 +49,7 @@
k = htkeys(st->dcl, &nk);
for (i = 0; i < nk; i++) {
s = htget(st->dcl, k[i]);
- htput(globls, s, asmname(s->decl.name));
+ htput(globls, s, asmname(s));
}
free(k);
@@ -76,7 +76,7 @@
dcl = mkdecl(Zloc, name, ty);
dcl->decl.isconst = 1;
dcl->decl.isextern = 1;
- htput(globls, dcl, asmname(dcl->decl.name));
+ htput(globls, dcl, asmname(dcl));
abortoob = mkexpr(Zloc, Ovar, name, NULL);
abortoob->expr.type = ty;
@@ -242,12 +242,11 @@
{
size_t i, len;
- if (sz == 0)
- fprintf(fd, "DATA %s<>+%zd(SB)/%zd,$\"\"\n", name, off, sz);
+ 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);
+ fprintf(fd, "DATA %s+%zd(SB)/%zd,$\"", name, off + i, len);
if (p[i] == '"' || p[i] == '\\')
fprintf(fd, "\\");
if (isprint(p[i]))
@@ -299,10 +298,13 @@
if (hthas(strtab, &v->lit.strval)) {
lbl = htget(strtab, &v->lit.strval);
} else {
- lbl = genlblstr(buf, sizeof buf);
+ lbl = gendatalbl(buf, sizeof buf);
htput(strtab, &v->lit.strval, strdup(lbl));
}
- fprintf(fd, "DATA %s+%zd(SB)/8,$%s<>+0(SB)\n", name, off, 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, lbl);
fprintf(fd, "DATA %s+%zd(SB)/8,$%zd\n", name, off+8, v->lit.strval.len);
break;
case Lfunc:
@@ -315,11 +317,16 @@
return sz;
}
-static size_t writepad(FILE *fd, size_t sz)
+static size_t writepad(FILE *fd, char *name, size_t off, size_t sz)
{
+ size_t n;
+
assert((ssize_t)sz >= 0);
- if (sz > 0)
- fprintf(fd, "\t.fill %zd,1,0\n", sz);
+ while (sz > 0) {
+ n = min(sz, 8);
+ fprintf(fd, "DATA %s+%zd(SB)/%zd,$0\n", name, off, n);
+ sz -= n;
+ }
return sz;
}
@@ -374,7 +381,7 @@
ndcl = t->nmemb;
for (i = 0; i < ndcl; i++) {
pad = alignto(off, decltype(dcl[i]));
- off += writepad(fd, pad - off);
+ 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]))) {
@@ -382,10 +389,10 @@
off += writeblob(fd, name, off, globls, strtab, n->expr.args[j]);
}
if (!found)
- off += writepad(fd, size(dcl[i]));
+ off += writepad(fd, name, off, size(dcl[i]));
}
end = alignto(off, t);
- off += writepad(fd, end - off);
+ 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)
@@ -397,7 +404,7 @@
case Oarr:
sz = 0;
for (i = 0; i < n->expr.nargs; i++)
- sz += writeblob(fd, name, off, globls, strtab, n->expr.args[i]);
+ sz += writeblob(fd, name, off + sz, globls, strtab, n->expr.args[i]);
break;
case Ostruct:
sz = writestruct(fd, name, off, globls, strtab, n);
@@ -427,8 +434,10 @@
for (i = 0; i < nk; i++) {
s = k[i];
lbl = htget(strtab, k[i]);
- fprintf(fd, "GLOBL %s<>+0(SB),$%lld\n", lbl, (vlong)s->len);
- writebytes(fd, lbl, 0, s->buf, s->len);
+ if (s->len) {
+ fprintf(fd, "GLOBL %s+0(SB),$%lld\n", lbl, (vlong)s->len);
+ writebytes(fd, lbl, 0, s->buf, s->len);
+ }
}
}
@@ -464,7 +473,7 @@
if (blob->decl.init)
writeblob(fd, lbl, 0, globls, strtab, blob->decl.init);
else
- writepad(fd, size(blob));
+ writepad(fd, lbl, 0, size(blob));
}
/* genfunc requires all nodes in 'nl' to map cleanly to operations that are
--- a/6/insns.def
+++ b/6/insns.def
@@ -169,17 +169,17 @@
/* branch instructions */
Insn(Isetz,
"\tsetz %v\n",
- "\tSETZ %V\n",
+ "\tSETEQ %V\n",
Use(None),
Def(.l={1}))
Insn(Isetnz,
"\tsetnz %v\n",
- "\tSETNZ %V\n",
+ "\tSETNE %V\n",
Use(None),
Def(.l={1}))
Insn(Isetl,
"\tsetl %v\n",
- "\tSETL %V\n",
+ "\tSETLT %V\n",
Use(None),
Def(.l={1}))
Insn(Isetle,
@@ -189,7 +189,7 @@
Def(.l={1}))
Insn(Isetg,
"\tsetg %v\n",
- "\tSETG %V\n",
+ "\tSETGT %V\n",
Use(None),
Def(.l={1}))
Insn(Isetge,
@@ -199,22 +199,22 @@
Def(.l={1}))
Insn(Isetb,
"\tsetb %v\n",
- "\tSETB %V\n",
+ "\tSETCS %V\n",
Use(None),
Def(.l={1}))
Insn(Isetbe,
"\tsetbe %v\n",
- "\tSETBE %V\n",
+ "\tSETLS %V\n",
Use(None),
Def(.l={1}))
Insn(Iseta,
"\tseta %v\n",
- "\tSETA %V\n",
+ "\tSETCC %V\n",
Use(None),
Def(.l={1}))
Insn(Isetae,
"\tsetae %v\n",
- "\tSETAE %V\n",
+ "\tSETHI %V\n",
Use(None),
Def(.l={1}))
@@ -313,7 +313,7 @@
Def(None))
Insn(Ijg,
"\tjg %v\n",
- "\tJG %V\n",
+ "\tJGT %V\n",
Use(.l={1}),
Def(None))
Insn(Ijge,
--- a/6/locs.c
+++ b/6/locs.c
@@ -31,44 +31,11 @@
return m == ModeF || m == ModeD;
}
-/* For x86, the assembly names are generated as follows:
- * local symbols: .name
- * un-namespaced symbols: <symprefix>name
- * namespaced symbols: <symprefix>namespace$name
- */
-char *asmname(Node *n)
-{
- char *s;
- int len;
-
- len = strlen(Symprefix);
- if (n->name.ns)
- len += strlen(n->name.ns) + 1; /* +1 for separator */
- len += strlen(n->name.name) + 1;
-
- s = xalloc(len + 1);
- s[0] = '\0';
- if (n->name.ns)
- snprintf(s, len, "%s%s$%s", Symprefix, n->name.ns, n->name.name);
- else if (n->name.name[0] == '.')
- snprintf(s, len, "%s", n->name.name);
- else
- snprintf(s, len, "%s%s", Symprefix, n->name.name);
- return s;
-}
-
-char *genlblstr(char *buf, size_t sz)
-{
- static int nextlbl;
- snprintf(buf, 128, ".L%d", nextlbl++);
- return buf;
-}
-
Node *genlbl(Srcloc loc)
{
char buf[128];
- genlblstr(buf, 128);
+ genjmplbl(buf, 128);
return mklbl(loc, buf);
}
--- a/6/main.c
+++ b/6/main.c
@@ -27,6 +27,7 @@
char *outfile;
char **incpaths;
size_t nincpaths;
+Asmsyntax asmsyntax;
static void usage(char *prog)
{
@@ -126,7 +127,6 @@
char buf[1024];
Stab *globls;
Optctx ctx;
- Asmsyntax asmsyntax;
size_t i;
optinit(&ctx, "d:hSo:I:9G", argv, argc);
@@ -188,7 +188,7 @@
} else {
gentemp(buf, sizeof buf, ctx.args[i], ".s");
}
- gen(asmsyntax, file, buf);
+ gen(file, buf);
assemble(buf, ctx.args[i]);
genuse(ctx.args[i]);
}
--- a/6/regs.def
+++ b/6/regs.def
@@ -1,15 +1,15 @@
Reg(Rnone, "%NOREG", "NOREG", ModeB)
/* byte regs */
-Reg(Ral, "%al", "AL", ModeB)
-Reg(Rcl, "%cl", "CL", ModeB)
-Reg(Rdl, "%dl", "DL", ModeB)
-Reg(Rbl, "%bl", "BL", ModeB)
-Reg(Rsil, "%sil", "SIL", ModeB)
-Reg(Rdil, "%dil", "DIL", ModeB)
-Reg(Rspl, "%spl", "SPL", ModeB)
-Reg(Rbpl, "%bpl", "BPL", ModeB)
-Reg(Rr8b, "%r8b", "BPL", ModeB)
-Reg(Rr9b, "%r9b", "BPL", ModeB)
+Reg(Ral, "%al", "AL", ModeB)
+Reg(Rcl, "%cl", "CL", ModeB)
+Reg(Rdl, "%dl", "DL", ModeB)
+Reg(Rbl, "%bl", "BL", ModeB)
+Reg(Rsil, "%sil", "SIB", ModeB)
+Reg(Rdil, "%dil", "DIB", ModeB)
+Reg(Rspl, "%spl", "SPB", ModeB)
+Reg(Rbpl, "%bpl", "BPB", ModeB)
+Reg(Rr8b, "%r8b", "R8B", ModeB)
+Reg(Rr9b, "%r9b", "R9B", ModeB)
Reg(Rr10b, "%r10b", "R10", ModeB)
Reg(Rr11b, "%r11b", "R11", ModeB)
Reg(Rr12b, "%r12b", "R12", ModeB)
@@ -79,39 +79,39 @@
Reg(Rr15, "%r15", "R15", ModeQ)
/* floating point registers */
-Reg(Rxmm0f, "%xmm0", "MM0", ModeF)
-Reg(Rxmm1f, "%xmm1", "MM1", ModeF)
-Reg(Rxmm2f, "%xmm2", "MM2", ModeF)
-Reg(Rxmm3f, "%xmm3", "MM3", ModeF)
-Reg(Rxmm4f, "%xmm4", "MM4", ModeF)
-Reg(Rxmm5f, "%xmm5", "MM5", ModeF)
-Reg(Rxmm6f, "%xmm6", "MM6", ModeF)
-Reg(Rxmm7f, "%xmm7", "MM7", ModeF)
-Reg(Rxmm8f, "%xmm8", "MM8", ModeF)
-Reg(Rxmm9f, "%xmm9", "MM9", ModeF)
-Reg(Rxmm10f, "%xmm10", "MM10", ModeF)
-Reg(Rxmm11f, "%xmm11", "MM11", ModeF)
-Reg(Rxmm12f, "%xmm12", "MM12", ModeF)
-Reg(Rxmm13f, "%xmm13", "MM13", ModeF)
-Reg(Rxmm14f, "%xmm14", "MM14", ModeF)
-Reg(Rxmm15f, "%xmm15", "MM15", ModeF)
+Reg(Rxmm0f, "%xmm0", "X0", ModeF)
+Reg(Rxmm1f, "%xmm1", "X1", ModeF)
+Reg(Rxmm2f, "%xmm2", "X2", ModeF)
+Reg(Rxmm3f, "%xmm3", "X3", ModeF)
+Reg(Rxmm4f, "%xmm4", "X4", ModeF)
+Reg(Rxmm5f, "%xmm5", "X5", ModeF)
+Reg(Rxmm6f, "%xmm6", "X6", ModeF)
+Reg(Rxmm7f, "%xmm7", "X7", ModeF)
+Reg(Rxmm8f, "%xmm8", "X8", ModeF)
+Reg(Rxmm9f, "%xmm9", "X9", ModeF)
+Reg(Rxmm10f, "%xmm10", "X10", ModeF)
+Reg(Rxmm11f, "%xmm11", "X11", ModeF)
+Reg(Rxmm12f, "%xmm12", "X12", ModeF)
+Reg(Rxmm13f, "%xmm13", "X13", ModeF)
+Reg(Rxmm14f, "%xmm14", "X14", ModeF)
+Reg(Rxmm15f, "%xmm15", "X15", ModeF)
/* double precision floating point registers */
-Reg(Rxmm0d, "%xmm0", "MM0", ModeD)
-Reg(Rxmm1d, "%xmm1", "MM1", ModeD)
-Reg(Rxmm2d, "%xmm2", "MM2", ModeD)
-Reg(Rxmm3d, "%xmm3", "MM3", ModeD)
-Reg(Rxmm4d, "%xmm4", "MM4", ModeD)
-Reg(Rxmm5d, "%xmm5", "MM5", ModeD)
-Reg(Rxmm6d, "%xmm6", "MM6", ModeD)
-Reg(Rxmm7d, "%xmm7", "MM7", ModeD)
-Reg(Rxmm8d, "%xmm8", "MM8", ModeD)
-Reg(Rxmm9d, "%xmm9", "MM9", ModeD)
-Reg(Rxmm10d, "%xmm10", "MM10", ModeD)
-Reg(Rxmm11d, "%xmm11", "MM11", ModeD)
-Reg(Rxmm12d, "%xmm12", "MM12", ModeD)
-Reg(Rxmm13d, "%xmm13", "MM13", ModeD)
-Reg(Rxmm14d, "%xmm14", "MM14", ModeD)
-Reg(Rxmm15d, "%xmm15", "MM15", ModeD)
+Reg(Rxmm0d, "%xmm0", "X0", ModeD)
+Reg(Rxmm1d, "%xmm1", "X1", ModeD)
+Reg(Rxmm2d, "%xmm2", "X2", ModeD)
+Reg(Rxmm3d, "%xmm3", "X3", ModeD)
+Reg(Rxmm4d, "%xmm4", "X4", ModeD)
+Reg(Rxmm5d, "%xmm5", "X5", ModeD)
+Reg(Rxmm6d, "%xmm6", "X6", ModeD)
+Reg(Rxmm7d, "%xmm7", "X7", ModeD)
+Reg(Rxmm8d, "%xmm8", "X8", ModeD)
+Reg(Rxmm9d, "%xmm9", "X9", ModeD)
+Reg(Rxmm10d, "%xmm10", "X10", ModeD)
+Reg(Rxmm11d, "%xmm11", "X11", ModeD)
+Reg(Rxmm12d, "%xmm12", "X12", ModeD)
+Reg(Rxmm13d, "%xmm13", "X13", ModeD)
+Reg(Rxmm14d, "%xmm14", "X14", ModeD)
+Reg(Rxmm15d, "%xmm15", "X15", ModeD)
Reg(Rrip, "%rip", "PC", ModeQ)
--- a/6/simp.c
+++ b/6/simp.c
@@ -688,7 +688,7 @@
Node *n, *d, *r;
char lbl[128];
- n = mkname(blob->loc, genlblstr(lbl, 128));
+ n = mkname(blob->loc, gendatalbl(lbl, 128));
d = mkdecl(blob->loc, n, blob->expr.type);
r = mkexpr(blob->loc, Ovar, n, NULL);
@@ -1684,6 +1684,16 @@
}
}
+int ismain(Node *dcl)
+{
+ Node *n;
+
+ n = dcl->decl.name;
+ if (n->name.ns)
+ return 0;
+ return strcmp(n->name.name, "main") == 0;
+}
+
void simpglobl(Node *dcl, Htab *globls, Func ***fn, size_t *nfn, Node ***blob, size_t *nblob)
{
Simp s = {0,};
@@ -1690,11 +1700,13 @@
char *name;
Func *f;
- name = asmname(dcl->decl.name);
+ if (ismain(dcl))
+ dcl->decl.vis = Vishidden;
s.stkoff = mkht(varhash, vareq);
s.globls = globls;
s.blobs = *blob;
s.nblobs = *nblob;
+ name = asmname(dcl);
if (dcl->decl.isextern || dcl->decl.isgeneric)
return;