shithub: mc

Download patch

ref: 52a4d88af911ccd62125f55e72155b3d76878a66
parent: ec60839982dffcb2212f6b7e9eeb8b11a0b4d292
author: Ori Bernstein <[email protected]>
date: Thu Dec 19 18:44:01 EST 2013

Suport taking addresses of functions for nested calls.

--- a/6/isel.c
+++ b/6/isel.c
@@ -87,10 +87,7 @@
     switch (exprop(n)) {
         case Ovar:
             if (hthas(s->globls, n)) {
-                if (tybase(exprtype(n))->type == Tyfunc)
-                    rip = NULL;
-                else
-                    rip = locphysreg(Rrip);
+                rip = locphysreg(Rrip);
                 l = locmeml(htget(s->globls, n), rip, NULL, mode(n));
             } else if (hthas(s->stkoff, n)) {
                 stkoff = (ssize_t)htget(s->stkoff, n);
@@ -374,9 +371,28 @@
     g(s, Irepmovsb, NULL);
 }
 
+static void call(Isel *s, Node *n)
+{
+    AsmOp op;
+    Node *d;
+    Loc *f;
+
+    d = NULL;
+    if (exprop(n) == Ovar)
+        d = decls[n->expr.did];
+    if (hthas(s->globls, n) && d && d->decl.isconst && tybase(decltype(d))->type == Tyfunc) {
+        op = Icall;
+        f = locmeml(htget(s->globls, n), NULL, NULL, mode(n));
+    } else {
+        op = Icallind;
+        f = selexpr(s, n);
+    }
+    g(s, op, f, NULL);
+}
+
 static Loc *gencall(Isel *s, Node *n)
 {
-    Loc *src, *dst, *arg, *fn;  /* values we reduced */
+    Loc *src, *dst, *arg;  /* values we reduced */
     Loc *retloc, *rsp, *ret;       /* hard-coded registers */
     Loc *stkbump;        /* calculated stack offset */
     int argsz, argoff;
@@ -428,11 +444,7 @@
         }
         argoff += size(n->expr.args[i]);
     }
-    fn = selexpr(s, n->expr.args[0]);
-    if (fn->type == Loclbl || fn->type == Locmeml)
-        g(s, Icall, fn, NULL);
-    else
-        g(s, Icallind, fn, NULL);
+    call(s, n->expr.args[0]);
     if (argsz)
         g(s, Iadd, stkbump, rsp, NULL);
     if (retloc)