Annotation of researchv10no/cmd/lcc/gen3/gen.c, revision 1.1

1.1     ! root        1: /* C compiler: VAX subset code generator */
        !             2: 
        !             3: #include "c.h"
        !             4: 
        !             5: #ifdef DEBUG
        !             6: #define debug(x,y) if (x) y
        !             7: static void lprint(Node, char *);
        !             8: static void nprint(Node);
        !             9: static char *rnames(unsigned);
        !            10: static int id;
        !            11: static Node lhead;
        !            12: 
        !            13: #else
        !            14: #define debug(x,y)
        !            15: #endif
        !            16: 
        !            17: static int rflag;              /* != 0 to trace register allocation */
        !            18: static int framesize;          /* size of activation record */
        !            19: static int offset;             /* current frame offset */
        !            20: static int argbuildsize;       /* size of argument build area */
        !            21: static int argoffset;          /* offset from top of stack for next argument */
        !            22: static int nregs = 12;         /* number of allocatable registers */
        !            23: static unsigned rmask;         /* rmask&(1<<r) == 0 if register r is free */
        !            24: static unsigned usedmask;      /* usedmask&(1<<r) == 1 if register r was used */
        !            25: static int reginfo[] = {       /*      1<<x if op+x is legal; */
        !            26:        0,                      /* 0x1000<<x if op+x needs a register */
        !            27: #include "reginfo.h"
        !            28: };
        !            29: 
        !            30: static void genreloads(Node, Node, Symbol);
        !            31: static Symbol genspill(Node);
        !            32: static void getreg(Node);
        !            33: static Node *linearize(Node, Node *, Node);
        !            34: static int needsreg(Node);
        !            35: static void putreg(Node);
        !            36: static void ralloc(Node);
        !            37: static void restore(unsigned);
        !            38: static void save(unsigned);
        !            39: static int spillee(Node, unsigned);
        !            40: static void spill(int, unsigned, Node);
        !            41: static unsigned uses(Node);
        !            42: static int valid(int);
        !            43: 
        !            44: #define typecode(p) (optype(p->op) == U ? I : optype(p->op) == B ? P : optype(p->op))
        !            45: #define sets(p) ((p)->x.rmask<<(p)->x.reg)
        !            46: 
        !            47: /* address - initialize q for addressing expression p+n */
        !            48: static void address(Symbol q, Symbol p, int n) {
        !            49:        if (p->scope == GLOBAL || p->sclass == STATIC || p->sclass == EXTERN)
        !            50:                q->x.name = stringf("%s%s%d", p->x.name, n >= 0 ? "+" : "", n);
        !            51:        else {
        !            52:                q->x.offset = p->x.offset + n;
        !            53:                q->x.name = stringf("%d(%s)", q->x.offset,
        !            54:                        p->scope == PARAM ? "ap" : "fp");
        !            55:        }
        !            56: }
        !            57: 
        !            58: /* blockbeg - begin a compound statement */
        !            59: static void blockbeg(Env *e) {
        !            60:        assert(rmask == (((~0)<<nregs)|1));
        !            61:        e->rmask = rmask;
        !            62:        e->offset = offset;
        !            63: }
        !            64: 
        !            65: /* blockend - end a compound statement */
        !            66: static void blockend(Env *e) {
        !            67:        if (offset > framesize)
        !            68:                framesize = offset;
        !            69:        offset = e->offset;
        !            70:        rmask = e->rmask;
        !            71: }
        !            72: 
        !            73: /* defaddress - initialize an address */
        !            74: static void defaddress(Symbol p) {
        !            75:        print(".long %s\n", p->x.name);
        !            76: }
        !            77: 
        !            78: /* defconst - define a constant */
        !            79: static void defconst(int ty, Value v) {
        !            80:        switch (ty) {
        !            81:        case C: print(".byte %d\n",   v.uc); break;
        !            82:        case S: print(".word %d\n",   v.us); break;
        !            83:        case I: print(".long %d\n",   v.i ); break;
        !            84:        case U: print(".long 0x%x\n", v.u ); break;
        !            85:        case P: print(".long 0x%x\n", v.p ); break;
        !            86: #ifdef vax
        !            87:        case F:
        !            88:                print(".long 0x%x\n", ((unsigned *) &v.f)[0]);
        !            89:                break;
        !            90:        case D: 
        !            91:                print(".long 0x%x,0x%x\n", ((unsigned *) &v.d)[0],
        !            92:                        ((unsigned *) &v.d)[1]);
        !            93:                break;
        !            94: #else
        !            95:        case F: {
        !            96:                char buf[MAXLINE];
        !            97:                sprintf(buf, ".float 0f%.8e\n", v.f);
        !            98:                outs(buf);
        !            99:                break;
        !           100:                }
        !           101:        case D: {
        !           102:                char buf[MAXLINE];
        !           103:                sprintf(buf, ".double 0d%.18e\n", v.d);
        !           104:                outs(buf);
        !           105:                break;
        !           106:                }
        !           107: #endif
        !           108:        default: assert(0);
        !           109:        }
        !           110: }
        !           111: 
        !           112: /* defstring - emit a string constant */
        !           113: static void defstring(int len, char *s) {
        !           114:        while (len-- > 0)
        !           115:                print(".byte %d\n", *s++);
        !           116: }
        !           117: 
        !           118: /* defsymbol - initialize p's Xsymbol fields */
        !           119: static void defsymbol(Symbol p) {
        !           120:        if (p->scope == CONSTANTS)
        !           121:                p->x.name = p->name;
        !           122:        else if (p->scope >= LOCAL && p->sclass == STATIC)
        !           123:                p->x.name = stringf("L%d", genlabel(1));
        !           124:        else if (p->generated)
        !           125:                p->x.name = stringf("L%s", p->name);
        !           126:        else
        !           127:                p->x.name = stringf("_%s", p->name);
        !           128: }
        !           129: 
        !           130:                  /* " FDCSIUPVB" */
        !           131: #define suffix(p)    ".fdbwllll."[optype((p)->op)]
        !           132: #define binary(inst) print("%s%c3 r%d,r%d,r%d\n", inst, suffix(p), \
        !           133:                         b->x.reg, a->x.reg, r)
        !           134: #define unary(inst)  print("%s%c r%d,r%d\n", inst, suffix(p), a->x.reg, r)
        !           135: #define compare(cp)  print("cmp%c r%d,r%d; j%s %s\n", suffix(p), \
        !           136:                         a->x.reg, b->x.reg, cp, p->syms[0]->x.name)
        !           137: 
        !           138: /* emit - emit the dags on list p */
        !           139: static void emit(Node p) {
        !           140:        for (; p; p = p->x.next) {
        !           141:                Node a = p->kids[0], b = p->kids[1];
        !           142:                int r = p->x.reg;
        !           143:                switch (p->op) {
        !           144:                case BANDU:                             binary("bic");   break;
        !           145:                case BORU:                              binary("bis");   break;
        !           146:                case BXORU:                             binary("xor");   break;
        !           147:                case ADDD:  case ADDF:                  binary("add");   break;
        !           148:                case ADDI:  case ADDP:  case ADDU:      binary("add");   break;
        !           149:                case SUBD:  case SUBF:                  binary("sub");   break;
        !           150:                case SUBI:  case SUBP:  case SUBU:      binary("sub");   break;
        !           151:                case MULD:  case MULF:                  binary("mul");   break;
        !           152:                case MULI:  case MULU:                  binary("mul");   break;
        !           153:                case DIVD:  case DIVF:  case DIVI:      binary("div");   break;
        !           154:                case DIVU:
        !           155:                        save(p->x.busy&0x3e);
        !           156:                        print("pushl r%d; pushl r%d; calls $2,udiv; movl r0,r%d\n",
        !           157:                                b->x.reg, a->x.reg, r);
        !           158:                        restore(p->x.busy&0x3e);
        !           159:                        break;
        !           160:                case MODI:
        !           161:                        print("divl3 r%d,r%d,r0; mull2 r%d,r0; subl3 r0,r%d,r%d\n",
        !           162:                                b->x.reg, a->x.reg, b->x.reg, a->x.reg, r);
        !           163:                        break;
        !           164:                case MODU:
        !           165:                        save(p->x.busy&0x3e);
        !           166:                        print("pushl r%d; pushl r%d; calls $2,urem; movl r0,r%d\n",
        !           167:                                b->x.reg, a->x.reg, r);
        !           168:                        restore(p->x.busy&0x3e);
        !           169:                        break;
        !           170:                case RSHU:
        !           171:                        print("subl3 r%d,$32,r0; extzv r%d,r0,r%d,r%d\n",
        !           172:                                b->x.reg, b->x.reg, a->x.reg, r);
        !           173:                        break;
        !           174:                case RSHI: case LSHI: case LSHU:
        !           175:                        print("ashl r%d,r%d,r%d\n", b->x.reg, a->x.reg, r);
        !           176:                        break;
        !           177:                case INDIRB:
        !           178:                        print("moval (r%d),r%d\n", a->x.reg, r);
        !           179:                        break;
        !           180:                case INDIRC: case INDIRD: case INDIRF: case INDIRI:
        !           181:                case INDIRP: case INDIRS:
        !           182:                        print("mov%c (r%d),r%d\n", suffix(p), a->x.reg, r);
        !           183:                        break;
        !           184:                case BCOMU:                             unary("mcom" );  break;
        !           185:                case NEGD:  case NEGF:  case NEGI:      unary("mneg" );  break;
        !           186:                case CVCI:                              unary("cvtb" );  break;
        !           187:                case CVCU:                              unary("movzb");  break;
        !           188:                case CVSI:                              unary("cvtw" );  break;
        !           189:                case CVSU:                              unary("movzw");  break;
        !           190:                case CVDF:  case CVDI:                  unary("cvtd" );  break;
        !           191:                case CVFD:                              unary("cvtf" );  break;
        !           192:                case CVUC:  case CVUS:                  unary("cvtl" );  break;
        !           193:                case CVIC:  case CVIS:  case CVID:      unary("cvtl" );  break;
        !           194:                case CVIU:  case CVUI:                  unary("mov"  );  break;
        !           195:                case CVPU:  case CVUP:                  unary("mov"  );  break;
        !           196:                case RETD: case RETF: case RETI:
        !           197:                        print("mov%c r%d,r0; ret\n", suffix(p), a->x.reg);
        !           198:                        break;
        !           199:                case RETV:
        !           200:                        print("ret\n");
        !           201:                        break;
        !           202:                case ADDRGP: case ADDRFP: case ADDRLP:
        !           203:                        print("moval %s,r%d\n", p->syms[0]->x.name, r);
        !           204:                        break;
        !           205:                case CNSTC: case CNSTI: case CNSTP:
        !           206:                case CNSTS: case CNSTU:
        !           207:                        print("movl $%s,r%d\n", p->syms[0]->x.name, r);
        !           208:                        break;
        !           209:                case JUMPV:
        !           210:                        print("jmp (r%d)\n", a->x.reg);
        !           211:                        break;
        !           212:                case ASGNB:
        !           213:                        save(p->x.busy&0x3f);
        !           214:                        print("movc3 $%s,(r%d),(r%d)\n", p->syms[0]->x.name,
        !           215:                                b->x.reg, a->x.reg);
        !           216:                        restore(p->x.busy&0x3f);
        !           217:                        break;
        !           218:                case ASGNC: case ASGND: case ASGNF: case ASGNI: case ASGNP: case ASGNS:
        !           219:                        print("mov%c r%d,(r%d)\n", suffix(p), b->x.reg, a->x.reg);
        !           220:                        break;
        !           221:                case ARGB:
        !           222:                        save(p->x.busy&0x3f);
        !           223:                        print("movc3 $%s,(r%d),%d(sp)\n", p->syms[0]->x.name,
        !           224:                                a->x.reg, p->x.argoffset);
        !           225:                        restore(p->x.busy&0x3f);
        !           226:                        break;
        !           227:                case ARGD: case ARGF: case ARGI: case ARGP:
        !           228:                        print("mov%c r%d,%d(sp)\n", suffix(p),
        !           229:                                a->x.reg, p->x.argoffset);
        !           230:                        break;
        !           231:                case CALLB:
        !           232:                        save(p->x.busy&0x3e);
        !           233:                        if (a->x.reg == 1) {
        !           234:                                print("movl r1,r0\n");
        !           235:                                a->x.reg = 0;
        !           236:                        }
        !           237:                        if (b->x.reg != 1)
        !           238:                                print("movl r%d,r1\n", b->x.reg);
        !           239:                        print("calls $0,(r%d)\n", a->x.reg);
        !           240:                        restore(p->x.busy&0x3e);
        !           241:                        break;
        !           242:                case CALLD: case CALLF: case CALLI: case CALLV:
        !           243:                        save(p->x.busy&0x3e);
        !           244:                        print("calls $0,(r%d)\n", a->x.reg);
        !           245:                        if (p->op != CALLV)
        !           246:                                print("mov%c r0,r%d\n", suffix(p), r);
        !           247:                        restore(p->x.busy&0x3e);
        !           248:                        break;
        !           249:                case EQD:   case EQF:   case EQI:       compare("eql" ); break;
        !           250:                case GED:   case GEF:   case GEI:       compare("geq" ); break;
        !           251:                case GEU:                               compare("gequ"); break;
        !           252:                case GTD:   case GTF:   case GTI:       compare("gtr" ); break;
        !           253:                case GTU:                               compare("gtru"); break;
        !           254:                case LED:   case LEF:   case LEI:       compare("leq" ); break;
        !           255:                case LEU:                               compare("lequ"); break;
        !           256:                case LTD:   case LTF:   case LTI:       compare("lss" ); break;
        !           257:                case LTU:                               compare("lssu"); break;
        !           258:                case NED:   case NEF:   case NEI:       compare("neq" ); break;
        !           259:                case LABELV:
        !           260:                        print("%s:", p->syms[0]->x.name);
        !           261:                        break;
        !           262:                default: assert(0);
        !           263:                }
        !           264:        }
        !           265: }
        !           266: 
        !           267: /* export - announce an exported symbol */
        !           268: static void export(Symbol p) {
        !           269:        print(".globl %s\n", p->x.name);
        !           270: }
        !           271: 
        !           272: /* function - generate code for a function */
        !           273: static void function(Symbol f, Symbol caller[],
        !           274:        Symbol callee[], int ncalls) {
        !           275:        int i;
        !           276: 
        !           277:        offset = 4;
        !           278:        for (i = 0; caller[i] && callee[i]; i++) {
        !           279:                offset = roundup(offset, caller[i]->type->align);
        !           280:                callee[i]->x.offset = caller[i]->x.offset = offset;
        !           281:                callee[i]->x.name = caller[i]->x.name = stringf("%d(ap)", offset);
        !           282:                offset += caller[i]->type->size;
        !           283:                callee[i]->sclass = AUTO;
        !           284:        }
        !           285:        usedmask = argbuildsize = framesize = offset = 0;
        !           286:        gencode(caller, callee);
        !           287:        print("%s:.word 0x%x\n", f->x.name, usedmask&~0x3f);
        !           288:        framesize += 4*nregs + argbuildsize;
        !           289:        print("subl2 $%d,sp\n", framesize);
        !           290:        if (isstruct(freturn(f->type)))
        !           291:                print("movl r1,-4(fp)\n");
        !           292:        emitcode();
        !           293:        if (glevel > 1)
        !           294:                print("ret\n");
        !           295: }
        !           296: 
        !           297: /* gen - generate code for the dags on list p */
        !           298: static Node gen(Node p) {
        !           299:        Node head, *last;
        !           300: 
        !           301:        debug(1,id = 0);
        !           302:        for (last = &head; p; p = p->link)
        !           303:                last = linearize(p, last, 0);
        !           304:        debug(rflag,(lhead = head, lprint(head," before ralloc")));
        !           305:        for (p = head; p; p = p->x.next) {
        !           306:                ralloc(p);
        !           307:                if (p->count == 0 && sets(p))
        !           308:                        putreg(p);
        !           309:        }
        !           310:        debug(rflag,lprint(lhead," after ralloc"));
        !           311:        return head;
        !           312: }
        !           313: 
        !           314: /* getreg - allocate 1 or 2 registers for node p */
        !           315: static void getreg(Node p) {
        !           316:        int r, m = optype(p->op) == D ? 3 : 1;
        !           317: 
        !           318:        for (r = 0; r < nregs; r++)
        !           319:                if ((rmask&(m<<r)) == 0) {
        !           320:                        p->x.rmask = m;
        !           321:                        p->x.reg = r;
        !           322:                        rmask |= sets(p);
        !           323:                        usedmask |= sets(p);
        !           324:                        debug(rflag,fprint(2,"allocating %s to node #%d\n", rnames(sets(p)), p->x.id));
        !           325:                        return;
        !           326:                }
        !           327:        debug(rflag,lprint(lhead, " before spillee"));
        !           328:        r = spillee(p, m);
        !           329:        spill(r, m, p);
        !           330:        debug(rflag,lprint(lhead, " after spill"));
        !           331:        assert((rmask&(m<<r)) == 0);
        !           332:        getreg(p);
        !           333: }
        !           334: 
        !           335: /* genreloads - make the nodes after dot use reloads of temp instead of p's register */
        !           336: static void genreloads(Node dot, Node p, Symbol temp) {
        !           337:        int i;
        !           338:        Node last;
        !           339: 
        !           340:        for (last = dot; dot = dot->x.next; last = dot)
        !           341:                for (i = 0; i < MAXKIDS; i++)
        !           342:                        if (dot->kids[i] == p) {
        !           343:                                dot->kids[i] = newnode(INDIR + typecode(p),
        !           344:                                        newnode(ADDRL+P, 0, 0, temp), 0, 0);
        !           345:                                dot->kids[i]->count = 1;
        !           346:                                p->count--;
        !           347:                                linearize(dot->kids[i], &last->x.next, last->x.next);
        !           348:                                last = dot->kids[i];
        !           349:                        }
        !           350:        assert(p->count == 0);
        !           351: }
        !           352: 
        !           353: /* genspill - generate code to spill p's register and return the temporary used */
        !           354: static Symbol genspill(Node p) {
        !           355:        Symbol temp = newtemp(AUTO, typecode(p));
        !           356:        Node q = p->x.next;
        !           357: 
        !           358:        linearize(newnode(ASGN + typecode(p),
        !           359:                newnode(ADDRLP, 0, 0, temp), p, 0),
        !           360:                &p->x.next, p->x.next);
        !           361:        rmask &= ~1;
        !           362:        for (p = p->x.next; p != q; p = p->x.next)
        !           363:                ralloc(p);
        !           364:        rmask |= 1;
        !           365:        return temp;
        !           366: }
        !           367: 
        !           368: /* global - global id */
        !           369: static void global(Symbol p) {
        !           370:        switch (p->type->align) {
        !           371:        case 2: print(".align 1; "); break;
        !           372:        case 4: print(".align 2; "); break;
        !           373:        case 8: print(".align 3; "); break;
        !           374:        }
        !           375:        print("%s:", p->x.name);
        !           376: }
        !           377: 
        !           378: /* import - announce an imported symbol */
        !           379: static void import(Symbol p) {
        !           380: }
        !           381: 
        !           382: /* linearize - linearize node list p */
        !           383: static Node *linearize(Node p, Node *last, Node next) {
        !           384:        if (p && !p->x.visited) {
        !           385:                last = linearize(p->kids[0], last, 0);
        !           386:                last = linearize(p->kids[1], last, 0);
        !           387:                p->x.visited = 1;
        !           388:                *last = p;
        !           389:                last = &p->x.next;
        !           390:                debug(1,if (p->x.id == 0) p->x.id = ++id);              
        !           391:                debug(rflag,{fprint(2,"listing node "); nprint(p);})
        !           392:        }
        !           393:        *last = next;
        !           394:        return last;
        !           395: }
        !           396: 
        !           397: /* local - local variable */
        !           398: static void local(Symbol p) {
        !           399:        offset = roundup(offset + p->type->size, p->type->align);
        !           400:        offset = roundup(offset, 4);
        !           401:        p->x.offset = -offset;
        !           402:        p->x.name = stringf("%d(fp)", -offset);
        !           403:        p->sclass = AUTO;
        !           404: }
        !           405: 
        !           406: /* needsreg - does p need a register? */
        !           407: static int needsreg(p) Node p; {
        !           408:        assert(opindex(p->op) > 0 && opindex(p->op) < sizeof reginfo/sizeof reginfo[0]);
        !           409:        return reginfo[opindex(p->op)]&(0x1000<<optype(p->op));
        !           410: }
        !           411: 
        !           412: /* progbeg - beginning of program */
        !           413: static void progbeg(int argc, char *argv[]) {
        !           414:        extern int atoi(char *);                /* (omit) */
        !           415:        while (--argc > 0)
        !           416:                if (**++argv == '-' && argv[0][1] >= '0' && argv[0][1] <= '9')
        !           417:                        nregs = atoi(*argv + 1);
        !           418:                else if (strcmp(*argv, "-r") == 0)      /* (omit) */
        !           419:                        rflag++;                        /* (omit) */
        !           420:        rmask = ((~0)<<nregs)|1;
        !           421: }
        !           422: 
        !           423: /* progend - end of program */
        !           424: static void progend(void) {
        !           425: }
        !           426: 
        !           427: /* putreg - decrement register usage */
        !           428: static void putreg(Node p) {
        !           429:        if (p && --p->count <= 0)
        !           430:                { assert(p->x.rmask);
        !           431:                rmask &= ~sets(p);
        !           432:                debug(rflag,fprint(2,"deallocating %s from node #%d\n", rnames(sets(p)), p->x.id)); }
        !           433: }
        !           434: 
        !           435: /* ralloc - assign a register for p */
        !           436: static void ralloc(Node p) {
        !           437:        int i;
        !           438: 
        !           439:        assert(p);
        !           440:        assert(p->x.rmask == 0);
        !           441:        switch (generic(p->op)) {
        !           442:        case ARG:
        !           443:                argoffset = roundup(argoffset, p->syms[1]->u.c.v.i);
        !           444:                p->x.argoffset = argoffset;
        !           445:                argoffset += p->syms[0]->u.c.v.i;
        !           446:                if (argoffset > argbuildsize)
        !           447:                        argbuildsize = roundup(argoffset, 4);
        !           448:                break;
        !           449:        case CALL:
        !           450:                argoffset = 0;
        !           451:                break;
        !           452:        default:assert(valid(p->op));
        !           453:        }
        !           454:        for (i = 0; i < MAXKIDS; i++)
        !           455:                putreg(p->kids[i]);
        !           456:        p->x.busy = rmask;
        !           457:        if (needsreg(p))
        !           458:                getreg(p);
        !           459: }
        !           460: 
        !           461: /* restore - restore registers in mask */
        !           462: static void restore(unsigned mask) {
        !           463:        int i;
        !           464: 
        !           465:        for (i = 1; i < nregs; i++)
        !           466:                if (mask&(1<<i))
        !           467:                        print("movl %d(fp),r%d\n",
        !           468:                                4*i - framesize + argbuildsize, i);
        !           469: }
        !           470: 
        !           471: /* save - save registers in mask */
        !           472: static void save(unsigned mask) {
        !           473:        int i;
        !           474: 
        !           475:        for (i = 1; i < nregs; i++)
        !           476:                if (mask&(1<<i))
        !           477:                        print("movl r%d,%d(fp)\n", i,
        !           478:                                4*i - framesize + argbuildsize);
        !           479: }
        !           480: 
        !           481: /* segment - switch to logical segment s */
        !           482: static void segment(int s) {
        !           483:        switch (s) {
        !           484:        case CODE: print(".text\n");   break;
        !           485:        case  LIT: print(".text 1\n"); break;
        !           486:        case DATA:
        !           487:        case  BSS: print(".data\n");   break;
        !           488:        default: assert(0);
        !           489:        }
        !           490: }
        !           491: 
        !           492: /* space - initialize n bytes of space */
        !           493: static void space(int n) {
        !           494:        print(".space %d\n", n);
        !           495: }
        !           496: 
        !           497: /* spill - spill all registers that overlap (r,m) */
        !           498: static void spill(int r, unsigned m, Node dot) {
        !           499:        int i;
        !           500:        Node p = dot;
        !           501: 
        !           502:        while (p = p->x.next)
        !           503:                for (i = 0; i < MAXKIDS; i++)
        !           504:                        if (p->kids[i] && sets(p->kids[i])&(m<<r)) {
        !           505:                                Symbol temp = genspill(p->kids[i]);
        !           506:                                rmask &= ~sets(p->kids[i]);
        !           507:                                genreloads(dot, p->kids[i], temp);
        !           508:                        }
        !           509: }
        !           510: 
        !           511: /* spillee - identify the most-distantly-used register */
        !           512: static int spillee(Node dot, unsigned m) {
        !           513:        int bestdist = -1, bestreg = 0, dist, r;
        !           514:        Node q;
        !           515: 
        !           516:        debug(rflag,fprint(2,"spillee: dot is node #%d\n", dot->x.id));
        !           517:        for (r = 1; r < nregs - (m>>1); r++) {
        !           518:                dist = 0;
        !           519:                for (q = dot->x.next; q && !(uses(q)&(m<<r)); q = q->x.next)
        !           520:                        dist++;
        !           521:                assert(q);      /* (omit) */
        !           522:                debug(rflag,fprint(2,"r%d used in node #%d at distance %d\n", r, q->x.id, dist));
        !           523:                if (dist > bestdist) {
        !           524:                        bestdist = dist;
        !           525:                        bestreg = r;
        !           526:                }
        !           527:        }
        !           528:        debug(rflag,fprint(2,"spilling %s\n",rnames(m<<bestreg)));
        !           529:        assert(bestreg);        /* (omit) */
        !           530:        return bestreg;
        !           531: }
        !           532: 
        !           533: /* uses - return mask of registers used by node p */
        !           534: static unsigned uses(Node p) {
        !           535:        int i;
        !           536:        unsigned m = 0;
        !           537: 
        !           538:        for (i = 0; i < MAXKIDS; i++)
        !           539:                if (p->kids[i])
        !           540:                        m |= sets(p->kids[i]);
        !           541:        return m;
        !           542: }
        !           543: 
        !           544: /* valid - is operator op a valid operator ? */
        !           545: static int valid(op) {
        !           546:        return opindex(op) > 0 && opindex(op) < sizeof reginfo/sizeof reginfo[0] ?
        !           547:                reginfo[opindex(op)]&(1<<optype(op)) : 0;
        !           548: }
        !           549: 
        !           550: #ifdef DEBUG
        !           551: /* lprint - print the nodelist beginning at p */
        !           552: static void lprint(Node p, char *s) {
        !           553:        fprint(2, "node list%s:\n", s);
        !           554:        if (p) {
        !           555:                char buf[100];
        !           556:                sprintf(buf, "%-4s%-8s%-8s%-8s%-7s%-13s%s",
        !           557:                        " #", "op", "kids", "syms", "count", "uses", "sets");
        !           558:                fprint(2, "%s\n", buf);
        !           559:        }
        !           560:        for ( ; p; p = p->x.next)
        !           561:                nprint(p);
        !           562: }
        !           563: 
        !           564: /* nprint - print a line describing node p */
        !           565: static void nprint(Node p) {
        !           566:        int i;
        !           567:        char *kids = "", *syms = "", buf[200];
        !           568: 
        !           569:        if (p->kids[0]) {
        !           570:                static char buf[100];
        !           571:                buf[0] = 0;
        !           572:                for (i = 0; i < MAXKIDS && p->kids[i]; i++)
        !           573:                        sprintf(buf + strlen(buf), "%3d", p->kids[i]->x.id);
        !           574:                kids = &buf[1];
        !           575:        }
        !           576:        if (p->syms[0] && p->syms[0]->x.name) {
        !           577:                static char buf[100];
        !           578:                buf[0] = 0;
        !           579:                for (i = 0; i < MAXSYMS && p->syms[i]; i++) {
        !           580:                        if (p->syms[i]->x.name)
        !           581:                                sprintf(buf + strlen(buf), " %s", p->syms[i]->x.name);
        !           582:                        if (p->syms[i]->u.c.loc)
        !           583:                                sprintf(buf + strlen(buf), "=%s", p->syms[i]->u.c.loc->name);
        !           584:                }
        !           585:                syms = &buf[1];
        !           586:        }
        !           587:        sprintf(buf, "%2d. %-8s%-8s%-8s %2d    %-13s",
        !           588:                p->x.id, opname(p->op), kids, syms, p->count, rnames(uses(p)));
        !           589:        sprintf(buf + strlen(buf), "%s", rnames(sets(p)));
        !           590:        fprint(2, "%s\n", buf);
        !           591: }
        !           592: 
        !           593: /* rnames - return names of registers given by mask m */
        !           594: static char *rnames(unsigned m) {
        !           595:        static char buf[100];
        !           596:        int r;
        !           597: 
        !           598:        buf[0] = buf[1] = 0;
        !           599:        for (r = 0; r < nregs; r++)
        !           600:                if (m&(1<<r))
        !           601:                        sprintf(buf + strlen(buf), " r%d", r);
        !           602:        return &buf[1];
        !           603: }
        !           604: #endif
        !           605: 
        !           606: #ifndef V9
        !           607: #include <errno.h>
        !           608: #ifndef errno
        !           609: extern int errno;
        !           610: #endif
        !           611: 
        !           612: /* strtol - interpret str as a base b number; if ptr!=0, *ptr gets updated str */
        !           613: long strtol(str, ptr, b) char *str, **ptr; {
        !           614:        long n = 0;
        !           615:        char *s, sign = '+';
        !           616:        int d, overflow = 0;
        !           617: 
        !           618:        if (ptr)
        !           619:                *ptr = str;
        !           620:        if (b < 0 || b == 1 || b > 36)
        !           621:                return 0;
        !           622:        while (*str==' '||*str=='\f'||*str=='\n'||*str=='\r'||*str=='\t'||*str=='\v')
        !           623:                str++;
        !           624:        if (*str == '-' || *str == '+')
        !           625:                sign = *str++;
        !           626:        if (b == 0)
        !           627:                if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
        !           628:                        b = 16;
        !           629:                        str += 2;
        !           630:                } else if (str[0] == '0')
        !           631:                        b = 8;
        !           632:                else
        !           633:                        b = 10;
        !           634:        for (s = str; *str; str++) {
        !           635:                if (*str >= '0' && *str <= '9')
        !           636:                        d = *str - '0';
        !           637:                else if (*str >= 'a' && *str <= 'z' || *str >= 'A' && *str <= 'Z')
        !           638:                        d = (*str&~040) - 'A' + 10;
        !           639:                else
        !           640:                        break;
        !           641:                if (d >= b)
        !           642:                        break;
        !           643:                if (n < (LONG_MIN + d)/b)
        !           644:                        overflow = 1;
        !           645:                n = b*n - d;
        !           646:        }
        !           647:        if (s == str)
        !           648:                return 0;
        !           649:        if (ptr)
        !           650:                *ptr = str;
        !           651:        if (overflow || (sign == '+' && n == LONG_MIN)) {
        !           652:                errno = ERANGE;
        !           653:                return sign == '+' ? LONG_MAX : LONG_MIN;
        !           654:        }
        !           655:        return sign == '+' ? -n : n;
        !           656: }
        !           657: #endif
        !           658: 
        !           659: static Interface naiveVAX = {
        !           660:        "naiveVAX",
        !           661:        1, 1, 0,        /* char */
        !           662:        2, 2, 0,        /* short */
        !           663:        4, 4, 0,        /* int */
        !           664:        4, 4, 1,        /* float */
        !           665:        8, 4, 1,        /* double */
        !           666:        4, 4, 0,        /* T * */
        !           667:        0, 1, 0,        /* struct */
        !           668:        1,              /* left_to_right */
        !           669:        1,              /* little_endian */
        !           670:        0,              /* jump_on_return */
        !           671:        0,              /* mulops_are_calls */ 
        !           672:        1,              /* compl_band */
        !           673:        0,              /* no_argb */
        !           674:        0,              /* no_dag */
        !           675:        address,
        !           676:        blockbeg,
        !           677:        blockend,
        !           678:        defaddress,
        !           679:        defconst,
        !           680:        defstring,
        !           681:        defsymbol,
        !           682:        emit,
        !           683:        export,
        !           684:        function,
        !           685:        gen,
        !           686:        global,
        !           687:        import,
        !           688:        local,
        !           689:        progbeg,
        !           690:        progend,
        !           691:        segment,
        !           692:        space,
        !           693: };
        !           694: Interface *interfaces[] = { &naiveVAX, 0 };
        !           695: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.