ref: 36ce95316220f7b7bf4bcb205533b919a65ef750
parent: 36a3a5fa99dc4887ca46c7807436ad44da19422f
author: Ori Bernstein <[email protected]>
date: Fri May 4 18:37:53 EDT 2012
Start work on isntruction selection. Fix instruction printing, do some very crude instruction selection (broken, not working, etc, etc.)
--- a/8/asm.h
+++ b/8/asm.h
@@ -7,7 +7,7 @@
} AsmOp;
typedef enum {
-#define Reg(r, name) r,
+#define Reg(r, name, mode) r,
#include "regs.def"
#undef Reg
} Reg;
@@ -52,5 +52,7 @@
struct Insn {
AsmOp op;
Loc args[MaxArg];
- int nloc;
+ int narg;
};
+
+void genasm(Node **nl, int nn);
--- a/8/insns.def
+++ b/8/insns.def
@@ -14,13 +14,16 @@
*/
/* Note, the mov instruction is specified in an overly general manner. */
-Insn(Imov, "mov%m %x,%x", 0)
-Insn(Imovz, "movz%0m%1m %x,%x", 0)
-Insn(Imovs, "movs%0m%1m %x,%x", 0)
+Insn(Imov, "\tmov%t %x,%x\n", 0)
+Insn(Imovz, "\tmovz%0t%1t %x,%x\n", 0)
+Insn(Imovs, "\tmovs%0t%1t %x,%x\n", 0)
/* arithmetic instructions. */
-Insn(Iadd, "add%m %r,%x", 0)
-Insn(Iret, "ret", 0)
+Insn(Iadd, "\tadd%t %r,%x\n", 0)
+/* flow instructions */
+Insn(Ijmp, "\tjmp %v\n", 0)
+Insn(Iret, "\tret\n", 0)
+
/* not really an insn... */
-Insn(Ilbl, "%s:", 0)
+Insn(Ilbl, "%v:\n", 0)
--- a/8/isel.c
+++ b/8/isel.c
@@ -1,6 +1,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
+#include <stdarg.h>
#include <ctype.h>
#include <string.h>
#include <assert.h>
@@ -20,11 +21,17 @@
};
char *regnames[] = {
-#define Reg(r, name) name,
+#define Reg(r, name, mode) name,
#include "regs.def"
#undef Reg
};
+Mode regmodes[] = {
+#define Reg(r, name, mode) mode,
+#include "regs.def"
+#undef Reg
+};
+
char *insnfmts[] = {
#define Insn(val, fmt, attr) fmt,
#include "insns.def"
@@ -31,38 +38,202 @@
#undef Insn
};
-void selexpr(Node *n)
+
+Loc *loclbl(Loc *l, char *lbl)
{
+ l->type = Loclbl;
+ l->mode = ModeL;
+ l->lbl = strdup(lbl);
+ return l;
+}
+
+Loc *locreg(Loc *l, Reg r)
+{
+ l->type = Locreg;
+ l->mode = regmodes[r];
+ l->reg = r;
+ return l;
+}
+
+Loc *locmem(Loc *l, long disp, Reg base, Reg idx, Mode mode)
+{
+ l->type = Locmem;
+ l->mode = mode;
+ l->mem.constdisp = disp;
+ l->mem.base = base;
+ l->mem.idx = idx;
+ return l;
+}
+
+Loc *locmeml(Loc *l, char *disp, Reg base, Reg idx, Mode mode)
+{
+ l->type = Locmem;
+ l->mode = mode;
+ l->mem.lbldisp = strdup(disp);
+ l->mem.base = base;
+ l->mem.idx = idx;
+ return l;
+}
+
+Loc *loclit(Loc *l, long val)
+{
+ l->type = Loclit;
+ l->mode = ModeL; /* FIXME: what do we do for mode? */
+ l->lit = val;
+ return l;
+}
+
+Insn *mkinsnv(AsmOp op, va_list ap)
+{
+ Loc *l;
+ Insn *i;
+ int n;
+
+ n = 0;
+ i = malloc(sizeof(Insn));
+ i->op = op;
+ while ((l = va_arg(ap, Loc*)) != NULL)
+ i->args[n++] = *l;
+ i->narg = n;
+ return i;
+}
+
+Insn *mkinsn(AsmOp op, ...)
+{
+ va_list ap;
+ Insn *i;
+
+ va_start(ap, op);
+ i = mkinsnv(op, ap);
+ va_end(ap);
+ return i;
+}
+
+void g(Isel *s, AsmOp op, ...)
+{
+ va_list ap;
+ Insn *i;
+
+ va_start(ap, op);
+ i = mkinsnv(op, ap);
+ va_end(ap);
+ lappend(&s->il, &s->ni, i);
+}
+
+void selexpr(Isel *s, Node *n)
+{
+ Loc a, b;
+ Node **args;
+
+ args = n->expr.args;
switch (exprop(n)) {
- case Obad:
case Oadd:
+ die("Unimplemented op %s", opstr(exprop(n)));
+ break;
case Osub:
+ die("Unimplemented op %s", opstr(exprop(n)));
+ break;
case Omul:
+ die("Unimplemented op %s", opstr(exprop(n)));
+ break;
case Odiv:
+ die("Unimplemented op %s", opstr(exprop(n)));
+ break;
case Omod:
+ die("Unimplemented op %s", opstr(exprop(n)));
+ break;
case Oneg:
+ die("Unimplemented op %s", opstr(exprop(n)));
+ break;
+
case Obor:
+ die("Unimplemented op %s", opstr(exprop(n)));
+ break;
case Oband:
+ die("Unimplemented op %s", opstr(exprop(n)));
+ break;
case Obxor:
+ die("Unimplemented op %s", opstr(exprop(n)));
+ break;
case Obsl:
+ die("Unimplemented op %s", opstr(exprop(n)));
+ break;
case Obsr:
+ die("Unimplemented op %s", opstr(exprop(n)));
+ break;
case Obnot:
- case Opreinc:
- case Opostinc:
- case Opredec:
- case Opostdec:
+ die("Unimplemented op %s", opstr(exprop(n)));
+ break;
+
case Oaddr:
+ die("Unimplemented op %s", opstr(exprop(n)));
+ break;
case Oderef:
- case Olor:
- case Oland:
- case Olnot:
+ die("Unimplemented op %s", opstr(exprop(n)));
+ break;
+
case Oeq:
+ die("Unimplemented op %s", opstr(exprop(n)));
+ break;
case One:
+ die("Unimplemented op %s", opstr(exprop(n)));
+ break;
case Ogt:
+ die("Unimplemented op %s", opstr(exprop(n)));
+ break;
case Oge:
+ die("Unimplemented op %s", opstr(exprop(n)));
+ break;
case Olt:
+ die("Unimplemented op %s", opstr(exprop(n)));
+ break;
case Ole:
+ die("Unimplemented op %s", opstr(exprop(n)));
+ break;
+
case Oasn:
+ g(s, Imov, locreg(&b, Rebx), locreg(&a, Reax), NULL);
+ break;
+ case Oidx:
+ die("Unimplemented op %s", opstr(exprop(n)));
+ break;
+ case Oslice:
+ die("Unimplemented op %s", opstr(exprop(n)));
+ break;
+ case Osize:
+ die("Unimplemented op %s", opstr(exprop(n)));
+ break;
+ case Ocall:
+ die("Unimplemented op %s", opstr(exprop(n)));
+ break;
+ case Ocast:
+ die("Unimplemented op %s", opstr(exprop(n)));
+ break;
+ case Ojmp:
+ g(s, Ijmp, loclbl(&a, args[0]->lbl.name), NULL);
+ break;
+ case Ocjmp:
+ die("Unimplemented op %s", opstr(exprop(n)));
+ break;
+ case Ovar:
+ die("Unimplemented op %s", opstr(exprop(n)));
+ break;
+ case Olit:
+ die("Unimplemented op %s", opstr(exprop(n)));
+ break;
+ case Olbl:
+ die("Unimplemented op %s", opstr(exprop(n)));
+ break;
+
+ case Obad:
+ case Oret:
+ case Opreinc:
+ case Opostinc:
+ case Opredec:
+ case Opostdec:
+ case Olor:
+ case Oland:
+ case Olnot:
case Oaddeq:
case Osubeq:
case Omuleq:
@@ -73,26 +244,12 @@
case Obxoreq:
case Obsleq:
case Obsreq:
- case Oidx:
- case Oslice:
case Omemb:
- case Osize:
- case Ocall:
- case Ocast:
- case Oret:
- case Ojmp:
- case Ocjmp:
- case Ovar:
- case Olit:
- case Olbl:
+ die("Should not see %s in isel", opstr(exprop(n)));
break;
}
}
-void ilbl(Isel *s, char *name)
-{
-}
-
void locprint(FILE *fd, Loc *l)
{
@@ -138,6 +295,7 @@
int modeidx;
p = insnfmts[insn->op];
+ i = 0;
for (; *p; p++) {
if (*p != '%') {
fputc(*p, fd);
@@ -158,12 +316,15 @@
i++;
break;
case 't':
+ modeidx = 0;
default:
if (isdigit(*p))
modeidx = strtol(p, &p, 10);
+
+ if (*p == 't')
+ modeprint(fd, &insn->args[modeidx]);
else
- modeidx = 0;
- modeprint(fd, &insn->args[modeidx]);
+ die("Invalid %%-specifier '%c'", *p);
break;
}
}
@@ -174,12 +335,15 @@
void isel(Node *n)
{
struct Isel is = {0,};
+ Loc lbl;
+ int i;
+
switch (n->type) {
case Nlbl:
- ilbl(&is, n->lbl.name);
+ g(&is, Ilbl, loclbl(&lbl, n->lbl.name), NULL);
break;
case Nexpr:
- selexpr(n);
+ selexpr(&is, n);
break;
case Ndecl:
break;
@@ -187,4 +351,14 @@
die("Bad node type in isel()");
break;
}
+ for (i = 0; i < is.ni; i++)
+ iprintf(stdout, is.il[i]);
+}
+
+void genasm(Node **nl, int nn)
+{
+ int i;
+
+ for (i = 0; i < nn; i++)
+ isel(nl[i]);
}
--- a/8/reduce.c
+++ b/8/reduce.c
@@ -143,17 +143,20 @@
for (i = 0; i < n->block.nstmts; i++) {
e = simp(s, n->block.stmts[i]);
- append(s, e);
+ if (e)
+ append(s, e);
}
}
Node *simpexpr(Simp *s, Node *n)
{
- Node *r, *t;
+ Node *r, *t, *v;
int i;
+ r = NULL;
switch (exprop(n)) {
case Ovar:
+ r = n;
break;
case Oret:
if (n->expr.args[0]) {
@@ -164,16 +167,17 @@
break;
default:
if (isimpure(n)) {
- r = simp(s, n);
- t = storetmp(r);
+ v = simp(s, n);
+ t = storetmp(v);
append(s, t);
- return t;
+ r = t;
} else {
for (i = 0; i < n->expr.nargs; i++)
n->expr.args[i] = simp(s, n->expr.args[i]);
+ r = n;
}
}
- return n;
+ return r;
}
Node *simp(Simp *s, Node *n)
--- a/8/regs.def
+++ b/8/regs.def
@@ -1,25 +1,25 @@
-Reg(Rnone, "%NOREG")
+Reg(Rnone, "%NOREG", ModeB)
/* byte regs */
-Reg(Ral, "%al")
-Reg(Rcl, "%cl")
-Reg(Rdl, "%dl")
-Reg(Rbl, "%bl")
+Reg(Ral, "%al", ModeB)
+Reg(Rcl, "%cl", ModeB)
+Reg(Rdl, "%dl", ModeB)
+Reg(Rbl, "%bl", ModeB)
/* short regs */
-Reg(Rax, "%ax")
-Reg(Rbx, "%bx")
-Reg(Rcx, "%cx")
-Reg(Rdx, "%dx")
-Reg(Rsi, "%si")
-Reg(Rdi, "%di")
+Reg(Rax, "%ax", ModeS)
+Reg(Rbx, "%bx", ModeS)
+Reg(Rcx, "%cx", ModeS)
+Reg(Rdx, "%dx", ModeS)
+Reg(Rsi, "%si", ModeS)
+Reg(Rdi, "%di", ModeS)
/* long regs */
-Reg(Reax, "%eax")
-Reg(Recx, "%ecx")
-Reg(Redx, "%edx")
-Reg(Rebx, "%ebx")
-Reg(Resi, "%esi")
-Reg(Redi, "%edi")
-Reg(Resp, "%esp")
-Reg(Rebp, "%ebp")
+Reg(Reax, "%eax", ModeL)
+Reg(Recx, "%ecx", ModeL)
+Reg(Redx, "%edx", ModeL)
+Reg(Rebx, "%ebx", ModeL)
+Reg(Resi, "%esi", ModeL)
+Reg(Redi, "%edi", ModeL)
+Reg(Resp, "%esp", ModeL)
+Reg(Rebp, "%ebp", ModeL)
--- a/8/simp.c
+++ b/8/simp.c
@@ -11,14 +11,9 @@
#include "parse.h"
#include "gen.h"
+#include "asm.h"
-static Node *lowerexpr(Comp *c, Fn *fn, Node *n);
-static void label(Comp *c, Fn *fn, Node *lbl);
-static void lowerlocal(Comp *c, Fn *fn, Node *init);
static void lowerglobl(Comp *c, char *name, Node *init);
-static void lowerif(Comp *c, Fn *fn, Node *cond);
-static void lowerloop(Comp *c, Fn *fn, Node *loop);
-void lowerblock(Comp *c, Fn *fn, Node *blk);
static void lowerfn(Comp *c, char *name, Node *n);
Fn *mkfn(char *name)
@@ -28,13 +23,6 @@
f = zalloc(sizeof(Fn));
f->name = strdup(name);
- f->start = mkbb();
- f->cur = mkbb();
- f->end = mkbb();
-
- edge(f->start, f->cur);
- edge(f->cur, f->end);
-
return f;
}
@@ -58,147 +46,11 @@
return s;
}
-
-Bb *mkbb()
-{
- static int bbid;
- Bb *bb;
-
- bb = zalloc(sizeof(Bb));
- bb->id = bbid++;
-
- return bb;
-}
-
-void edge(Bb *from, Bb *to)
-{
- lappend(&from->out, &from->nout, to);
- lappend(&to->in, &to->nin, to);
-}
-
-static Node *genlbl()
-{
- static int lblid;
- static char buf[128];
-
- /* generate a local label */
- snprintf(buf, 128, ".L%d", lblid++);
- return mklbl(-1, strdup(buf));
-}
-
-static void jmp(Comp *c, Fn *fn, Node *targ)
-{
-}
-
-static void cjmp(Comp *c, Fn *fn, Node *cond, Node *iftrue, Node *iffalse)
-{
-}
-
static void lowerglobl(Comp *c, char *name, Node *init)
{
printf("gen globl %s\n", name);
}
-static void lowerlocal(Comp *c, Fn *fn, Node *dcl)
-{
- printf("gen local");
-}
-
-static Node *lowerexpr(Comp *c, Fn *fn, Node *n)
-{
- lappend(&fn->cur->n, &fn->cur->nn, n);
- return n;
-}
-
-static void lowerif(Comp *c, Fn *fn, Node *cond)
-{
- lowerexpr(c, fn, cond->ifstmt.cond);
- label(c, fn, genlbl());
- lowerexpr(c, fn, cond->ifstmt.iftrue);
- label(c, fn, genlbl());
- lowerexpr(c, fn, cond->ifstmt.iffalse);
-}
-
-static void lowerloop(Comp *c, Fn *fn, Node *loop)
-{
- Node *start;
- Node *test;
- Node *end;
- Node *cond;
-
- /* structure of loop:
- init
- jmp test (if for/while, otherwise, fall through)
- start:
- body
- inc
- test:
- test
- cjmp cond start end
- end:
- */
- start = genlbl();
- test = genlbl();
- end = genlbl();
-
- jmp(c, fn, start);
- /* init */
- if (loop->loopstmt.init->type == Ndecl)
- lowerlocal(c, fn, loop->loopstmt.init);
- else
- lowerexpr(c, fn, loop->loopstmt.init);
- label(c, fn, start);
-
- /* body and inc */
- lowerexpr(c, fn, loop->loopstmt.body);
- lowerexpr(c, fn, loop->loopstmt.step);
-
- /* test */
- label(c, fn, test);
- cond = lowerexpr(c, fn, loop->loopstmt.cond);
- cjmp(c, fn, cond, start, end);
- label(c, fn, end);
-}
-
-static void label(Comp *c, Fn *fn, Node *lbl)
-{
- lappend(&fn->fixup, &fn->nfixup, fn->cur);
- fn->cur = mkbb();
-}
-
-void lowerblock(Comp *c, Fn *fn, Node *blk)
-{
- Node **n;
- size_t nn;
- int i;
-
- assert(blk && blk->type == Nblock);
- n = blk->block.stmts;
- nn = blk->block.nstmts;
- for (i = 0; i < nn; i++) {
- switch (n[i]->type) {
- case Ndecl:
- lowerlocal(c, fn, n[i]);
- break;
- case Nexpr:
- lowerexpr(c, fn, n[i]);
- break;
- case Nifstmt:
- lowerif(c, fn, n[i]);
- break;
- case Nloopstmt:
- lowerloop(c, fn, n[i]);
- break;
- case Nlbl:
- label(c, fn, n[i]);
- break;
- default:
- die("Bad node %s in block", nodestr(n[i]->type));
- break;
- }
- }
-}
-
static void lowerfn(Comp *c, char *name, Node *n)
{
Fn *fn;
@@ -221,6 +73,8 @@
for (i = 0; i < nn; i++) {
dump(nl[i], stdout);
}
+
+ genasm(nl, nn);
}
int isconstfn(Sym *s)
@@ -243,51 +97,6 @@
fprintf(fd, "\n");
}
-void bbdump(Bb *bb, FILE *fd)
-{
- int i;
- char *sep = "";
-
- fprintf(fd, "\t\tbb %d\n", bb->id);
- fprintf(fd, "\t\t\tin = [ ");
- for (i = 0; i < bb->nin; i++) {
- fprintf(fd, "%s%d ", sep, bb->in[i]->id);
- sep = ",";
- }
- fprintf(fd, "]\n");
- sep = "";
- fprintf(fd, "\t\t\tout = [ ");
- for (i = 0; i < bb->nout; i++) {
- fprintf(fd, "%s%d ", sep, bb->out[i]->id);
- sep = ",";
- }
- fprintf(fd, "]\n");
-
- for (i = 0; i < bb->nn; i++)
- dump(bb->n[i], fd);
-}
-
-void fndump(Fn *f, FILE *fd)
-{
- int i;
-
- fprintf(fd, "\tfn %s\n", f->name);
- for (i = 0; i < f->nbb; i++)
- bbdump(f->bb[i], fd);
-}
-
-void compdump(Comp *c, FILE *fd)
-{
- int i;
-
- fprintf(fd, "** globals **:\n");
- for (i = 0; i < c->nglobl; i++)
- blobdump(c->globl[i], fd);
- fprintf(fd, "** funcs **:\n");
- for (i = 0; i < c->nfunc; i++)
- fndump(c->func[i], fd);
-}
-
void gen(Node *file, char *out)
{
Node **n;
@@ -320,10 +129,4 @@
break;
}
}
- compdump(c, stdout);
-
- /*
- isel();
- regalloc();
- */
}