|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.