]> Cypherpunks repositories - gostls13.git/commitdiff
reg and peep
authorKen Thompson <ken@golang.org>
Sun, 23 Nov 2008 01:58:53 +0000 (17:58 -0800)
committerKen Thompson <ken@golang.org>
Sun, 23 Nov 2008 01:58:53 +0000 (17:58 -0800)
R=r
OCL=19871
CL=19871

src/cmd/6g/cgen.c
src/cmd/6g/gen.c
src/cmd/6g/gsubr.c
src/cmd/6g/opt.h
src/cmd/6g/peep.c
src/cmd/6g/reg.c
src/cmd/gc/go.h
src/cmd/gc/walk.c

index 4fb9e3415d6887b963c2e83517231acda8c07d17..d6f27a929609daadc75e1b9f71b746631b13f935 100644 (file)
@@ -176,12 +176,14 @@ cgen(Node *n, Node *res)
                        gins(optoas(OCMP, types[tptr]), &n1, &n2);
                        p1 = gbranch(optoas(OEQ, types[tptr]), T);
 
-                       n1.op = OINDREG;
-                       n1.type = types[TINT32];
-                       gmove(&n1, res);
+                       n2 = n1;
+                       n2.op = OINDREG;
+                       n2.type = types[TINT32];
+                       gmove(&n2, &n1);
 
                        patch(p1, pc);
 
+                       gmove(&n1, res);
                        regfree(&n1);
                        break;
                }
