Quick Search:

Mode

Context

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

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.74
 
1.75
 
MAIN:ragge:20050917075840
 
regs.c
_>2626  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 2727  */
 2828 
<>29 -
 30 -/*
 31 - * Register allocation and assignment.
 32 - * Will walk through a tree and assign reasonable registers to
 33 - * each node in it.
 34 - *
 35 - * Basic principle of register assignment:
 36 - *      - If the node has no preferences or registers allocated,
 37 - *        do not allocate any registers but instead just recurse
 38 - *        down and see what we get.
 39 - *      - Follow the evaluation order setup by sucomp().
 40 - *      - All allocation is done on the way up.
 41 - *
 42 - * The member n_rall holds the allocated register if the table entry
 43 - * has needs. Return value used at rewriting is determined by the
 44 - * reclaim field in the table.
 45 - *
 46 - * The type regcode keeps track of allocated registers used when
 47 - * assigning registers. It is not stored in the node.
 48 - *
 49 - * alloregs() returns the return registers from each instruction.
 50 - */
 51 -
5229 #include "pass2.h"
 5330 #include <strings.h>
 5431 #include <stdlib.h>
 5532 
 5633 #define MAX(a,b) (((a) > (b)) ? (a) : (b))
<>57 -void printip(struct interpass *pole); /* XXX */
5834  
<>59 -#ifdef OLDSTYLE
 60 -static int usedregs;
 61 -int regblk[REGSZ];
 62 -
 63 -static int isfree(int wreg, int nreg);
 64 -static void setused(int wreg, int nreg);
 65 -static int findfree(int nreg, int breg);
 66 -
 67 -int finduni(NODE *p, int); /* XXX - used by movenode */
 68 -
