]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/cmd/7l/pass.c
aux/realemu: run cpuproc in same fd group as fileserver
[plan9front.git] / sys / src / cmd / 7l / pass.c
index e0451b5324e10f53f2329c88da13056229d2e396..ad3d9a439525d3607b2f9efa055378695de111be 100644 (file)
@@ -1,13 +1,67 @@
 #include       "l.h"
 
+vlong
+atolwhex(char *s)
+{
+       vlong n;
+       int f;
+
+       n = 0;
+       f = 0;
+       while(*s == ' ' || *s == '\t')
+               s++;
+       if(*s == '-' || *s == '+') {
+               if(*s++ == '-')
+                       f = 1;
+               while(*s == ' ' || *s == '\t')
+                       s++;
+       }
+       if(s[0]=='0' && s[1]){
+               if(s[1]=='x' || s[1]=='X'){
+                       s += 2;
+                       for(;;){
+                               if(*s >= '0' && *s <= '9')
+                                       n = n*16 + *s++ - '0';
+                               else if(*s >= 'a' && *s <= 'f')
+                                       n = n*16 + *s++ - 'a' + 10;
+                               else if(*s >= 'A' && *s <= 'F')
+                                       n = n*16 + *s++ - 'A' + 10;
+                               else
+                                       break;
+                       }
+               } else
+                       while(*s >= '0' && *s <= '7')
+                               n = n*8 + *s++ - '0';
+       } else
+               while(*s >= '0' && *s <= '9')
+                       n = n*10 + *s++ - '0';
+       if(f)
+               n = -n;
+       return n;
+}
+
+vlong
+rnd(vlong v, long r)
+{
+       long c;
+
+       if(r <= 0)
+               return v;
+       v += r - 1;
+       c = v % r;
+       if(c < 0)
+               c += r;
+       v -= c;
+       return v;
+}
+
 void
 dodata(void)
 {
-       int i, t, size;
+       int i, t;
        Sym *s;
-       Prog *p, *p1;
-       long orig, orig1, v;
-       vlong vv;
+       Prog *p;
+       long orig, v;
 
        if(debug['v'])
                Bprint(&bso, "%5.2f dodata\n", cputime());
@@ -23,14 +77,25 @@ dodata(void)
                                s->type, s->name, p);
                v = p->from.offset + p->reg;
                if(v > s->value)
-                       diag("initialize bounds (%ld): %s\n%P",
-                               s->value, s->name, p);
+                       diag("initialize bounds (%lld): %s\n%P",
+                               (vlong)s->value, s->name, p);
+       }
+
+       if(debug['t']) {
+               /*
+                * pull out string constants
+                */
+               for(p = datap; p != P; p = p->link) {
+                       s = p->from.sym;
+                       if(p->to.type == D_SCONST)
+                               s->type = SSTRING;
+               }
        }
 
        /*
         * pass 1
         *      assign 'small' variables to data segment
-        *      (rational is that data segment is more easily
+        *      (rationale is that data segment is more easily
         *       addressed through offset on REGSB)
         */
        orig = 0;
@@ -44,24 +109,22 @@ dodata(void)
                        diag("%s: no size", s->name);
                        v = 1;
                }
-               while(v & 3)
-                       v++;
-               
+               v = rnd(v, 4);
                s->value = v;
                if(v > MINSIZ)
                        continue;
-               if (v >= 8)
+               if(v >= 16)
+                       orig = rnd(orig, 16);
+               else if(v >= 8)
                        orig = rnd(orig, 8);
                s->value = orig;
                orig += v;
                s->type = SDATA1;
        }
-       orig = rnd(orig, 8);
-       orig1 = orig;
 
        /*
         * pass 2
-        *      assign 'data' variables to data segment
+        *      assign large 'data' variables to data segment
         */
        for(i=0; i<NHASH; i++)
        for(s = hash[i]; s != S; s = s->link) {
@@ -72,14 +135,16 @@ dodata(void)
                        continue;
                }
                v = s->value;
-               if (v >= 8)
+               if(v >= 16)
+                       orig = rnd(orig, 16);
+               else if(v >= 8)
                        orig = rnd(orig, 8);
                s->value = orig;
                orig += v;
