Annotation of researchv10no/cmd/lcc/gen0/gen.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.