6935 /*
<>70 - * Build a matrix to deal with different requirements of allocations.
 71 - */
 72 -#define R_DOR   000001
 73 -#define R_RREG  000002
 74 -#define R_LREG  000004
 75 -#define R_NASL  000010
 76 -#define R_NASR  000020
 77 -#define R_PREF  000040
 78 -#define R_RRGHT 000100
 79 -#define R_RLEFT 000200
 80 -#define R_RESC  000400
 81 -
 82 -/*
 83 - * Print the codeword in a readable format.
 84 - */
 85 -static void
 86 -prtcword(int cword)
 87 -{
 88 -        static char *names[] = { "DORIGHT", "RREG", "LREG", "NASL", "NASR",
 89 -            "PREF", "RRIGHT", "RLEFT", "RESCx" };
 90 -        int i, c;
 91 -
 92 -        for (i = c = 0; i < 9; i++) {
 93 -                if ((cword & (1 << i)) == 0)
 94 -                        continue;
 95 -                if (c)
 96 -                        fputc(',', stderr);
 97 -                fprintf(stderr, "%s", names[i]);
 98 -                c = 1;
 99 -        }
 100 -}
 101 -
 102 -/*
 103 - * Print temp registers inuse in a readable format.
 104 - */
 105 -static void
 106 -prtuse(void)
 107 -{
 108 -        int i, c;
 109 -
 110 -        fprintf(stderr, " reguse=<");
 111 -        for (i = c = 0; i < REGSZ; i++) {
 112 -                if (istreg(i) == 0)
 113 -                        continue;
 114 -                if ((regblk[i] & 1) == 0)
 115 -                        continue;
 116 -                if (c)
 117 -                        fputc(',', stderr);
 118 -                fprintf(stderr, "%s", rnames[i]);
 119 -                c = 1;
 120 -        }
 121 -        fputc('>', stderr);
 122 -}
 123 -
 124 -/*
 125 - * Create a node that will do reg-reg move.
 126 - */
 127 -NODE *
 128 -movenode(NODE *p, int reg)
 129 -{
 130 -        NODE *q = talloc();
 131 -
 132 -        q->n_op = MOVE;
 133 -        q->n_type = p->n_type;
 134 -        q->n_rval = q->n_rall = reg;
 135 -        q->n_left = p;
 136 -        if ((q->n_su = finduni(q, INTAREG|INTBREG)) == -1)
 137 -                comperr("movenode failed, subnode=%p", p);
 138 -        q->n_su |= LREG;
 139 -        return q;
 140 -}
 141 -
 142 -/*
 143 - * Get nreg number of (consecutive) registers.
 144 - * wantreg is a hint on which regs are preferred.
 145 - * XXX - check allowed regs.
 146 - */
 147 -regcode
 148 -getregs(int wantreg, int nreg, int breg)
 149 -{
 150 -        regcode regc;
 151 -
 152 -        if ((wantreg == NOPREF) || !isfree(wantreg, nreg)) {
 153 -                if ((wantreg = findfree(nreg, breg)) < 0)
 154 -                        comperr("getregs: can't alloc %d regs type %d",
 155 -                            nreg, breg);
 156 -        }
 157 -        setused(wantreg, nreg);
 158 -        MKREGC(regc, wantreg, nreg);
 159 -
 160 -        return regc;
 161 -}
 162 -
 163 -/*
 164 - * Free previously allocated registers.
 165 - */
 166 -void
 167 -freeregs(regcode regc)
 168 -{
 169 -        int reg = REGNUM(regc), cnt = REGSIZE(regc);
 170 -        int i;
 171 -
 172 -        for (i = reg; i < reg+cnt; i++) {
 173 -                if ((regblk[i] & 1) == 0)
 174 -                        comperr("freeregs: freeing free reg %d", i);
 175 -                regblk[i] &= ~1;
 176 -        }
 177 -}
 178 -
 179 -/*
 180 - * Free registers allocated by needs but not returned.
 181 - * Returns regcode of the returned registers.
 182 - */
 183 -static regcode
 184 -shave(regcode regc, int nreg, int rewrite)
 185 -{
 186 -        regcode regc2;
 187 -        int size;
 188 -
 189 -        if (nreg <= 1)
 190 -                return regc; /* No unneccessary regs allocated */
 191 -        size = REGSIZE(regc)/nreg;
 192 -        if (rewrite & RESC1) {
 193 -                MKREGC(regc2, REGNUM(regc)+size, REGSIZE(regc)-size);
 194 -                MKREGC(regc, REGNUM(regc), size);
 195 -        } else if (rewrite & RESC2) {
 196 -                if (nreg > 2) {
 197 -                        MKREGC(regc2, REGNUM(regc)+2*size, size);
 198 -                        freeregs(regc2);
 199 -                }
 200 -                MKREGC(regc2, REGNUM(regc), size);
 201 -                MKREGC(regc, REGNUM(regc)+size, size);
 202 -        } else if (rewrite & RESC3) {
 203 -                MKREGC(regc2, REGNUM(regc), REGSIZE(regc)-size);
 204 -                MKREGC(regc, REGNUM(regc)+2*size, size);
 205 -        }
 206 -        freeregs(regc2);
 207 -        return regc;
 208 -}
 209 -
 210 -void
 211 -genregs(NODE *p)
 212 -{
 213 -        regcode regc;
 214 -        int i;
 215 -
 216 -        for (i = 0; i < REGSZ; i++)
 217 -                regblk[i] = 0;
 218 -        usedregs = 0;
 219 -        if (p->n_op == FORCE) {
 220 -                regc = alloregs(p, RETREG);
 221 -                if (REGNUM(regc) != RETREG)
 222 -                        p->n_left = movenode(p->n_left, RETREG);
 223 -                freeregs(regc);
 224 -                setused(RETREG, REGSIZE(regc));
 225 -                MKREGC(regc, RETREG, REGSIZE(regc));
 226 -        } else
 227 -                regc = alloregs(p, NOPREF);
 228 -
 229 -        /* Check that no unwanted registers are still allocated */
 230 -        freeregs(regc);
 231 -        for (i = 0; i < REGSZ; i++) {
 232 -                if (istreg(i) == 0)
 233 -                        continue;
 234 -                if (regblk[i] & 1)
 235 -                        comperr("register %d lost!", i);
 236 -        }
 237 -}
 238 -
 239 -/*
 240 - * Check if nreg registers at position wreg are unused.
 241 - */
 242 -static int
 243 -isfree(int wreg, int nreg)
 244 -{
 245 -        int i, isb, ist;
 246 -
 247 -        if (wreg < 0)
 248 -                return 0;
 249 -        isb = isbreg(wreg) != 0;
 250 -        ist = istreg(wreg) != 0;
 251 -        for (i = wreg; i < (wreg+nreg); i++) {
 252 -                if (isb != (isbreg(i) != 0))
 253 -                        return 0;
 254 -                if (ist != (istreg(i) != 0))
 255 -                        return 0;
 256 -                if ((regblk[i] & 1) == 1)
 257 -                        return 0;
 258 -        }
 259 -        return 1; /* Free! */
 260 -}
 261 -
 262 -/*
 263 - * Set use bit on some registers.
 264 - */
 265 -static void
 266 -setused(int wreg, int nreg)
 267 -{
 268 -        int i;
 269 -
 270 -        if (wreg < 0)
 271 -                comperr("setused on reg %d size %d\n", wreg, nreg);
 272 -        for (i = wreg; i < (wreg+nreg); i++) {
 273 -                if (regblk[i] & 1)
 274 -                        comperr("setused on used reg %d size %d\n", wreg, nreg);
 275 -                regblk[i] |= 1;
 276 -        }
 277 -}
 278 -
 279 -/*
 280 - * Find nreg free regs somewhere.
 281 - */
 282 -static int
 283 -findfree(int nreg, int breg)
 284 -{
 285 -        int i;
 286 -
 287 -        for (i = 0; i < REGSZ-nreg; i++) {
 288 -                if ((breg && !isbreg(i)) || (!breg && isbreg(i)))
 289 -                        continue;
 290 -                if (isfree(i, nreg))
 291 -                        return i;
 292 -        }
 293 -        return -1;
 294 -}
 295 -
 296 -/*
 297 - * Be sure not to trash a non-temporary register.
 298 - */
 299 -static NODE *
 300 -checkreg(regcode *reg, int wantreg, NODE *p)
 301 -{
 302 -        regcode regc;
 303 -
 304 -        if (!istreg(REGNUM(*reg)) && wantreg != REGNUM(*reg)) {
 305 -                /* left is neither temporary, nor wanted and
 306 -                 * is soon to be trashed. Must move */
 307 -                regc = getregs(NOPREF, REGSIZE(*reg), isbreg(wantreg));
 308 -                p = movenode(p, REGNUM(regc));
 309 -                freeregs(*reg);
 310 -                *reg = regc;
 311 -        }
 312 -        return p;
 313 -}
 314 -
 315 -#ifdef notyet
 316 -/*
 317 - * See if a wanted reg can be shared with regs alloced, taken in account that
 318 - * return regs may not be the expected.
 319 - * wantreg refer to already allocated registers.
 320 - * XXX - wantreg should be of type regcode.
 321 - */
 322 -static regcode
 323 -canshare(NODE *p, struct optab *q, int wantreg)
 324 -{
 325 -        int nreg = (q->needs & NACOUNT);
 326 -        int sz = szty(p->n_type);
 327 -        regcode regc;
 328 -
 329 -        if (nreg == 1) {
 330 -                MKREGC(regc,wantreg,sz); /* XXX what if different size? */
 331 -        } else if ((q->rewrite & RESC1) && isfree(wantreg+sz, sz*(nreg-1))) {
 332 -                        MKREGC(regc, wantreg, sz);
 333 -                        setused(wantreg+sz, sz*(nreg-1));
 334 -        } else if ((q->rewrite & RESC2) && isfree(wantreg-sz, sz) &&
 335 -                    (nreg > 2 ? isfree(wantreg+sz, sz) : 1)) {
 336 -                        MKREGC(regc, wantreg, sz);
 337 -                        setused(wantreg-sz, sz);
 338 -                        if (nreg > 2)
 339 -                                setused(wantreg+sz, sz);
 340 -        } else if ((q->rewrite & RESC3) && isfree(wantreg-sz*2, sz*2)) {
 341 -                        MKREGC(regc, wantreg, sz);
 342 -                        setused(wantreg-sz*2, sz*2);
 343 -        } else
 344 -                regc = getregs(NOPREF, nreg*sz);
 345 -        return regc;
 346 -}
 347 -#endif
 348 -
 349 -regcode
 350 -alloregs(NODE *p, int wantreg)
 351 -{
 352 -        struct optab *q = &table[TBLIDX(p->n_su)];
 353 -        regcode regc, regc2, regc3;
 354 -        int i, size;
 355 -        int cword = 0, rallset = 0;
 356 -        int nareg, nbreg, sreg;
 357 -        NODE *r;
 358 -
 359 -        if (p->n_su == -1) /* For OREGs and similar */
 360 -                return alloregs(p->n_left, wantreg);
 361 -        nbreg = nareg = sreg = size = 0; /* XXX gcc */
 362 -        /*
 363 -         * There may be instructions that have very strange
 364 -         * requirements on register allocation.
 365 -         * Call machine-dependent code to get to know:
 366 -         * - left input reg
 367 -         * - right input reg
 368 -         * - node needed reg
 369 -         * - return reg
 370 -         */
 371 -        if (q->needs & NSPECIAL)
 372 -                return regalloc(p, q, wantreg);
 373 -
 374 -        /*
 375 -         * Are there any allocation requirements?
 376 -         * If so, registers must be available (is guaranteed by sucomp()).
 377 -         */
 378 -        if (q->needs & (NACOUNT|NBCOUNT)) {
 379 -                int nr = q->needs & (NACOUNT|NBCOUNT);
 380 -                while (nr & NACOUNT) nareg++, nr -= NAREG;
 381 -#ifndef BREGS_STACK
 382 -                while (nr & NBCOUNT) nbreg++, nr -= NBREG;
 383 -#endif
 384 -                size = szty(p->n_type);
 385 -                sreg = nareg * size;
 386 -                sreg += nbreg * size;
 387 -                if (nareg && nbreg)
 388 -                        comperr("%p: cannot alloc both AREG and BREG (yet)", p);
 389 -                cword = R_PREF;
 390 -        }
 391 -
 392 -        if (p->n_su & RMASK)
 393 -                cword += R_RREG;
 394 -        if (p->n_su & LMASK)
 395 -                cword += R_LREG;
 396 -        if (q->needs & (NASL|NBSL))
 397 -                cword += R_NASL;
 398 -        if (q->needs & (NASR|NBSR))
 399 -                cword += R_NASR;
 400 -        if (p->n_su & DORIGHT)
 401 -                cword += R_DOR;
 402 -        if (q->rewrite & RLEFT)
 403 -                cword += R_RLEFT;
 404 -        if (q->rewrite & RRIGHT)
 405 -                cword += R_RRGHT;
 406 -        if (q->rewrite & (RESC1|RESC2|RESC3))
 407 -                cword += R_RESC;
 408 -
 409 -#ifdef PCC_DEBUG
 410 -        if (rdebug) {
 411 -                fprintf(stderr, "%p) cword ", p);
 412 -                prtcword(cword);
 413 -                prtuse();
 414 -                fputc('\n', stderr);
 415 -        }
 416 -#endif
 417 -
 418 -        /*
 419 -         * Some registers may not be allowed to use for storing a specific
 420 -         * datatype, so check the wanted reg here.
 421 -         */
 422 -        if (wantreg != NOPREF && mayuse(wantreg, p->n_type) == 0) {
 423 -                wantreg = findfree(szty(p->n_type), nbreg);
 424 -#ifdef PCC_DEBUG
 425 -                if (rdebug)
 426 -                        fprintf(stderr, "wantreg changed to %s\n",
 427 -                            rnames[wantreg]);
 428 -#endif
 429 -        }
 430 -
 431 -        /*
 432 -         * Handle some ops separate.
 433 -         */
 434 -        switch (p->n_op) {
 435 -        case UCALL:
 436 -                /* All registers must be free here. */
 437 -#ifdef old
 438 -                if (findfree(fregs, 0) < 0) /* XXX check BREGs */
 439 -                        comperr("UCALL and not all regs free!");
 440 -#else
 441 -                { int bs, rmsk = TAREGS|TBREGS;
 442 -                        while ((bs = ffs(rmsk))) {
 443 -                                bs--;
 444 -                                if (regblk[bs] & 1)
 445 -                                        comperr("UCALL and reg %d used", bs);
 446 -                                rmsk &= ~(1 << bs);
 447 -                        }
 448 -                }
 449 -#endif
 450 -                if (cword & R_LREG) {
 451 -                        regc = alloregs(p->n_left, NOPREF);
 452 -                        freeregs(regc);
 453 -                        /* Check that all regs are free? */
 454 -                }
 455 -                regc = getregs(RETREG, szty(p->n_type), nbreg);
 456 -                p->n_rall = RETREG;
 457 -                return regc;
 458 -
 459 -        case UMUL:
 460 -                if ((p->n_su & LMASK) != LOREG)
 461 -                        break;
 462 -                /* This op will be folded into OREG in code generation */
 463 -                regc = alloregs(p->n_left, wantreg);
 464 -                i = REGNUM(regc);
 465 -                freeregs(regc);
 466 -                regc = getregs(i, sreg, nbreg);
 467 -                p->n_rall = REGNUM(regc);
 468 -                return shave(regc, nareg+nbreg, q->rewrite);
 469 -
 470 -        case ASSIGN:
 471 -                /*
 472 -                 * If left is in a register, and right is requested to
 473 -                 * be in a register, try to make it the same reg.
 474 -                 */
 475 -                if (p->n_left->n_op == REG && (p->n_su & RMASK) == RREG) {
 476 -                        regc = alloregs(p->n_right, p->n_left->n_rval);
 477 -                        if (REGNUM(regc) == p->n_left->n_rval) {
 478 -                                p->n_su = DORIGHT; /* Forget this node */
 479 -                                return regc;
 480 -                        }  else
 481 -                                freeregs(regc); /* do the normal way */
 482 -                }
 483 -                break;
 484 -        }
 485 -
 486 -        switch (cword) {
 487 -        case 0: /* No registers, ignore */
 488 -                MKREGC(regc,0,0);
 489 -                break;
 490 -
 491 -        case R_DOR:
 492 -                regc = alloregs(p->n_right, wantreg);
 493 -                break;
 494 -
 495 -        case R_PREF:
 496 -                regc = getregs(wantreg, sreg, nbreg);
 497 -                p->n_rall = REGNUM(regc);
 498 -                rallset = 1;
 499 -                freeregs(regc);
 500 -                MKREGC(regc,0,0);
 501 -                break;
 502 -
 503 -        case R_RRGHT: /* Reclaim, be careful about regs */
 504 -        case R_RLEFT:
 505 -                r = getlr(p, cword == R_RRGHT ? 'R' : 'L');
 506 -                if (r->n_op == REG) {
 507 -                        MKREGC(regc, r->n_rval, szty(r->n_type));
 508 -                        setused(r->n_rval, szty(r->n_type));
 509 -                } else
 510 -                        MKREGC(regc,0,0);
 511 -                break;
 512 -
 513 -        case R_LREG: /* Left in register */
 514 -                regc = alloregs(p->n_left, wantreg);
 515 -                break;
 516 -
 517 -        case R_RREG: /* Typical for ASSIGN node */
 518 -                regc = alloregs(p->n_right, wantreg);
 519 -                freeregs(regc);
 520 -                MKREGC(regc,0,0);
 521 -                break;
 522 -
 523 -        case R_RREG+R_LREG+R_PREF:
 524 -                regc = alloregs(p->n_left, wantreg);
 525 -                regc2 = alloregs(p->n_right, NOPREF);
 526 -                regc3 = getregs(wantreg, sreg, nbreg);
 527 -                freeregs(regc);
 528 -                freeregs(regc2);
 529 -                p->n_rall = REGNUM(regc3);
 530 -                freeregs(regc3);
 531 -                rallset = 1;
 532 -                MKREGC(regc,0,0);
 533 -                break;
 534 -
 535 -        case R_RREG+R_PREF:
 536 -                regc = alloregs(p->n_right, wantreg);
 537 -                regc2 = getregs(wantreg, sreg, nbreg);
 538 -                p->n_rall = REGNUM(regc2);
 539 -                freeregs(regc2);
 540 -                freeregs(regc);
 541 -                rallset = 1;
 542 -                MKREGC(regc,0,0);
 543 -                break;
 544 -
 545 -        case R_RESC: /* Reclaim allocated stuff */
 546 -                regc = getregs(wantreg, sreg, nbreg);
 547 -                break;
 548 -
 549 -        case R_LREG+R_RRGHT: /* Left in register */
 550 -                regc = alloregs(p->n_left, wantreg);
 551 -                freeregs(regc);
 552 -                MKREGC(regc,0,0);
 553 -                break;
 554 -
 555 -        case R_LREG+R_PREF+R_RESC:
 556 -                regc2 = alloregs(p->n_left, wantreg);
 557 -                regc = getregs(NOPREF, sreg, nbreg);
 558 -                freeregs(regc2);
 559 -                p->n_rall = REGNUM(regc);
 560 -                rallset = 1;
 561 -                regc = shave(regc, nareg+nbreg, q->rewrite);
 562 -                break;
 563 -
 564 -        case R_LREG+R_PREF+R_RLEFT: /* Allocate regs, reclaim left */
 565 -                regc = alloregs(p->n_left, wantreg);
 566 -                regc2 = getregs(NOPREF, sreg, nbreg);
 567 -                p->n_rall = REGNUM(regc2);
 568 -                rallset = 1;
 569 -                p->n_left = checkreg(&regc, wantreg, p->n_left);
 570 -                freeregs(regc2);
 571 -                break;
 572 -
 573 -        case R_LREG+R_PREF: /* Allocate regs, reclaim nothing */
 574 -                regc = alloregs(p->n_left, wantreg);
 575 -                regc2 = getregs(NOPREF, sreg, nbreg);
 576 -                p->n_rall = REGNUM(regc2);
 577 -                rallset = 1;
 578 -                freeregs(regc2);
 579 -                freeregs(regc);
 580 -                /* Nothing to reclaim */
 581 -                MKREGC(regc, 0, 0);
 582 -                break;
 583 -
 584 -        case R_LREG+R_PREF+R_RRGHT: /* Allocate regs, reclaim right */
 585 -                regc = alloregs(p->n_left, wantreg);
 586 -                regc2 = getregs(NOPREF, sreg, nbreg);
 587 -                p->n_rall = REGNUM(regc2);
 588 -                rallset = 1;
 589 -                freeregs(regc2);
 590 -                freeregs(regc);
 591 -                /* Nothing to reclaim unless right is in a reg */
 592 -                MKREGC(regc, p->n_rval, szty(p->n_type));
 593 -                break;
 594 -
 595 -        case R_LREG+R_NASL+R_PREF:
 596 -                /* left in a reg, alloc regs, no reclaim, may share left */
 597 -                regc2 = alloregs(p->n_left, wantreg);
 598 -                /* Check for sharing. XXX - fix common routine */
 599 -                i = REGNUM(regc2);
 600 -                freeregs(regc2);
 601 -                regc = getregs(i, sreg, nbreg);
 602 -                p->n_rall = REGNUM(regc);
 603 -                rallset = 1;
 604 -                freeregs(regc);
 605 -                MKREGC(regc, 0, 0); /* Nothing to reclaim */
 606 -                break;
 607 -
 608 -        case R_LREG+R_NASL+R_RLEFT:
 609 -                /* left in a reg, alloc regs, reclaim regs, may share left */
 610 -                regc = alloregs(p->n_left, wantreg);
 611 -                break;
 612 -
 613 -        case R_LREG+R_NASL+R_PREF+R_RESC:
 614 -                /* left in a reg, alloc regs, reclaim regs, may share left */
 615 -                regc2 = alloregs(p->n_left, wantreg);
 616 -                /* Check for sharing. XXX - fix common routine */
 617 -                i = REGNUM(regc2);
 618 -                freeregs(regc2);
 619 -                regc = getregs(i, sreg, nbreg);
 620 -                p->n_rall = REGNUM(regc);
 621 -                rallset = 1;
 622 -                regc = shave(regc, nareg+nbreg, q->rewrite);
 623 -                break;
 624 -
 625 -        case R_DOR+R_RREG: /* Typical for ASSIGN node */
 626 -        case R_DOR+R_RLEFT+R_RREG: /* Typical for ASSIGN node */
 627 -        case R_DOR+R_RRGHT+R_RREG: /* Typical for ASSIGN node */
 628 -        case R_RREG+R_RRGHT: /* Typical for ASSIGN node */
 629 -        case R_RREG+R_RLEFT: /* Typical for ASSIGN node */
 630 -                regc = alloregs(p->n_right, wantreg);
 631 -                break;
 632 -
 633 -        case R_DOR+R_RREG+R_LREG:
 634 -                regc = alloregs(p->n_right, NOPREF);
 635 -                regc2 = alloregs(p->n_left, NOPREF);
 636 -                freeregs(regc2);
 637 -                freeregs(regc);
 638 -                MKREGC(regc, 0, 0);
 639 -                break;
 640 -
 641 -        case R_DOR+R_RREG+R_PREF:
 642 -                regc = alloregs(p->n_right, NOPREF);
 643 -                regc3 = getregs(NOPREF, sreg, nbreg);
 644 -                p->n_rall = REGNUM(regc3);
 645 -                rallset = 1;
 646 -                freeregs(regc3);
 647 -                freeregs(regc);
 648 -                MKREGC(regc, 0, 0);
 649 -                break;
 650 -
 651 -        case R_DOR+R_RREG+R_LREG+R_PREF:
 652 -                regc = alloregs(p->n_right, NOPREF);
 653 -                regc2 = alloregs(p->n_left, NOPREF);
 654 -                regc3 = getregs(NOPREF, sreg, nbreg);
 655 -                p->n_rall = REGNUM(regc3);
 656 -                rallset = 1;
 657 -                freeregs(regc3);
 658 -                freeregs(regc2);
 659 -                freeregs(regc);
 660 -                MKREGC(regc, 0, 0);
 661 -                break;
 662 -
 663 -        case R_RREG+R_LREG+R_PREF+R_RRGHT:
 664 -                regc2 = alloregs(p->n_left, NOPREF);
 665 -                regc = alloregs(p->n_right, wantreg);
 666 -                regc3 = getregs(NOPREF, sreg, nbreg);
 667 -                p->n_rall = REGNUM(regc3);
 668 -                rallset = 1;
 669 -                freeregs(regc3);
 670 -                freeregs(regc2);
 671 -                break;
 672 -
 673 -        case R_DOR+R_RREG+R_PREF+R_RRGHT:
 674 -                regc = alloregs(p->n_right, wantreg);
 675 -                regc2 = getregs(NOPREF, sreg, nbreg);
 676 -                p->n_right = checkreg(&regc, wantreg, p->n_right);
 677 -                freeregs(regc2);
 678 -                break;
 679 -
 680 -        case R_DOR+R_RREG+R_LREG+R_RRGHT:
 681 -                regc = alloregs(p->n_right, wantreg);
 682 -                regc2 = alloregs(p->n_left, NOPREF);
 683 -                p->n_right = checkreg(&regc, wantreg, p->n_right);
 684 -                freeregs(regc2);
 685 -                break;
 686 -
 687 -        case R_DOR+R_RREG+R_NASL+R_PREF+R_RESC:
 688 -                regc3 = alloregs(p->n_right, NOPREF);
 689 -                regc2 = getregs(wantreg, sreg, nbreg);
 690 -                regc = shave(regc2, nareg+nbreg, q->rewrite);
 691 -                p->n_rall = REGNUM(regc2);
 692 -                rallset = 1;
 693 -                freeregs(regc3);
 694 -                break;
 695 -
 696 -        /*
 697 -         * Leaf nodes is where it all begin.
 698 -         */
 699 -        case R_PREF+R_RESC: /* Leaf node that puts a value into a register */
 700 -        case R_NASR+R_PREF+R_RESC:
 701 -                regc = getregs(wantreg, sreg, nbreg);
 702 -                break;
 703 -
 704 -        case R_NASL+R_PREF+R_RESC: /* alloc + reclaim regs, may share left */
 705 -                regc2 = getregs(wantreg, sreg, nbreg);
 706 -                regc = shave(regc2, nareg+nbreg, q->rewrite);
 707 -                p->n_rall = REGNUM(regc2);
 708 -                rallset = 1;
 709 -                break;
 710 -
 711 -        case R_NASL+R_PREF: /* alloc, may share left */
 712 -                regc = getregs(wantreg, sreg, nbreg);
 713 -                p->n_rall = REGNUM(regc);
 714 -                rallset = 1;
 715 -                freeregs(regc);
 716 -                MKREGC(regc,0,0);
 717 -                break;
 718 -
 719 -        case R_LREG+R_RLEFT: /* Operate on left leg */
 720 -                regc = alloregs(p->n_left, wantreg);
 721 -                p->n_left = checkreg(&regc, wantreg, p->n_left);
 722 -                break;
 723 -
 724 -        case R_LREG+R_RREG: /* both legs in registers, no reclaim */
 725 -                /* Used for logical ops */
 726 -                regc = alloregs(p->n_left, wantreg);
 727 -                regc2 = alloregs(p->n_right, NOPREF);
 728 -                freeregs(regc2);
 729 -                freeregs(regc);
 730 -                MKREGC(regc,0,0);
 731 -                break;
 732 -
 733 -        case R_LREG+R_RREG+R_RLEFT: /* binop, reclaim left */
 734 -                regc = alloregs(p->n_left, wantreg);
 735 -                regc2 = alloregs(p->n_right, NOPREF);
 736 -
 737 -                p->n_left = checkreg(&regc, wantreg, p->n_left);
 738 -                freeregs(regc2);
 739 -                break;
 740 -
 741 -        case R_LREG+R_RREG+R_RRGHT: /* binop, reclaim right */
 742 -                regc2 = alloregs(p->n_left, NOPREF);
 743 -                regc = alloregs(p->n_right, wantreg);
 744 -                p->n_right = checkreg(&regc, wantreg, p->n_right);
 745 -                freeregs(regc2);
 746 -                break;
 747 -
 748 -        case R_RREG+R_LREG+R_NASL+R_PREF+R_RESC:
 749 -                /* l+r in reg, need regs, reclaim alloced regs, may share l */
 750 -
 751 -                /* Traverse left first, it may be shared */
 752 -                regc = alloregs(p->n_left, NOPREF);
 753 -                freeregs(regc);
 754 -                regc = getregs(wantreg, sreg, nbreg);
 755 -                regc3 = alloregs(p->n_right, NOPREF);
 756 -                freeregs(regc3);
 757 -                p->n_rall = REGNUM(regc);
 758 -                rallset = 1;
 759 -                regc = shave(regc, nareg+nbreg, q->rewrite);
 760 -
 761 -                break;
 762 -
 763 -        case R_DOR+R_RREG+R_LREG+R_NASL+R_PREF+R_RESC:
 764 -                /* l+r in reg, need regs, reclaim alloced regs, may share l */
 765 -
 766 -                /* Traverse right first, it may not be shared */
 767 -                regc3 = alloregs(p->n_right, NOPREF);
 768 -                if (findfree(sreg, 0) < 0) { /* XXX BREGs */
 769 -                        /* No regs found, must move around */
 770 -                        regc = getregs(NOPREF, REGSIZE(regc3), nbreg);
 771 -                        p->n_right = movenode(p->n_right, REGNUM(regc));
 772 -                        freeregs(regc3);
 773 -                        regc3 = regc;
 774 -                }
 775 -
 776 -                /* Check where to get our own regs. Try wantreg first */
 777 -                if (isfree(wantreg, sreg))
 778 -                        i = wantreg;
 779 -                else if ((i = findfree(sreg, 0)) < 0) /* XXX BREGs */
 780 -                        comperr("alloregs out of regs");
 781 -
 782 -                /* Now allocate left, try to share it with our needs */
 783 -                regc = alloregs(p->n_left, i);
 784 -
 785 -                /* So, at last finished. Cleanup */
 786 -                freeregs(regc);
 787 -                freeregs(regc3);
 788 -
 789 -                regc = getregs(i, size, nbreg);
 790 -                p->n_rall = REGNUM(regc);
 791 -                rallset = 1;
 792 -                regc = shave(regc, nareg+nbreg, q->rewrite);
 793 -                break;
 794 -
 795 -        case R_DOR+R_RREG+R_LREG+R_RLEFT:
 796 -                /* l+r in reg, reclaim left */
 797 -                regc2 = alloregs(p->n_right, NOPREF);
 798 -                regc = alloregs(p->n_left, wantreg);
 799 -                p->n_left = checkreg(&regc, wantreg, p->n_left);
 800 -                freeregs(regc2);
 801 -                break;
 802 -
 803 -        case R_DOR+R_RREG+R_LREG+R_PREF+R_RRGHT:
 804 -                /* l+r in reg, reclaim right */
 805 -                regc = alloregs(p->n_right, wantreg);
 806 -                regc2 = alloregs(p->n_left, NOPREF);
 807 -                if ((p->n_rall = findfree(sreg, 0)) < 0) /* XXX BREGs */
 808 -                        comperr("alloregs out of regs2");
 809 -                rallset = 1;
 810 -                freeregs(regc2);
 811 -                break;
 812 -
 813 -        default:
 814 -#ifdef PCC_DEBUG
 815 -                fprintf(stderr, "%p) cword ", p);
 816 -                prtcword(cword);
 817 -                fputc('\n', stderr);
 818 -#endif
 819 -                comperr("alloregs");
 820 -        }
 821 -        if (rallset == 0)
 822 -                p->n_rall = REGNUM(regc);
 823 -        if (REGSIZE(regc) > szty(p->n_type) && !logop(p->n_op))
 824 -                comperr("too many regs returned for %p (%d)", p, REGSIZE(regc));
 825 -        return regc;
 826 -}
 827 -
 828 -/*
 829 - * Count the number of registers needed to evaluate a tree.
 830 - * This is the trivial implementation, for machines with symmetric
 831 - * registers. Machines with difficult register assignment strategies
 832 - * may need to define this function themselves.
 833 - * Return value is the number of registers used so far.
 834 - */
 835 -int
 836 -sucomp(NODE *p)
 837 -{
 838 -        struct optab *q = &table[TBLIDX(p->n_su)];
 839 -        int left, right;
 840 -        int nreg;
 841 -
 842 -        if (p->n_su == -1)
 843 -                return sucomp(p->n_left);
 844 -  
 845 -        if (p->n_op == UCALL) {
 846 -                if ((p->n_su & LMASK) && sucomp(p->n_left) < 0)
 847 -                        return -1;
 848 -                return fregs;
 849 -        }
 850 -
 851 -        nreg = (q->needs & NACOUNT) * szty(p->n_type);
 852 -
 853 -        switch (p->n_su & RMASK) {
 854 -        case RREG:
 855 -        case ROREG:
 856 -                if ((right = sucomp(p->n_right)) < 0)
 857 -                        return right;
 858 -                break;
 859 -        case RTEMP:
 860 -                cerror("sucomp RTEMP");
 861 -        default:
 862 -                right = 0;
 863 -        }
 864 -        switch (p->n_su & LMASK) {
 865 -        case LREG:
 866 -        case LOREG:
 867 -                if ((left = sucomp(p->n_left)) < 0)
 868 -                        return left;
 869 -                break;  
 870 -        case LTEMP:
 871 -                cerror("sucomp LTEMP");
 872 -        default:
 873 -                left = 0;
 874 -        }
 875 -//printf("sucomp: node %p right %d left %d\n", p, right, left);
 876 -        if ((p->n_su & RMASK) && (p->n_su & LMASK) &&
 877 -            right + szty(p->n_left->n_type) > fregs &&
 878 -            left + szty(p->n_right->n_type) > fregs) {
 879 -                int r = p->n_right->n_op;
 880 -                int l = p->n_left->n_op;
 881 -                /*
 882 -                 * Must store one subtree. Store the tree
 883 -                 * with highest SU, or left (unless it is an assign node).
 884 -                 * Be careful to not try to store an OREG.
 885 -                 */
 886 -                if (r == OREG && l == OREG)
 887 -                        comperr("sucomp: cannot generate code, node %p", p);
 888 -                if ((right > left && r != OREG) || l == OREG) {
 889 -                        p->n_right = store(p->n_right);
 890 -                } else {
 891 -                        if (p->n_op == ASSIGN && l == UMUL)
 892 -                                p->n_left->n_left = store(p->n_left->n_left);
 893 -                        else
 894 -                                p->n_left = store(p->n_left);
 895 -                }
 896 -                return -1;
 897 -        }
 898 -        if ((right+left) > fregs) {
 899 -                /* Almost out of regs, traverse the highest SU first */
 900 -                if (right > left)
 901 -                        p->n_su |= DORIGHT;
 902 -        } else if (right && (q->needs & (NASL|NBSL)) && (q->rewrite & RLEFT)) {
 903 -                /* Make it easier to share regs */
 904 -                p->n_su |= DORIGHT;
 905 -        } else if (right > left) {
 906 -                p->n_su |= DORIGHT;
 907 -        }
 908 -        /* If both in regs and equal size, return l+r */
 909 -        if (left && left == right)
 910 -                left += right; /* returned below */
 911 -
 912 -        if (right > nreg)
 913 -                nreg = right;
 914 -        if (left > nreg)
 915 -                nreg = left;
 916 -        return nreg;
 917 -}
 918 -#endif
 919 -
 920 -/*
92136  * New-style register allocator using graph coloring.
 92237  * The design is based on the George and Appel paper
 92338  * "Iterated Register Coalescing", ACM Transactions, No 3, May 1996.
 92439  */
 92540 
 92641 #define BIT2BYTE(bits) ((((bits)+NUMBITS-1)/NUMBITS)*(NUMBITS/8))
