Quick Search:

Mode

Context

Displaying 3 lines of context. None | Less | More | Full

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.48
 
1.49
 
MAIN:ragge:20030901082854
 
reader.c
_>3434  */
 3535 
 3636 # include "pass2.h"
<> 37+#include "external.h"
3738 
 3839 /*      some storage declarations */
<>39 -/*
 40 - * TODO: re-invent autoincr()/deltest()
 41 - */
 42 -
4340 int nrecur;
 4441 int lflag;
 4542 int x2debug;
     
 !
6259 void deltemp(NODE *p);
 6360 void optdump(struct interpass *ip);
 6461 void cvtemps(struct interpass *epil);
<> 62+static int findops(NODE *p);
6563 
 6664 #define DELAYS 20
 6765 NODE *deltrees[DELAYS];
     
 !
328326         switch (m = p->n_op) {
 329327 
 330328         case PLUS:
<>331 -                /*
 332 -                 * Be sure that both sides are addressable.
 333 -                 */
 334 -                if (!canaddr(p->n_left))
 335 -                        order(p->n_left, INTAREG|INTBREG);
 336 -                if (!canaddr(p->n_right))
 337 -                        order(p->n_right, INTAREG|INTBREG);
  329+                {
  330+                        struct optab *q;
  331+                        int rv;
338332 
<>339 -                /*
 340 -                 * If any of the leaves are already in a temp reg,
 341 -                 * try to add to it.
 342 -                 */
 343 -                if (istnode(p->n_left))
 344 -                        if ((m = nmatch(p, NDLEFT)) == MDONE)
 345 -                                goto cleanup;
 346 -                if (istnode(p->n_right))
 347 -                        if ((m = nmatch(p, NDRIGHT)) == MDONE)
 348 -                                goto cleanup;
  333+                        /*
  334+                         * Be sure that both sides are addressable.
  335+                         */
  336+                        if (!canaddr(p->n_left))
  337+                                order(p->n_left, INTAREG|INTBREG);
  338+                        if (!canaddr(p->n_right))
  339+                                order(p->n_right, INTAREG|INTBREG);
349340 
<>350 -                /*
 351 -                 * None of the leaves are in a temp register, try to find
 352 -                 * a matching instruction that ends in a register.
 353 -                 */
 354 -                if ((m = nmatch(p, 0)) == MDONE)
 355 -                        goto cleanup;
 356 -                /*
 357 -                 * Search for a match if any of the leaves are put
 358 -                 * in a register.  Use the dynamic programming
 359 -                 * algorithm?
 360 -                 * This can be made much more efficient.
 361 -                 */
 362 -                if (chkmatch(p, STAREG|STBREG, SANY, NDLEFT) == MDONE) {
 363 -                        /* offstar? */
 364 -                        order(p->n_left, INTAREG|INTBREG);
 365 -                        goto again;
  341+                        /*
  342+                         *
  343+                         */
  344+#define LTMP    1
  345+#define RTMP    2
  346+                        rv = findops(p);
  347+                        if (rv < 0)
  348+                                goto nomat;
  349+                        if (rv & LTMP)
  350+                                order(p->n_left, INTAREG|INTBREG);
  351+                        if (rv & RTMP)
  352+                                order(p->n_right, INTAREG|INTBREG);
  353+                
  354+
  355+                        q = &table[rv >> 2];
  356+                        if (!allo(p, q))
  357+                                cerror("allo failed");
  358+                        expand(p, INTAREG|INTBREG, q->cstring);
  359+                        reclaim(p, q->rewrite, INTAREG|INTBREG);
366360                 }
<>367 -                if (chkmatch(p, SANY, STAREG|STBREG, NDRIGHT) == MDONE) {
 368 -                        /* offstar? */
 369 -                        order(p->n_right, INTAREG|INTBREG);
 370 -                        goto again;
 371 -                }
 372 -                cerror("add failed");
 373 -                goto nomat;
  361+                goto cleanup;
  362+
374363         default:
 375364 #ifdef notyet
 376365                 if ((cookie & (INTAREG|INTBREG)) && optype(m) == LTYPE) {
     
 !
507496         case INCR/* INCR and DECR */
 508497                 if( setincr(p) ) goto again;
 509498 
<>510 -                /* x++ becomes (x += 1) -1; */
  499+                /* x++ becomes (x = x + 1) -1; */
511500 
<>512 -                if( cook & FOREFF ){  /* result not needed so inc or dec and be done with it */
 513 -                        /* x++ => x += 1 */
 514 -                        p->n_op = (p->n_op==INCR)?ASG PLUS:ASG MINUS;
 515 -                        goto again;
 516 -                        }
 517 -
518501                 p1 = tcopy(p);
<>519 -                reclaim( p->n_left, RNULL, 0 );
 520 -                p->n_left = p1;
 521 -                p1->n_op = (p->n_op==INCR)?ASG PLUS:ASG MINUS;
 522 -                p->n_op = (p->n_op==INCR)?MINUS:PLUS;
  502+                if (cook & FOREFF) {
  503+                        nfree(p->n_right);
  504+                        p->n_right = p1;
  505+                        p->n_op = ASSIGN;
  506+                        p1->n_op = (p->n_op == INCR) ? PLUS: MINUS;
  507+                } else {
  508+                        p2 = talloc();
  509+                        p2->n_rall = NOPREF;
  510+                        p2->n_name = "";
  511+                        p2->n_op = ASSIGN;
  512+                        p2->n_type = p->n_type;
  513+                        p2->n_left = p->n_left;
  514+                        p2->n_right = p1;
  515+                        p1->n_op = (p->n_op == INCR) ? PLUS: MINUS;
  516+                        p->n_op = (p->n_op == INCR) ? MINUS : PLUS;
  517+                }
523518                 goto again;
 524519 
 525520         case STASG:
     
 !
10981093                 break;
 10991094         }
 11001095 }
<_ 1096+
  1097+/*
  1098+ * Find the best ops for a given tree.
  1099+ * Different instruction sequences are graded as:
  1100+        add2 reg,reg     = 0
  1101+        add2 mem,reg     = 1
  1102+        add3 mem,reg,reg = 2
  1103+        add3 reg,mem,reg = 2
  1104+        add3 mem,mem,reg = 3
  1105+        move mem,reg ; add2 mem,reg     = 4
  1106+        move mem,reg ; add3 mem,reg,reg = 5
  1107+        move mem,reg ; move mem,reg ; add2 reg,reg = 6
  1108+        move mem,reg ; move mem,reg ; add3 reg,reg,reg = 7
  1109+ * The instruction with the lowest grading is emitted.
  1110+ */
  1111+int
  1112+findops(NODE *p)
  1113+{
  1114+        extern int *qtable[];
  1115+        struct optab *q;
  1116+        int i, shl, shr, tl, tr, is3, rsr, rsl;
  1117+        NODE *l, *r;
  1118+        int *ixp;
  1119+        int rv = -1, mtchno = 10;
  1120+
  1121+        ixp = qtable[p->n_op];
  1122+        for (i = 0; ixp[i] != 0; i++) {
  1123+                q = &table[ixp[i]];
  1124+
  1125+if (f2debug) printf("findop: ixp %d\n", ixp[i]);
  1126+                l = getlr(p, 'L');
  1127+                r = getlr(p, 'R');
  1128+                if (ttype(l->n_type, q->ltype) == 0 ||
  1129+                    ttype(r->n_type, q->rtype) == 0)
  1130+                        continue; /* Types must be correct */
  1131+
  1132+if (f2debug) printf("findop got types\n");
  1133+                shl = tshape(l, q->lshape);
  1134+                rsl = (q->lshape & (SAREG|STAREG)) != 0;
  1135+                if (shl == 0 && rsl == 0)
  1136+                        continue; /* useless */
  1137+if (f2debug) printf("findop lshape %d\n", shl);
  1138+if (f2debug) fwalk(l, e2print, 0);
  1139+                shr = tshape(r, q->rshape);
  1140+                rsr = (q->rshape & (SAREG|STAREG)) != 0;
  1141+                if (shr == 0 && rsr == 0)
  1142+                        continue; /* useless */
  1143+if (f2debug) printf("findop rshape %d\n", shr);
  1144+if (f2debug) fwalk(r, e2print, 0);
  1145+                if (q->needs & REWRITE)
  1146+                        break;  /* Done here */
  1147+
  1148+                tl = istnode(p->n_left);
  1149+                tr = istnode(p->n_right);
  1150+                is3 = ((q->needs & (NDLEFT|NDRIGHT)) == 0);
  1151+
  1152+                if (shl && shr) {
  1153+                        int got = 10;
  1154+                        /*
  1155+                         * Both shapes matches. If one of them is in a
  1156+                         * temp register and there is a corresponding
  1157+                         * 2-op instruction, be very happy. If not, but
  1158+                         * there is a 3-op instruction that ends in a reg,
  1159+                         * be quite happy. If neither, cannot do anything.
  1160+                         */
  1161+                        if (tl && (q->needs & NDLEFT)) {
  1162+                                got = 1;
  1163+                        } else if (tr && (q->needs & NDRIGHT)) {
  1164+                                got = 1;
  1165+                        } else if ((q->needs & (NDLEFT|NDRIGHT)) == 0) {
  1166+                                got = 3;
  1167+                        }
  1168+                        if (got < mtchno) {
  1169+                                mtchno = got;
  1170+                                rv = ixp[i] << 2;
  1171+                        }
  1172+                        if (got != 10)
  1173+                                continue;
  1174+                }
  1175+if (f2debug) printf("second\n");
  1176+                if (shr) {
  1177+                        /*
  1178+                         * Right shape matched. If left node can be put into
  1179+                         * a temporary register, and the current op matches,
  1180+                         * be happy.
  1181+                         */
  1182+                        if (q->needs & NDLEFT) {
  1183+                                if (4 < mtchno) {
  1184+                                        mtchno = 4;
  1185+                                        rv = (ixp[i] << 2) | LTMP;
  1186+                                }
  1187+                                continue; /* Can't do anything else */
  1188+                        } else if (is3) {
  1189+                                if (5 < mtchno) {
  1190+                                        mtchno = 5;
  1191+                                        rv = (ixp[i] << 2) | LTMP;
  1192+                                }
  1193+                                continue; /* Can't do anything else */
  1194+                        }
  1195+                }
  1196+if (f2debug) printf("third\n");
  1197+                if (shl) {
  1198+                        /*
  1199+                         * Left shape matched. If right node can be put into
  1200+                         * a temporary register, and the current op matches,
  1201+                         * be happy.
  1202+                         */
  1203+                        if (q->needs & NDRIGHT) {
  1204+                                if (4 < mtchno) {
  1205+                                        mtchno = 4;
  1206+                                        rv = (ixp[i] << 2) | RTMP;
  1207+                                }
  1208+                                continue; /* Can't do anything */
  1209+                        } else if (is3) {
  1210+                                if (5 < mtchno) {
  1211+                                        mtchno = 5;
  1212+                                        rv = (ixp[i] << 2) | RTMP;
  1213+                                }
  1214+                                continue; /* Can't do anything */
  1215+                        }
  1216+                }
  1217+                /*
  1218+                 * Neither of the shapes matched. Put both args in
  1219+                 * regs and be done with it.
  1220+                 */
  1221+                if (rsr && rsl) { /* both can be in reg */
  1222+                        if (is3) {
  1223+                                if (7 < mtchno) {
  1224+                                        mtchno = 7;
  1225+                                        rv = (ixp[i] << 2) | RTMP|LTMP;
  1226+                                }
  1227+                        } else {
  1228+                                if (6 < mtchno) {
  1229+                                        mtchno = 6;
  1230+                                        rv = (ixp[i] << 2) | RTMP|LTMP;
  1231+                                }
  1232+                        }
  1233+                }
  1234+        }
  1235+        return rv;
  1236+}
FishEye: Open Source License registered to PCC.
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-12-21 06:29 +0100