shithub: mc

Download patch

ref: 3c49faca8d3bb0dd12065897dd2efb6b8f234420
parent: 8865ed9510427f9af64eeeaa18f8209c91aeb456
author: Ori Bernstein <[email protected]>
date: Tue Jun 12 20:58:28 EDT 2012

Start stubbing out changes to do spilling

    Our simple codegen currently fails if we need to spill. Fix
    this in a crufty, inelegant, inefficient, but simple way.

--- a/8/asm.h
+++ b/8/asm.h
@@ -89,8 +89,11 @@
     Htab *locs; /* decl id => int stkoff */
     Htab *globls; /* decl id => char *globlname */
 
-    /* 6 general purpose regs */
+    /* register and spill states */
+    size_t stksz;
     int rtaken[Nreg];
+    Node *rcontains[Nreg];
+    Loc *locmap;
 };
 
 /* entry points */
@@ -111,13 +114,17 @@
 
 /* register allocation */
 Loc getreg(Isel *s, Mode m);
-void freeloc(Isel *s, Loc l);
 Loc claimreg(Isel *s, Reg r);
+void freeloc(Isel *s, Loc l);
 void freereg(Isel *s, Reg r);
 extern const char *regnames[];
 extern const Mode regmodes[];
 
+/* code gen */
+void spill(Isel *s, Reg r);
+void g(Isel *s, AsmOp op, ...);
 
 /* useful functions */
 size_t size(Node *n);
+size_t tysize(Type *t);
 void breakhere();
--- a/8/isel.c
+++ b/8/isel.c
@@ -132,7 +132,7 @@
     return i;
 }
 
-static void g(Isel *s, AsmOp op, ...)
+void g(Isel *s, AsmOp op, ...)
 {
     va_list ap;
     Insn *i;
--- a/8/reduce.c
+++ b/8/reduce.c
@@ -84,7 +84,7 @@
     return s;
 }
 
-static size_t tysize(Type *t)
+size_t tysize(Type *t)
 {
     size_t sz;
     size_t i;
--- a/8/regalloc.c
+++ b/8/regalloc.c
@@ -119,6 +119,25 @@
     return l;
 }
 
+void spill(Isel *s, Reg r)
+{
+    size_t i;
+    Loc l;
+    Node *n;
+
+    for (i = 0; i < Nmode; i++) {
+        if (!s->rcontains[i])
+            continue;
+        n = s->rcontains[i];
+        if (exprop(n) != Ovar) {
+            s->stksz += tysize(exprtype(n));
+            locmem(&s->locmap[n->nid], s->stksz, Rebp, Rnone, ModeL);
+            g(s, Imov, locreg(&l, r), &s->locmap[n->nid], NULL);
+        }
+        s->rcontains[i] = NULL;
+    }
+}
+
 Loc getreg(Isel *s, Mode m)
 {
 
@@ -147,7 +166,7 @@
     int i;
 
     if (s->rtaken[r])
-        die("Reg %s is already taken", regnames[r]);
+        spill(s, r);
     for (i = 0; i < Nmode; i++)
         s->rtaken[reginterferes[r][i]] = 1;
     locreg(&l, r);
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -124,6 +124,7 @@
 struct Node {
     int line;
     Ntype type;
+    int nid;
     union {
         struct {
             char  *name;