-               s->type = SDATA1;
        }
 
-       orig = rnd(orig, 8);
+       while(orig & 7)
+               orig++;
        datsize = orig;
 
        /*
@@ -91,132 +156,35 @@ dodata(void)
                if(s->type != SBSS)
                        continue;
                v = s->value;
-               if (v >= 8)
+               if(v >= 16)
+                       orig = rnd(orig, 16);
+               else if(v >= 8)
                        orig = rnd(orig, 8);
                s->value = orig;
                orig += v;
        }
-       orig = rnd(orig, 8);
+       while(orig & 7)
+               orig++;
        bsssize = orig-datsize;
 
-       /*
-        * pass 4
-        *      add literals to all large values.
-        *      at this time:
-        *              small data is allocated DATA
-        *              large data is allocated DATA1
-        *              large bss is allocated BSS
-        *      the new literals are loaded between
-        *      small data and large data.
-        */
-       orig = 0;
-       for(p = firstp; p != P; p = p->link) {
-               if(p->as != AMOVQ)
-                       continue;
-               if(p->from.type != D_CONST)
-                       continue;
-               if(s = p->from.sym) {
-                       t = s->type;
-                       if(t != SDATA && t != SDATA1 && t != SBSS)
-                               continue;
-                       t = p->from.name;
-                       if(t != D_EXTERN && t != D_STATIC)
-                               continue;
-                       v = s->value + p->from.offset;
-                       size = 4;
-                       if(v >= 0 && v <= 0xffff)
-                               continue;
-                       if(!strcmp(s->name, "setSB"))
-                               continue;
-                       /* size should be 19 max */
-                       if(strlen(s->name) >= 10)       /* has loader address */ 
-                               snprint(literal, sizeof literal, "$%p.%llux", s, p->from.offset);
-                       else
-                               snprint(literal, sizeof literal, "$%s.%d.%llux", s->name, s->version, p->from.offset);
-               } else {
-                       if(p->from.name != D_NONE)
-                               continue;
-                       if(p->from.reg != NREG)
-                               continue;
-                       vv = p->from.offset;
-                       if(vv >= -0x8000LL && vv <= 0x7fff)
-                               continue;
-                       if(!(vv & 0xffff))
-                               continue;
-                       size = 8;
-                       if (vv <= 0x7FFFFFFFLL && vv >= -0x80000000LL)
-                               size = 4;
-                       /* size should be 17 max */
-                       snprint(literal, sizeof literal, "$%llux", vv);
-               }
-               s = lookup(literal, 0);
-               if(s->type == 0) {
-                       s->type = SDATA;
-                       orig = rnd(orig, size);
-                       s->value = orig1+orig;
-                       orig += size;
-                       p1 = prg();
-                       p1->line = p->line;
-                       p1->as = ADATA;
-                       p1->from.type = D_OREG;
-                       p1->from.sym = s;
-                       p1->from.name = D_EXTERN;
-                       p1->reg = size;
-                       p1->to = p->from;
-                       p1->link = datap;
-                       datap = p1;
-                       if(debug['C'])
-                               Bprint(&bso, "literal %P for %P\n", p1, p);
-               }
-               if(s->type != SDATA)
-                       diag("literal not data: %s", s->name);
-               if (size == 4)
-                       p->as = AMOVL;
-               p->from.type = D_OREG;
-               p->from.sym = s;
-               p->from.name = D_EXTERN;
-               p->from.offset = 0;
-               continue;
-       }
-       orig = rnd(orig, 8);
-
-       /*
-        * pass 5
-        *      re-adjust offsets
-        */
-       for(i=0; i<NHASH; i++)
-       for(s = hash[i]; s != S; s = s->link) {
-               t = s->type;
-               if(t == SBSS) {
-                       s->value += orig;
-                       continue;
-               }
-               if(t == SDATA1) {
-                       s->type = SDATA;
-                       s->value += orig;
-                       continue;
-               }
-       }
-       datsize += orig;
-       if (debug['v'] || debug['z'])
-               Bprint(&bso, "datsize = %lux, bsssize = %lux\n", datsize, bsssize);
-       xdefine("setSB", SDATA, 0L+BIG);
+       xdefine("setSB", SDATA, 0L);
        xdefine("bdata", SDATA, 0L);
        xdefine("edata", SDATA, datsize);
        xdefine("end", SBSS, datsize+bsssize);
        xdefine("etext", STEXT, 0L);
 }
 