<>927 -
92842 #define BITALLOC(ptr,all,sz) { \
 92943         int __s = BIT2BYTE(sz); ptr = all(__s); memset(ptr, 0, __s); }
 93044 
     
 !
1185299 #define LIVEDEL(x) BITCLEAR(live, (x-tempmin))
 1186300 #endif
 1187301 
<>1188 -static void
 1189 -LIVEADDLOOP(int rall, int sz)
 1190 -{
 1191 -        while (sz--) {
 1192 -                LIVEADD(rall);
 1193 -                rall++;
 1194 -        }
 1195 -}
 1196 -
 1197 -static void
 1198 -LIVEDELLOOP(int rall, int sz)
 1199 -{
 1200 -        while (sz--) {
 1201 -                LIVEDEL(rall);
 1202 -                rall++;
 1203 -        }
 1204 -}
 1205 -
 1206 -
1207302 #define MOVELISTADD(t, p) movelistadd(t, p)
 1208303 #define WORKLISTMOVEADD(s,d) worklistmoveadd(s,d)
 1209304 
     
 !
1380475         addalledges(def);
 1381476 }
 1382477 
<>1383 -#if 0
 1384 -static void
 1385 -bmedge(int reg, int rmsk)
 1386 -{
 1387 -        int i;
 1388 -
 1389 -        while (rmsk) {
 1390 -                i = ffs(rmsk)-1;
 1391 -                AddEdge(reg, i);
 1392 -                rmsk &= ~(1 << i);
 1393 -        }
 1394 -}
 1395 -#endif
 1396 -
 1397 -static void
 1398 -AddEdgeloop(int t1, int n1, int t2, int n2)
 1399 -{
 1400 -        int i, j;
 1401 -
 1402 -        for (i = 0; i < n1; i++)
 1403 -                for (j = 0; j < n2; j++)
 1404 -                        AddEdge(t1+i, t2+j);
 1405 -}
 1406 -
 1407 -static void
 1408 -moveaddloop(int t1, int t2, int num)
 1409 -{
 1410 -        while (--num >= 0)
 1411 -                moveadd(t1+num, t2+num);
 1412 -}
 1413 -
 1414 -static void
 1415 -moveaddlink(int rall, int *nt)
 1416 -{
 1417 -        while (*nt >= 0)
 1418 -                moveadd(rall++, *nt++);
 1419 -}
 1420 -
 1421 -static void
 1422 -addalledgesloop(int t1, int sz)
 1423 -{
 1424 -        while (--sz >= 0)
 1425 -                addalledges(t1+sz);
 1426 -}
 1427 -
 1428 -static void
 1429 -addalledgeslink(int *t)
 1430 -{
 1431 -        while (*t >= 0)
 1432 -                addalledges(*t++);
 1433 -}
 1434 -
