|
|
1.1 ! root 1: /* C compiler: symbolic code generator */ ! 2: ! 3: #include "c.h" ! 4: ! 5: static int maxoffset; /* maximum value of offset */ ! 6: static int offset; /* current frame offset */ ! 7: static Node *tail; ! 8: ! 9: dclproto(static Node gen,(Node)); ! 10: dclproto(static int gen1,(Node, int, int)); ! 11: dclproto(static int regoffset,(int, int)); ! 12: dclproto(static unsigned regloc,(Symbol)); ! 13: dclproto(static void address,(Symbol, Symbol, int)); ! 14: dclproto(static void blockbeg,(Env *)); ! 15: dclproto(static void blockend,(Env *)); ! 16: dclproto(static void defaddress,(Symbol)); ! 17: dclproto(static void defconst,(int, Value)); ! 18: dclproto(static void defstring,(int, char *)); ! 19: dclproto(static void defsymbol,(Symbol)); ! 20: dclproto(static void emit,(Node)); ! 21: dclproto(static void export,(Symbol)); ! 22: dclproto(static void function,(Symbol, Symbol [], Symbol [], int)); ! 23: dclproto(static void global,(Symbol)); ! 24: dclproto(static void import,(Symbol)); ! 25: dclproto(static void local,(Symbol)); ! 26: dclproto(static void progbeg,(int, char **)); ! 27: dclproto(static void progend,(void)); ! 28: dclproto(static void segment,(int)); ! 29: dclproto(static void space,(int)); ! 30: dclproto(static void stabend,(Coordinate *, Symbol, Coordinate **, Symbol *, Symbol *)); ! 31: dclproto(static void stabline,(Coordinate *)); ! 32: dclproto(static void sym,(char *, Symbol, char *)); ! 33: dclproto(static void symname,(Symbol)); ! 34: ! 35: static Interface symbolic = { ! 36: "symbolic", ! 37: 1, 1, 0, /* char */ ! 38: 2, 2, 0, /* short */ ! 39: 4, 4, 0, /* int */ ! 40: 4, 4, 1, /* float */ ! 41: 8, 4, 1, /* double */ ! 42: 4, 4, 0, /* T * */ ! 43: 0, 4, 0, /* struct */ ! 44: 1, /* left_to_right */ ! 45: 0, /* little_endian */ ! 46: 1, /* jump_on_return */ ! 47: 0, /* mulops_are_calls */ ! 48: 0, /* compl_band */ ! 49: 0, /* no_argb */ ! 50: 0, /* no_dag */ ! 51: address, ! 52: blockbeg, ! 53: blockend, ! 54: defaddress, ! 55: defconst, ! 56: defstring, ! 57: defsymbol, ! 58: emit, ! 59: export, ! 60: function, ! 61: gen, ! 62: global, ! 63: import, ! 64: local, ! 65: progbeg, ! 66: progend, ! 67: segment, ! 68: space, ! 69: 0, /* stabblock */ ! 70: stabend, ! 71: 0, /* stabfend */ ! 72: 0, /* stabinit */ ! 73: stabline, ! 74: 0, /* stabsym */ ! 75: 0, /* stabtype */ ! 76: }; ! 77: Interface *interfaces[] = { &symbolic, 0 }; ! 78: ! 79: /* address - initialize q for addressing expression p+n */ ! 80: static void address(q, p, n) Symbol q, p; int n; { ! 81: q->x.name = stringf("%s%s%d", p->x.name, n > 0 ? "+" : "", n); ! 82: } ! 83: ! 84: /* blockbeg - begin a compound statement */ ! 85: static void blockbeg(e) Env *e; { ! 86: *e = offset; ! 87: } ! 88: ! 89: /* blockend - end a compound statement */ ! 90: static void blockend(e) Env *e; { ! 91: if (offset > maxoffset) ! 92: maxoffset = offset; ! 93: offset = *e; ! 94: } ! 95: ! 96: /* defaddress - initialize an address */ ! 97: static void defaddress(p) Symbol p; { ! 98: print("defaddress %s\n", p->x.name); ! 99: } ! 100: ! 101: /* defconst - define a constant */ ! 102: static void defconst(ty, v) Value v; { ! 103: print("defconst "); ! 104: switch (ty) { ! 105: case C: print("char %d\n", v.uc); break; ! 106: case S: print("short %d\n", v.ss); break; ! 107: case I: print("int %d\n", v.i ); break; ! 108: case U: print("unsigned 0x%x\n", v.u ); break; ! 109: case P: print("void* 0x%x\n", v.p ); break; ! 110: case F: { ! 111: char buf[MAXLINE]; ! 112: sprintf(buf, "float %.8e\n", v.f); /* fix */ ! 113: outs(buf); ! 114: break; ! 115: } ! 116: case D: { ! 117: char buf[MAXLINE]; ! 118: sprintf(buf, "double %.18e\n", v.d); /* fix */ ! 119: outs(buf); ! 120: break; ! 121: } ! 122: default: assert(0); ! 123: } ! 124: } ! 125: ! 126: /* defstring - emit a string constant */ ! 127: static void defstring(len, s) char *s; { ! 128: int n; ! 129: ! 130: print("defstring \""); ! 131: for (n = 0; len-- > 0; s++) { ! 132: if (n >= 72) { ! 133: print("\n"); ! 134: n = 0; ! 135: } ! 136: if (*s == '"' || *s == '\\') { ! 137: print("\\%c", *s); ! 138: n += 2; ! 139: } else if (*s >= ' ' && *s < 0177) { ! 140: *bp++ = *s; ! 141: n += 1; ! 142: } else { ! 143: print("\\%d%d%d", (*s>>6)&3, (*s>>3)&7, *s&7); ! 144: n += 4; ! 145: } ! 146: } ! 147: print("\"\n"); ! 148: } ! 149: ! 150: /* defsymbol - define a symbol: initialize p->x */ ! 151: static void defsymbol(p) Symbol p; { ! 152: p->x.name = p->name; ! 153: if (glevel > 2 && p->scope >= LOCAL && p->type && isfunc(p->type)) ! 154: sym("extern", p, "\n"); ! 155: } ! 156: ! 157: /* emit - emit the dags on list p */ ! 158: static void emit(p) Node p; { ! 159: for (; p; p = p->x.next) ! 160: if (p->op == LABEL+V) { ! 161: assert(p->syms[0]); ! 162: print("%s:\n", p->syms[0]->x.name); ! 163: } else { ! 164: int i; ! 165: assert(p->link == 0 || p->x.lev == 0); ! 166: print("node%c%d %s count=%d", p->x.lev == 0 ? '\'' : '#', p->x.id, ! 167: opname(p->op), p->count); ! 168: for (i = 0; i < MAXKIDS && p->kids[i]; i++) ! 169: print(" #%d", p->kids[i]->x.id); ! 170: for (i = 0; i < MAXSYMS && p->syms[i]; i++) { ! 171: if (p->syms[i]->x.name) ! 172: print(" %s", p->syms[i]->x.name); ! 173: if (p->syms[i]->name != p->syms[i]->x.name) ! 174: print(" (%s)", p->syms[i]->name); ! 175: } ! 176: print("\n"); ! 177: } ! 178: } ! 179: ! 180: /* export - announce p as exported */ ! 181: static void export(p) Symbol p; { ! 182: print("export %s\n", p->x.name); ! 183: } ! 184: ! 185: /* function - generate code for a function */ ! 186: static void function(f, caller, callee, ncalls) Symbol f, caller[], callee[]; { ! 187: int i; ! 188: ! 189: sym("function", f, ncalls ? (char *)0 : "\n"); ! 190: if (ncalls) ! 191: print(" ncalls=%d\n", ncalls); ! 192: offset = 0; ! 193: for (i = 0; caller[i] && callee[i]; i++) { ! 194: offset = roundup(offset, caller[i]->type->align); ! 195: caller[i]->x.name = caller[i]->name; ! 196: callee[i]->x.name = callee[i]->name; ! 197: caller[i]->x.offset = callee[i]->x.offset = offset; ! 198: sym("caller's parameter", caller[i], "\n"); ! 199: sym("callee's parameter", callee[i], "\n"); ! 200: offset += caller[i]->type->size; ! 201: } ! 202: maxoffset = offset = 0; ! 203: gencode(caller, callee); ! 204: print("maxoffset=%d\n", maxoffset); ! 205: emitcode(); ! 206: print("end %s\n", f->x.name); ! 207: } ! 208: ! 209: /* gen - generate code for the dags on list p */ ! 210: static Node gen(p) Node p; { ! 211: int n; ! 212: Node nodelist; ! 213: ! 214: tail = &nodelist; ! 215: for (n = 0; p; p = p->link) { ! 216: switch (generic(p->op)) { /* check for valid nodelist */ ! 217: case CALL: ! 218: assert(!IR->no_dag || p->count == 0); ! 219: break; ! 220: case ARG: ! 221: case ASGN: case JUMP: case LABEL: case RET: ! 222: case EQ: case GE: case GT: case LE: case LT: case NE: ! 223: assert(p->count == 0); ! 224: break; ! 225: case INDIR: ! 226: assert(!IR->no_dag && p->count > 0); ! 227: break; ! 228: default: ! 229: assert(0); ! 230: } ! 231: n = gen1(p, 0, n); ! 232: } ! 233: *tail = 0; ! 234: return nodelist; ! 235: } ! 236: ! 237: /* gen1 - generate code for *p */ ! 238: static int gen1(p, lev, n) Node p; { ! 239: if (p && p->x.id == 0) { ! 240: p->x.lev = lev; ! 241: p->x.id = ++n; ! 242: n = gen1(p->kids[0], lev + 1, n); ! 243: n = gen1(p->kids[1], lev + 1, n); ! 244: *tail = p; ! 245: tail = &p->x.next; ! 246: } ! 247: return n; ! 248: } ! 249: ! 250: /* global - announce a global */ ! 251: static void global(p) Symbol p; { ! 252: sym("global", p, "\n"); ! 253: } ! 254: ! 255: /* import - import a symbol */ ! 256: static void import(p) Symbol p; { ! 257: print("import %s\n", p->x.name); ! 258: } ! 259: ! 260: /* local - local variable */ ! 261: static void local(p) Symbol p; { ! 262: offset = roundup(offset, p->type->align); ! 263: p->x.name = p->name; ! 264: p->x.offset = offset; ! 265: sym("local", p, "\n"); ! 266: offset += p->type->size; ! 267: } ! 268: ! 269: /* progbeg - beginning of program */ ! 270: static void progbeg(argc, argv) char *argv[]; { ! 271: print("progbeg argv="); ! 272: while (argc--) ! 273: print("%s ", *argv++); ! 274: print("\n"); ! 275: } ! 276: ! 277: /* progend - end of program */ ! 278: static void progend() { ! 279: print("progend\n"); ! 280: } ! 281: ! 282: /* regloc - return "id" for p's register */ ! 283: static unsigned regloc(p) Symbol p; { ! 284: assert(p && p->sclass == REGISTER); ! 285: return 0; ! 286: } ! 287: ! 288: /* regoffset - return stack offset of cell that saves reg */ ! 289: static int regoffset(regset, regnum) { ! 290: return -1; ! 291: } ! 292: ! 293: /* segment - switch to segment s */ ! 294: static void segment(s) { ! 295: print("segment %s\n", &"text\0bss\0.data\0lit\0.sym\0."[5*s-5]); ! 296: } ! 297: ! 298: /* space - initialize n bytes of space */ ! 299: static void space(n) { ! 300: print("space %d\n", n); ! 301: } ! 302: ! 303: /* sym - print symbol table entry for p, followed by str */ ! 304: static void sym(kind, p, str) char *kind, *str; Symbol p; { ! 305: assert(kind); ! 306: if (glevel > 2) { ! 307: print("%s ", kind); ! 308: symname(p); ! 309: } else ! 310: print("%s %s", kind, p->name); ! 311: if (p->name != p->x.name) ! 312: print(" (%s)", p->x.name); ! 313: print(" type=%t class=%k scope=", p->type, p->sclass); ! 314: switch (p->scope) { ! 315: case CONSTANTS: print("CONSTANTS"); break; ! 316: case LABELS: print("LABELS"); break; ! 317: case GLOBAL: print("GLOBAL"); break; ! 318: case PARAM: print("PARAM"); break; ! 319: case LOCAL: print("LOCAL"); break; ! 320: default: ! 321: if (p->scope > LOCAL) ! 322: print("LOCAL+%d", p->scope - LOCAL); ! 323: else ! 324: print("%d", p->scope); ! 325: } ! 326: if (p->scope >= PARAM && p->sclass != STATIC) ! 327: print(" offset=%d ref=%d", p->x.offset, (int)(1000*p->ref)); ! 328: if (glevel > 2) { ! 329: print(" up="); ! 330: symname(p->up); ! 331: } ! 332: if (str) ! 333: print(str); ! 334: } ! 335: ! 336: /* symname - print prefix, p's name, declaration source coordinate, suffix */ ! 337: static void symname(p) Symbol p; { ! 338: if (p) ! 339: print("%s@%w.%d", p->name, &p->src, p->src.x); ! 340: else ! 341: print("0"); ! 342: } ! 343: ! 344: /* stabend - finalize stab output */ ! 345: static void stabend(cp, p, cpp, sp, stab) Coordinate *cp, **cpp; Symbol p, *sp, *stab; { ! 346: int i; ! 347: ! 348: symname(p); ! 349: print("\n"); ! 350: for (i = 0; cpp[i] && sp[i]; i++) { ! 351: print("%w.%d: ", cpp[i], cpp[i]->x); ! 352: symname(sp[i]); ! 353: print("\n"); ! 354: } ! 355: } ! 356: ! 357: /* stabline - emit line number information for source coordinate *cp */ ! 358: static void stabline(cp) Coordinate *cp; { ! 359: if (cp->file) ! 360: print("%s:", cp->file); ! 361: print("%d.%d:\n", cp->y, cp->x); ! 362: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.