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