1435478 /*
 1436479  * Do the actual liveness analysis inside a tree.
 1437480  * The tree is walked in backward-execution order to catch the
 1438481  * long-term temporaries.
 1439482  * Moves to/from precolored registers are implicitly placed
 1440483  * inside the affected nodes (like return value from CALLs).
 1441484  */
<>1442 -#if 0
1443485 static void
 1444486 insnwalk(NODE *p)
 1445487 {
 1446488         struct optab *q;
 1447489         int def, nreg;
 1448490         int i, l, r, f, t, size;
<>1449 -        int left, right, rmask;
 1450 -        TWORD rt, lt;
  491+        int *left, *right, *rmask;
1451492 
 1452493         RDEBUG(("insnwalk: %p\n", p));
 1453494 
     
 !
1461502 #define SZSLOOP(i,s) for (i = 0; i < szty(s); i++)
 1462503         if (p->n_op == ASSIGN) {
 1463504                 if (p->n_left->n_op == TEMP) {
<>1464 -                        SZLOOP(i) {
 1465 -                                /* Remove from live set */
 1466 -                                LIVEDEL((int)p->n_left->n_lval+i);
 1467 -                                /* always move via itself */
 1468 -                                moveadd((int)p->n_left->n_lval+i, p->n_rall+i);
 1469 -                        }
  505+                        /* Remove from live set */
  506+                        LIVEDEL((int)p->n_left->n_lval);
  507+                        /* always move via itself */
  508+                        moveadd((int)p->n_left->n_lval, p->n_rall);
1470509                                 
 1471510                 }
 1472511                 if (((l = p->n_left->n_op) == TEMP || l == REG) &&
 1473512                     ((r = p->n_right->n_op) == TEMP || r == REG)) {
 1474513                         f = r == REG ? p->n_right->n_rval : p->n_right->n_lval;
 1475514                         t = l == REG ? p->n_left->n_rval : p->n_left->n_lval;
<>1476 -                        SZLOOP(i)
 1477 -                                moveadd(t+i, f+i);
  515+                        moveadd(t, f);
1478516                 }
 1479517         }
 1480518         def = p->n_rall;
<>1481 -        SZLOOP(i)
 1482 -                addalledges(def+i);
  519+        addalledges(def);
1483520         nreg = (q->needs & NACOUNT) * size;
 1484521         for (i = 0; i < nreg; i++)
 1485522                 MYADDEDGE(i+def, p->n_type); /* register constraints */
 1486523 
<>1487 -        left = right = rmask = 0;
  524+        left = right = 0;
  525+        rmask = 0;
1488526         if (q->needs & NSPECIAL) {
<>1489 -                int res;
  527+                struct rspecial *rs = nspecial(q);
1490528                 /* special instruction requirements */
 1491529 
<>1492 -                nspecial(q, &left, &right, &res, &rmask);
1493530 
 1494531                 /* if result ends up in a certain register, add move */
<>1495 -                if (res) {
 1496 -                        SZLOOP(i) {
 1497 -                                t = ffs(res)-1;
 1498 -#ifdef PCC_DEBUG
 1499 -                                if (t < 0)
 1500 -                                        comperr("special reg error");
 1501 -#endif
 1502 -                                moveadd(def+i, t+i);
 1503 -                                res &= ~(1 << t);
 1504 -                        }
 1505 -                }
  532+                if (rs->res)
  533+                        moveadd(def, rs->res[0]);
1506534 
<> 535+                rmask = rs->rmask;
  536+                left = rs->left;
  537+                right = rs->right;
1507538                 /* Add edges for used registers */
<>1508 -                l = rmask;
 1509 -                for (i = 0; l; i++) {
 1510 -                        if (l & 1) {
 1511 -                                addalledges(i);
 1512 -                        }
 1513 -                        l >>= 1;
 1514 -                }
  539+                for (i = 0; rmask && rmask[i] >= 0; i++)
  540+                        addalledges(rmask[i]);
1515541                 nreg = 0;
 1516542         }
 1517543 
     
 !
1521547                         if (TAREGS & (1 << i))
 1522548                                 addalledges(i);
 1523549                 /* implicit move after call */
<>1524 -                SZLOOP(i)
 1525 -                        moveadd(def+i, RETREG+i);
  550+                moveadd(def, RETREG);
1526551                 nreg = 0;
 1527552         }
 1528553         /*
     
 !
1539564                 NODE *lp = GETP(p->n_left);
 1540565                 int lr = lp->n_rall;
 1541566 
<>1542 -                if (!(q->needs & NASL)) {
 1543 -                        for (i = 0; i < szty(lp->n_type); i++)
 1544 -                                addalledges(lr+i);
 1545 -                }
  567+                if (!(q->needs & NASL))
  568+                        addalledges(lr);
  569+
1546570                 /* If a register will be clobbered, and this register */
 1547571                 /* is not the leg register, add edge */
