ref: 24a3d753f2ac998c0b10579191984d79cfed0b7d
parent: 008887ccd998a43db6980fa57f1e210ec26c4acf
author: Ori Bernstein <[email protected]>
date: Sat Dec 13 18:21:11 EST 2014
Add plan9 instruction formats. Work towards a plan9 port. This commit also fixes a bug with strings that contain '\0'. The commits got tangled, and I'm too lazy to detangle them.
--- a/6/asm.h
+++ b/6/asm.h
@@ -14,7 +14,7 @@
typedef struct Asmbb Asmbb;
typedef enum {
-#define Insn(val, fmt, use, def) val,
+#define Insn(val, gasfmt, p9fmt, use, def) val,
#include "insns.def"
#undef Insn
} AsmOp;
--- a/6/gen.c
+++ b/6/gen.c
@@ -15,13 +15,19 @@
#include "../config.h"
/* string tables */
-char *insnfmts[] = {
-#define Insn(val, fmt, use, def) fmt,
+char *gasinsnfmt[] = {
+#define Insn(val, gasfmt, p9fmt, use, def) gasfmt,
#include "insns.def"
#undef Insn
};
-char* modenames[] = {
+char *p9insnfmt[] = {
+#define Insn(val, gasfmt, p9fmt, use, def) p9fmt,
+#include "insns.def"
+#undef Insn
+};
+
+char* gasmodenames[] = {
[ModeB] = "b",
[ModeW] = "w",
[ModeL] = "l",
@@ -30,6 +36,14 @@
[ModeD] = "d"
};
+char* p9modenames[] = {
+ [ModeB] = "B",
+ [ModeW] = "W",
+ [ModeL] = "L",
+ [ModeQ] = "Q",
+ [ModeF] = "S",
+ [ModeD] = "D"
+};
static size_t writeblob(FILE *fd, Htab *globls, Htab *strtab, Node *blob);
@@ -78,8 +92,42 @@
abortoob->expr.isconst = 1;
}
+void gasprintmem(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) {
+ fprintf(fd, "(");
+ locprint(fd, l->mem.base, 'r');
+ if (l->mem.idx) {
+ fprintf(fd, ",");
+ locprint(fd, l->mem.idx, 'r');
+ }
+ if (l->mem.scale > 1)
+ fprintf(fd, ",%d", l->mem.scale);
+ if (l->mem.base)
+ fprintf(fd, ")");
+ } else if (l->type != Locmeml) {
+ die("Only locmeml can have unspecified base reg");
+ }
+}
+
+void p9printmem(FILE *fd, Loc *l, char spec)
+{
+ gasprintmem(fd, l, spec);
+}
+
void locprint(FILE *fd, Loc *l, char spec)
{
+ int isp9;
+
+ isp9 = isupper(spec);
+ spec = tolower(spec);
assert(l->mode);
switch (l->type) {
case Loclitl:
@@ -97,7 +145,7 @@
spec == 'x' ||
spec == 'u');
if (l->reg.colour == Rnone)
- fprintf(fd, "%%P.%zd%s", l->reg.id, modenames[l->mode]);
+ fprintf(fd, "%%P.%zd%s", l->reg.id, gasmodenames[l->mode]);
else
fprintf(fd, "%s", regnames[l->reg.colour]);
break;
@@ -104,27 +152,10 @@
case Locmem:
case Locmeml:
assert(spec == 'm' || spec == 'v' || spec == 'x');
- 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) {
- fprintf(fd, "(");
- locprint(fd, l->mem.base, 'r');
- if (l->mem.idx) {
- fprintf(fd, ",");
- locprint(fd, l->mem.idx, 'r');
- }
- if (l->mem.scale > 1)
- fprintf(fd, ",%d", l->mem.scale);
- if (l->mem.base)
- fprintf(fd, ")");
- } else if (l->type != Locmeml) {
- die("Only locmeml can have unspecified base reg");
- }
+ if (isp9)
+ p9printmem(fd, l, spec);
+ else
+ gasprintmem(fd, l, spec);
break;
case Loclit:
assert(spec == 'i' || spec == 'x' || spec == 'u');
@@ -184,7 +215,7 @@
default:
break;
}
- p = insnfmts[insn->op];
+ p = insnfmt[insn->op];
i = 0;
modeidx = 0;
for (; *p; p++) {
@@ -208,7 +239,18 @@
locprint(fd, insn->args[i], *p);
i++;
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[i], *p);
+ i++;
+ break;
case 't':
+ case 'T':
default:
/* the asm description uses 1-based indexing, so that 0
* can be used as a sentinel. */
@@ -216,7 +258,9 @@
modeidx = strtol(p, &p, 10) - 1;
if (*p == 't')
- fputs(modenames[insn->args[modeidx]->mode], fd);
+ fputs(gasmodenames[insn->args[modeidx]->mode], fd);
+ else if (*p == 'T')
+ fputs(p9modenames[insn->args[modeidx]->mode], fd);
else
die("Invalid %%-specifier '%c'", *p);
break;
@@ -280,14 +324,14 @@
}
break;
case Lstr:
- if (hthas(strtab, v->lit.strval)) {
- lbl = htget(strtab, v->lit.strval);
+ if (hthas(strtab, &v->lit.strval)) {
+ lbl = htget(strtab, &v->lit.strval);
} else {
lbl = genlblstr(buf, sizeof buf);
- htput(strtab, v->lit.strval, strdup(lbl));
+ htput(strtab, &v->lit.strval, strdup(lbl));
}
fprintf(fd, "\t.quad %s\n", lbl);
- fprintf(fd, "\t.quad %zd\n", strlen(v->lit.strval));
+ fprintf(fd, "\t.quad %zd\n", v->lit.strval.len);
break;
case Lfunc:
die("Generating this shit ain't ready yet ");
@@ -403,12 +447,14 @@
void genstrings(FILE *fd, Htab *strtab)
{
void **k;
+ Str *s;
size_t i, nk;
k = htkeys(strtab, &nk);
for (i = 0; i < nk; i++) {
+ s = k[i];
fprintf(fd, "%s:\n", (char*)htget(strtab, k[i]));
- writebytes(fd, k[i], strlen(k[i]));
+ writebytes(fd, s->buf, s->len);
}
}
@@ -512,7 +558,7 @@
if (!fd)
die("Couldn't open fd %s", out);
- strtab = mkht(strhash, streq);
+ strtab = mkht(strlithash, strliteq);
fprintf(fd, ".data\n");
for (i = 0; i < nblob; i++)
genblob(fd, blob[i], globls, strtab);
--- a/6/insns.def
+++ b/6/insns.def
@@ -13,86 +13,343 @@
preceeding it is the operand desired for
the mode.
Currently, there aren't any attrs, because none were needed yet.
- Eventually, they'll probably include flag setting and so on.
+ Eventually, they'll probably include flag setting and so on. The
+ upper case versions of these indicate Plan9 location formatting.
For technical reasons, the indexing on use and def statments is 1-based,
instead of 0-based. (0 is the sentinel value).
*/
#define None .l={0},.r={0}
-Insn(Inone, "BAD_INSN", Use(None), Def(None))
+Insn(Inone,
+ "BAD_INSN",
+ "BAD_INSN",
+ Use(None),
+ Def(None))
/* Note, the mov instruction is specified in an overly general manner. */
-Insn(Imov, "\tmov%t %x,%x\n", Use(.l={1}), Def(.l={2}))
-Insn(Imovt, "PSEUDO: TRUNCATE\n", Use(.l={1}), Def(.l={2}))
-Insn(Imovzx, "\tmovz%1t%2t %x,%x\n", Use(.l={1}), Def(.l={2}))
-Insn(Imovsx, "\tmovs%1t%2t %x,%x\n", Use(.l={1}), Def(.l={2}))
-Insn(Irepmovsb, "\trep movsb\n", Use(.r={Rrcx,Rrsi,Rrdi}), Def(None))
-Insn(Irepmovsw, "\trep movsw\n", Use(.r={Rrcx,Rrsi,Rrdi}), Def(None))
-Insn(Irepmovsl, "\trep movsl\n", Use(.r={Rrcx,Rrsi,Rrdi}), Def(None))
-Insn(Irepmovsq, "\trep movsq\n", Use(.r={Rrcx,Rrsi,Rrdi}), Def(None))
-Insn(Ilea, "\tlea%2t %m,%r\n", Use(.l={1}), Def(.l={2}))
+Insn(Imov,
+ "\tmov%t %x,%x\n",
+ "\tMOV%t %X,%X\n",
+ Use(.l={1}),
+ Def(.l={2}))
+Insn(Imovt,
+ "PSEUDO: TRUNCATE\n",
+ "PSEUDO: TRUNCATE\n",
+ Use(.l={1}),
+ Def(.l={2}))
+Insn(Imovzx,
+ "\tmovz%1t%2t %x,%x\n",
+ "\tMOVZ%1t%2t %X,%X\n",
+ Use(.l={1}),
+ Def(.l={2}))
+Insn(Imovsx,
+ "\tmovs%1t%2t %x,%x\n",
+ "\tMOVS%1T%2T %X,%X\n",
+ Use(.l={1}),
+ Def(.l={2}))
+Insn(Irepmovsb,
+ "\trep movsb\n",
+ "\tREP MOVSB\n",
+ Use(.r={Rrcx,Rrsi,Rrdi}),
+ Def(None))
+Insn(Irepmovsw,
+ "\trep movsw\n",
+ "\tREP MOVSW\n",
+ Use(.r={Rrcx,Rrsi,Rrdi}),
+ Def(None))
+Insn(Irepmovsl,
+ "\trep movsl\n",
+ "\tREP MOVSL\n",
+ Use(.r={Rrcx,Rrsi,Rrdi}),
+ Def(None))
+Insn(Irepmovsq,
+ "\trep movsq\n",
+ "\tREP MOVSQ\n",
+ Use(.r={Rrcx,Rrsi,Rrdi}),
+ Def(None))
+Insn(Ilea,
+ "\tlea%2t %m,%r\n",
+ "\tLEA%2T %M,%R\n",
+ Use(.l={1}),
+ Def(.l={2}))
-Insn(Iadd, "\tadd%t %x,%r\n", Use(.l={1,2}), Def(.l={2}))
-Insn(Isub, "\tsub%t %x,%r\n", Use(.l={1,2}), Def(.l={2}))
-Insn(Iimul, "\timul%t %x,%r\n", Use(.l={1,2}), Def(.l={2}))
+Insn(Iadd,
+ "\tadd%t %x,%r\n",
+ "\tADD%T %X,%R\n",
+ Use(.l={1,2}),
+ Def(.l={2}))
+Insn(Isub,
+ "\tsub%t %x,%r\n",
+ "\tSUB%T %X,%R\n",
+ Use(.l={1,2}),
+ Def(.l={2}))
+Insn(Iimul,
+ "\timul%t %x,%r\n",
+ "\tIMUL%T %X,%R\n",
+ Use(.l={1,2}),
+ Def(.l={2}))
/* there is no imul for 8 bit values. */
-Insn(Iimul_r, "\timul%t %r\n", Use(.l={1},.r={Ral}), Def(.r={Rax}))
-Insn(Imul, "\tmul%t %r\n", Use(.l={1},.r={Reax}), Def(.r={Reax,Redx}))
-Insn(Idiv, "\tdiv%t %r\n", Use(.l={1},.r={Reax,Redx}), Def(.r={Reax,Redx}))
-Insn(Ineg, "\tneg%t %r\n", Use(.l={1}), Def(.l={1}))
-Insn(Iand, "\tand%t %x,%r\n", Use(.l={1,2}), Def(.l={2}))
-Insn(Ior, "\tor%t %x,%r\n", Use(.l={1,2}), Def(.l={2}))
-Insn(Ixor, "\txor%t %x,%r\n", Use(.l={1,2}), Def(.l={2}))
-Insn(Inot, "\tnot%t %v\n", Use(.l={1}), Def(.l={1}))
-Insn(Ishl, "\tsal%2t %u,%r\n", Use(.l={1,2}), Def(.l={2}))
-Insn(Isar, "\tsar%2t %u,%r\n", Use(.l={1,2}), Def(.l={2}))
-Insn(Ishr, "\tshr%2t %u,%r\n", Use(.l={1,2}), Def(.l={2}))
+Insn(Iimul_r,
+ "\timul%t %r\n",
+ "\tIMUL%T %R\n",
+ Use(.l={1},.r={Ral}),
+ Def(.r={Rax}))
+Insn(Imul,
+ "\tmul%t %r\n",
+ "\tMUL%T %R\n",
+ Use(.l={1},.r={Reax}),
+ Def(.r={Reax,Redx}))
+Insn(Idiv,
+ "\tdiv%t %r\n",
+ "\tDIV%T %R\n",
+ Use(.l={1},.r={Reax,Redx}),
+ Def(.r={Reax,Redx}))
+Insn(Ineg,
+ "\tneg%t %r\n",
+ "\tNEG%T %R\n",
+ Use(.l={1}),
+ Def(.l={1}))
+Insn(Iand,
+ "\tand%t %x,%r\n",
+ "\tAND%T %X,%R\n",
+ Use(.l={1,2}),
+ Def(.l={2}))
+Insn(Ior,
+ "\tor%t %x,%r\n",
+ "\tOR%T %X,%R\n",
+ Use(.l={1,2}),
+ Def(.l={2}))
+Insn(Ixor,
+ "\txor%t %x,%r\n",
+ "\tXOR%T %X,%R\n",
+ Use(.l={1,2}),
+ Def(.l={2}))
+Insn(Inot,
+ "\tnot%t %v\n",
+ "\tNOT%T %V\n",
+ Use(.l={1}),
+ Def(.l={1}))
+Insn(Ishl,
+ "\tsal%2t %u,%r\n",
+ "\tSAL%2T %U,%R\n",
+ Use(.l={1,2}),
+ Def(.l={2}))
+Insn(Isar,
+ "\tsar%2t %u,%r\n",
+ "\tSAR%2T %U,%R\n",
+ Use(.l={1,2}),
+ Def(.l={2}))
+Insn(Ishr,
+ "\tshr%2t %u,%r\n",
+ "\tSHR%2T %U,%R\n",
+ Use(.l={1,2}),
+ Def(.l={2}))
-Insn(Itest, "\ttest%t %x,%r\n", Use(.l={1,2}), Def(None))
-Insn(Icmp, "\tcmp%t %x,%r\n", Use(.l={1,2}), Def(None))
+Insn(Itest,
+ "\ttest%t %x,%r\n",
+ "\tTEST%T %X,%R\n",
+ Use(.l={1,2}),
+ Def(None))
+Insn(Icmp,
+ "\tcmp%t %x,%r\n",
+ "\tCMP%T %X,%R\n",
+ Use(.l={1,2}),
+ Def(None))
-Insn(Ipush, "\tpush%t %r\n", Use(.l={1}), Def(None))
-Insn(Ipop, "\tpop%t %r\n", Use(.l={1}), Def(None))
+Insn(Ipush,
+ "\tpush%t %r\n",
+ "\tPUSH%T %R\n",
+ Use(.l={1}),
+ Def(None))
+Insn(Ipop,
+ "\tpop%t %r\n",
+ "\tPOP%T %R\n",
+ Use(.l={1}),
+ Def(None))
/* branch instructions */
-Insn(Isetz, "\tsetz %v\n", Use(None), Def(.l={1}))
-Insn(Isetnz, "\tsetnz %v\n", Use(None), Def(.l={1}))
-Insn(Isetl, "\tsetl %v\n", Use(None), Def(.l={1}))
-Insn(Isetle, "\tsetle %v\n", Use(None), Def(.l={1}))
-Insn(Isetg, "\tsetg %v\n", Use(None), Def(.l={1}))
-Insn(Isetge, "\tsetge %v\n", Use(None), Def(.l={1}))
-Insn(Isetb, "\tsetb %v\n", Use(None), Def(.l={1}))
-Insn(Isetbe, "\tsetbe %v\n", Use(None), Def(.l={1}))
-Insn(Iseta, "\tseta %v\n", Use(None), Def(.l={1}))
-Insn(Isetae, "\tsetae %v\n", Use(None), Def(.l={1}))
+Insn(Isetz,
+ "\tsetz %v\n",
+ "\tSETZ %V\n",
+ Use(None),
+ Def(.l={1}))
+Insn(Isetnz,
+ "\tsetnz %v\n",
+ "\tSETNZ %V\n",
+ Use(None),
+ Def(.l={1}))
+Insn(Isetl,
+ "\tsetl %v\n",
+ "\tSETL %V\n",
+ Use(None),
+ Def(.l={1}))
+Insn(Isetle,
+ "\tsetle %v\n",
+ "\tSETLE %V\n",
+ Use(None),
+ Def(.l={1}))
+Insn(Isetg,
+ "\tsetg %v\n",
+ "\tSETG %V\n",
+ Use(None),
+ Def(.l={1}))
+Insn(Isetge,
+ "\tsetge %v\n",
+ "\tSETGE %V\n",
+ Use(None),
+ Def(.l={1}))
+Insn(Isetb,
+ "\tsetb %v\n",
+ "\tSETB %V\n",
+ Use(None),
+ Def(.l={1}))
+Insn(Isetbe,
+ "\tsetbe %v\n",
+ "\tSETBE %V\n",
+ Use(None),
+ Def(.l={1}))
+Insn(Iseta,
+ "\tseta %v\n",
+ "\tSETA %V\n",
+ Use(None),
+ Def(.l={1}))
+Insn(Isetae,
+ "\tsetae %v\n",
+ "\tSETAE %V\n",
+ Use(None),
+ Def(.l={1}))
/* fp specific instructions */
-Insn(Imovs, "\tmovs%1t %x,%x\n", Use(.l={1}), Def(.l={2}))
-Insn(Icvttsd2si, "\tcvttsd2si%2t %x,%r\n", Use(.l={1}), Def(.l={2}))
-Insn(Icvttsi2sd, "\tcvttsi2sd%2t %x,%f\n", Use(.l={1}), Def(.l={2}))
-Insn(Icvttsd2ss, "\tcvtsd2ss %x,%f\n", Use(.l={1}), Def(.l={2}))
-Insn(Icvttss2sd, "\tcvtss2sd %x,%f\n", Use(.l={1}), Def(.l={2}))
-Insn(Iadds, "\tadds%t %x,%f\n", Use(.l={1,2}), Def(.l={2}))
-Insn(Isubs, "\tsubs%t %x,%f\n", Use(.l={1,2}), Def(.l={2}))
-Insn(Imuls, "\tmuls%t %x,%f\n", Use(.l={1,2}), Def(.l={2}))
-Insn(Idivs, "\tdivs%t %x,%f\n", Use(.l={1,2}), Def(.l={2}))
-Insn(Icomis, "\tcomis%t %x,%f\n", Use(.l={1,2}), Def(None))
-Insn(Ixorp, "\tmuls%t %x,%f\n", Use(.l={1,2}), Def(.l={2}))
+Insn(Imovs,
+ "\tmovs%1t %x,%x\n",
+ "\tMOVS%1T %X,%X\n",
+ Use(.l={1}),
+ Def(.l={2}))
+Insn(Icvttsd2si,
+ "\tcvttsd2si%2t %x,%r\n",
+ "\tCVTTSD2SI%2T %X,%R\n",
+ Use(.l={1}),
+ Def(.l={2}))
+Insn(Icvttsi2sd,
+ "\tcvttsi2sd%2t %x,%f\n",
+ "\tCVTTSI2SD%2T %X,%F\n",
+ Use(.l={1}),
+ Def(.l={2}))
+Insn(Icvttsd2ss,
+ "\tcvtsd2ss %x,%f\n",
+ "\tCVTSD2SS %X,%F\n",
+ Use(.l={1}),
+ Def(.l={2}))
+Insn(Icvttss2sd,
+ "\tcvtss2sd %x,%f\n",
+ "\tCVTSS2SD %X,%F\n",
+ Use(.l={1}),
+ Def(.l={2}))
+Insn(Iadds,
+ "\tadds%t %x,%f\n",
+ "\tADDS%T %X,%F\n",
+ Use(.l={1,2}),
+ Def(.l={2}))
+Insn(Isubs,
+ "\tsubs%t %x,%f\n",
+ "\tSUBS%T %X,%F\n",
+ Use(.l={1,2}),
+ Def(.l={2}))
+Insn(Imuls,
+ "\tmuls%t %x,%f\n",
+ "\tMULS%T %X,%F\n",
+ Use(.l={1,2}),
+ Def(.l={2}))
+Insn(Idivs,
+ "\tdivs%t %x,%f\n",
+ "\tDIVS%T %X,%F\n",
+ Use(.l={1,2}),
+ Def(.l={2}))
+Insn(Icomis,
+ "\tcomis%t %x,%f\n",
+ "\tCOMIS%T %X,%F\n",
+ Use(.l={1,2}),
+ Def(None))
+Insn(Ixorp,
+ "\tmuls%t %x,%f\n",
+ "\tMULS%T %X,%F\n",
+ Use(.l={1,2}),
+ Def(.l={2}))
/* branch instructions */
-Insn(Icall, "\tcall %v\n", Use(.l={1}), Def(.r={Rrax,Reax,Rax,Ral,Rah}))
-Insn(Icallind, "\tcall *%v\n", Use(.l={1}), Def(.r={Rrax,Reax,Rax,Ral,Rah}))
-Insn(Ijmp, "\tjmp %v\n", Use(.l={1}), Def(None))
-Insn(Ijz, "\tjz %v\n", Use(.l={1}), Def(None))
-Insn(Ijnz, "\tjnz %v\n", Use(.l={1}), Def(None))
-Insn(Ijl, "\tjl %v\n", Use(.l={1}), Def(None))
-Insn(Ijle, "\tjle %v\n", Use(.l={1}), Def(None))
-Insn(Ijg, "\tjg %v\n", Use(.l={1}), Def(None))
-Insn(Ijge, "\tjge %v\n", Use(.l={1}), Def(None))
-Insn(Ijb, "\tjb %v\n", Use(.l={1}), Def(None))
-Insn(Ijbe, "\tjbe %v\n", Use(.l={1}), Def(None))
-Insn(Ija, "\tja %v\n", Use(.l={1}), Def(None))
-Insn(Ijae, "\tjae %v\n", Use(.l={1}), Def(None))
-Insn(Iret, "\tret\n", Use(.r={Rrax,Rxmm0d}), Def(None))
+Insn(Icall,
+ "\tcall %v\n",
+ "\tCALL %V\n",
+ Use(.l={1}),
+ Def(.r={Rrax,Reax,Rax,Ral,Rah}))
+Insn(Icallind,
+ "\tcall *%v\n",
+ "\tCALL *%V\n",
+ Use(.l={1}),
+ Def(.r={Rrax,Reax,Rax,Ral,Rah}))
+Insn(Ijmp,
+ "\tjmp %v\n",
+ "\tJMP %V\n",
+ Use(.l={1}),
+ Def(None))
+Insn(Ijz,
+ "\tjz %v\n",
+ "\tJZ %V\n",
+ Use(.l={1}),
+ Def(None))
+Insn(Ijnz,
+ "\tjnz %v\n",
+ "\tJNZ %V\n",
+ Use(.l={1}),
+ Def(None))
+Insn(Ijl,
+ "\tjl %v\n",
+ "\tJL %V\n",
+ Use(.l={1}),
+ Def(None))
+Insn(Ijle,
+ "\tjle %v\n",
+ "\tJLE %V\n",
+ Use(.l={1}),
+ Def(None))
+Insn(Ijg,
+ "\tjg %v\n",
+ "\tJG %V\n",
+ Use(.l={1}),
+ Def(None))
+Insn(Ijge,
+ "\tjge %v\n",
+ "\tJGE %V\n",
+ Use(.l={1}),
+ Def(None))
+Insn(Ijb,
+ "\tjb %v\n",
+ "\tJB %V\n",
+ Use(.l={1}),
+ Def(None))
+Insn(Ijbe,
+ "\tjbe %v\n",
+ "\tJBE %V\n",
+ Use(.l={1}),
+ Def(None))
+Insn(Ija,
+ "\tja %v\n",
+ "\tJA %V\n",
+ Use(.l={1}),
+ Def(None))
+Insn(Ijae,
+ "\tjae %v\n",
+ "\tJAE %V\n",
+ Use(.l={1}),
+ Def(None))
+Insn(Iret,
+ "\tret\n",
+ "\tRET\n",
+ Use(.r={Rrax,Rxmm0d}),
+ Def(None))
/* not really an insn... */
-Insn(Ilbl, "%v:\n", Use(None), Def(None))
+Insn(Ilbl,
+ "%v:\n",
+ "%V:\n",
+ Use(None),
+ Def(None))
--- a/6/main.c
+++ b/6/main.c
@@ -23,6 +23,7 @@
char debugopt[128];
int writeasm;
int extracheck;
+int p9asm;
char *outfile;
char **incpaths;
size_t nincpaths;
--- a/6/ra.c
+++ b/6/ra.c
@@ -26,7 +26,7 @@
Usemap usetab[] = {
#define Def(...)
#define Use(...) {__VA_ARGS__}
-#define Insn(i, fmt, use, def) use,
+#define Insn(i, gasfmt, p9fmt, use, def) use,
#include "insns.def"
#undef Insn
#undef Use
@@ -36,7 +36,7 @@
Usemap deftab[] = {
#define Use(...)
#define Def(...) {__VA_ARGS__}
-#define Insn(i, fmt, use, def) def,
+#define Insn(i, gasfmt, p9fmt, use, def) def,
#include "insns.def"
#undef Insn
#undef Def
--- a/6/simp.c
+++ b/6/simp.c
@@ -567,12 +567,12 @@
lit = pat->expr.args[0];
if (exprop(pat) != Olit || lit->lit.littype != Lstr)
die("Unsupported pattern");
- str = lit->lit.strval;
+ str = lit->lit.strval.buf;
+ len = lit->lit.strval.len;
/* load slice length */
next = genlbl(pat->loc);
x = slicelen(s, val);
- len = strlen(str);
y = mkintlit(lit->loc, len);
y->expr.type = tyintptr;
v = mkexpr(pat->loc, Oeq, x, y, NULL);
--- a/configure
+++ b/configure
@@ -39,16 +39,19 @@
*Linux*)
echo '#define Asmcmd {"as", "-g", "-o", NULL}' >> config.h
echo '#define Symprefix ""' >> config.h
+ echo '#define insnfmt gasinsnfmt' >> config.h
echo 'export SYS=linux' >> config.mk
;;
*Darwin*)
echo '#define Asmcmd {"as", "-g", "-o", NULL}' >> config.h
echo '#define Symprefix "_"' >> config.h
+ echo '#define insnfmt gasinsnfmt' >> config.h
echo 'export SYS=osx' >> config.mk
;;
*FreeBSD*)
echo '#define Asmcmd {"as", "-g", "-o", NULL}' >> config.h
echo '#define Symprefix ""' >> config.h
+ echo '#define insnfmt gasinsnfmt' >> config.h
echo 'export SYS=freebsd' >> config.mk
;;
*)
--- a/parse/dump.c
+++ b/parse/dump.c
@@ -202,7 +202,7 @@
case Lbool: fprintf(fd, " Lbool %s\n", n->lit.boolval ? "true" : "false"); break;
case Lint: fprintf(fd, " Lint %llu\n", n->lit.intval); break;
case Lflt: fprintf(fd, " Lflt %lf\n", n->lit.fltval); break;
- case Lstr: fprintf(fd, " Lstr %s\n", n->lit.strval); break;
+ case Lstr: fprintf(fd, " Lstr %s\n", n->lit.strval.buf); break;
case Llbl: fprintf(fd, " Llbl %s\n", n->lit.lblval); break;
case Lfunc:
fprintf(fd, " Lfunc\n");
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -253,7 +253,7 @@
attrs : /* empty */ {$$.nstr = 0; $$.str = NULL;}
| Tattr attrs {
$$ = $2;
- lappend(&$$.str, &$$.nstr, strdup($1->str));
+ lappend(&$$.str, &$$.nstr, strdup($1->id));
}
;
@@ -267,8 +267,8 @@
}
;
-use : Tuse Tident {$$ = mkuse($1->loc, $2->str, 0);}
- | Tuse Tstrlit {$$ = mkuse($1->loc, $2->str, 1);}
+use : Tuse Tident {$$ = mkuse($1->loc, $2->id, 0);}
+ | Tuse Tstrlit {$$ = mkuse($1->loc, $2->strval.buf, 1);}
;
optident: Tident {$$ = $1;}
@@ -279,8 +279,8 @@
if (file->file.exports->name)
lfatal($1->loc, "Package already declared\n");
if ($2) {
- updatens(file->file.exports, $2->str);
- updatens(file->file.globls, $2->str);
+ updatens(file->file.exports, $2->id);
+ updatens(file->file.globls, $2->id);
}
}
;
@@ -339,8 +339,8 @@
: name Tcolon type {$$ = mkdecl($1->loc, $1, $3);}
;
-name : Tident {$$ = mkname($1->loc, $1->str);}
- | Tident Tdot name {$$ = $3; setns($3, $1->str);}
+name : Tident {$$ = mkname($1->loc, $1->id);}
+ | Tident Tdot name {$$ = $3; setns($3, $1->id);}
;
implstmt: Timpl name type {
@@ -357,7 +357,7 @@
| implbody Tident Tasn exprln optendlns {
Node *d;
$$ = $1;
- d = mkdecl($2->loc, mkname($2->loc, $2->str), mktyvar($2->loc));
+ d = mkdecl($2->loc, mkname($2->loc, $2->id), mktyvar($2->loc));
d->decl.init = $4;
d->decl.isconst = 1;
lappend(&$$.nl, &$$.nn, d);
@@ -365,11 +365,11 @@
;
traitdef: Ttrait Tident generictype /* trait prototype */ {
- $$ = mktrait($1->loc, mkname($2->loc, $2->str), $3, NULL, 0, NULL, 0, 1);
+ $$ = mktrait($1->loc, mkname($2->loc, $2->id), $3, NULL, 0, NULL, 0, 1);
}
| Ttrait Tident generictype Tasn traitbody Tendblk /* trait definition */ {
size_t i;
- $$ = mktrait($1->loc, mkname($2->loc, $2->str), $3, NULL, 0, $5.nl, $5.nn, 0);
+ $$ = mktrait($1->loc, mkname($2->loc, $2->id), $3, NULL, 0, $5.nl, $5.nn, 0);
for (i = 0; i < $5.nn; i++) {
$5.nl[i]->decl.trait = $$;
$5.nl[i]->decl.isgeneric = 1;
@@ -382,7 +382,7 @@
| traitbody Tident Tcolon type optendlns {
Node *d;
$$ = $1;
- d = mkdecl($2->loc, mkname($2->loc, $2->str), $4);
+ d = mkdecl($2->loc, mkname($2->loc, $2->id), $4);
d->decl.isgeneric = 1;
lappend(&$$.nl, &$$.nn, d);
}
@@ -398,13 +398,13 @@
typeid : Tident {
$$.loc = $1->loc;
- $$.name = $1->str;
+ $$.name = $1->id;
$$.params = NULL;
$$.type = NULL;
}
| Tident Toparen typarams Tcparen {
$$.loc = $1->loc;
- $$.name = $1->str;
+ $$.name = $1->id;
$$.params = $3.types;
$$.nparams = $3.ntypes;
$$.type = NULL;
@@ -427,14 +427,14 @@
;
generictype
- : Ttyparam {$$ = mktyparam($1->loc, $1->str);}
+ : Ttyparam {$$ = mktyparam($1->loc, $1->id);}
| Ttyparam Twith name {
- $$ = mktyparam($1->loc, $1->str);
+ $$ = mktyparam($1->loc, $1->id);
addtrait($$, $3->name.name);
}
| Ttyparam Twith Toparen typaramlist Tcparen {
size_t i;
- $$ = mktyparam($1->loc, $1->str);
+ $$ = mktyparam($1->loc, $1->id);
for (i = 0; i < $4.nn; i++)
addtrait($$, $4.nl[i]->name.name);
}
@@ -453,7 +453,7 @@
| type Tosqbrac Tcolon Tcsqbrac {$$ = mktyslice($2->loc, $1);}
| type Tosqbrac expr Tcsqbrac {$$ = mktyarray($2->loc, $1, $3);}
| type Tderef {$$ = mktyptr($2->loc, $1);}
- | Tat Tident {$$ = mktyparam($1->loc, $2->str);}
+ | Tat Tident {$$ = mktyparam($1->loc, $2->id);}
| name {$$ = mktyunres($1->loc, $1, NULL, 0);}
| name Toparen typelist Tcparen {$$ = mktyunres($1->loc, $1, $3.types, $3.ntypes);}
;
@@ -539,7 +539,7 @@
| Tendln {$$ = NULL;}
;
-goto : Tgoto Tident {$$ = mkexpr($1->loc, Ojmp, mklbl($2->loc, $2->str), NULL);}
+goto : Tgoto Tident {$$ = mkexpr($1->loc, Ojmp, mklbl($2->loc, $2->id), NULL);}
;
retexpr : Tret expr {$$ = mkexpr($1->loc, Oret, $2, NULL);}
@@ -659,7 +659,7 @@
postfixexpr
: postfixexpr Tdot Tident
- {$$ = mkexpr($1->loc, Omemb, $1, mkname($3->loc, $3->str), NULL);}
+ {$$ = mkexpr($1->loc, Omemb, $1, mkname($3->loc, $3->id), NULL);}
| postfixexpr Tinc
{$$ = mkexpr($1->loc, Opostinc, $1, NULL);}
| postfixexpr Tdec
@@ -685,7 +685,7 @@
atomicexpr
: Tident
- {$$ = mkexpr($1->loc, Ovar, mkname($1->loc, $1->str), NULL);}
+ {$$ = mkexpr($1->loc, Ovar, mkname($1->loc, $1->id), NULL);}
| literal
| Toparen expr Tcparen
{$$ = $2;}
@@ -719,10 +719,10 @@
tuplit : Toparen tupbody Tcparen
{$$ = mkexprl($1->loc, Otup, $2.nl, $2.nn);}
-littok : Tstrlit {$$ = mkstr($1->loc, $1->str);}
+littok : Tstrlit {$$ = mkstr($1->loc, $1->strval);}
| Tchrlit {$$ = mkchar($1->loc, $1->chrval);}
| Tfloatlit {$$ = mkfloat($1->loc, $1->fltval);}
- | Tboollit {$$ = mkbool($1->loc, !strcmp($1->str, "true"));}
+ | Tboollit {$$ = mkbool($1->loc, !strcmp($1->id, "true"));}
| Tintlit {
$$ = mkint($1->loc, $1->intval);
if ($1->inttype)
@@ -778,7 +778,7 @@
;
structelt: optendlns Tdot Tident Tasn expr optendlns
- {$$ = mkidxinit($2->loc, mkname($3->loc, $3->str), $5);}
+ {$$ = mkidxinit($2->loc, mkname($3->loc, $3->id), $5);}
;
optendlns : /* none */
@@ -882,7 +882,7 @@
;
label : Tcolon Tident
- {$$ = mklbl($2->loc, $2->str);}
+ {$$ = mklbl($2->loc, $2->id);}
;
%%
--- a/parse/htab.c
+++ b/parse/htab.c
@@ -227,6 +227,39 @@
return !strcmp(a, b);
}
+ulong strlithash(void *_s)
+{
+ Str *s;
+ ulong h, g, i;
+
+ s = _s;
+ h = 0;
+ for (i = 0; i < s->len; i++) {
+ h = ((h << 4) + s->buf[i]);
+
+ if ((g = (h & 0xF0000000)))
+ h ^= (g >> 24);
+
+ h &= ~g;
+ }
+ return h;
+}
+
+int strliteq(void *_a, void *_b)
+{
+ Str *a, *b;
+
+ a = _a;
+ b = _b;
+ if (a == b)
+ return 1;
+ if (a == NULL || b == NULL)
+ return 0;
+ if (a->len != b->len)
+ return 0;
+ return !memcmp(a, b, a->len);
+}
+
ulong ptrhash(void *key)
{
return inthash((intptr_t)key);
--- a/parse/node.c
+++ b/parse/node.c
@@ -214,13 +214,15 @@
return mkexpr(loc, Olit, n, NULL);
}
-Node *mkstr(Srcloc loc, char *val)
+Node *mkstr(Srcloc loc, Str val)
{
Node *n;
n = mknode(loc, Nlit);
n->lit.littype = Lstr;
- n->lit.strval = strdup(val);
+ n->lit.strval.len = val.len;
+ n->lit.strval.buf = malloc(val.len);
+ memcpy(n->lit.strval.buf, val.buf, val.len);
return n;
}
@@ -368,7 +370,8 @@
case Lflt:
return a->lit.fltval == b->lit.fltval;
case Lstr:
- return !strcmp(a->lit.strval, b->lit.strval);
+ return a->lit.strval.len == b->lit.strval.len &&
+ !memcmp(a->lit.strval.buf, b->lit.strval.buf, a->lit.strval.len);
case Lfunc:
return a->lit.fnval == b->lit.fnval;
case Llbl:
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -15,6 +15,7 @@
typedef struct Bitset Bitset;
typedef struct Htab Htab;
typedef struct Optctx Optctx;
+typedef struct Str Str;
typedef struct Tok Tok;
typedef struct Node Node;
@@ -64,6 +65,11 @@
int file;
};
+struct Str {
+ size_t len;
+ char *buf;
+};
+
typedef enum {
Visintern,
Visexport,
@@ -95,7 +101,7 @@
struct Tok {
int type;
Srcloc loc;
- char *str;
+ char *id;
/* values parsed out */
vlong intval;
@@ -102,6 +108,7 @@
Ty inttype; /* for explicitly specified suffixes */
double fltval;
uint32_t chrval;
+ Str strval;
};
struct Stab {
@@ -222,7 +229,7 @@
uvlong intval;
double fltval;
uint32_t chrval;
- char *strval;
+ Str strval;
char *lblval;
int boolval;
Node *fnval;
@@ -396,6 +403,8 @@
int liteq(Node *a, Node *b);
ulong strhash(void *key);
int streq(void *a, void *b);
+ulong strlithash(void *key);
+int strliteq(void *a, void *b);
ulong ptrhash(void *key);
int ptreq(void *a, void *b);
ulong inthash(uint64_t key);
@@ -506,7 +515,7 @@
Node *mkbool(Srcloc l, int val);
Node *mkint(Srcloc l, uint64_t val);
Node *mkchar(Srcloc l, uint32_t val);
-Node *mkstr(Srcloc l, char *s);
+Node *mkstr(Srcloc l, Str str);
Node *mkfloat(Srcloc l, double flt);
Node *mkfunc(Srcloc l, Node **args, size_t nargs, Type *ret, Node *body);
Node *mkname(Srcloc l, char *name);
@@ -582,6 +591,8 @@
long rdint(FILE *fd);
void wrstr(FILE *fd, char *val);
char *rdstr(FILE *fd);
+void wrstrbuf(FILE *fd, Str str);
+void rdstrbuf(FILE *fd, Str *str);
void wrflt(FILE *fd, double val);
double rdflt(FILE *fd);
void wrbool(FILE *fd, int val);
--- a/parse/tok.c
+++ b/parse/tok.c
@@ -233,7 +233,7 @@
if (!identstr(buf, sizeof buf))
return NULL;
t = mktok(kwd(buf));
- t->str = strdup(buf);
+ t->id = strdup(buf);
return t;
}
@@ -248,7 +248,8 @@
*buf = realloc(*buf, *sz);
}
- buf[0][len[0]++] = c;
+ buf[0][*len] = c;
+ (*len)++;
}
@@ -408,10 +409,13 @@
else
append(&buf, &len, &sz, c);
};
- append(&buf, &len, &sz, '\0');
-
t = mktok(Tstrlit);
- t->str = buf;
+ t->strval.len = len;
+
+ /* null terminator should not count towards length */
+ append(&buf, &len, &sz, '\0');
+ t->strval.buf = buf;
+ t->id = buf;
return t;
}
@@ -472,7 +476,7 @@
t = mktok(Tchrlit);
t->chrval = val;
- t->str = buf;
+ t->id = buf;
return t;
}
@@ -656,11 +660,11 @@
/* we only support base 10 floats */
if (isfloat && base == 10) {
t = mktok(Tfloatlit);
- t->str = strdupn(&fbuf[start], fidx - start);
+ t->id = strdupn(&fbuf[start], fidx - start);
t->fltval = strtod(buf, NULL);
} else {
t = mktok(Tintlit);
- t->str = strdupn(&fbuf[start], fidx - start);
+ t->id = strdupn(&fbuf[start], fidx - start);
t->intval = strtoull(buf, NULL, base);
/* check suffixes:
* u -> unsigned
@@ -748,7 +752,7 @@
if (!identstr(buf, 1024))
return NULL;
t = mktok(Ttyparam);
- t->str = strdup(buf);
+ t->id = strdup(buf);
return t;
}
@@ -829,8 +833,8 @@
void yyerror(const char *s)
{
fprintf(stderr, "%s:%d: %s", filename, curloc.line, s);
- if (curtok->str)
- fprintf(stderr, " near \"%s\"", curtok->str);
+ if (curtok->id)
+ fprintf(stderr, " near \"%s\"", curtok->id);
fprintf(stderr, "\n");
exit(1);
}
--- a/parse/use.c
+++ b/parse/use.c
@@ -453,7 +453,7 @@
case Lchr: wrint(fd, n->lit.chrval); break;
case Lint: wrint(fd, n->lit.intval); break;
case Lflt: wrflt(fd, n->lit.fltval); break;
- case Lstr: wrstr(fd, n->lit.strval); break;
+ case Lstr: wrstrbuf(fd, n->lit.strval); break;
case Llbl: wrstr(fd, n->lit.lblval); break;
case Lbool: wrbool(fd, n->lit.boolval); break;
case Lfunc: pickle(fd, n->lit.fnval); break;
@@ -585,10 +585,10 @@
case Lchr: n->lit.chrval = rdint(fd); break;
case Lint: n->lit.intval = rdint(fd); break;
case Lflt: n->lit.fltval = rdflt(fd); break;
- case Lstr: n->lit.strval = rdstr(fd); break;
+ case Lstr: rdstrbuf(fd, &n->lit.strval); break;
case Llbl: n->lit.lblval = rdstr(fd); break;
case Lbool: n->lit.boolval = rdbool(fd); break;
- case Lfunc: n->lit.fnval = unpickle(fd); break;
+ case Lfunc: n->lit.fnval = unpickle(fd); break;
}
break;
case Nloopstmt:
--- a/parse/util.c
+++ b/parse/util.c
@@ -316,6 +316,20 @@
}
}
+void wrstrbuf(FILE *fd, Str str)
+{
+ wrint(fd, str.len);
+ wrbuf(fd, str.buf, str.len);
+}
+
+void rdstrbuf(FILE *fd, Str *str)
+{
+ str->len = rdint(fd);
+ str->buf = xalloc(str->len + 1);
+ rdbuf(fd, str->buf, str->len);
+ str->buf[str->len] = '\0';
+}
+
void wrflt(FILE *fd, double val)
{
byte buf[8];