index 4851f5ad9c980d24ea73f29f681119ac968667d4..3d47360be80896e9a730f475045a8f40ccecb284 100644 (file)
@@ -100,9 +100,8 @@ if(throwreturn == N) {
        pc->as = ARET;  // overwrite AEND
        pc->lineno = lineno;
 
-       if(debug['N']) {
+       if(!debug['N'] || debug['R'] || debug['P'])
                regopt(ptxt);
-       }
 
        // fill in argument size
        ptxt->to.offset = rnd(curfn->type->argwid, maxround);
@@ -918,6 +917,33 @@ cgen_asop(Node *n)
        nl = n->left;
        nr = n->right;
 
+       if(nl->addable && nr->op == OLITERAL)
+       switch(n->etype) {
+       case OADD:
+               if(!isint[nl->type->etype])
+                       goto com;
+               if(mpgetfix(nr->val.u.xval) != 1)
+                       goto com;
+               gins(optoas(OINC, nl->type), N, nl);
+               goto ret;
+       case OSUB:
+               if(!isint[nl->type->etype])
+                       goto com;
+               if(mpgetfix(nr->val.u.xval) != 1)
+                       goto com;
+               gins(optoas(ODEC, nl->type), N, nl);
+               goto ret;
+
+       com:
+       case OXOR:
+       case OAND:
+       case OOR:
+               if(!isint[nl->type->etype])
+                       break;
+               gins(optoas(n->etype, nl->type), nr, nl);
+               goto ret;
+       }
+
        if(nr->ullman >= UINF && nl->ullman >= UINF) {
                tempname(&n1, nr->type);
                cgen(nr, &n1);
@@ -960,10 +986,12 @@ cgen_as(Node *nl, Node *nr, int op)
        Node nc, n1;
        Type *tl;
        uint32 w, c;
+       int iszer;
 
        if(nl == N)
                return;
 
+       iszer = 0;
        if(nr == N || isnil(nr)) {
                if(nl->op == OLIST) {
                        cgen_as(nl->left, nr, op);
@@ -1008,6 +1036,7 @@ cgen_as(Node *nl, Node *nr, int op)
                }
 
                /* invent a "zero" for the rhs */
+               iszer = 1;
                nr = &nc;
                memset(nr, 0, sizeof(*nr));
                switch(tl->etype) {
@@ -1062,6 +1091,9 @@ cgen_as(Node *nl, Node *nr, int op)
                return;
 
        cgen(nr, nl);
+       if(iszer && nl->addable)
+               gins(ANOP, nl, N);      // used
+               
 
 ret:
        ;
index 62e986a16956af326160b3bb06ce616ec91177db..273e10f873faea2f638f27e8566e3d9d94c7f9be 100644 (file)
@@ -383,7 +383,7 @@ gmove(Node *f, Node *t)
        case TPTR32:
                a = AMOVL;
                if(t64)
-                       a = AMOVLQZX;   /* could probably use plain MOVL */
+                       a = AMOVLQZX;
                goto ld;
        case TINT64:
                if(isfloat[tt]) {
@@ -480,50 +480,50 @@ gmove(Node *f, Node *t)
 /*
  * integer to integer
  ********
              a = AGOK;       break;
-
      case CASE(TBOOL, TBOOL):
      case CASE(TINT8, TBOOL):
      case CASE(TUINT8, TBOOL):
      case CASE(TINT16, TBOOL):
      case CASE(TUINT16, TBOOL):
      case CASE(TINT32, TBOOL):
      case CASE(TUINT32, TBOOL):
      case CASE(TPTR64, TBOOL):
-
      case CASE(TBOOL, TINT8):
      case CASE(TINT8, TINT8):
      case CASE(TUINT8, TINT8):
      case CASE(TINT16, TINT8):
      case CASE(TUINT16, TINT8):
      case CASE(TINT32, TINT8):
      case CASE(TUINT32, TINT8):
      case CASE(TPTR64, TINT8):
-
      case CASE(TBOOL, TUINT8):
      case CASE(TINT8, TUINT8):
      case CASE(TUINT8, TUINT8):
      case CASE(TINT16, TUINT8):
      case CASE(TUINT16, TUINT8):
      case CASE(TINT32, TUINT8):
      case CASE(TUINT32, TUINT8):
      case CASE(TPTR64, TUINT8):
-
      case CASE(TINT16, TINT16):
      case CASE(TUINT16, TINT16):
      case CASE(TINT32, TINT16):
      case CASE(TUINT32, TINT16):
      case CASE(TPTR64, TINT16):
-
      case CASE(TINT16, TUINT16):
      case CASE(TUINT16, TUINT16):
      case CASE(TINT32, TUINT16):
      case CASE(TUINT32, TUINT16):
      case CASE(TPTR64, TUINT16):
-
      case CASE(TINT64, TUINT):
      case CASE(TINT64, TUINT32):
      case CASE(TUINT64, TUINT32):
*             a = AGOK;       break;
+
*     case CASE(TBOOL, TBOOL):
*     case CASE(TINT8, TBOOL):
*     case CASE(TUINT8, TBOOL):
*     case CASE(TINT16, TBOOL):
*     case CASE(TUINT16, TBOOL):
*     case CASE(TINT32, TBOOL):
*     case CASE(TUINT32, TBOOL):
*     case CASE(TPTR64, TBOOL):
+
*     case CASE(TBOOL, TINT8):
*     case CASE(TINT8, TINT8):
*     case CASE(TUINT8, TINT8):
*     case CASE(TINT16, TINT8):
*     case CASE(TUINT16, TINT8):
*     case CASE(TINT32, TINT8):
*     case CASE(TUINT32, TINT8):
*     case CASE(TPTR64, TINT8):
+
*     case CASE(TBOOL, TUINT8):
*     case CASE(TINT8, TUINT8):
*     case CASE(TUINT8, TUINT8):
*     case CASE(TINT16, TUINT8):
*     case CASE(TUINT16, TUINT8):
*     case CASE(TINT32, TUINT8):
*     case CASE(TUINT32, TUINT8):
*     case CASE(TPTR64, TUINT8):
+
*     case CASE(TINT16, TINT16):
*     case CASE(TUINT16, TINT16):
*     case CASE(TINT32, TINT16):
*     case CASE(TUINT32, TINT16):
*     case CASE(TPTR64, TINT16):
+
*     case CASE(TINT16, TUINT16):
*     case CASE(TUINT16, TUINT16):
*     case CASE(TINT32, TUINT16):
*     case CASE(TUINT32, TUINT16):
*     case CASE(TPTR64, TUINT16):
+
*     case CASE(TINT64, TUINT):
*     case CASE(TINT64, TUINT32):
*     case CASE(TUINT64, TUINT32):
  *****/
                a = AMOVL;
                break;
@@ -534,25 +534,21 @@ gmove(Node *f, Node *t)
        case CASE(TUINT64, TINT8):
        case CASE(TUINT64, TINT16):
        case CASE(TUINT64, TINT32):
+               a = AMOVLQSX;           // this looks bad
+               break;
+
        case CASE(TINT32, TINT64):
        case CASE(TINT32, TPTR64):
                a = AMOVLQSX;
-//             if(f->op == OCONST) {
-//                     f->val.vval &= (uvlong)0xffffffffU;
-//                     if(f->val.vval & 0x80000000)
-//                             f->val.vval |= (vlong)0xffffffff << 32;
-//                     a = AMOVQ;
-//             }
                break;
 
        case CASE(TUINT32, TINT64):
        case CASE(TUINT32, TUINT64):
        case CASE(TUINT32, TPTR64):
-               a = AMOVL;      /* same effect as AMOVLQZX */
-//             if(f->op == OCONST) {
-//                     f->val.vval &= (uvlong)0xffffffffU;
-//                     a = AMOVQ;
-//             }
+       case CASE(TPTR32, TINT64):
+       case CASE(TPTR32, TUINT64):
+       case CASE(TPTR32, TPTR64):
+               a = AMOVLQZX;
                break;
 
        case CASE(TPTR64, TINT64):
@@ -1239,6 +1235,50 @@ optoas(int op, Type *t)
                a = ASUBSD;
                break;
 
+       case CASE(OINC, TINT8):
+       case CASE(OINC, TUINT8):
+               a = AINCB;
+               break;
+
+       case CASE(OINC, TINT16):
+       case CASE(OINC, TUINT16):
+               a = AINCW;
+               break;
+
+       case CASE(OINC, TINT32):
+       case CASE(OINC, TUINT32):
+       case CASE(OINC, TPTR32):
+               a = AINCL;
+               break;
+
+       case CASE(OINC, TINT64):
+       case CASE(OINC, TUINT64):
+       case CASE(OINC, TPTR64):
+               a = AINCQ;
+               break;
+
+       case CASE(ODEC, TINT8):
+       case CASE(ODEC, TUINT8):
+               a = ADECB;
+               break;
+
+       case CASE(ODEC, TINT16):
+       case CASE(ODEC, TUINT16):
+               a = ADECW;
+               break;
+
+       case CASE(ODEC, TINT32):
+       case CASE(ODEC, TUINT32):
+       case CASE(ODEC, TPTR32):
+               a = ADECL;
+               break;
+
+       case CASE(ODEC, TINT64):
+       case CASE(ODEC, TUINT64):
+       case CASE(ODEC, TPTR64):
+               a = ADECQ;
+               break;
+
        case CASE(OMINUS, TINT8):
        case CASE(OMINUS, TUINT8):
                a = ANEGB;
index a73e45ffc71c74a763c0448be4dd6f27d7385a3b..571bcd6cb77b0e1d276ad67e1cfd0f6f5a81d65a 100644 (file)
@@ -60,7 +60,6 @@ struct        Bits
        uint32  b[BITS];
 };
 
-
 struct Reg
 {
 
@@ -75,14 +74,12 @@ struct      Reg
        Bits    regdiff;
        Bits    act;
 
-       int32   regu;
-       int32   loop;           /* could be shorter */
-       int32   rpo;            /* reverse post ordering */
+       int32   regu;           // register used bitmap
+       int32   rpo;            // reverse post ordering
        int32   active;
 
-//     uint32  magic;
-//     int32   pc;
-//     Reg*    log5;
+       uint16  loop;           // x5 for every loop
+       uchar   refset;         // diagnostic generated
 
        Reg*    p1;
        Reg*    p2;
@@ -130,10 +127,9 @@ EXTERN     Bits    externs;
 EXTERN Bits    params;
 EXTERN Bits    consts;
 EXTERN Bits    addrs;
+EXTERN Bits    ovar;
 EXTERN int     change;
 EXTERN Bits    zbits;
-EXTERN uchar   typechlpfd[NTYPE];      // botch
-EXTERN uchar   typev[NTYPE];           // botch
 EXTERN int32   maxnr;
 EXTERN int32*  idom;
 
@@ -150,6 +146,15 @@ int        beq(Bits, Bits);
 int    bset(Bits, uint);
 int    Qconv(Fmt *fp);
 int    bitno(int32);
+struct
+{
+       int32   ncvtreg;
+       int32   nspill;
+       int32   nreload;
+       int32   ndelmov;
+       int32   nvar;
+       int32   naddr;
+} ostats;
 
 /*
  * reg.c
@@ -167,6 +172,8 @@ void        paint1(Reg*, int);
 uint32 paint2(Reg*, int);
 void   paint3(Reg*, int, int32, int);
 void   addreg(Adr*, int);
+void   dumpit(char *str, Reg *r0);
+int    noreturn(Prog *p);
 
 /*
  * peep.c
index b85e88d158879a410648d339e49e2af2abe4f08b..cdf8a8bc351f6ef517c90065f3ddb8c9e7869fe4 100644 (file)
@@ -31,6 +31,7 @@
 #include "gg.h"
 #include "opt.h"
 
+
 static int
 needc(Prog *p)
 {
@@ -67,7 +68,7 @@ rnops(Reg *r)
        Reg *r1;
 
        if(r != R)
-       for(;;){
+       for(;;) {
                p = r->prog;
                if(p->as != ANOP || p->from.type != D_NONE || p->to.type != D_NONE)
                        break;
@@ -103,6 +104,8 @@ peep(void)
                        r2->link = r1;
 
                        r2->prog = p;
+                       p->reg = r2;
+
                        r2->p1 = r;
                        r->s1 = r2;
                        r2->s1 = r1;
@@ -119,10 +122,11 @@ peep(void)
                }
        }
 
-       pc = 0; /* speculating it won't kill */
-
 loop1:
 
+       if(debug['P'] && debug['v'])
+               dumpit("loop1", firstr);
+
        t = 0;
        for(r=firstr; r!=R; r=r->link) {
                p = r->prog;
@@ -186,13 +190,15 @@ loop1:
                        if(p->from.offset == -1){
                                if(p->as == AADDQ)
                                        p->as = ADECQ;
-                               else if(p->as == AADDL)
+                               else
+                               if(p->as == AADDL)
                                        p->as = ADECL;
                                else
                                        p->as = ADECW;
                                p->from = zprog.from;
                        }
-                       else if(p->from.offset == 1){
+                       else
+                       if(p->from.offset == 1){
                                if(p->as == AADDQ)
                                        p->as = AINCQ;
                                else if(p->as == AADDL)
@@ -211,16 +217,19 @@ loop1:
                        if(p->from.offset == -1) {
                                if(p->as == ASUBQ)
                                        p->as = AINCQ;
-                               else if(p->as == ASUBL)
+                               else
+                               if(p->as == ASUBL)
                                        p->as = AINCL;
                                else
                                        p->as = AINCW;
                                p->from = zprog.from;
                        }
-                       else if(p->from.offset == 1){
+                       else
+                       if(p->from.offset == 1){
                                if(p->as == ASUBQ)
                                        p->as = ADECQ;
-                               else if(p->as == ASUBL)
+                               else
+                               if(p->as == ASUBL)
                                        p->as = ADECL;
                                else
                                        p->as = ADECW;
@@ -239,9 +248,14 @@ excise(Reg *r)
        Prog *p;
 
        p = r->prog;
+       if(debug['P'] && debug['v'])
+               print("%P ===delete===\n", p);
+
        p->as = ANOP;
        p->from = zprog.from;
        p->to = zprog.to;
+
+       ostats.ndelmov++;
 }
 
 Reg*
index 3e319919dba752d31d976b3ea6926a420e2b3cd5..0715faa0972924b109a184ea4d3a503403650c61 100644 (file)
 #include "opt.h"
 
 #define        P2R(p)  (Reg*)(p->reg)
-#define        MAGIC   0xb00fbabe
 
 static int     first   = 1;
-static void    dumpit(char *str, Reg *r0);
-static int     noreturn(Prog *p);
 
 Reg*
 rega(void)
@@ -70,6 +67,30 @@ rcmp(const void *a1, const void *a2)
        return p2->varno - p1->varno;
 }
 
+void
+setoutvar(void)
+{
+       Type *t;
+       Node *n;
+       Addr a;
+       Iter save;
+       Bits bit;
+       int z;
+
+       t = structfirst(&save, getoutarg(curfn->type));
+       while(t != T) {
+               n = nodarg(t, 1);
+               a = zprog.from;
+               naddr(n, &a);
+               bit = mkvar(R, &a);
+               for(z=0; z<BITS; z++)
+                       ovar.b[z] |= bit.b[z];
+               t = structnext(&save);
+       }
+//if(bany(b))
+//print("ovars = %Q\n", &ovar);
+}
+
 void
 regopt(Prog *firstp)
 {
@@ -93,8 +114,12 @@ regopt(Prog *firstp)
                params.b[z] = 0;
                consts.b[z] = 0;
                addrs.b[z] = 0;
+               ovar.b[z] = 0;
        }
 
+       // build list of return variables
+       setoutvar();
+
        /*
         * pass 1
         * build aux data structure
@@ -221,6 +246,15 @@ regopt(Prog *firstp)
                /*
                 * right side read+write
                 */
+               case AINCB:
+               case AINCL:
+               case AINCQ:
+               case AINCW:
+               case ADECB:
+               case ADECL:
+               case ADECQ:
+               case ADECW:
+
                case AADDB:
                case AADDL:
                case AADDQ:
@@ -380,7 +414,9 @@ regopt(Prog *firstp)
        }
        if(firstr == R)
                return;
-//dumpit("pass1", firstr);
+
+       if(debug['R'] && debug['v'])
+               dumpit("pass1", firstr);
 
        /*
         * pass 2
@@ -396,7 +432,7 @@ regopt(Prog *firstp)
                        if(r1 == R)
                                fatal("rnil %P", p);
                        if(r1 == r) {
-                               fatal("ref to self %P", p);
+                               //fatal("ref to self %P", p);
                                continue;
                        }
                        r->s2 = r1;
@@ -404,7 +440,9 @@ regopt(Prog *firstp)
                        r1->p2 = r;
                }
        }
-//dumpit("pass2", firstr);
+
+       if(debug['R'] && debug['v'])
+               dumpit("pass2", firstr);
 
        /*
         * pass 2.5
@@ -414,7 +452,9 @@ regopt(Prog *firstp)
                r->active = 0;
        change = 0;
        loopit(firstr, nr);
-//dumpit("pass2.5", firstr);
+
+       if(debug['R'] && debug['v'])
+               dumpit("pass2.5", firstr);
 
        /*
         * pass 3
@@ -443,7 +483,8 @@ loop11:
        if(change)
                goto loop1;
 
-//dumpit("pass3", firstr);
+       if(debug['R'] && debug['v'])
+               dumpit("pass3", firstr);
 
        /*
         * pass 4
@@ -458,7 +499,8 @@ loop2:
        if(change)
                goto loop2;
 
-//dumpit("pass4", firstr);
+       if(debug['R'] && debug['v'])
+               dumpit("pass4", firstr);
 
        /*
         * pass 5
@@ -470,10 +512,11 @@ loop2:
                for(z=0; z<BITS; z++)
                        bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) &
                          ~(externs.b[z] | params.b[z] | addrs.b[z] | consts.b[z]);
-               if(bany(&bit)) {
-                       warn("used and not set: %Q", bit);
-                       if(debug['R'] && !debug['w'])
-                               print("used and not set: %Q\n", bit);
+               if(bany(&bit) && !r->refset) {
+                       // should never happen - all variables are preset
+                       if(debug['w'])
+                               print("%L: used and not set: %Q\n", r->prog->lineno, bit);
+                       r->refset = 1;
                }
        }
        for(r = firstr; r != R; r = r->link)
@@ -484,10 +527,10 @@ loop2:
                for(z=0; z<BITS; z++)
                        bit.b[z] = r->set.b[z] &
                          ~(r->refahead.b[z] | r->calahead.b[z] | addrs.b[z]);
-               if(bany(&bit)) {
-                       warn("set and not used: %Q", bit);
-                       if(debug['R'])
-                               print("set and not used: %Q\n", bit);
+               if(bany(&bit) && !r->refset) {
+                       if(debug['w'])
+                               print("%L: set and not used: %Q\n", r->prog->lineno, bit);
+                       r->refset = 1;
                        excise(r);
                }
                for(z=0; z<BITS; z++)
@@ -497,20 +540,15 @@ loop2:
                        rgp->enter = r;
                        rgp->varno = i;
                        change = 0;
-                       if(debug['R'] && debug['v'])
-                               print("\n");
                        paint1(r, i);
                        bit.b[i/32] &= ~(1L<<(i%32));
-                       if(change <= 0) {
-                               if(debug['R'])
-                                       print("%L$%d: %Q\n",
-                                               r->prog->lineno, change, blsh(i));
+                       if(change <= 0)
                                continue;
-                       }
                        rgp->cost = change;
                        nregion++;
                        if(nregion >= NRGN) {
-                               fatal("too many regions");
+                               if(debug['R'] && debug['v'])
+                                       print("too many regions\n");
                                goto brk;
                        }
                        rgp++;
@@ -534,11 +572,14 @@ brk:
                rgp++;
        }
 
+       if(debug['R'] && debug['v'])
+               dumpit("pass6", firstr);
+
        /*
         * pass 7
         * peep-hole on basic block
         */
-       if(debug['P']) {
+       if(!debug['R'] || debug['P']) {
                peep();
        }
 
@@ -547,14 +588,43 @@ brk:
         * free aux structures
         */
        for(p=firstp; p!=P; p=p->link) {
-               while(p->link && p->link->as == ANOP)
+               while(p->link != P && p->link->as == ANOP)
                        p->link = p->link->link;
+               if(p->to.type == D_BRANCH)
+                       while(p->to.branch != P && p->to.branch->as == ANOP)
+                               p->to.branch = p->to.branch->link;
        }
 
        if(r1 != R) {
                r1->link = freer;
                freer = firstr;
        }
+
+       if(debug['R']) {
+               if(ostats.ncvtreg ||
+                  ostats.nspill ||
+                  ostats.nreload ||
+                  ostats.ndelmov ||
+                  ostats.nvar ||
+                  ostats.naddr ||
+                  0)
+                       print("\nstats\n");
+
+               if(ostats.ncvtreg)
+                       print(" %4ld cvtreg\n", ostats.ncvtreg);
+               if(ostats.nspill)
+                       print(" %4ld spill\n", ostats.nspill);
+               if(ostats.nreload)
+                       print(" %4ld reload\n", ostats.nreload);
+               if(ostats.ndelmov)
+                       print(" %4ld delmov\n", ostats.ndelmov);
+               if(ostats.nvar)
+                       print(" %4ld delmov\n", ostats.nvar);
+               if(ostats.naddr)
+                       print(" %4ld delmov\n", ostats.naddr);
+
+               memset(&ostats, 0, sizeof(ostats));
+       }
 }
 
 /*
@@ -585,7 +655,7 @@ addmove(Reg *r, int bn, int rn, int f)
        a->etype = v->etype;
        a->type = v->name;
 
-       // need to chean this up with wptr and
+       // need to clean this up with wptr and
        // some of the defaults
        p1->as = AMOVL;
        switch(v->etype) {
@@ -611,7 +681,7 @@ addmove(Reg *r, int bn, int rn, int f)
                p1->as = AMOVSS;
                break;
        case TFLOAT64:
-               p1->as = AMOVSS;
+               p1->as = AMOVSD;
                break;
        case TINT:
        case TUINT:
@@ -631,8 +701,9 @@ addmove(Reg *r, int bn, int rn, int f)
                if(v->etype == TUINT16)
                        p1->as = AMOVW;
        }
-//     if(debug['R'])
-               print("%P\t.a%P\n", p, p1);
+       if(debug['R'] && debug['v'])
+               print("%P ===add=== %P\n", p, p1);
+       ostats.nspill++;
 }
 
 uint32
@@ -670,8 +741,10 @@ mkvar(Reg *r, Adr *a)
         * mark registers used
         */
        t = a->type;
-       r->regu |= doregbits(t);
-       r->regu |= doregbits(a->index);
+       if(r != R) {
+               r->regu |= doregbits(t);
+               r->regu |= doregbits(a->index);
+       }
 
        switch(t) {
        default:
@@ -682,6 +755,7 @@ mkvar(Reg *r, Adr *a)
                for(z=0; z<BITS; z++)
                        addrs.b[z] |= bit.b[z];
                a->type = t;
+               ostats.naddr++;
                goto none;
        case D_EXTERN:
        case D_STATIC:
@@ -727,6 +801,7 @@ mkvar(Reg *r, Adr *a)
        v->etype = et;
        if(debug['R'])
                print("bit=%2d et=%2d %D\n", i, et, a);
+       ostats.nvar++;
 
 out:
        bit = blsh(i);
@@ -738,7 +813,8 @@ out:
                        params.b[z] |= bit.b[z];
        if(v->etype != et) {
                /* funny punning */
-print("pun %d %d %S\n", v->etype, et, s);
+               if(debug['R'])
+                       print("pun %d %d %S\n", v->etype, et, s);
                for(z=0; z<BITS; z++)
                        addrs.b[z] |= bit.b[z];
        }
@@ -787,9 +863,10 @@ prop(Reg *r, Bits ref, Bits cal)
 
                case ARET:
                        for(z=0; z<BITS; z++) {
-                               cal.b[z] = externs.b[z];
+                               cal.b[z] = externs.b[z] | ovar.b[z];
                                ref.b[z] = 0;
                        }
+                       break;
                }
                for(z=0; z<BITS; z++) {
                        ref.b[z] = (ref.b[z] & ~r1->set.b[z]) |
@@ -1044,9 +1121,6 @@ paint1(Reg *r, int bn)
 
        if(LOAD(r) & ~(r->set.b[z]&~(r->use1.b[z]|r->use2.b[z])) & bb) {
                change -= CLOAD * r->loop;
-               if(debug['R'] && debug['v'])
-                       print("%ld%P\tld %Q $%d\n", r->loop,
-                               r->prog, blsh(bn), change);
        }
        for(;;) {
                r->act.b[z] |= bb;
@@ -1054,23 +1128,14 @@ paint1(Reg *r, int bn)
 
                if(r->use1.b[z] & bb) {
                        change += CREF * r->loop;
-                       if(debug['R'] && debug['v'])
-                               print("%ld%P\tu1 %Q $%d\n", r->loop,
-                                       p, blsh(bn), change);
                }
 
                if((r->use2.b[z]|r->set.b[z]) & bb) {
                        change += CREF * r->loop;
-                       if(debug['R'] && debug['v'])
-                               print("%ld%P\tu2 %Q $%d\n", r->loop,
-                                       p, blsh(bn), change);
                }
 
                if(STORE(r) & r->regdiff.b[z] & bb) {
                        change -= CLOAD * r->loop;
-                       if(debug['R'] && debug['v'])
-                               print("%ld%P\tst %Q $%d\n", r->loop,
-                                       p, blsh(bn), change);
                }
 
                if(r->refbehind.b[z] & bb)
@@ -1226,18 +1291,18 @@ paint3(Reg *r, int bn, int32 rb, int rn)
                p = r->prog;
 
                if(r->use1.b[z] & bb) {
-                       if(debug['R'])
+                       if(debug['R'] && debug['v'])
                                print("%P", p);
                        addreg(&p->from, rn);
-                       if(debug['R'])
-                               print("\t.c%P\n", p);
+                       if(debug['R'] && debug['v'])
+                               print(" ===change== %P\n", p);
                }
                if((r->use2.b[z]|r->set.b[z]) & bb) {
-                       if(debug['R'])
+                       if(debug['R'] && debug['v'])
                                print("%P", p);
                        addreg(&p->to, rn);
-                       if(debug['R'])
-                               print("\t.c%P\n", p);
+                       if(debug['R'] && debug['v'])
+                               print(" ===change== %P\n", p);
                }
 
                if(STORE(r) & r->regdiff.b[z] & bb)
@@ -1272,6 +1337,8 @@ addreg(Adr *a, int rn)
        a->sym = 0;
        a->offset = 0;
        a->type = rn;
+
+       ostats.ncvtreg++;
 }
 
 int32
@@ -1286,8 +1353,7 @@ RtoB(int r)
 int
 BtoR(int32 b)
 {
-
-       b &= 0xffffL;
+       b &= 0x3fffL;           // no R14 or R15
        if(b == 0)
                return 0;
        return bitno(b) + D_AX;
@@ -1317,7 +1383,7 @@ BtoF(int32 b)
        return bitno(b) - 16 + FREGMIN;
 }
 
-static void
+void
 dumpit(char *str, Reg *r0)
 {
        Reg *r, *r1;
@@ -1380,7 +1446,7 @@ dumpit(char *str, Reg *r0)
 
 static Sym*    symlist[10];
 
-static int
+int
 noreturn(Prog *p)
 {
        Sym *s;
@@ -1388,6 +1454,7 @@ noreturn(Prog *p)
 
        if(symlist[0] == S) {
                symlist[0] = pkglookup("throwindex", "sys");
+               symlist[1] = pkglookup("panicl", "sys");
        }
 
        s = p->to.sym;
index c5e35a1e481ba4447e9b572e50e338ada4420ef8..ce1d4cee504ecf22b55d2a6f6d1ce639bb397e6d 100644 (file)
@@ -284,6 +284,7 @@ enum
        OEQ, ONE, OLT, OLE, OGE, OGT,
        OADD, OSUB, OOR, OXOR,
        OMUL, ODIV, OMOD, OLSH, ORSH, OAND,
+       OINC, ODEC,     // placeholders - not used
        OFUNC,
        OLABEL,
        OBREAK,
index 685267c279a32d2a76a08947f0ba82cba884fd4b..1c87e05eb0fbb3480af68ada76f6e75ddf22a06e 100644 (file)
@@ -1094,7 +1094,20 @@ loop:
        goto ret;
 
 nottop:
-       yyerror("didn't expect %O here", n->op);
+       switch(top) {
+       default:
+               yyerror("didn't expect %O here", n->op);
+               break;
+       case Etop:
+               yyerror("operation %O not allowed in statement context", n->op);
+               break;
+       case Elv:
+               yyerror("operation %O not allowed in assignment context", n->op);
+               break;
+       case Erv:
+               yyerror("operation %O not allowed in expression context", n->op);
+               break;
+       }
        goto ret;
 
 badt: