|
|
1.1 ! root 1: /* ! 2: * n3/i386/igen.c ! 3: * C compiler intermediate file printer. ! 4: * Machine and assembly format dependent output routines. ! 5: * i386. ! 6: */ ! 7: ! 8: #ifdef vax ! 9: #include "INC$LIB:cc3.h" ! 10: #else ! 11: #include "cc3.h" ! 12: #endif ! 13: ! 14: extern char *tempnam(); ! 15: ! 16: /* Output strings which depend on assembler format. */ ! 17: #if AS_FORMAT ! 18: #define SHRI ".text" ! 19: #define PRVI ".text" ! 20: #define SHRD ".text" /* unused, we think */ ! 21: #define STRN ".text" ! 22: #define PRVD ".data" ! 23: #define BSSD ".data" ! 24: #define COMMFMT "\t.comm" ! 25: #define ALFMT ".align" ! 26: #define GLOBL ".globl" ! 27: #define BLKBFMT "\t.blkb\t0x%lx\n" ! 28: #define MODNAM "/\tmodule name" ! 29: #else ! 30: #define SHRI "code" ! 31: #define PRVI "linkage" ! 32: #define SHRD "pure" ! 33: #define STRN "strings" ! 34: #define PRVD "impure" ! 35: #define BSSD "bss" ! 36: #define COMMFMT ";\tcommon" ! 37: #define ALFMT "align" ! 38: #define GLOBL "public" ! 39: #define BLKBFMT "\tdb\t0%lxh dup(0)\n" ! 40: #define MODNAM "\tname" ! 41: #endif ! 42: ! 43: #define NSEGS 6 /* number of output segments */ ! 44: char sfname[NSEGS][L_tmpnam]; /* per-segment tempfile names */ ! 45: FILE *sfp[NSEGS]; /* per-segment output FILEs */ ! 46: ! 47: /* ! 48: * How to enter or leave a segment. ! 49: */ ! 50: char *seg_enter[] = { ! 51: SHRI, PRVI, SHRD, STRN, PRVD, BSSD ! 52: }; ! 53: ! 54: #if 0 ! 55: char *seg_leave[] = { ! 56: NULL, NULL, NULL, NULL, NULL, NULL ! 57: }; ! 58: #endif ! 59: ! 60: /* ! 61: * Initialize the disassembler phase. ! 62: */ ! 63: cc3init() ! 64: { ! 65: if (notvariant(VPSTR)) ! 66: seg_enter[SSTRN] = PRVD; ! 67: sfp[SCODE] = ofp; /* write CODE directly to ofp */ ! 68: } ! 69: ! 70: /* ! 71: * Terminate the disassembler. ! 72: * Output for each segment goes to a separate file; ! 73: * this copies the segments to the actual output file ! 74: * and cleans up. ! 75: */ ! 76: cc3close() ! 77: { ! 78: register int i, c; ! 79: register FILE *fp; ! 80: int prev; ! 81: ! 82: ofp = sfp[SCODE]; ! 83: prev = SCODE; /* previous segment written */ ! 84: for (i = 1; i < NSEGS; i++) { ! 85: if ((fp = sfp[i]) == NULL) ! 86: continue; /* unused */ ! 87: fprintf(ofp, "\t.align\t4\n"); ! 88: if (strcmp(seg_enter[prev], seg_enter[i]) != 0) ! 89: fprintf(ofp, "\n\t%s\n", seg_enter[i]); ! 90: prev = i; ! 91: rewind(fp); ! 92: while ((c = getc(fp)) != EOF) ! 93: putc(c, ofp); /* copy to ofp */ ! 94: fclose(fp); ! 95: unlink(sfname[i]); ! 96: } ! 97: } ! 98: ! 99: /* ! 100: * Process AUTOS items. ! 101: * The opcode byte has been read. ! 102: * Read in operands used by the target machine ! 103: * and print them out in a nice way. ! 104: */ ! 105: genautos() ! 106: { ! 107: register ival_t numauto; ! 108: register int regmask; ! 109: register int reg; ! 110: register int sepchar; ! 111: ! 112: numauto = iget(); ! 113: regmask = iget(); ! 114: fprintf(ofp, "\tautos\t%ld", (long)numauto); ! 115: sepchar = '\t'; ! 116: for (reg = FRREG; reg <= NFBREG; ++reg) { ! 117: if ((regmask&01) != 0) { ! 118: fprintf(ofp, "%c%s", sepchar, regnames[reg]); ! 119: sepchar = ' '; ! 120: } ! 121: regmask >>= 1; ! 122: } ! 123: fprintf(ofp, "\n"); ! 124: } ! 125: ! 126: /* ! 127: * Output a double value. ! 128: */ ! 129: gendval(dp) ! 130: register dval_t dp; ! 131: { ! 132: register int i; ! 133: ! 134: for (i = 0; i < sizeof(dval_t); i += 1) ! 135: fprintf(ofp, "%02x", dp[i] & 0377); ! 136: } ! 137: ! 138: /* ! 139: * Generate a machine dependent leaf node. ! 140: */ ! 141: genmdl(op) ! 142: { ! 143: cbotch("bad mdl: %d", op); ! 144: } ! 145: ! 146: /* ! 147: * Generate a machine dependent operator node. ! 148: */ ! 149: genmdo(op) ! 150: { ! 151: cbotch("bad mdo: %d", op); ! 152: } ! 153: ! 154: /* ! 155: * Generat a .comm record. ! 156: * The operands must be read. ! 157: */ ! 158: gencomm() ! 159: { ! 160: sget(id, NCSYMB); ! 161: if (isvariant(VASM)) ! 162: fprintf(ofp, COMMFMT); ! 163: else ! 164: fprintf(ofp, "common"); ! 165: fprintf(ofp, "\t%s,\t%ld\n", id, (long)zget()); ! 166: } ! 167: ! 168: /* ! 169: * Generate an assembly operator involving a name. ! 170: */ ! 171: genname(op, id) ! 172: char *id; ! 173: { ! 174: switch (op) { ! 175: case FNAME: ! 176: fprintf(ofp, "%s\tfile name %s\n", CMTSTR, id); ! 177: break; ! 178: case MNAME: ! 179: fprintf(ofp, "%s %s\n", MODNAM, id); ! 180: #if AS_FORMAT ! 181: fprintf(ofp, "\t.alignoff\n"); ! 182: fprintf(ofp, "\t.intelorder\n"); ! 183: #endif ! 184: break; ! 185: case GLABEL: ! 186: fprintf(ofp, "\t%s %s\n%s:\n", GLOBL, id, id); ! 187: break; ! 188: case SLABEL: ! 189: fprintf(ofp, "%s:\n", id); ! 190: break; ! 191: #ifdef UREFER ! 192: case UREFER: ! 193: fprintf(ofp, "%s\tundefined reference %s\n", CMTSTR, id); ! 194: break; ! 195: #endif ! 196: default: ! 197: cbotch("genname: bad op: %d", op); ! 198: } ! 199: } ! 200: ! 201: /* ! 202: * Generate an assembly operator involving an integer value. ! 203: */ ! 204: genival(op, i) int op; register long i; ! 205: { ! 206: register char *s; ! 207: ! 208: switch (op) { ! 209: case LINE: ! 210: fprintf(ofp, "%s\tline number %ld\n", CMTSTR, i); ! 211: break; ! 212: case BLOCK: ! 213: fprintf(ofp, BLKBFMT, i); ! 214: break; ! 215: case ALIGN: ! 216: fprintf(ofp, "\t%s\t%d\n", ALFMT, i); ! 217: break; ! 218: case ENTER: ! 219: #if 1 ! 220: /* ! 221: * Write each segment to a different FILE. ! 222: * This allows the assember to assemble the .s to the ! 223: * same bits as those produced by the compiler. ! 224: */ ! 225: if (dotseg == -1) /* first ENTER */ ! 226: fprintf(ofp, "\n\t%s\n", seg_enter[SCODE]); ! 227: if (i != dotseg) { /* new segment */ ! 228: dotseg = i; ! 229: if (sfp[i] == NULL) { /* previously unused segment */ ! 230: s = tempnam(NULL, "cc3"); ! 231: strcpy(sfname[i], s); ! 232: if ((sfp[i] = fopen(s, "w+")) == NULL) ! 233: cfatal("cannot open temp file %s", s); ! 234: free(s); ! 235: } ! 236: ofp = sfp[i]; ! 237: } ! 238: break; ! 239: #else ! 240: /* Old code, just print appropriate entering text. */ ! 241: #if 0 ! 242: /* Nothing special required when leaving segments. */ ! 243: if (dotseg >= 0 && (s=seg_leave[dotseg]) != NULL) ! 244: fprintf(ofp, "\n\t%s\n\n", s); ! 245: #endif ! 246: dotseg = i; ! 247: if (dotseg >= 0 && (s=seg_enter[dotseg]) != NULL) ! 248: fprintf(ofp, "\n\t%s\n\n", s); ! 249: break; ! 250: #endif ! 251: case LLABEL: ! 252: fprintf(ofp, ".L%ld:\n", i); ! 253: break; ! 254: default: ! 255: cbotch("genival: bad op: %d", op); ! 256: } ! 257: } ! 258: ! 259: /* end of n3/i386/igen.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.