BSD 3 development
[unix-history] / usr / src / cmd / mip / match.c
CommitLineData
5a7128e9
BJ
1# include "mfile2"
2
3
4int fldsz, fldshf;
5
6static 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
31int sdebug = 0;
32
33tshape( 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
127int tdebug = 0;
128
129ttype( 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
178struct optab *rwtable;
179
180struct optab *opptr[DSIZE];
181
182setrew(){
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
227match( 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
281expand( 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
354NODE *
355getlr( 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 }