-void
-undef(void)
+Prog*
+brchain(Prog *p)
 {
        int i;
-       Sym *s;
 
-       for(i=0; i<NHASH; i++)
-       for(s = hash[i]; s != S; s = s->link)
-               if(s->type == SXREF)
-                       diag("%s: not defined", s->name);
+       for(i=0; i<20; i++) {
+               if(p == P || !isbranch(p->as))
+                       return p;
+               p = p->cond;
+       }
+       return P;
 }
 
 void
@@ -246,10 +214,10 @@ loop:
        a = p->as;
        if(a == ATEXT)
                curtext = p;
-       if(a == AJMP) {
+       if(isbranch(a)) {
                q = p->cond;
                if(q != P) {
-                       p->mark = FOLL;
+                       p->mark |= FOLL;
                        p = q;
                        if(!(p->mark & FOLL))
                                goto loop;
@@ -264,9 +232,9 @@ loop:
                                i--;
                                continue;
                        }
-                       if(a == AJMP || a == ARET || a == AREI)
+                       if(isbranch(a) || isreturn(a))
                                goto copy;
-                       if(!q->cond || (q->cond->mark&FOLL))
+                       if(q->cond == nil || (q->cond->mark&FOLL))
                                continue;
                        if(a != ABEQ && a != ABNE)
                                continue;
@@ -276,7 +244,7 @@ loop:
                                *r = *p;
                                if(!(r->mark&FOLL))
                                        print("cant happen 1\n");
-                               r->mark = FOLL;
+                               r->mark |= FOLL;
                                if(p != q) {
                                        p = p->link;
                                        lastp->link = r;
@@ -285,11 +253,9 @@ loop:
                                }
                                lastp->link = r;
                                lastp = r;
-                               if(a == AJMP || a == ARET || a == AREI)
+                               if(isbranch(a) || isreturn(a))
                                        return;
-                               r->as = ABNE;
-                               if(a == ABNE)
-                                       r->as = ABEQ;
+                               r->as = a == ABNE? ABEQ: ABNE;
                                r->cond = p->link;
                                r->link = p->cond;
                                if(!(r->link->mark&FOLL))
@@ -299,7 +265,7 @@ loop:
                                return;
                        }
                }
-               a = AJMP;
+               a = branchop();
                q = prg();
                q->as = a;
                q->line = p->line;
@@ -308,17 +274,29 @@ loop:
                q->cond = p;
                p = q;
        }
-       p->mark = FOLL;
+       p->mark |= FOLL;
        lastp->link = p;
        lastp = p;
-       if(a == AJMP || a == ARET || a == AREI)
+       if(isbranch(a) || isreturn(a))
                return;
        if(p->cond != P)
