|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.