|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)util.c 1.1 86/02/03 Copyr 1985 Sun Micro";
3: #endif
4:
5: /*
6: * Copyright (c) 1985 by Sun Microsystems, Inc.
7: */
8:
9: #include "as.h"
10: #include "c2.h"
11:
12: int
13: cntbits( vl )
14: {
15: register unsigned long v = vl;
16: register n;
17: n = 0;
18: do{
19: n += v&1;
20: }while( v>>=1 );
21: return n;
22: }
23:
24:
25: /* can this address operand be incremented by n? */
26: int
27: incraddr( o, n )
28: register struct oper *o;
29: {
30: /*
31: * Because we don't want to mess up potential device drivers,
32: * we must be very prudent here. Too bad.
33: * We can only do this to a memory location if its an offset from
34: * the stack or frame pointers. Those had better not point to
35: * device registers, damn them.
36: * We must also (I fear) be careful around immediates that are still
37: * relocatable.
38: */
39: extern int Xperimental;
40:
41: switch (o->type_o){
42: case T_IMMED:
43: if (n!=0 && o->sym_o!=NULL) return 1;
44: return 0;
45: case T_REG:
46: if (o->value_o >= A0REG && n != 0 ) return 1;
47: else return 0;
48: case T_DISPL:
49: if (!Xperimental)
50: if ( (o->reg_o < (fortranprog?(A0REG+4):FPREG))
51: || (n+o->value_o > 0x7fff) ) return 1;
52: o->value_o += n;
53: return 0;
54: case T_DEFER:
55: if (!Xperimental)
56: if (o->value_o < (fortranprog?(A0REG+4):FPREG)) return 1;
57: if (n != 0){
58: o->reg_o = o->value_o;
59: o->value_o = n;
60: o->sym_o = 0;
61: o->type_o = T_DISPL;
62: }
63: return 0;
64: case T_INDEX:
65: if (!Xperimental)
66: if (o->reg_o < (fortranprog?(A0REG+4):FPREG)) return 1;
67: if (!Xperimental)
68: if (o->disp_o+n > 0x7f) return 1;
69: if (o->flags_o & O_INDIRECT)
70: o->disp2_o += n;
71: else
72: o->disp_o += n;
73: return 0;
74: }
75: /* default falls through here */
76: return 1; /* no way */
77: }
78:
79: /* can this operand reference be deleted? */
80: int
81: deladdr( o )
82: struct oper *o;
83: {
84: return !incraddr( o, 0) ;
85: }
86:
87: /* compare operands, instructions */
88:
89: int
90: sameops( op1, op2)
91: register struct oper *op1, *op2;
92: {
93: # define SAME( a ) if (op1->a != op2->a) return 0
94: /* are these two operands the same? */
95: SAME( type_o );
96: SAME( flags_o );
97: switch (op1->type_o){
98: case T_IMMED:
99: if ( op1->flags_o & O_FLOAT ){
100: SAME( fval_o );
101: break;
102: }
103: /* fall through */
104: case T_NORMAL:
105: case T_ABSS:
106: case T_ABSL:
107: SAME( sym_o );
108: /* fall through */
109: case T_REG:
110: case T_DEFER:
111: case T_POSTINC:
112: case T_PREDEC:
113: SAME( value_o );
114: break;
115: case T_INDEX:
116: SAME( disp_o );
117: if (op1->flags_o & O_INDIRECT){
118: SAME( disp2_o );
119: SAME( sym2_o );
120: }
121: if (op1->flags_o & (O_PREINDEX|O_POSTINDEX)){
122: SAME( scale_o );
123: }
124: /* fall through */
125: case T_DISPL:
126: SAME( sym_o );
127: /* fall through */
128: case T_REGPAIR:
129: SAME( value_o );
130: SAME( reg_o );
131: break;
132: default: return 0;
133: }
134: if (op1->flags_o & O_BFLD){
135: SAME( bfoffset_o );
136: SAME( bfwidth_o );
137: }
138: return 1;
139: # undef SAME
140: }
141:
142: int
143: sameins( i1, i2 )
144: register NODE *i1, *i2;
145: {
146: register int refs, nrefs;
147:
148: if (!ISINSTRUC( i1->op) )
149: sys_error("sameins: got non-instruction as comperand\n");
150: if (i1->instr != i2->instr|| (nrefs=i1->nref) != i2->nref)
151: return 0;
152: for (refs=0; refs<nrefs; refs++)
153: if (!sameops( i1->ref[refs], i2->ref[refs]) )
154: return 0;
155: return 1;
156: }
157:
158:
159: extern void printmask();
160:
161: /* flush an instruction directly to stdout */
162: putinstr( ip )
163: struct ins_bkt *ip;
164: {
165: register i,n;
166: printf(" %s", ip->text_i);
167: if (n = numops ){
168: putchar('\t');
169: printoperand( &operands[0] );
170: for (i=1; i<n; i++){
171: putchar(',');
172: printoperand( &operands[i] );
173: }
174: }
175: putchar('\n');
176: }
177:
178:
179: void
180: dumpnode( np, verbose )
181: register NODE *np;
182: {
183: register i,n;
184: struct sym_bkt *switchlabel;
185:
186: switch (np->op){
187: case OP_LABEL:
188: if (verbose)
189: printf("%s: | referenced %d times",
190: np->name->name_s, np->nref );
191: else
192: printf("%s:", np->name->name_s );
193: break;
194: case OP_COMMENT:
195: printf("|%s", (char *)(np->ref[0]));
196: break;
197: default:
198: printf(" %s", np->instr->text_i);
199: if (n = np->nref ){
200: putchar('\t');
201: printoperand( np->ref[0] );
202: for (i=1; i<n; i++){
203: putchar(',');
204: printoperand( np->ref[i] );
205: }
206: }
207: if ( np->op==OP_JUMP || np->op==OP_DJMP ){
208: if (np->subop==JIND){
209: fputs("\tpc@(2,d0:w)", stdout);
210: switchlabel = np->luse->name;
211: } else {
212: putchar((n)?',':'\t');
213: fputs(np->luse->name->name_s, stdout);
214: }
215: } else if (np->op==OP_CSWITCH){
216: putchar('\t');
217: fputs(np->luse->name->name_s, stdout);
218: putchar('-');
219: fputs(switchlabel->name_s, stdout);
220: }
221: break;
222: }
223: if (verbose){
224: fputs(" | ", stdout);
225: if (!emptymask(np->ruse)){
226: fputs(" reads:", stdout); printmask( np->ruse);
227: }
228: if (!emptymask(np->rset)){
229: fputs(" writes:", stdout);printmask( np->rset);
230: }
231: if (!emptymask(np->rlive)){
232: fputs(" live:", stdout); printmask( np->rlive);
233: }
234: }
235: putchar('\n');
236: }
237:
238: void
239: dumpprogram(verbose)
240: {
241: NODE *np;
242:
243: printf(" .text\n");
244: for (np=first.forw; np != &first; np = np->forw){
245: dumpnode( np, verbose );
246: }
247: }
248:
249: void
250: sortints( ip, n )
251: register int *ip;
252: register n;
253: {
254: /* sort the array of n ints. Not quick, but compact */
255: register int *np, *p;
256: register changed, temp;
257: np = ip + n - 1;
258: changed = 1;
259: while(changed){
260: changed = 0;
261: for (p = ip; p < np; p++)
262: if (*p > *(p+1) ){
263: temp = *p;
264: *p = *(p+1);
265: *(p+1) = temp;
266: changed = 1;
267: }
268: }
269: }
270:
271: void
272: xref(){
273: register NODE *p, *u;
274: int allocsize = 100, usecnt;
275: int *ip, *tp;
276: ip = (int *)malloc( allocsize * sizeof * p );
277: for (p=first.forw; p != &first; p=p->forw){
278: if (p->op==OP_LABEL){
279: fputs( p->name->name_s, stdout );
280: if (p->nref+1 > allocsize ){
281: allocsize += allocsize;
282: if (p->nref+1 > allocsize )
283: allocsize = p->nref + 5;
284: ip = (int *)realloc( ip, allocsize * sizeof * p );
285: }
286: tp = ip;
287: *tp++ = p->lineno;
288: for (usecnt = p->nref, u=p->luse; usecnt--; ){
289: if (u==NULL)
290: *tp++ = -1;
291: else {
292: *tp++ = u->lineno;
293: u = u->lnext;
294: }
295: }
296: sortints( ip, p->nref+1 );
297: putchar( ':' );
298: for ( usecnt = p->nref+1, tp=ip ; usecnt--; tp++ ){
299: if (*tp == -1)
300: fputs(" ???", stdout);
301: else
302: printf(" %3d", *tp);
303: if (*tp == p->lineno)
304: putchar('*' );
305: }
306: putchar('\n');
307: }
308: }
309: free( ip );
310: }
311:
312: /*
313: * Insert a node after another one
314: */
315: insert(p, after)
316: NODE *p;
317: NODE *after;
318: {
319: NODE *lastp;
320:
321: for (lastp = p; lastp->forw != NULL; lastp = lastp->forw)
322: ;
323: after->forw->back = lastp;
324: lastp->forw = after->forw;
325: after->forw = p;
326: p->back = after;
327: }
328:
329: #ifdef C2
330: char *
331: docomment(p)
332: register char *p;
333: {
334: extern char *c2pseudocomment();
335: NODE *n;
336:
337: if (*p != '#' && *p != '|') return p;
338: n = new();
339: n->op = OP_COMMENT;
340: n->ref[0] = (struct oper *)malloc( strlen(p) );
341: strcpy( (char *)n->ref[0], p+1 );
342: addnode( n );
343: if (strncmp(p,C2MAGIC,C2MAGICSIZE) == 0){
344: p = c2pseudocomment( p+=C2MAGICSIZE );
345: }
346: return p;
347: }
348: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.