-       if(a != AJSR && p->link != P) {
+       if(!iscall(a) && p->link != P) {
+               q = brchain(p->link);
+               if(canfollow(a))
+               if(q != P && (q->mark&FOLL)) {
+                       p->as = relinv(a);
+                       p->link = p->cond;
+                       p->cond = q;
+               }
                xfol(p->link);
-               p = p->cond;
-               if(p == P || (p->mark&FOLL))
+               q = brchain(p->cond);
+               if(q == P)
+                       q = p->cond;
+               if(q->mark&FOLL) {
+                       p->cond = q;
                        return;
+               }
+               p = q;
                goto loop;
        }
        p = p->link;
@@ -343,20 +321,35 @@ patch(void)
                a = p->as;
                if(a == ATEXT)
                        curtext = p;
-               if((a == AJSR || a == AJMP || a == ARET) &&
+               if((iscall(a) || isbranch(a) || isreturn(a)) &&
                   p->to.type != D_BRANCH && p->to.sym != S) {
                        s = p->to.sym;
-                       if(s->type != STEXT) {
+                       switch(s->type) {
+                       default:
                                diag("undefined: %s\n%P", s->name, p);
                                s->type = STEXT;
                                s->value = vexit;
+                               break;
+                       case STEXT:
+                               p->to.offset = s->value;
+                               break;
+                       case SUNDEF:
+                               if(!iscall(p->as))
+                                       diag("help: SUNDEF in AB || ARET");
+                               p->to.offset = 0;
+                               p->cond = UP;
+                               break;
                        }
-                       p->to.offset = s->value;
                        p->to.type = D_BRANCH;
                }
-               if(p->to.type != D_BRANCH)
+               if(p->cond == UP)
+                       continue;
+               if(p->to.type == D_BRANCH)
+                       c = p->to.offset;
+               else if(p->from.type == D_BRANCH)
+                       c = p->from.offset;
+               else
                        continue;
-               c = p->to.offset;
                for(q = firstp; q != P;) {
                        if(q->forwd != P)
                        if(c >= q->forwd->pc) {
@@ -377,16 +370,19 @@ patch(void)
        for(p = firstp; p != P; p = p->link) {
                if(p->as == ATEXT)
                        curtext = p;
-               if(p->cond != P) {
+               if(p->cond != P && p->cond != UP) {
                        p->cond = brloop(p->cond);
-                       if(p->cond != P)
-                       if(p->to.type == D_BRANCH)
-                               p->to.offset = p->cond->pc;
+                       if(p->cond != P){
+                               if(p->to.type == D_BRANCH)
+                                       p->to.offset = p->cond->pc;
+                               if(p->from.type == D_BRANCH)
+                                       p->from.offset = p->cond->pc;
+                       }
                }
        }
 }
 
-#define        LOG     5
+#define        LOG     6
 void
 mkfwd(void)
 {
@@ -426,12 +422,12 @@ brloop(Prog *p)
        int c;
 
        for(c=0; p!=P;) {
-               if(p->as != AJMP)
+               if(!isbranch(p->as))
                        return p;
                q = p->cond;
                if(q <= p) {
                        c++;
-                       if(q == p || c > 50)
+                       if(q == p || c > 5000)
                                break;
                }
                p = q;
@@ -439,57 +435,14 @@ brloop(Prog *p)
        return P;
 }
 
-long
-atolwhex(char *s)
-{
-       long n;
-       int f;
-
-       n = 0;
-       f = 0;
-       while(*s == ' ' || *s == '\t')
-               s++;
-       if(*s == '-' || *s == '+') {
-               if(*s++ == '-')
-                       f = 1;
-               while(*s == ' ' || *s == '\t')
-                       s++;
-       }
-       if(s[0]=='0' && s[1]){
-               if(s[1]=='x' || s[1]=='X'){
-                       s += 2;
-                       for(;;){
-                               if(*s >= '0' && *s <= '9')
-                                       n = n*16 + *s++ - '0';
-                               else if(*s >= 'a' && *s <= 'f')
-                                       n = n*16 + *s++ - 'a' + 10;
-                               else if(*s >= 'A' && *s <= 'F')
-                                       n = n*16 + *s++ - 'A' + 10;
-                               else
-                                       break;
-                       }
-               } else
-                       while(*s >= '0' && *s <= '7')
-                               n = n*8 + *s++ - '0';
-       } else
-               while(*s >= '0' && *s <= '9')
-                       n = n*10 + *s++ - '0';
-       if(f)
-               n = -n;
-       return n;
-}
-
-long
-rnd(long v, long r)
+void
+undef(void)
 {
-       long c;
+       int i;
+       Sym *s;
 
-       if(r <= 0)
-               return v;
-       v += r - 1;
-       c = v % r;
-       if(c < 0)
-               c += r;
-       v -= c;
-       return v;
+       for(i=0; i<NHASH; i++)
+       for(s = hash[i]; s != S; s = s->link)
+               if(s->type == SXREF)
+                       diag("%s: not defined", s->name);
 }