shithub: mc

Download patch

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;