|
|
1.1 ! root 1: /* ! 2: * n2/cc2.c ! 3: * Main driving routine for the code assembly phase of the C compiler. ! 4: * It reads the intermediate file and calls ! 5: * off to the appropriate routines to get things done. ! 6: */ ! 7: ! 8: #ifdef vax ! 9: #include "INC$LIB:cc2.h" ! 10: #else ! 11: #include "cc2.h" ! 12: #endif ! 13: ! 14: /* Verbosity. Parallel to ccscan.c. */ ! 15: #ifdef COHERENT ! 16: #define ERRMSG "cc:" ! 17: #else ! 18: #if INTEL ! 19: #define ERRMSG "***" ! 20: #else ! 21: #if OMF286 ! 22: #define ERRMSG "MWC286:" ! 23: #else ! 24: #define ERRMSG "MWC86:" ! 25: #endif ! 26: #endif ! 27: #endif ! 28: ! 29: #if !OVERLAID ! 30: FILE *ifp; /* Input file */ ! 31: FILE *ofp; /* Output file */ ! 32: char file[NFNAME]; /* File name */ ! 33: char module[NMNAME]; /* Module name */ ! 34: int line; /* Line number */ ! 35: char id[NCSYMB]; /* Name buffer */ ! 36: VARIANT variant; /* Variant template */ ! 37: int dotseg; /* Current segment # */ ! 38: #endif ! 39: ! 40: int changes; /* Change flag */ ! 41: ADDRESS dot; /* Current location */ ! 42: SYM *hash2[NSHASH]; /* Symbol table */ ! 43: INS ins; /* Head of instruction list */ ! 44: int nlabdel; /* # of labels deleted */ ! 45: int ndead; /* # of dead instructions deleted */ ! 46: int nbrbr; /* # of branches to branches */ ! 47: int nexbr; /* # of extra branches */ ! 48: int ncbrbr; /* # of conditional branches to branches */ ! 49: int nbrnext; /* # of branches to next instruction */ ! 50: int nxjump; /* # of cross jumps */ ! 51: int ncomseq; /* # of common sequences */ ! 52: int nsimplify; /* # of instructions simplified */ ! 53: int nuseless; /* # of instructions deleted */ ! 54: ! 55: #if !TINY ! 56: int vflag; /* Verbosity */ ! 57: int xflag; /* More verbosity */ ! 58: #endif ! 59: ! 60: /* ! 61: * Segment table. ! 62: */ ! 63: SEG seg[NSEG]; ! 64: ! 65: #if !OVERLAID ! 66: /* ! 67: * Mainline. ! 68: * Interpret options and ! 69: * open files. ! 70: */ ! 71: main(argc, argv) ! 72: char *argv[]; ! 73: { ! 74: #ifdef vax ! 75: int ofd; ! 76: #endif ! 77: ! 78: passname = "cc2"; ! 79: if (argc < 4) ! 80: usage(); ! 81: getvariant(argv[1]); ! 82: #if GEMDOS ! 83: { ! 84: extern long gemdos(); ! 85: extern char *lmalloc(); ! 86: free(lmalloc((gemdos(0x48,-1L)-4096) & ~1023L)); ! 87: } ! 88: #endif ! 89: if ((ifp=fopen(argv[2], SRMODE)) == NULL) { ! 90: fprintf(stderr, "%s: cannot open.\n", argv[2]); ! 91: exit(BAD); ! 92: } ! 93: if (isvariant(VASM)) { ! 94: if ((ofp=fopen(argv[3], SWMODE)) == NULL) ! 95: nocreate(argv[3]); ! 96: } else { ! 97: if (argc < 5) ! 98: usage(); ! 99: if ((ofp=fopen(argv[4], SWMODE)) == NULL) ! 100: nocreate(argv[4]); ! 101: } ! 102: #if !TINY ! 103: if (argc > 5) ! 104: vflag = atoi(argv[5]); ! 105: if (argc > 6) ! 106: xflag = atoi(argv[6]); ! 107: #endif ! 108: labgen = 20000; ! 109: dotseg = -1; ! 110: outinit(); ! 111: work2(); ! 112: outdone(); ! 113: if (notvariant(VASM)) { ! 114: fclose(ifp); ! 115: fclose(ofp); ! 116: if ((ifp=fopen(argv[4], SRMODE)) == NULL) ! 117: cfatal("%s: cannot reopen", argv[4]); ! 118: #ifdef vax ! 119: #if VAXFMT ! 120: if ((ofd=creat(argv[3], 0666, "rfm=var")) < 0 ! 121: || (ofp=fdopen(ofd, SWMODE)) == NULL) ! 122: #else ! 123: if ((ofp=fopen(argv[3], SWMODE)) == NULL) ! 124: #endif ! 125: #else ! 126: if ((ofp=fopen(argv[3], SWMODE)) == NULL) ! 127: #endif ! 128: nocreate(argv[3]); ! 129: copycode(); ! 130: } ! 131: if (isvariant(VSTAT)) ! 132: showstats(); ! 133: if (nerr != 0) ! 134: exit(BAD); ! 135: exit(OK); ! 136: } ! 137: ! 138: /* ! 139: * Print usage message. ! 140: */ ! 141: usage() ! 142: { ! 143: fprintf(stderr, "Usage: cc2 variant in out [temp]\n"); ! 144: exit(BAD); ! 145: } ! 146: ! 147: /* ! 148: * Complain that a file cannot be ! 149: * created. ! 150: */ ! 151: nocreate(fn) ! 152: char *fn; ! 153: { ! 154: fprintf(stderr, "%s: cannot create.\n", fn); ! 155: exit(BAD); ! 156: } ! 157: #else ! 158: /* ! 159: * Driving routine for the ! 160: * overlaid version of the optimizer and ! 161: * code assembly phase. The files have all been ! 162: * opened by the command line scanner in the ! 163: * root segment. Set up a fatal error context and ! 164: * do the work. Return exit status. ! 165: */ ! 166: cc2a() ! 167: { ! 168: #if MONOLITHIC ! 169: register int i; ! 170: #endif ! 171: passname = "cc2a"; ! 172: if (setjmp(death) != 0) { ! 173: freesym2(); ! 174: return (ABORT); ! 175: } ! 176: labgen = 20000; ! 177: dotseg = -1; ! 178: #if MONOLITHIC ! 179: dot = 0; ! 180: nlabdel = 0; ! 181: ndead = 0; ! 182: nbrbr = 0; ! 183: nexbr = 0; ! 184: ncbrbr = 0; ! 185: nbrnext = 0; ! 186: nxjump = 0; ! 187: ncomseq = 0; ! 188: nsimplify = 0; ! 189: nuseless = 0; ! 190: for (i=0; i<NSEG; ++i) ! 191: seg[i].s_dot = 0; ! 192: gendbgt(-1); ! 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((ival_t)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 ! 491: ! 492: /* end of n2/cc2.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.