Annotation of researchv10no/cmd/lcc/gen3/gen.c, revision 1.1.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.