<>1548 -                if (rmask & ~left)
 1549 -                        bmedge(lr, rmask & ~left);
  572+                for (i = 0; rmask && rmask[i] >= 0; i++) {
  573+                        if (left && rmask[i] == left[0])
  574+                                continue;
  575+                        AddEdge(lr, rmask[i]);
  576+                }
1550577         }
 1551578         if ((p->n_su & RMASK) == RREG) {
 1552579                 NODE *rp = GETP(p->n_right);
 1553580                 int rr = rp->n_rall;
<>1554 -                if (!(q->needs & NASR)) {
 1555 -                        for (i = 0; i < szty(rp->n_type); i++)
 1556 -                                addalledges(rr+i);
  581+                if (!(q->needs & NASR))
  582+                        addalledges(rr);
  583+
  584+                for (i = 0; rmask && rmask[i] >= 0; i++) {
  585+                        if (right && rmask[i] == right[0])
  586+                                continue;
  587+                        AddEdge(rr, rmask[i]);
1557588                 }
<>1558 -                if (rmask & ~right)
 1559 -                        bmedge(rr, rmask & ~right);
1560589         }
 1561590 
 1562591         /* now remove the needs from the live set */
 1563592         for (i = 0; i < nreg; i++)
 1564593                 LIVEDEL(def+i);
<>1565 -#if 0
 1566 -        for (l = rmask, i = 0; l; i++) {
 1567 -                if (l & 1)
 1568 -                        LIVEDEL(i);
 1569 -                l >>= 1;
 1570 -        }
 1571 -#endif
1572594 
 1573595         /* walk down the legs and add interference edges */
 1574596         l = r = 0;
<>1575 -        lt = rt = 0;
1576597         if ((p->n_su & DORIGHT) && (p->n_su & LMASK)) {
 1577598                 NODE *rp = GETP(p->n_right);
 1578599                 r = rp->n_rall;
<>1579 -                rt = rp->n_type;
 1580 -                SZSLOOP(i, rt)
 1581 -                        LIVEADD(r+i);
  600+                LIVEADD(r);
1582601                 if (q->rewrite & RLEFT) {
 1583602                         l = GETRALL(p->n_left);
<>1584 -                        SZLOOP(i)
 1585 -                                moveadd(p->n_rall+i, l+i);
  603+                        moveadd(p->n_rall, l);
1586604                 }
 1587605                 if (q->needs & NSPECIAL && left) {
 1588606                         NODE *lp = GETP(p->n_left);
<>1589 -                        int xl = left;
 1590 -                        SZSLOOP(i, lp->n_type) {
 1591 -                                l = ffs(xl)-1;
 1592 -                                moveadd(lp->n_rall+i, l);
 1593 -                                xl &= ~(1 << l);
 1594 -                        }
  607+                        if (left)
  608+                                moveadd(lp->n_rall, left[0]);
1595609                 }
 1596610                 insnwalk(p->n_left);
 1597611                 if (p->n_right->n_op != TEMP ||
 1598612                     p->n_right->n_rall != p->n_right->n_lval) {
<>1599 -                        SZSLOOP(i, rt)
 1600 -                                LIVEDEL(r+i);
  613+                        LIVEDEL(r);
1601614                 } else
 1602615                         r = 0;
 1603616         }
     
 !
1606619                 if (r == 0 && (p->n_su & LMASK)) {
 1607620                         lp = GETP(p->n_left);
 1608621                         l = lp->n_rall;
<>1609 -                        lt = lp->n_type;
 1610 -                        SZSLOOP(i, lt)
 1611 -                                LIVEADD(l+i);
  622+                        LIVEADD(l);
1612623                 }
 1613624                 if (q->rewrite & RRIGHT) {
 1614625                         if (p->n_su & LMASK) {
 1615626                                 t = GETRALL(p->n_left);
<>1616 -                                SZLOOP(i)
 1617 -                                        moveadd(p->n_rall+i, t+i);
  627+                                moveadd(p->n_rall, t);
1618628                         }
<> 629+                        moveadd(p->n_rall, GETRALL(p->n_right));
1619630                 }
 1620631                 if (q->needs & NSPECIAL && right) {
 1621632                         NODE *rp = GETP(p->n_right);
<>1622 -                        int xr = right;
 1623 -                        SZSLOOP(i, rp->n_type) {
 1624 -                                t = ffs(xr)-1;
 1625 -                                moveadd(rp->n_rall+i, t);
 1626 -                                xr &= ~(1 << t);
 1627 -                        }
  633+                        if (right)
  634+                                moveadd(rp->n_rall, right[0]);
1628635                 }
 1629636                 insnwalk(p->n_right);
 1630637                 if (p->n_su & LMASK) {
 1631638                         if (p->n_left->n_op != TEMP ||
 1632639                             p->n_left->n_rall != p->n_left->n_lval) {
 1633640                                 if (l) {
<>1634 -                                        SZSLOOP(i, lt)
 1635 -                                                LIVEDEL(l+i);
  641+                                        LIVEDEL(l);
1636642                                 }
 1637643                         } else
 1638644                                 l = 0;
 1639645                 }
 1640646         }
 1641647         if (!(p->n_su & DORIGHT) && (p->n_su & LMASK)) {
<>1642 -                if (q->rewrite & RLEFT) {
 1643 -                        int ll = GETRALL(p->n_left);
 1644 -                        SZLOOP(i)
 1645 -                                moveadd(p->n_rall+i, ll+i);
 1646 -                }
  648+                if (q->rewrite & RLEFT)
  649+                        moveadd(p->n_rall, GETRALL(p->n_left));
  650+
1647651                 if (q->needs & NSPECIAL && left) {
 1648652                         NODE *lp = GETP(p->n_left);
<>1649 -                        int xl = left;
 1650 -                        SZSLOOP(i, lp->n_type) {
 1651 -                                int pl = ffs(xl)-1;
 1652 -                                moveadd(lp->n_rall+i, pl);
 1653 -                                xl &= ~(1 << pl);
 1654 -                        }
  653+                        if (left)
  654+                                moveadd(lp->n_rall, left[0]);
1655655                 }
 1656656                 insnwalk(p->n_left);
 1657657         }
 1658658         if (p->n_op == TEMP) {
<>1659 -                SZLOOP(i) {
 1660 -                        moveadd(p->n_lval+i, def+i);
 1661 -                        LIVEADD((int)p->n_lval+i);
 1662 -                }
 1663 -        }
 1664 -        /* XXX - fix artificial edges */
  659+                moveadd(p->n_lval, def);
  660+                LIVEADD((int)p->n_lval);
  661+        } /* XXX - fix artificial edges */
