shithub: mc

Download patch

ref: 5ebd3da62bc8a5e0633647dfb481ea9ecdb82286
parent: 07cf448ccf4c27ad905272d6d6033676710b7541
author: Ori Bernstein <[email protected]>
date: Sun Apr 22 07:49:25 EDT 2012

Add missing files.

--- /dev/null
+++ b/8/gen.c
@@ -1,0 +1,2 @@
+
+
--- /dev/null
+++ b/8/gen.h
@@ -1,0 +1,58 @@
+typedef struct Comp Comp;
+typedef struct Blob Blob;
+typedef struct Fn   Fn;
+typedef struct Bb   Bb;
+
+struct Comp {
+    /* we generate blobs and functions */
+    Blob **globl;
+    size_t nglobl;
+    Fn **func;
+    size_t nfunc;
+};
+
+struct Blob {
+    char *name; /* mangled asm name */
+    void *data;
+    size_t ndata;
+};
+
+struct Fn {
+    char *name; /* assembly name; mangled */
+    
+    Htab *bbnames; /* char* => Bb* map */
+    Bb *start;
+    Bb *end;
+    Bb *cur;
+    Bb **bb;
+    size_t nbb;
+
+    /* we can't know all the edges as we
+     * construct the bb list, so we fix up later */
+    Bb **fixup;
+    size_t nfixup;
+};
+
+struct Bb {
+    int id;
+
+    /* nodes in bb */
+    Node **n;
+    size_t nn;
+
+    /* edges */
+    Bb **in;
+    size_t nin;
+    Bb *out;
+    size_t nout;
+};
+
+/* toplevel code gen */
+Comp *mkcomp(Node *f);
+void gen(Node *file, char *out);
+void assemble(char *asmfile, char *out);
+
+/* cfg */
+Fn *mkfn(char *name);
+Bb *mkbb(void);
+void edge(Bb *from, Bb *to);
--- /dev/null
+++ b/8/simp.c
@@ -1,0 +1,282 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <ctype.h>
+#include <string.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "parse.h"
+#include "gen.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);
+static void lowerblock(Comp *c, Fn *fn, Node *blk);
+static void lowerfn(Comp *c, char *name, Node *n);
+
+Fn *mkfn(char *name)
+{
+    Fn *f;
+
+    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;
+}
+
+static char *asmname(Node *n)
+{
+    int i;
+    char *s;
+    char *sep;
+    int len;
+
+    for (i = 0; i < n->name.nparts; i++)
+        len += strlen(n->name.parts[i]) + 1;
+
+    s = xalloc(len);
+    s[0] = '\0';
+    sep = "";
+    for (i = 0; i < n->name.nparts; i++) {
+        sprintf(s, "%s%s", sep, n->name.parts[i]);
+        sep = "$";
+    }
+    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));
+}
+
+/* support functions */
+static void jmp(Comp *c, Fn *fn, Node *targ)
+{
+}
+
+/* support functions */
+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();
+}
+
+static 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;
+    int i;
+    Bb *fix;
+    Node *last;
+
+    /* unwrap to the function body */
+    assert(n->type == Nexpr && exprop(n) == Olit);
+    n = n->expr.args[0];
+    assert(n->type == Nlit && n->lit.littype == Lfunc);
+    n = n->lit.fnval;
+    assert(n->type == Nfunc);
+
+    /* lower */
+    fn = mkfn(name);
+    fn = zalloc(sizeof(Fn));
+    fn->name = strdup(name);
+    lowerblock(c, fn, n->func.body);
+    lappend(&c->func, &c->nfunc, fn);
+
+    for (i = 0; i < fn->nfixup; i++) {
+        fix = fn->fixup[i];
+        last = fix->n[fix->nn - 1];
+        switch (exprop(last)) {
+            case Ocjmp:
+                break;
+            case Ojmp:
+                break;
+            default:
+                die("Invalid last node in BB");
+                break;
+        }
+    }
+}
+
+int isconstfn(Sym *s)
+{
+    return s->isconst && s->type->type == Tyfunc;
+}
+
+void gen(Node *file, char *out)
+{
+    Node **n;
+    int nn, i;
+    Sym *s;
+    char *name;
+    Comp *c;
+
+    c = zalloc(sizeof(Comp));
+
+    n = file->file.stmts;
+    nn = file->file.nstmts;
+
+    for (i = 0; i < nn; i++) {
+        switch (n[i]->type) {
+            case Nuse: /* nothing to do */ 
+                break;
+            case Ndecl:
+                s = n[i]->decl.sym;
+                name = asmname(s->name);
+                if (isconstfn(s)) {
+                    lowerfn(c, name, n[i]->decl.init);
+                    free(name);
+                } else {
+                    lowerglobl(c, name, n[i]);
+                }
+                break;
+            default:
+                die("Bad node %s in toplevel", nodestr(n[i]->type));
+                break;
+        }
+    }
+
+    /*
+    isel();
+    regalloc();
+    */
+}