Annotation of researchv9/cmd/sun/c2/label.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char sccsid[] = "@(#)label.c 1.1 86/02/03 Copyr 1983 Sun Micro";
        !             3: #endif
        !             4: 
        !             5: /*
        !             6:  * Copyright (c) 1983 by Sun Microsystems, Inc.
        !             7:  */
        !             8: 
        !             9: #include "as.h"
        !            10: #include "c2.h"
        !            11: 
        !            12: /* for local labels: ``[0-9]:'', and references ``[0-9][bh]'' */
        !            13: extern char *ll_format;
        !            14: int   ll_val[10] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
        !            15: 
        !            16: 
        !            17: /* handle definition of label */
        !            18: slabel(t)
        !            19:     char * t;
        !            20: {
        !            21:     register char *token = t;
        !            22:     register char *p;
        !            23:     register NODE *np;
        !            24:     struct sym_bkt *sbp;
        !            25:     char nextc;
        !            26:     static char ltoken[20];
        !            27: 
        !            28:     /* make asciz version of label */
        !            29:     p = token;
        !            30:     while (cinfo[*p] & T) p++;
        !            31:     nextc = *p; /* may be a , a + a \n ... */
        !            32:     *p = '\0';
        !            33: 
        !            34:     /* look for numeric-only labels, as opposed to numeric-$ labels */
        !            35:     if ( (p == token+1) && (cinfo[token[0]]&D)){
        !            36:        sprintf( ltoken, ll_format, token[0], ++ll_val[token[0]-'0'] );
        !            37:        token=ltoken;
        !            38:     }
        !            39: 
        !            40:     /* find/enter symbol in the symbol table */
        !            41:     sbp = lookup(token);
        !            42: 
        !            43:     /* on pass 1 look for multiply defined symbols.  if ok, label
        !            44:        value is dot in current csect
        !            45:     */
        !            46: #   ifdef EBUG
        !            47:        if (debflag)
        !            48:            printf("Label %s, line %d offset 0x%X\n",sbp->name_s,line_no,dot);
        !            49: #   endif
        !            50:        if (sbp->attr_s & (S_LABEL|S_REG)) {
        !            51:                prog_error(E_MULTSYM);
        !            52:        }
        !            53:         sbp->attr_s |= S_LABEL | S_DEC | S_DEF;
        !            54:         sbp->csect_s = cur_csect_name;
        !            55:         sbp->value_s = dot;
        !            56: 
        !            57:     if (!(cinfo[t[0]] & D)) 
        !            58:        last_symbol = sbp;
        !            59: 
        !            60: #if C2
        !            61:     if (cur_csect_name == C_TEXT){
        !            62:        /* make label node */
        !            63:        np = new();
        !            64:        np->op = OP_LABEL;
        !            65:        np->name = sbp;
        !            66:        sbp->where_s = np;
        !            67:        addnode(np);
        !            68:     } else {
        !            69:        /* print directly */
        !            70:        printf("%s:\n", token);
        !            71:     }
        !            72: #endif
        !            73: 
        !            74:     *p = nextc; /* replace next character before proceeding */
        !            75: } /* end slabel */
        !            76: 
        !            77: void
        !            78: newreference( l, r )
        !            79:     NODE *l, *r;
        !            80: {
        !            81:     /*
        !            82:      * l is a label node.
        !            83:      * r is a jump node that should be made to reference it.
        !            84:      * r has already been unreferenced from wherever it pointed before.
        !            85:      */
        !            86:     r->lnext = l->luse;
        !            87:     r->luse=l;
        !            88:     l->luse=r;
        !            89:     l->nref++;
        !            90: }
        !            91: 
        !            92: void
        !            93: unreference( l, r )
        !            94:     NODE *l, *r;
        !            95: {
        !            96:     /*
        !            97:      * r is a jump that references node l.
        !            98:      * unhook r from l's use chain, and decrement l's reference count.
        !            99:      */
        !           100:     register NODE **up;
        !           101: 
        !           102:     if (l == NULL) {
        !           103:        if (r->op == OP_EXIT)
        !           104:            return;
        !           105:        sys_error("no label to unreference, op = 0x%x", r->op);
        !           106:     }
        !           107:     up = & l->luse;
        !           108: 
        !           109:     while( *up ){
        !           110:        if ( *up == r ){
        !           111:            *up = r->lnext;
        !           112:            l->nref--;
        !           113:            return;
        !           114:        }
        !           115:        up = & (*up)->lnext;
        !           116:     }
        !           117:     sys_error( "tangled usage list for label %s\n", l->name->name_s );
        !           118: }
        !           119: 
        !           120: relabel(){
        !           121:     /*
        !           122:      * find all unreferenced labels and delete them.
        !           123:      * find all instances (in .text) of multiple labels in a row
        !           124:      * and collapse them into one label. The difficulty here is
        !           125:      * the case where we cannot find all references to one of the labels
        !           126:      * for instance, where a reference is in a switch list, so must treat
        !           127:      * that one very carefully.
        !           128:      */
        !           129:     register NODE * n, *lastlabel;
        !           130:     register NODE *labelref;
        !           131:     NODE * nextlabel;
        !           132:     int nchanged, nuses;
        !           133:     char labelmoved;
        !           134: 
        !           135:     nchanged = 0;
        !           136:     for (n=first.forw ; n != &first; n = n->forw){
        !           137:        if (n->op != OP_LABEL) continue;
        !           138:        labelmoved = 0;
        !           139:        lastlabel = n;
        !           140:        /* find the last label of this group of labels */
        !           141:        while (lastlabel->forw->op == OP_LABEL)
        !           142:            lastlabel = lastlabel->forw;
        !           143:        while (n != lastlabel){
        !           144:            /*
        !           145:             * for all labels but the last, retarget all references
        !           146:             * to that last one.
        !           147:             */
        !           148:            if (n->nref){
        !           149:                if ( labelref = n->luse ){
        !           150:                    nuses = 1;
        !           151:                    while (labelref->lnext){
        !           152:                        labelref=labelref->lnext;
        !           153:                        nuses++;
        !           154:                    }
        !           155:                } else {
        !           156:                    nuses = 0;
        !           157:                }
        !           158:                /*
        !           159:                 * if we couldn't find all the references, we must
        !           160:                 * leave this label in place, so it can be referenced.
        !           161:                 * It would be nice to emit an equate statement between 
        !           162:                 * this label and the one we plan on keeping, but the assembler
        !           163:                 * cannot handle such a reference, so we cannot do it.
        !           164:                 * try to make this label the "last" one, if this hasn't 
        !           165:                 * already been done.
        !           166:                 */
        !           167:                if (nuses != n->nref){
        !           168:                    nextlabel = n->forw;
        !           169:                    n->back->forw = n->forw;
        !           170:                    n->forw->back = n->back;
        !           171:                    n->back = lastlabel;
        !           172:                    n->forw = lastlabel->forw;
        !           173:                    lastlabel->forw->back = n;
        !           174:                    lastlabel->forw = n;
        !           175:                    if (!labelmoved){
        !           176:                        lastlabel = n;
        !           177:                        labelmoved++;
        !           178:                    }
        !           179:                    n = nextlabel;
        !           180:                    continue;
        !           181:                }
        !           182:                /*
        !           183:                 * we have a chain of references to this label.
        !           184:                 * n->luse addresses the first use, labelref addresses
        !           185:                 * the last use. add this to lastlabel's reference chain.
        !           186:                 */
        !           187:                if (labelref){
        !           188:                    labelref->lnext = lastlabel->luse;
        !           189:                    lastlabel->luse = n->luse;
        !           190:                    lastlabel->nref+= nuses;
        !           191:                    for (labelref=n->luse; labelref != 0; labelref=labelref->lnext){
        !           192:                        labelref->luse = lastlabel;
        !           193:                    }
        !           194:                }
        !           195:            }
        !           196:            /* this label is now useless */
        !           197:            n = deletenode( n );
        !           198:            meter.nrlab++;
        !           199:            nchanged++;
        !           200:            n=n->forw;
        !           201:        }
        !           202:        /* we are now looking at the last label in a bunch delete it if unreferenced */
        !           203:        if (lastlabel->nref==0){
        !           204:            n = deletenode( lastlabel );
        !           205:            meter.nrlab++;
        !           206:            nchanged++;
        !           207:        }
        !           208:     }
        !           209:     return nchanged;
        !           210: }

unix.superglobalmegacorp.com

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