1665662 
 1666663         /* Finished, clean up live set */
 1667664         if (r) {
<>1668 -                SZSLOOP(i, rt)
 1669 -                        LIVEDEL(r+i);
  665+                LIVEDEL(r);
1670666         }
 1671667         if (l) {
<>1672 -                SZSLOOP(i, lt)
 1673 -                        LIVEDEL(l+i);
  668+                LIVEDEL(l);
1674669         }
 1675670 }
<>1676 -#else
 1677 -/*
 1678 - * Do liveness analysis of a binary node.
 1679 - */
 1680 -static void
 1681 -analbitype(struct optab *q, NODE *p, struct rspecial *spec)
 1682 -{
 1683 -        int size, rsz, lsz, lrall, rrall;
 1684 -        NODE *rp, *lp;
1685671 
<>1686 -        size = szty(p->n_type);
 1687 -        rsz = szty((rp = GETP(p->n_right))->n_type);
 1688 -        rrall = rp->n_rall;
 1689 -        lsz = szty((lp = GETP(p->n_left))->n_type);
 1690 -        lrall = lp->n_rall;
 1691 -
 1692 -        /* Add moves/edges to correct legs */
 1693 -        if (q->rewrite & RLEFT) {
 1694 -                AddEdgeloop(p->n_rall, size, rrall, rsz);
 1695 -                moveaddloop(p->n_rall, lrall, size);
 1696 -        } else if (q->rewrite & RRIGHT) {
 1697 -                AddEdgeloop(p->n_rall, size, lrall, lsz);
 1698 -                moveaddloop(p->n_rall, rrall, size);
 1699 -        }
 1700 -
 1701 -        AddEdgeloop(lrall, lsz, rrall, rsz);
 1702 -        addalledgesloop(lrall, lsz);
 1703 -        addalledgesloop(rrall, rsz);
 1704 -
 1705 -        if ((q->needs & NASL) == 0 && (q->rewrite & RLEFT) == 0)
 1706 -                AddEdgeloop(p->n_rall, size, lrall, lsz);
 1707 -        if ((q->needs & NASR) == 0 && (q->rewrite & RRIGHT) == 0)
 1708 -                AddEdgeloop(p->n_rall, size, rrall, rsz);
 1709 -
 1710 -        if (spec->left)
 1711 -                moveaddlink(lrall, spec->left);
 1712 -        if (spec->right)
 1713 -                moveaddlink(rrall, spec->right);
 1714 -
 1715 -        LIVEADDLOOP(lrall, lsz);
 1716 -        LIVEADDLOOP(rrall, rsz);
 1717 -}
 1718 -
 1719 -/*
 1720 - * Do liveness analysis of a leaf node.
 1721 - */
 1722 -static void
 1723 -analltype(struct optab *q, NODE *p, struct rspecial *spec)
 1724 -{
 1725 -        int size;
 1726 -
 1727 -        if (p->n_op != TEMP)
 1728 -                return;
 1729 -
 1730 -        size = szty(p->n_type);
 1731 -        moveaddloop(p->n_rall, p->n_lval, size);
 1732 -        LIVEADDLOOP(p->n_lval, size);
 1733 -}
 1734 -
 1735 -/*
 1736 - * Do liveness analysis of a unary node.
 1737 - */
 1738 -static void
 1739 -analutype(struct optab *q, NODE *p, struct rspecial *spec)
 1740 -{
 1741 -        int size, sz, rall, rew, nasl;
 1742 -        NODE *dp;
 1743 -
 1744 -        size = szty(p->n_type);
 1745 -        if (p->n_su & LMASK) {
 1746 -                dp = p->n_left;
 1747 -                rew = RLEFT;
 1748 -                nasl = NASL;
 1749 -        } else {
 1750 -                dp = p->n_right;
 1751 -                rew = RRIGHT;
 1752 -                nasl = NASR;
 1753 -        }
 1754 -        dp = GETP(dp);
 1755 -        sz = szty(dp->n_type);
 1756 -        rall = dp->n_rall;
 1757 -
 1758 -        /* Add move to correct leg */
 1759 -        if (q->rewrite & rew)
 1760 -                moveaddloop(p->n_rall, rall, size);
 1761 -
 1762 -        addalledgesloop(rall, sz);
 1763 -
 1764 -        if ((q->needs & nasl) == 0 && (q->rewrite & rew) == 0)
 1765 -                AddEdgeloop(p->n_rall, size, rall, sz);
 1766 -
 1767 -        if (rew == RLEFT && spec->left)
 1768 -                moveaddlink(rall, spec->left);
 1769 -        if (rew == RRIGHT && spec->right)
 1770 -                moveaddlink(rall, spec->right);
 1771 -
 1772 -        LIVEADDLOOP(rall, sz);
 1773 -}
 1774 -
 1775 -/*
 1776 - * Deal with liveness analysis on ASSIGN nodes.
 1777 - */
 1778 -static void
 1779 -analassign(struct optab *q, NODE *p, struct rspecial *spec)
 1780 -{
 1781 -        int size, l;
 1782 -
 1783 -#ifdef PCC_DEBUG
 1784 -        if (p->n_left->n_type != p->n_right->n_type)
 1785 -                comperr("cannot ASSIGN between types");
 1786 -#endif
 1787 -        size = szty(p->n_type);
 1788 -
 1789 -        if ((p->n_su & RMASK) == RREG ||
 1790 -            (l = p->n_right->n_op) == TEMP || l == REG)
 1791 -                moveaddloop(p->n_rall, p->n_right->n_rall, size);
 1792 -                
 1793 -        if ((l = p->n_left->n_op) == TEMP || l == REG) {
 1794 -                LIVEDELLOOP((int)p->n_left->n_lval, size);
 1795 -                moveaddloop((int)p->n_left->n_lval, p->n_rall, size);
 1796 -        }
 1797 -
 1798 -}
 1799 -
 1800 -static void
 1801 -insnwalk(NODE *p)
 1802 -{
 1803 -        struct optab *q;
 1804 -        struct rspecial *spec;
 1805 -        int size, nreg, def;
 1806 -
 1807 -        RDEBUG(("insnwalk: %p\n", p));
 1808 -
 1809 -        if (p->n_su == -1)
 1810 -                return insnwalk(p->n_left);
 1811 -
 1812 -        q = &table[TBLIDX(p->n_su)];
 1813 -
 1814 -        size = szty(p->n_type); /* outgoing count of regs used */
 1815 -        nreg = (q->needs & NACOUNT) * size; /* # of int regs needed */
 1816 -        def = p->n_rall;
 1817 -
 1818 -        /* NSPECIAL sätt left, right, res, rmask */
 1819 -        spec = NULL;
 1820 -        if (q->needs & NSPECIAL)
 1821 -                spec = nspecial(q);
 1822 -
 1823 -        /* Add destination moves */
 1824 -        if (spec->res)
 1825 -                moveaddlink(def, spec->res);
 1826 -
 1827 -        if (spec->rmask)
 1828 -                addalledgeslink(spec->rmask);
 1829 -
 1830 -        if (nreg)
 1831 -                addalledgesloop(def, nreg);
 1832 -
 1833 -        /* Remove dest from live set */
 1834 -        LIVEDELLOOP(def, size);
 1835 -
 1836 -        if (p->n_op == ASSIGN) {
 1837 -                analassign(q, p, spec);
 1838 -        } else if (callop(p->n_op)) {
 1839 -                analcall();
 1840 -        } else if ((p->n_su & LMASK) && (p->n_su & RMASK)) {
 1841 -                analbitype(q, p, spec);
 1842 -        } else if ((p->n_su & LMASK) || (p->n_su & RMASK)) {
 1843 -                analutype(q, p, spec);
 1844 -        } else
 1845 -                analltype(q, p, spec);
 1846 -
 1847 -}
 1848 -#endif
