|
|
1.1 root 1: # include "mfile2"
2:
3:
4: int fldsz, fldshf;
5:
6: static int mamask[] = { /* masks for matching dope with shapes */
7: SIMPFLG, /* OPSIMP */
8: SIMPFLG|ASGFLG, /* ASG OPSIMP */
9: COMMFLG, /* OPCOMM */
10: COMMFLG|ASGFLG, /* ASG OPCOMM */
11: MULFLG, /* OPMUL */
12: MULFLG|ASGFLG, /* ASG OPMUL */
13: DIVFLG, /* OPDIV */
14: DIVFLG|ASGFLG, /* ASG OPDIV */
15: UTYPE, /* OPUNARY */
16: TYFLG, /* ASG OPUNARY is senseless */
17: LTYPE, /* OPLEAF */
18: TYFLG, /* ASG OPLEAF is senseless */
19: 0, /* OPANY */
20: ASGOPFLG|ASGFLG, /* ASG OPANY */
21: LOGFLG, /* OPLOG */
22: TYFLG, /* ASG OPLOG is senseless */
23: FLOFLG, /* OPFLOAT */
24: FLOFLG|ASGFLG, /* ASG OPFLOAT */
25: SHFFLG, /* OPSHFT */
26: SHFFLG|ASGFLG, /* ASG OPSHIFT */
27: SPFLG, /* OPLTYPE */
28: TYFLG, /* ASG OPLTYPE is senseless */
29: };
30:
31: int sdebug = 0;
32:
33: tshape( p, shape ) NODE *p; {
34: /* return true if shape is appropriate for the node p
35: side effect for SFLD is to set up fldsz,etc */
36: register o, mask;
37:
38: o = p->op;
39:
40: if( sdebug ){
41: printf( "tshape( %o, %o), op = %d\n", p, shape, o );
42: }
43:
44: if( shape & SPECIAL ){
45:
46: switch( shape ){
47:
48: case SZERO:
49: case SONE:
50: case SMONE:
51: case SSCON:
52: case SCCON:
53: if( o != ICON || p->name[0] ) return(0);
54: if( p->lval == 0 && shape == SZERO ) return(1);
55: else if( p->lval == 1 && shape == SONE ) return(1);
56: else if( p->lval == -1 && shape == SMONE ) return(1);
57: else if( p->lval > -257 && p->lval < 256 && shape == SCCON ) return(1);
58: else if( p->lval > -32769 && p->lval < 32768 && shape == SSCON ) return(1);
59: else return(0);
60:
61: case SSOREG: /* non-indexed OREG */
62: if( o == OREG && !R2TEST(p->rval) ) return(1);
63: else return(0);
64:
65: default:
66: return( special( p, shape ) );
67: }
68: }
69:
70: if( shape & SANY ) return(1);
71:
72: if( (shape&INTEMP) && shtemp(p) ) return(1);
73:
74: if( (shape&SWADD) && (o==NAME||o==OREG) ){
75: if( BYTEOFF(p->lval) ) return(0);
76: }
77:
78: switch( o ){
79:
80: case NAME:
81: return( shape&SNAME );
82: case ICON:
83: mask = SCON;
84: return( shape & mask );
85:
86: case FLD:
87: if( shape & SFLD ){
88: if( !flshape( p->left ) ) return(0);
89: /* it is a FIELD shape; make side-effects */
90: o = p->rval;
91: fldsz = UPKFSZ(o);
92: # ifdef RTOLBYTES
93: fldshf = UPKFOFF(o);
94: # else
95: fldshf = SZINT - fldsz - UPKFOFF(o);
96: # endif
97: return(1);
98: }
99: return(0);
100:
101: case CCODES:
102: return( shape&SCC );
103:
104: case REG:
105: /* distinctions:
106: SAREG any scalar register
107: STAREG any temporary scalar register
108: SBREG any lvalue (index) register
109: STBREG any temporary lvalue register
110: */
111: mask = isbreg( p->rval ) ? SBREG : SAREG;
112: if( istreg( p->rval ) && busy[p->rval]<=1 ) mask |= mask==SAREG ? STAREG : STBREG;
113: return( shape & mask );
114:
115: case OREG:
116: return( shape & SOREG );
117:
118: case UNARY MUL:
119: /* return STARNM or STARREG or 0 */
120: return( shumul(p->left) & shape );
121:
122: }
123:
124: return(0);
125: }
126:
127: int tdebug = 0;
128:
129: ttype( t, tword ) TWORD t; {
130: /* does the type t match tword */
131:
132: if( tword & TANY ) return(1);
133:
134: if( tdebug ){
135: printf( "ttype( %o, %o )\n", t, tword );
136: }
137: if( ISPTR(t) && (tword&TPTRTO) ) {
138: do {
139: t = DECREF(t);
140: } while ( ISARY(t) );
141: /* arrays that are left are usually only
142: in structure references... */
143: return( ttype( t, tword&(~TPTRTO) ) );
144: }
145: if( t != BTYPE(t) ) return( tword & TPOINT ); /* TPOINT means not simple! */
146: if( tword & TPTRTO ) return(0);
147:
148: switch( t ){
149:
150: case CHAR:
151: return( tword & TCHAR );
152: case SHORT:
153: return( tword & TSHORT );
154: case STRTY:
155: case UNIONTY:
156: return( tword & TSTRUCT );
157: case INT:
158: return( tword & TINT );
159: case UNSIGNED:
160: return( tword & TUNSIGNED );
161: case USHORT:
162: return( tword & TUSHORT );
163: case UCHAR:
164: return( tword & TUCHAR );
165: case ULONG:
166: return( tword & TULONG );
167: case LONG:
168: return( tword & TLONG );
169: case FLOAT:
170: return( tword & TFLOAT );
171: case DOUBLE:
172: return( tword & TDOUBLE );
173: }
174:
175: return(0);
176: }
177:
178: struct optab *rwtable;
179:
180: struct optab *opptr[DSIZE];
181:
182: setrew(){
183: /* set rwtable to first value which allows rewrite */
184: register struct optab *q;
185: register int i;
186:
187: for( q = table; q->op != FREE; ++q ){
188: if( q->needs == REWRITE ){
189: rwtable = q;
190: goto more;
191: }
192: }
193: cerror( "bad setrew" );
194:
195:
196: more:
197: for( i=0; i<DSIZE; ++i ){
198: if( dope[i] ){ /* there is an op... */
199: for( q=table; q->op != FREE; ++q ){
200: /* beware; things like LTYPE that match
201: multiple things in the tree must
202: not try to look at the NIL at this
203: stage of things! Put something else
204: first in table.c */
205: /* at one point, the operator matching was 15% of the
206: total comile time; thus, the function
207: call that was here was removed...
208: */
209:
210: if( q->op < OPSIMP ){
211: if( q->op==i ) break;
212: }
213: else {
214: register opmtemp;
215: if((opmtemp=mamask[q->op - OPSIMP])&SPFLG){
216: if( i==NAME || i==ICON || i==OREG ) break;
217: else if( shltype( i, NIL ) ) break;
218: }
219: else if( (dope[i]&(opmtemp|ASGFLG)) == opmtemp ) break;
220: }
221: }
222: opptr[i] = q;
223: }
224: }
225: }
226:
227: match( p, cookie ) NODE *p; {
228: /* called by: order, gencall
229: look for match in table and generate code if found unless
230: entry specified REWRITE.
231: returns MDONE, MNOPE, or rewrite specification from table */
232:
233: register struct optab *q;
234: register NODE *r;
235:
236: rcount();
237: if( cookie == FORREW ) q = rwtable;
238: else q = opptr[p->op];
239:
240: for( ; q->op != FREE; ++q ){
241:
242: /* at one point the call that was here was over 15% of the total time;
243: thus the function call was expanded inline */
244: if( q->op < OPSIMP ){
245: if( q->op!=p->op ) continue;
246: }
247: else {
248: register opmtemp;
249: if((opmtemp=mamask[q->op - OPSIMP])&SPFLG){
250: if( p->op!=NAME && p->op!=ICON && p->op!= OREG &&
251: ! shltype( p->op, p ) ) continue;
252: }
253: else if( (dope[p->op]&(opmtemp|ASGFLG)) != opmtemp ) continue;
254: }
255:
256: if( !(q->visit & cookie ) ) continue;
257: r = getlr( p, 'L' ); /* see if left child matches */
258: if( !tshape( r, q->lshape ) ) continue;
259: if( !ttype( r->type, q->ltype ) ) continue;
260: r = getlr( p, 'R' ); /* see if right child matches */
261: if( !tshape( r, q->rshape ) ) continue;
262: if( !ttype( r->type, q->rtype ) ) continue;
263:
264: /* REWRITE means no code from this match but go ahead
265: and rewrite node to help future match */
266: if( q->needs & REWRITE ) return( q->rewrite );
267: if( !allo( p, q ) ) continue; /* if can't generate code, skip entry */
268:
269: /* resources are available */
270:
271: expand( p, cookie, q->cstring ); /* generate code */
272: reclaim( p, q->rewrite, cookie );
273:
274: return(MDONE);
275:
276: }
277:
278: return(MNOPE);
279: }
280:
281: expand( p, cookie, cp ) NODE *p; register char *cp; {
282: /* generate code by interpreting table entry */
283:
284: CONSZ val;
285:
286: for( ; *cp; ++cp ){
287: switch( *cp ){
288:
289: default:
290: PUTCHAR( *cp );
291: continue; /* this is the usual case... */
292:
293: case 'Z': /* special machine dependent operations */
294: zzzcode( p, *++cp );
295: continue;
296:
297: case 'F': /* this line deleted if FOREFF is active */
298: if( cookie & FOREFF ) while( *++cp != '\n' ) ; /* VOID */
299: continue;
300:
301: case 'S': /* field size */
302: printf( "$%d", fldsz );
303: continue;
304:
305: case 'H': /* field shift */
306: printf( "$%d", fldshf );
307: continue;
308:
309: case 'M': /* field mask */
310: case 'N': /* complement of field mask */
311: val = 1;
312: val <<= fldsz;
313: --val;
314: val <<= fldshf;
315: adrcon( *cp=='M' ? val : ~val );
316: continue;
317:
318: case 'L': /* output special label field */
319: printf( "%d", p->label );
320: continue;
321:
322: case 'O': /* opcode string */
323: hopcode( *++cp, p->op );
324: continue;
325:
326: case 'B': /* byte offset in word */
327: val = getlr(p,*++cp)->lval;
328: val = BYTEOFF(val);
329: printf( CONFMT, val );
330: continue;
331:
332: case 'C': /* for constant value only */
333: conput( getlr( p, *++cp ) );
334: continue;
335:
336: case 'I': /* in instruction */
337: insput( getlr( p, *++cp ) );
338: continue;
339:
340: case 'A': /* address of */
341: adrput( getlr( p, *++cp ) );
342: continue;
343:
344: case 'U': /* for upper half of address, only */
345: upput( getlr( p, *++cp ) );
346: continue;
347:
348: }
349:
350: }
351:
352: }
353:
354: NODE *
355: getlr( p, c ) NODE *p; {
356:
357: /* return the pointer to the left or right side of p, or p itself,
358: depending on the optype of p */
359:
360: switch( c ) {
361:
362: case '1':
363: case '2':
364: case '3':
365: return( &resc[c-'1'] );
366:
367: case 'L':
368: return( optype( p->op ) == LTYPE ? p : p->left );
369:
370: case 'R':
371: return( optype( p->op ) != BITYPE ? p : p->right );
372:
373: }
374: cerror( "bad getlr: %c", c );
375: /* NOTREACHED */
376: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.