Annotation of researchv10no/cmd/lcc/gen0/gen.c, revision 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.