1849672 static bittype **gen, **kill, **in, **out;
 1850673 
 1851674 static void
     
 !
1939762         bittype *saved;
 1940763         int i, j, again, nbits;
 1941764 
<>1942 -#ifdef OLDSTYLE
 1943 -        if (xsaveip && xssaflag) {
 1944 -#else
1945765         if (xtemps) {
<>1946 -#endif
1947766                 /* Just fetch space for the temporaries from stack */
 1948767 
 1949768                 nbits = tempfe - tempmin;
     
 !
24611280                 for (o = tempmin; o < tempmax; o++)
 24621281                         printf("%d: %d\n", o, COLOR(o));
 24631282         if (DLIST_ISEMPTY(&spilledNodes, link)) {
<>2464 -#ifdef OLDSTYLE
 2465 -                if (xsaveip) {
 2466 -                        struct interpass *ip2;
 2467 -                        DLIST_FOREACH(ip2, ip, qelem)
 2468 -                                if (ip2->type == IP_NODE)
 2469 -                                        walkf(ip2->ip_node, paint);
 2470 -                } else if (ip->type == IP_NODE)
 2471 -                        walkf(ip->ip_node, paint);
 2472 -#else
24731283                 struct interpass *ip2;
 24741284                 DLIST_FOREACH(ip2, ip, qelem)
 24751285                         if (ip2->type == IP_NODE)
 24761286                                 walkf(ip2->ip_node, paint);
<>2477 -#endif
24781287         }
 24791288 }
 24801289 
<>2481 -#ifdef OLDSTYLE
 2482 -static  struct interpass ipbase; /* to save nodes before calling emit */
 2483 -
 2484 -static void
 2485 -modifytree(NODE *p)
 2486 -{
 2487 -        extern struct interpass *storesave;
 2488 -        REGW *w;
 2489 -        NODE *q;
 2490 -
 2491 -        /* Check for the node in the spilled list */
 2492 -        DLIST_FOREACH(w, &spilledNodes, link) {
 2493 -                if (R_TEMP(w) != p->n_rall)
 2494 -                        continue;
 2495 -                /* Got the matching temp */
 2496 -                RDEBUG(("modifytree: storing node %p\n", p));
 2497 -                q = talloc();
 2498 -                *q = *p;
 2499 -                q = store(q);
 2500 -                *p = *q;
 2501 -                nfree(q);
 2502 -                DLIST_INSERT_BEFORE(&ipbase, storesave, qelem);
 2503 -                DELWLIST(w);
 2504 -                return;
 2505 -        }
 2506 -}
 2507 -#endif
 2508 -
25091290 /*
 25101291  * Store all spilled nodes in memory by fetching a temporary on the stack.
 25111292  * In the non-optimizing case recurse into emit() and let it handle the
 25121293  * stack space, otherwise generate stacklevel nodes and put them into
 25131294  * the full function chain.
 25141295  * In the non-optimizing case be careful so that the coloring code won't
 25151296  * overwrite itself during recursion.
<> 1297+ * XXX - check this comment.
25161298  */
<>2517 -#ifdef OLDSTYLE
 2518 -static void
 2519 -RewriteProgram(struct interpass *ip)
 2520 -{
25211299 
<>2522 -        DLIST_INIT(&ipbase, qelem);
 2523 -
 2524 -        /* walk the tree bottom-up and isolate found nodes for spilling */
 2525 -        walkf(ip->ip_node, modifytree);
 2526 -        if (!DLIST_ISEMPTY(&spilledNodes, link))
 2527 -                comperr("RewriteProgram");
 2528 -        DLIST_FOREACH(ip, &ipbase, qelem) {
 2529 -                emit(ip);
 2530 -        }
 2531 -}
 2532 -#endif
 2533 -
25341300 static REGW *spole;
 25351301 
 25361302 static void
     
 !
26511417 /*
 26521418  * Do register allocation for trees by graph-coloring.
 26531419  */
<>2654 -#ifdef OLDSTYLE
 2655 -int
 2656 -#else
26571420 void
<>2658 -#endif
26591421 ngenregs(struct interpass *ipole)
 26601422 {
 26611423         struct interpass_prolog *ipp, *epp;
     
 !
26711433         tempmin = ipp->ip_tmpnum - NREGREG;
 26721434         tempfe = tempmax = epp->ip_tmpnum;
 26731435 
<>2674 -#ifdef OLDSTYLE
 2675 -        allregs = xsaveip ? AREGS : TAREGS;
 2676 -#else
26771436         allregs = xtemps ? AREGS : TAREGS;
<>2678 -#endif
<_26791437         maxregs = 0;
 26801438         
 26811439         /* Get total number of registers */
FishEye: Open Source License registered to PCC.
Your maintenance has expired. You can renew your license at http://www.atlassian.com/fisheye/renew
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-10-01 22:24 +0200