Annotation of researchv10no/cmd/lcc/gen2/sparc/pseudos.c, revision 1.1

1.1     ! root        1: /* C compiler: SPARC code generator */
        !             2: 
        !             3: #include "c.h"
        !             4: 
        !             5: #ifdef sparc
        !             6: #include <stab.h>
        !             7: #include "stabbsd.c"
        !             8: #endif
        !             9: 
        !            10: dclproto(static void address,(Symbol, Symbol, int));
        !            11: dclproto(static void blkfetch,(int, int, int, int));
        !            12: dclproto(static void blkloop,(int, int, int, int, int, int[]));
        !            13: dclproto(static void blkstore,(int, int, int, int));
        !            14: dclproto(static void defaddress,(Symbol));
        !            15: dclproto(static void defconst,(int, Value));
        !            16: dclproto(static void defstring,(int, char *));
        !            17: dclproto(static void defsymbol,(Symbol));
        !            18: dclproto(static void doarg,(Node));
        !            19: dclproto(static void emitspecial,(Node));
        !            20: dclproto(static void function,(Symbol, Symbol [], Symbol [], int));
        !            21: dclproto(static void global,(Symbol));
        !            22: dclproto(static void import,(Symbol));
        !            23: dclproto(static void local,(Symbol));
        !            24: dclproto(static Symbol nextreg,(Symbol));
        !            25: dclproto(static void progbeg,(int, char **));
        !            26: dclproto(static void segment,(int));
        !            27: dclproto(static void space,(int));
        !            28: 
        !            29: dclproto(static void initgen,(void));
        !            30: dclproto(static void final,(Node));
        !            31: 
        !            32: #ifdef GEN4
        !            33: dclproto(static unsigned emit2,(Node,Node[],short[]));
        !            34: dclproto(static void target,(Node));
        !            35: #endif
        !            36: 
        !            37: Interface sparcInterface = {
        !            38:        "sparc",
        !            39:        1, 1, 0,        /* char */
        !            40:        2, 2, 0,        /* short */
        !            41:        4, 4, 0,        /* int */
        !            42:        4, 4, 1,        /* float */
        !            43:        8, 8, 1,        /* double */
        !            44:        4, 4, 0,        /* T * */
        !            45:        0, 1, 0,        /* struct */
        !            46:        1,              /* left_to_right */
        !            47:        0,              /* little_endian */
        !            48:        1,              /* jump_on_return */
        !            49:        1,              /* mulops_are_calls */
        !            50:        0,              /* compl_band */
        !            51:        1,              /* no_argb */
        !            52:        NODAG,          /* no_dag */
        !            53:        address,
        !            54:        blockbeg,
        !            55:        blockend,
        !            56:        defaddress,
        !            57:        defconst,
        !            58:        defstring,
        !            59:        defsymbol,
        !            60:        0,
        !            61:        export,
        !            62:        function,
        !            63:        gen,
        !            64:        global,
        !            65:        import,
        !            66:        local,
        !            67:        progbeg,
        !            68:        progend,
        !            69:        segment,
        !            70:        space,
        !            71: #ifdef sparc
        !            72:        stabblock, 0, 0, stabinit, stabline, stabsym, stabtype,
        !            73: #else
        !            74:        0, 0, 0, 0, 0, 0, 0,
        !            75: #endif
        !            76:        {".global %s\n", 0, 1, {".seg \"text\"", ".seg \"bss\"", ".seg \"data\"", ".seg \"text\""},
        !            77:        doarg, docall, blkfetch, blkloop, blkstore,
        !            78:        final, 0, emitspecial,
        !            79: #ifdef GEN4
        !            80:        sparc_kids, sparc_ntname, sparc_nts, sparc_rule, sparc_state, sparc_string, sparc_cost,
        !            81:        rules, emit2, target
        !            82: #endif
        !            83:        }
        !            84: };
        !            85: 
        !            86: static Symbol curfunc;
        !            87: static int nlocals;
        !            88: static Symbol d0, f0, g0, i0, freg[32], ireg[6], oreg[6];
        !            89: dclproto(static void rename,(int));
        !            90: 
        !            91: /* address - initialize q for addressing expression p+n */
        !            92: static void address(q, p, n) Symbol q, p; int n; {
        !            93:        q->x.offset = p->x.offset + n;
        !            94:        if (p->scope == GLOBAL || p->sclass == STATIC || p->sclass == EXTERN)
        !            95:                q->x.name = stringf("%s%s%d", p->x.name, n >= 0 ? "+" : "", n);
        !            96:        else
        !            97:                q->x.name = stringd(q->x.offset);
        !            98: }
        !            99: 
        !           100: /* blkfetch - emit code to load k bytes from reg+off into tmp */
        !           101: static void blkfetch(k, off, reg, tmp) {
        !           102:        assert(k == 1 || k == 2 || k == 4);
        !           103:        assert(salign >= k);
        !           104:        print("ld%s [%%r%d+%d],%%r%d\n", &"ub\0uh\0..\0\0"[3*(k-1)], reg, off, tmp);
        !           105: }
        !           106: 
        !           107: /* blkloop - emit loop to copy size bytes from sreg+soff to dreg+doff using tmp regs */
        !           108: static void blkloop(dreg, doff, sreg, soff, size, tmp) int tmp[]; {
        !           109:        if ((size&~7) > 4096) {
        !           110:                print("set %d,%%%s\n", size&~7, tmp[2]);
        !           111:                print("add %%r%d,%%r%d,%%r%d\n", sreg, tmp[2], sreg);
        !           112:                print("add %%r%d,%%r%d,%%r%d\n", dreg, tmp[2], tmp[2]);
        !           113:        } else {
        !           114:                print("add %%r%d,%d,%%r%d\n", sreg, size&~7, sreg);
        !           115:                print("add %%r%d,%d,%%r%d\n", dreg, size&~7, tmp[2]);
        !           116:        }
        !           117:        blkcopy(tmp[2], doff, sreg, soff, size&7, tmp);
        !           118:        print("1: dec 8,%%r%d\n", tmp[2]);
        !           119:        blkcopy(tmp[2], doff, sreg, soff - 8, 8, tmp);
        !           120:        print("cmp %%r%d,%%r%d; bgt 1b; dec 8,%%r%d\n", tmp[2], dreg, sreg);
        !           121: }
        !           122: 
        !           123: /* blkstore - emit code to store k bytes from tmp to reg+off */
        !           124: static void blkstore(k, off, reg, tmp) {
        !           125:        assert(k == 1 || k == 2 || k == 4);
        !           126:        assert(dalign >= k);
        !           127:        print("st%s %%r%d,[%%r%d+%d]\n", &"b\0h\0.\0\0"[2*(k-1)], tmp, reg, off);
        !           128: }
        !           129: 
        !           130: 
        !           131: static void defaddress(p) Symbol p; {
        !           132:        if (p->scope == LABELS)
        !           133:                print(".align 4; ");    /* for switch tables */
        !           134:        print(".word %s\n", p->x.name);
        !           135: }
        !           136: 
        !           137: /* defconst - define a constant */
        !           138: static void defconst(ty, v) Value v; {
        !           139:        struct real r;
        !           140: 
        !           141:        switch (ty) {
        !           142:        case C: print(".byte %d\n",   v.uc); break;
        !           143:        case S: print(".half %d\n",   v.ss); break;
        !           144:        case I: print(".word %d\n",   v.i ); break;
        !           145:        case U: print(".word 0x%x\n", v.u ); break;
        !           146:        case P: print(".word 0x%x\n", v.p ); break;
        !           147:        case F:
        !           148:                r = decode(F, v.f);
        !           149:                if (v.f)
        !           150:                        r.exp = (r.exp + 127)&0xff;
        !           151:                print(".word 0x%x\n", (r.sign<<31) | (r.exp<<23) | (r.msb>>9));
        !           152:                break;
        !           153:        case D:
        !           154:                r = decode(D, v.d);
        !           155:                if (v.d)
        !           156:                        r.exp = (r.exp + 1023)&0x7ff;
        !           157:                print(".word 0x%x,0x%x\n",
        !           158:                        (r.sign<<31) | (r.exp<<20) | (r.msb>>12),
        !           159:                        ( r.msb<<20) | (r.lsb>>12));
        !           160:                break;
        !           161:        default:
        !           162:                assert(0);
        !           163:        }
        !           164: }
        !           165: 
        !           166: static void defstring(n, s) char *s; {
        !           167:        genascii(".ascii", ".byte", n, s);
        !           168: }
        !           169: 
        !           170: /* defsymbol - compute and store p's back-end name */
        !           171: static void defsymbol(p) Symbol p; {
        !           172:        if (p->scope >= LOCAL && p->sclass == STATIC)
        !           173:                p->x.name = stringf("%d", genlabel(1));
        !           174:        else
        !           175:                p->x.name = p->name;
        !           176:        if (p->scope >= LABELS)
        !           177:                p->x.name = stringf(p->generated ? "L%s" : "_%s", p->x.name);
        !           178: }
        !           179: 
        !           180: /* doarg - assign offset for next ARG node */
        !           181: static void doarg(p) Node p; {
        !           182:        static int reg;
        !           183:        
        !           184:        if (argoffset == 0)
        !           185:                reg = 0;
        !           186:        assert(p);
        !           187:        assert(p->syms[0]);
        !           188:        assert(p->syms[1]);
        !           189:        p->syms[2] = intconst(mkactual((p->syms[1]->u.c.v.i == 8 ? 4 : p->syms[1]->u.c.v.i), p->syms[0]->u.c.v.i, 4)/4);
        !           190:        p->syms[1] = intconst(reg/4);
        !           191:        assert(p->op != ARG+B);
        !           192:        reg += roundup(p->syms[0]->u.c.v.i, 4);
        !           193: }
        !           194: 
        !           195: #ifdef GEN4
        !           196: char **opcodes;
        !           197: #endif
        !           198: 
        !           199: /* emitspecial - emit hard double-precision operators */
        !           200: static void emitspecial(p) Node p; {
        !           201:        if (genx == 4 ? (p->op == ASGN+B) : !strcmp(opcodes[p->op], "# asgnb")) {
        !           202:                static int tmp[] = { 1, 2, 3 };
        !           203:                dalign = salign = p->syms[1]->u.c.v.i;
        !           204:                blkcopy(getregnode(p->kids[0]->syms[RX])->regnum, 0,
        !           205:                        getregnode(p->kids[1]->syms[RX])->regnum, 0, p->syms[0]->u.c.v.i, tmp);
        !           206:        } else if (genx == 4 ? (p->op == ARG+D) : !strcmp(opcodes[p->op], "# argd")) {
        !           207:                int dstoff = p->syms[2]->u.c.v.i;
        !           208:                int dstreg = p->syms[1]->u.c.v.i;
        !           209:                int src = getregnode(p->kids[0]->syms[RX])->regnum;
        !           210:                print("st %%f%d,[%%sp+4*%d+68]\n", src, dstoff);
        !           211:                print("st %%f%d,[%%sp+4*%d+68]\n", src+1, dstoff+1);
        !           212:                if (dstreg <= 5)
        !           213:                        print("ld [%%sp+4*%d+68],%%o%d\n", dstoff, dstreg);
        !           214:                if (dstreg <= 4)
        !           215:                        print("ld [%%sp+4*%d+68],%%o%d\n", dstoff+1, dstreg+1);
        !           216:        } else if (genx == 4 ? (p->op == LOAD+D) : !strcmp(opcodes[p->op], "# movd")) {
        !           217:                int dst = getregnode(p->syms[RX])->regnum;
        !           218:                int src = getregnode(p->kids[0]->syms[RX])->regnum;
        !           219:                print("fmovs %%f%d,%%f%d; fmovs %%f%d,%%f%d\n", src, dst, src+1, dst+1);
        !           220:        } else if (genx == 4 ? (p->op == NEG+D) : !strcmp(opcodes[p->op], "# negd")) {
        !           221:                int dst = getregnode(p->syms[RX])->regnum;
        !           222:                int src = getregnode(p->kids[0]->syms[RX])->regnum;
        !           223:                print("fnegs %%f%d,%%f%d; fmovs %%f%d,%%f%d\n", src, dst, src+1, dst+1);
        !           224:        }
        !           225: }
        !           226: 
        !           227: /* function - generate code for a function */
        !           228: static void function(f, caller, callee, n) Symbol f, callee[], caller[]; {
        !           229:        int fpused = 0, framesize, i, reg = 0, varargs;
        !           230:        Symbol p, q;
        !           231: 
        !           232:        initfunc(n + glevel + pflag, 4*(16 + 1), 6*4);
        !           233:        for (i = 0; callee[i]; i++)
        !           234:                ;
        !           235:        varargs = variadic(f->type) || i > 0 && strcmp(callee[i-1]->name, "__builtin_va_alist") == 0;
        !           236:        for (i = 0; p = callee[i]; i++) {
        !           237:                q = caller[i];
        !           238:                assert(q);
        !           239:                if (isfloat(p->type) || isstruct(p->type) || reg >= 6) {
        !           240:                        p->x.offset = offset;
        !           241:                        p->x.name = q->x.name = stringd(p->x.offset);
        !           242:                        p->sclass = q->sclass = AUTO;
        !           243:                        fpused++;
        !           244:                } else if (p->addressed || varargs || glevel && glevel != 3) {
        !           245:                        p->x.offset = offset;
        !           246:                        p->x.name = stringd(p->x.offset);
        !           247:                        p->sclass = AUTO;
        !           248:                        q->sclass = REGISTER;
        !           249:                        if (!getregvar(q, ireg[reg]))
        !           250:                                assert(0);
        !           251:                        fpused++;
        !           252:                } else {
        !           253:                        p->sclass = q->sclass = REGISTER;
        !           254:                        if (!getregvar(p, ireg[reg]))
        !           255:                                assert(0);
        !           256:                        q->x.name = p->x.name;
        !           257:                }
        !           258:                reg += isstruct(p->type) ? 1 : roundup(q->type->size, 4)/4;
        !           259:                offset += roundup(q->type->size, 4);
        !           260:        }
        !           261:        assert(caller[i] == 0);
        !           262:        curfunc = f;
        !           263:        nlocals = offset = 0;
        !           264:        gencode(caller, callee);
        !           265:        freeregvars();
        !           266:        if (isstruct(freturn(f->type)))
        !           267:                fpused++;
        !           268:        if (maxoffset > 0 || (usedmask[IREG]&0x00ffff00) || (usedmask[FREG]&~3) || varargs)
        !           269:                ncalls++;
        !           270:        framesize = roundup(4*(16 + 1) + argbuildsize + maxoffset, 8);
        !           271:        savebase[IREG] = framesize;
        !           272:        print(".align 4\n.proc 4\n%s:", f->x.name);
        !           273:        savemask[IREG] = 0xffff0000;
        !           274:        if (ncalls == 0) {
        !           275:                Symbol p;
        !           276:                rename(-16);
        !           277:                for (p = regvars; p; p = p->x.nextregvar)
        !           278:                        p->x.name = p->x.regvar->x.name;
        !           279:                print(fpused ? "mov %%fp,%%g7; mov %%sp,%%fp\n" : "\n");
        !           280:                savemask[IREG] = 0;
        !           281:        } else if (framesize <= 4095)
        !           282:                print("save %%sp,%d,%%sp\n", -framesize);
        !           283:        else
        !           284:                print("set %d,%%g1; save %%sp,%%g1,%%sp\n", -framesize);
        !           285:        if (varargs)
        !           286:                for (; reg < 6; reg++)
        !           287:                        print("st %%i%d,[%%fp+%d]\n", reg, 4*reg + 68);
        !           288:        else
        !           289:                for (offset = 4*(16 + 1), reg = i = 0; p = caller[i]; i++) {
        !           290:                        if (isdouble(p->type) && reg <= 4) {
        !           291:                                print("st %%%s,[%%fp+%d]\n", ireg[reg++]->x.name, offset);
        !           292:                                print("st %%%s,[%%fp+%d]\n", ireg[reg++]->x.name, offset + 4);
        !           293:                        } else if (isfloat(p->type) && reg <= 5)
        !           294:                                print("st %%%s,[%%fp+%d]\n", ireg[reg++]->x.name, offset);
        !           295:                        else
        !           296:                                reg++;
        !           297:                        offset += roundup(p->type->size, 4);
        !           298:                }
        !           299:        if (pflag) {
        !           300:                int lab = genlabel(1);
        !           301:                print("set L%d,%%o0; call mcount; nop\n", lab);
        !           302:                print(".seg \"data\"\n.align 4; L%d:.word 0\n.seg \"text\"\n", lab);
        !           303:        }
        !           304:        emitcode();
        !           305:        if (ncalls == 0) {
        !           306:                rename(16);
        !           307:                if (fpused)
        !           308:                        print("retl; mov %%g7,%%fp\n");
        !           309:                else
        !           310:                        print("retl; nop\n");
        !           311:        } else
        !           312:                print("ret; restore\n");
        !           313: }
        !           314: 
        !           315: /* global - global id */
        !           316: static void global(p) Symbol p; {
        !           317:        if (p->type->align > 1)
        !           318:                print(".align %d; ", p->type->align);
        !           319:        assert(p->u.seg);
        !           320:        if (p->u.seg == BSS && (p->sclass == STATIC || Aflag >= 2))
        !           321:                print(".reserve %s,", p->x.name);
        !           322:        else if (p->u.seg == BSS)
        !           323:                print(".common %s,", p->x.name);
        !           324:        else
        !           325:                print("%s:", p->x.name);
        !           326: }
        !           327: 
        !           328: static void import(p) Symbol p; {
        !           329:        p->x.name = stringf("_%s", p->name);
        !           330: }
        !           331: 
        !           332: /* local - local */
        !           333: static void local(p) Symbol p; {
        !           334:        if (nlocals++ == 0 && isstruct(freturn(curfunc->type))) {
        !           335:                p->x.name = stringd(4*16);
        !           336:                return;
        !           337:        }
        !           338:        if (!p->addressed && isscalar(p->type) && !isfloat(p->type))
        !           339:                p->sclass = REGISTER;
        !           340:        if (glevel && glevel != 3)
        !           341:                p->sclass = AUTO;
        !           342:        if (getregvar(p, rmap[ttob(p->type)]) == 0)
        !           343:                p->x.name = stringd(mkauto(p, p->type->align));
        !           344: }
        !           345: 
        !           346: static Symbol nextreg(p) Symbol p; {
        !           347:        return freg[getregnode(p)->regnum+1];
        !           348: }
        !           349: 
        !           350: /* progbeg - beginning of program */
        !           351: static void progbeg(argc, argv) char *argv[]; {
        !           352:        int i;
        !           353: 
        !           354:        nregsets = 2;
        !           355:        eemask[IREG] = 0xffff0000; eemask[FREG] = 0;
        !           356:        tmask[IREG]  = 0x3fffff00; tmask[FREG]  = -1;
        !           357:        vmask[IREG]  = 0x3ff00000; vmask[FREG]  = 0;
        !           358:        parseflags(argc, argv);
        !           359:        initgen();
        !           360:        d0 = mkregs(  "0",  0,  0, 2, 3, FREG, D, 0);
        !           361:        f0 = mkregs(  "0",  0,  0, 1, 1, FREG, F, 0);
        !           362:        g0 = mkregs( "r0",  0,  0, 1, 1, IREG, I, 0);
        !           363:        i0 = mkregs("r24", 24, 24, 1, 0, IREG, I, 0);  /* zero mask; use only for RETI. */
        !           364:        for (i = 0; i < 6; i++) {
        !           365:                oreg[i]  = mkregs("r%d", i +  8, i +  8, 1, 1, IREG, I, 0);
        !           366:                ireg[i]  = mkregs("r%d", i + 24, i + 24, 1, 1, IREG, I, 0);
        !           367:        }
        !           368:        for (i = 0; i < 32; i++)
        !           369:                freg[i] = mkregs("%d", i, i, 1, 1, FREG, F, 0);
        !           370:        rmap[I] = mkregs("r%d",  8, 13, 1, 1, IREG, I, rmap[I]);
        !           371:        rmap[I] = mkregs("r%d", 16, 23, 1, 1, IREG, I, rmap[I]);
        !           372:        rmap[I] = mkregs("r%d", 24, 29, 1, 1, IREG, I, rmap[I]);
        !           373:        rmap[F] = mkregs("%d", 0, 31, 1, 1, FREG, F, rmap[F]);
        !           374:        rmap[D] = mkregs("%d", 0, 31, 2, 3, FREG, D, rmap[D]);
        !           375:        rmap[C] = rmap[S] = rmap[P] = rmap[U] = rmap[I];
        !           376: }
        !           377: 
        !           378: static void rename(inc) {
        !           379:        Symbol p;
        !           380: 
        !           381:        for (p = regs; p; p = p->x.regnode->next)
        !           382:                if (p == i0 || p->x.regnode->regset == IREG && p->x.regnode->mask&0x3f000000)
        !           383:                        p->x.name = stringf("r%d", p->x.regnode->regnum += inc);
        !           384: }
        !           385: 
        !           386: static void segment(n) {
        !           387:        setseg(n);
        !           388: }
        !           389: 
        !           390: static void space(n) {
        !           391:        spacen((n), ".skip");
        !           392: }

unix.superglobalmegacorp.com

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