Annotation of researchv9/cmd/sun/c2/label.c, revision 1.1.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.