ref: 017a4c99e5701996225fb75f9edb27a434b81bf4
parent: 3e6f824c6113b7c4defaa01cf25cd94d1b050f69
author: Ori Bernstein <[email protected]>
date: Sat May 5 09:13:42 EDT 2012
More code generation work.
--- a/8/asm.h
+++ b/8/asm.h
@@ -14,8 +14,8 @@
typedef enum {
+ Locnone,
Loclbl,
- Locpseudo,
Locreg,
Locmem,
Locmeml, /* label offset */
@@ -39,7 +39,6 @@
char *lbl;
Reg reg;
long lit;
- long pseudo;
/* disp(base + index) */
struct {
/* only one of lbldisp and constdisp may be used */
--- a/8/insns.def
+++ b/8/insns.def
@@ -18,10 +18,12 @@
Insn(Imovz, "\tmovz%0t%1t %x,%x\n", 0)
Insn(Imovs, "\tmovs%0t%1t %x,%x\n", 0)
-/* arithmetic instructions. */
Insn(Iadd, "\tadd%t %r,%x\n", 0)
+Insn(Isub, "\tsub%t %r,%x\n", 0)
+Insn(Ipush, "\tpush%t %r\n", 0)
+Insn(Ipop, "\tpop%t %r\n", 0)
-/* flow instructions */
+/* branch instructions */
Insn(Ijmp, "\tjmp %v\n", 0)
Insn(Iret, "\tret\n", 0)
--- a/8/isel.c
+++ b/8/isel.c
@@ -55,16 +55,6 @@
return l;
}
-Loc *locpseudo(Loc *l, Mode mode)
-{
- static long nextpseudo;
-
- l->type = Locpseudo;
- l->mode = mode;
- l->pseudo = nextpseudo++;
- return l;
-}
-
Loc *locmem(Loc *l, long disp, Reg base, Reg idx, Mode mode)
{
l->type = Locmem;
@@ -93,6 +83,43 @@
return l;
}
+Loc loc(Isel *s, Node *n)
+{
+ Loc l;
+ Node *v;
+ switch (exprop(n)) {
+ case Ovar:
+ locmem(&l, 0, Reax, Rnone, ModeL);
+ break;
+ case Olit:
+ v = n->expr.args[0];
+ switch (v->lit.littype) {
+ case Lchr: loclit(&l, v->lit.chrval); break;
+ case Lbool: loclit(&l, v->lit.boolval); break;
+ case Lint: loclit(&l, v->lit.intval); break;
+ default:
+ die("Literal type %s should be blob", litstr(v->lit.littype));
+ }
+ break;
+ default:
+ die("Node %s not leaf in loc()", opstr(exprop(n)));
+ break;
+ }
+ return l;
+}
+
+Mode mode(Node *n)
+{
+ return ModeL;
+}
+
+Loc getreg(Isel *s, Mode m)
+{
+ Loc l;
+ locreg(&l, Reax);
+ return l;
+}
+
Insn *mkinsnv(AsmOp op, va_list ap)
{
Loc *l;
@@ -130,134 +157,83 @@
lappend(&s->il, &s->ni, i);
}
-void selexpr(Isel *s, Node *n)
+Loc selexpr(Isel *s, Node *n)
{
- Loc a, b;
+ Loc a, b, r;
Node **args;
args = n->expr.args;
+ r = (Loc){Locnone, };
switch (exprop(n)) {
case Oadd:
- die("Unimplemented op %s", opstr(exprop(n)));
+ a = selexpr(s, args[0]);
+ b = selexpr(s, args[1]);
+ g(s, Iadd, &b, &a, NULL);
+ r = b;
break;
+
case Osub:
- die("Unimplemented op %s", opstr(exprop(n)));
+ a = selexpr(s, args[0]);
+ b = selexpr(s, args[1]);
+ g(s, Iadd, &b, &a, NULL);
+ r = b;
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:
- 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 Oaddr:
- die("Unimplemented op %s", opstr(exprop(n)));
- break;
- case Oderef:
- 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: 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 Oaddr: die("Unimplemented op %s", opstr(exprop(n))); break;
+ case Oderef: 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);
+ a = selexpr(s, args[0]);
+ b = selexpr(s, args[1]);
+ g(s, Imov, &b, &a, NULL);
+ r = b;
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 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 Ocjmp: die("Unimplemented op %s", opstr(exprop(n))); break;
+ case Olit:
case Ovar:
- die("Unimplemented op %s", opstr(exprop(n)));
+ a = loc(s, n);
+ b = getreg(s, mode(args[0]));
+ g(s, Imov, &a, &b, NULL);
+ r = b;
break;
- case Olit:
- die("Unimplemented op %s", opstr(exprop(n)));
- break;
- case Olbl:
- 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:
- case Odiveq:
- case Omodeq:
- case Oboreq:
- case Obandeq:
- case Obxoreq:
- case Obsleq:
- case Obsreq:
- case Omemb:
+ case Obad: case Oret: case Opreinc: case Opostinc: case Opredec:
+ case Opostdec: case Olor: case Oland: case Olnot: case Oaddeq:
+ case Osubeq: case Omuleq: case Odiveq: case Omodeq: case Oboreq:
+ case Obandeq: case Obxoreq: case Obsleq: case Obsreq: case Omemb:
die("Should not see %s in isel", opstr(exprop(n)));
break;
}
+ return r;
}
void locprint(FILE *fd, Loc *l)
@@ -270,9 +246,6 @@
case Locreg:
fprintf(fd, "%s", regnames[l->reg]);
break;
- case Locpseudo:
- fprintf(fd, "%%P%ld", l->pseudo);
- break;
case Locmem:
case Locmeml:
if (l->type == Locmem) {
@@ -290,7 +263,11 @@
fprintf(fd, ")");
break;
case Loclit:
+ fprintf(fd, "$%ld", l->lit);
break;
+ case Locnone:
+ die("Bad location in locprint()");
+ break;
}
}
@@ -344,18 +321,16 @@
return;
}
-void isel(Node *n)
+void isel(Isel *s, Node *n)
{
- struct Isel is = {0,};
Loc lbl;
- int i;
switch (n->type) {
case Nlbl:
- g(&is, Ilbl, loclbl(&lbl, n->lbl.name), NULL);
+ g(s, Ilbl, loclbl(&lbl, n->lbl.name), NULL);
break;
case Nexpr:
- selexpr(&is, n);
+ selexpr(s, n);
break;
case Ndecl:
break;
@@ -363,14 +338,45 @@
die("Bad node type in isel()");
break;
}
- for (i = 0; i < is.ni; i++)
- iprintf(stdout, is.il[i]);
}
+void prologue(Isel *s)
+{
+ Loc resp;
+ Loc rebp;
+ Loc stksz;
+
+ locreg(&resp, Resp);
+ locreg(&rebp, Rebp);
+ loclit(&stksz, 16);
+ g(s, Ipush, &rebp, NULL);
+ g(s, Imov, &resp, &rebp, NULL);
+ g(s, Isub, &stksz, &resp, NULL);
+}
+
+void epilogue(Isel *s)
+{
+ Loc resp;
+ Loc rebp;
+ Loc stksz;
+
+ locreg(&resp, Resp);
+ locreg(&rebp, Rebp);
+ loclit(&stksz, 16);
+ g(s, Imov, &rebp, &resp, NULL);
+ g(s, Ipop, &rebp, NULL);
+}
+
void genasm(Node **nl, int nn)
{
+ struct Isel is = {0,};
int i;
+ prologue(&is);
for (i = 0; i < nn; i++)
- isel(nl[i]);
+ isel(&is, nl[i]);
+ epilogue(&is);
+
+ for (i = 0; i < is.ni; i++)
+ iprintf(stdout, is.il[i]);
}