|
|
1.1 ! root 1: /* ! 2: * This file contains the main ! 3: * driving routine for the code assembly ! 4: * phase of the C compiler. ! 5: * It reads the intermediate file and calls ! 6: * off to the appropriate routines to get things ! 7: * done. ! 8: */ ! 9: #ifdef vax ! 10: #include "INC$LIB:cc2.h" ! 11: #else ! 12: #include "cc2.h" ! 13: #endif ! 14: ! 15: /* Verbosity. Parallel to ccscan.c. */ ! 16: #ifdef COHERENT ! 17: #define ERRMSG "cc:" ! 18: #else ! 19: #if INTEL ! 20: #define ERRMSG "***" ! 21: #else ! 22: #if OMF286 ! 23: #define ERRMSG "MWC286:" ! 24: #else ! 25: #define ERRMSG "MWC86:" ! 26: #endif ! 27: #endif ! 28: #endif ! 29: ! 30: #if !OVERLAID ! 31: FILE *ifp; /* Input file */ ! 32: FILE *ofp; /* Output file */ ! 33: char file[NFNAME]; /* File name */ ! 34: char module[NMNAME]; /* Module name */ ! 35: int line; /* Line number */ ! 36: char id[NCSYMB]; /* Name buffer */ ! 37: VARIANT variant; /* Variant template */ ! 38: int dotseg; /* Current segment # */ ! 39: #endif ! 40: ! 41: int changes; /* Change flag */ ! 42: ADDRESS dot; /* Current location */ ! 43: SYM *hash2[NSHASH]; /* Symbol table */ ! 44: INS ins; /* Head of instruction list */ ! 45: int nlabdel; /* # of labels deleted */ ! 46: int ndead; /* # of dead instructions deleted */ ! 47: int nbrbr; /* # of branches to branches */ ! 48: int nexbr; /* # of extra branches */ ! 49: int ncbrbr; /* # of conditional branches to branches */ ! 50: int nbrnext; /* # of branches to next instruction */ ! 51: int nxjump; /* # of cross jumps */ ! 52: int ncomseq; /* # of common sequences */ ! 53: int nsimplify; /* # of instructions simplified */ ! 54: int nuseless; /* # of instructions deleted */ ! 55: ! 56: #if !TINY ! 57: int vflag; /* Verbosity */ ! 58: int xflag; /* More verbosity */ ! 59: #endif ! 60: ! 61: /* ! 62: * Segment table. ! 63: */ ! 64: SEG seg[NSEG]; ! 65: ! 66: #if !OVERLAID ! 67: /* ! 68: * Mainline. ! 69: * Interpret options and ! 70: * open files. ! 71: */ ! 72: main(argc, argv) ! 73: char *argv[]; ! 74: { ! 75: #ifdef vax ! 76: int ofd; ! 77: #endif ! 78: ! 79: passname = "cc2"; ! 80: if (argc < 4) ! 81: usage(); ! 82: getvariant(argv[1]); ! 83: #if GEMDOS ! 84: { ! 85: extern long gemdos(); ! 86: extern char *lmalloc(); ! 87: free(lmalloc((gemdos(0x48,-1L)-4096) & ~1023L)); ! 88: } ! 89: #endif ! 90: if ((ifp=fopen(argv[2], SRMODE)) == NULL) { ! 91: fprintf(stderr, "%s: cannot open.\n", argv[2]); ! 92: exit(BAD); ! 93: } ! 94: if (isvariant(VASM)) { ! 95: if ((ofp=fopen(argv[3], SWMODE)) == NULL) ! 96: nocreate(argv[3]); ! 97: } else { ! 98: if (argc < 5) ! 99: usage(); ! 100: if ((ofp=fopen(argv[4], SWMODE)) == NULL) ! 101: nocreate(argv[4]); ! 102: } ! 103: #if !TINY ! 104: if (argc > 5) ! 105: vflag = atoi(argv[5]); ! 106: if (argc > 6) ! 107: xflag = atoi(argv[6]); ! 108: #endif ! 109: labgen = 20000; ! 110: dotseg = -1; ! 111: outinit(); ! 112: work2(); ! 113: outdone(); ! 114: if (notvariant(VASM)) { ! 115: fclose(ifp); ! 116: fclose(ofp); ! 117: if ((ifp=fopen(argv[4], SRMODE)) == NULL) ! 118: cfatal("%s: cannot reopen", argv[4]); ! 119: #ifdef vax ! 120: #if VAXFMT ! 121: if ((ofd=creat(argv[3], 0666, "rfm=var")) < 0 ! 122: || (ofp=fdopen(ofd, SWMODE)) == NULL) ! 123: #else ! 124: if ((ofp=fopen(argv[3], SWMODE)) == NULL) ! 125: #endif ! 126: #else ! 127: if ((ofp=fopen(argv[3], SWMODE)) == NULL) ! 128: #endif ! 129: nocreate(argv[3]); ! 130: copycode(); ! 131: } ! 132: if (isvariant(VSTAT)) ! 133: showstats(); ! 134: if (nerr != 0) ! 135: exit(BAD); ! 136: exit(OK); ! 137: } ! 138: ! 139: /* ! 140: * Print usage message. ! 141: */ ! 142: usage() ! 143: { ! 144: fprintf(stderr, "Usage: cc2 variant in out [temp]\n"); ! 145: exit(BAD); ! 146: } ! 147: ! 148: /* ! 149: * Complain that a file cannot be ! 150: * created. ! 151: */ ! 152: nocreate(fn) ! 153: char *fn; ! 154: { ! 155: fprintf(stderr, "%s: cannot create.\n", fn); ! 156: exit(BAD); ! 157: } ! 158: #else ! 159: /* ! 160: * Driving routine for the ! 161: * overlaid version of the optimizer and ! 162: * code assembly phase. The files have all been ! 163: * opened by the command line scanner in the ! 164: * root segment. Set up a fatal error context and ! 165: * do the work. Return exit status. ! 166: */ ! 167: cc2a() ! 168: { ! 169: #if MONOLITHIC ! 170: register int i; ! 171: #endif ! 172: passname = "cc2a"; ! 173: if (setjmp(death) != 0) { ! 174: freesym2(); ! 175: return (ABORT); ! 176: } ! 177: labgen = 20000; ! 178: dotseg = -1; ! 179: #if MONOLITHIC ! 180: dot = 0; ! 181: nlabdel = 0; ! 182: ndead = 0; ! 183: nbrbr = 0; ! 184: nexbr = 0; ! 185: ncbrbr = 0; ! 186: nbrnext = 0; ! 187: nxjump = 0; ! 188: ncomseq = 0; ! 189: nsimplify = 0; ! 190: nuseless = 0; ! 191: for (i=0; i<NSEG; ++i) ! 192: seg[i].s_dot = 0; ! 193: #endif ! 194: outinit(); ! 195: work2(); ! 196: outdone(); ! 197: if (isvariant(VSTAT)) ! 198: showstats(); ! 199: if (isvariant(VASM)) ! 200: freesym2(); ! 201: if (nerr != 0) ! 202: return (BAD); ! 203: return (OK); ! 204: } ! 205: ! 206: /* ! 207: * Second part. Copy the code back. This is ! 208: * only done if aflag==0. The root segment will have moved ! 209: * all of the files around. The same fatal error game is ! 210: * played. ! 211: */ ! 212: cc2b() ! 213: { ! 214: passname = "cc2b"; ! 215: if (setjmp(death) != 0) { ! 216: freesym2(); ! 217: return (ABORT); ! 218: } ! 219: copycode(); ! 220: freesym2(); ! 221: if (nerr != 0) ! 222: return (BAD); ! 223: return (OK); ! 224: } ! 225: #endif ! 226: ! 227: /* ! 228: * Print statistics. ! 229: */ ! 230: showstats() ! 231: { ! 232: printstat(nlabdel, "label# deleted"); ! 233: printstat(ndead, "dead instruction# deleted"); ! 234: printstat(nbrbr, "jump# to a jump"); ! 235: printstat(ncbrbr, "conditional jump# over a jump"); ! 236: printstat(nbrnext, "jump# to next instruction"); ! 237: printstat(nexbr, "extra jump#"); ! 238: printstat(nxjump, "cross jump#"); ! 239: printstat(ncomseq, "common sequence#"); ! 240: printstat(nsimplify, "instruction# simplified"); ! 241: printstat(nuseless, "instruction# deleted"); ! 242: } ! 243: ! 244: /* ! 245: * Print a statistic message. ! 246: */ ! 247: printstat(n, s) ! 248: register int n; ! 249: register char *s; ! 250: { ! 251: register int c; ! 252: ! 253: if (n != 0) { ! 254: #if OVERLAID ! 255: printf ("%s ", ERRMSG); ! 256: #endif ! 257: printf("%d ", n); ! 258: while ((c = *s++) != 0) { ! 259: if (c == '#') { ! 260: if (n != 1) ! 261: putchar('s'); ! 262: } else ! 263: putchar(c); ! 264: } ! 265: putchar('\n'); ! 266: } ! 267: } ! 268: ! 269: /* ! 270: * Read through the temporary file, ! 271: * processing things until you run into a ! 272: * function prolog operation. Functions ! 273: * get read in, optimized and written back ! 274: * out. ! 275: */ ! 276: work2() ! 277: { ! 278: register int op; ! 279: sizeof_t size; ! 280: register INS *ip; ! 281: register SYM *sp; ! 282: ! 283: for (;;) { ! 284: switch (op = bget()) { ! 285: ! 286: case LINE: ! 287: line = iget(); ! 288: break; ! 289: ! 290: case DLABEL: ! 291: gendbgt(0); ! 292: break; ! 293: ! 294: case FNAME: ! 295: sget(file, NFNAME); ! 296: break; ! 297: ! 298: case MNAME: ! 299: sget(module, NMNAME); ! 300: if (isvariant(VASM)) { ! 301: bput(op); ! 302: sput(module); ! 303: } ! 304: break; ! 305: ! 306: case GLABEL: ! 307: case SLABEL: ! 308: sget(id, NCSYMB); ! 309: sp = glookup(id, 1); ! 310: sp->s_seg = dotseg; ! 311: sp->s_value = dot; ! 312: if (op == GLABEL) { ! 313: sp->s_flag |= S_GBL; ! 314: } ! 315: if (isvariant(VASM)) { ! 316: bput(op); ! 317: sput(id); ! 318: } ! 319: break; ! 320: ! 321: case COMM: ! 322: sget(id, NCSYMB); ! 323: size = zget(); ! 324: sp = glookup(id, 0); ! 325: if ((sp->s_flag&S_DEF) == 0) { ! 326: sp->s_seg = SBSS; ! 327: sp->s_flag |= S_GBL; ! 328: if (size > sp->s_value) ! 329: sp->s_value = size; ! 330: } ! 331: if (isvariant(VASM)) { ! 332: bput(op); ! 333: sput(id); ! 334: zput(size); ! 335: } ! 336: break; ! 337: ! 338: #ifdef KLUDGE ! 339: case SGUESS: ! 340: { ! 341: int seg; ! 342: sget(id, NCSYMB); ! 343: seg = bget(); ! 344: sp = glookup(id, 0); ! 345: if ((sp->s_flag&S_DEF) == 0) ! 346: sp->s_seg = seg; ! 347: break; ! 348: } ! 349: ! 350: #endif ! 351: ! 352: case LLABEL: ! 353: sp = llookup(iget(), 1); ! 354: sp->s_seg = dotseg; ! 355: sp->s_value = dot; ! 356: sp->s_flag |= S_NFL; ! 357: if (isvariant(VASM)) { ! 358: bput(op); ! 359: iput(sp->s_labno); ! 360: } ! 361: break; ! 362: ! 363: case BLOCK: ! 364: genblock(zget()); ! 365: break; ! 366: ! 367: case ENTER: ! 368: genseg(bget()); ! 369: break; ! 370: ! 371: case PROLOG: ! 372: #if !TINY ! 373: #define vcheck(v,s) if (vflag>v) check(s) ! 374: #else ! 375: #define vcheck(v,s) /* if (vflag>v) check(s) */ ! 376: #endif ! 377: getfunc(); ! 378: fixdbgt(); ! 379: shuffle(); ! 380: vcheck(0, "Befor optim"); ! 381: do { ! 382: changes = 0; ! 383: labels(); ! 384: vcheck(8, "After labels"); ! 385: fixbr(); ! 386: vcheck(8, "After fixbr()"); ! 387: if (isvariant(VPEEP)) { ! 388: peephole(); ! 389: vcheck(8, "After peephole"); ! 390: } ! 391: if (notvariant(VNOOPT)) { ! 392: xjumps(); ! 393: vcheck(8, "After xjumps"); ! 394: comseq(); ! 395: vcheck(8, "After comseq"); ! 396: } ! 397: deadcode(); ! 398: vcheck(2, "Before while (changes)"); ! 399: } while (changes); ! 400: genprolog(); ! 401: genfunc(); ! 402: genepilog(); ! 403: break; ! 404: ! 405: case ALIGN: ! 406: genalign(bget()); ! 407: break; ! 408: ! 409: case CODE: ! 410: unbget(CODE); ! 411: ip = getins(); ! 412: genins(ip); ! 413: free((char *) ip); ! 414: break; ! 415: ! 416: case FINISH: ! 417: genseg(-1); ! 418: if (isvariant(VASM)) ! 419: bput(op); ! 420: return; ! 421: ! 422: case EOF: ! 423: cfatal("unexpected EOF"); ! 424: ! 425: default: ! 426: cbotch("bad temporary file opcode %d", op); ! 427: } ! 428: } ! 429: } ! 430: ! 431: #if !TINY ! 432: /* ! 433: * Compiler debugging printout. ! 434: */ ! 435: check(where) ! 436: char *where; ! 437: { ! 438: register INS *ip; ! 439: ! 440: printf("Check %s:\n", where); ! 441: for (ip = ins.i_fp; ip != &ins; ip = ip->i_fp) { ! 442: iprint(ip); ! 443: } ! 444: printf("\n"); ! 445: } ! 446: ! 447: iprint(ip) ! 448: register INS *ip; ! 449: { ! 450: dprint(ip); ! 451: #if RUNNING_LARGE ! 452: printf("\t%08lx: %08lx %08lx: ", ip, ip->i_bp, ip->i_fp); ! 453: #else ! 454: printf("\t%04x: %04x %04x: ", ip, ip->i_bp, ip->i_fp); ! 455: #endif ! 456: switch (ip->i_type) { ! 457: case ENTER: ! 458: printf("enter %d", ip->i_seg); ! 459: break; ! 460: case EPILOG: ! 461: printf("epilog"); ! 462: break; ! 463: case PROLOG: ! 464: printf("prolog"); ! 465: break; ! 466: case BLOCK: ! 467: printf("block %ld", (long)ip->i_len); ! 468: break; ! 469: case ALIGN: ! 470: printf("align %d", ip->i_align); ! 471: break; ! 472: case LLABEL: ! 473: printf("label L%d", ip->i_labno); ! 474: break; ! 475: case JUMP: ! 476: printf("jump %d L%d", ip->i_rel, ip->i_labno); ! 477: break; ! 478: case LLLINK: ! 479: printf("llink L%d", ip->i_labno); ! 480: break; ! 481: case CODE: ! 482: printf("code %d(%d)", ip->i_op, ip->i_naddr); ! 483: break; ! 484: default: ! 485: printf("?? %d", ip->i_type); ! 486: break; ! 487: } ! 488: printf("\n"); ! 489: } ! 490: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.