Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20121020201543

Diff

Diff from 1.100 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/mip/match.c

Annotated File View

plunky
1.100
1 /*      $Id: match.c,v 1.100 2012/10/20 20:15:43 plunky Exp $   */
ragge
1.34
2 /*
3  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
ragge
1.13
29 /*
30  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
31  *
32  * Redistribution and use in source and binary forms, with or without
33  * modification, are permitted provided that the following conditions
34  * are met:
35  *
36  * Redistributions of source code and documentation must retain the above
37  * copyright notice, this list of conditions and the following disclaimer.
38  * Redistributions in binary form must reproduce the above copyright
39  * notice, this list of conditionsand the following disclaimer in the
40  * documentation and/or other materials provided with the distribution.
41  * All advertising materials mentioning features or use of this software
42  * must display the following acknowledgement:
43  *      This product includes software developed or owned by Caldera
44  *      International, Inc.
45  * Neither the name of Caldera International, Inc. nor the names of other
46  * contributors may be used to endorse or promote products derived from
47  * this software without specific prior written permission.
48  *
49  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
50  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
51  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
52  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
53  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
54  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
58  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
59  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
60  * POSSIBILITY OF SUCH DAMAGE.
61  */
ragge
1.1
62
gmcgarry
1.79
63 #include "pass2.h"
ragge
1.1
64
gmcgarry
1.79
65 #ifdef HAVE_STRINGS_H
ragge
1.37
66 #include <strings.h>
gmcgarry
1.79
67 #endif
ragge
1.37
68
ragge
1.43
69 void setclass(int tmpint class);
ragge
1.44
70 int getclass(int tmp);
ragge
1.1
71
plunky
1.96
72 #ifdef PCC_DEBUG
ragge
1.65
73 static char *srtyp[] = { "SRNOPE""SRDIR""SROREG""SRREG" };
plunky
1.96
74 #endif
ragge
1.65
75
ragge
1.2
76 /*
77  * return true if shape is appropriate for the node p
ragge
1.61
78  *
79  * Return values:
80  * SRNOPE  Cannot match this shape.
81  * SRDIR   Direct match, may or may not traverse down.
82  * SRREG   Will match if put in a regster XXX - kill this?
ragge
1.2
83  */
84 int
85 tshape(NODE *pint shape)
86 {
87         int omask;
ragge
1.1
88
ragge
1.10
89         o = p->n_op;
ragge
1.1
90
ragge
1.13
91 #ifdef PCC_DEBUG
ragge
1.23
92         if (s2debug)
93                 printf("tshape(%p, %s) op = %s\n"pprcook(shape), opst[o]);
ragge
1.13
94 #endif
ragge
1.1
95
ragge
1.28
96         if (shape & SPECIAL) {
ragge
1.1
97
ragge
1.28
98                 switch (shape) {
ragge
1.1
99                 case SZERO:
100                 case SONE:
101                 case SMONE:
102                 case SSCON:
103                 case SCCON:
ragge
1.28
104                         if (o != ICON || p->n_name[0])
105                                 return SRNOPE;
106                         if (p->n_lval == 0 && shape == SZERO)
107                                 return SRDIR;
108                         if (p->n_lval == 1 && shape == SONE)
109                                 return SRDIR;
110                         if (p->n_lval == -1 && shape == SMONE)
111                                 return SRDIR;
112                         if (p->n_lval > -257 && p->n_lval < 256 &&
113                             shape == SCCON)
114                                 return SRDIR;
115                         if (p->n_lval > -32769 && p->n_lval < 32768 &&
116                             shape == SSCON)
117                                 return SRDIR;
118                         return SRNOPE;
ragge
1.1
119
120                 case SSOREG:    /* non-indexed OREG */
ragge
1.28
121                         if (o == OREG && !R2TEST(p->n_rval))
122                                 return SRDIR;
123                         return SRNOPE;
ragge
1.1
124
125                 default:
ragge
1.28
126                         return (special(pshape));
ragge
1.1
127                 }
ragge
1.28
128         }
ragge
1.1
129
ragge
1.28
130         if (shape & SANY)
131                 return SRDIR;
ragge
1.1
132
ragge
1.61
133         if ((shape&INTEMP) && shtemp(p)) /* XXX remove? */
ragge
1.28
134                 return SRDIR;
ragge
1.1
135
ragge
1.28
136         if ((shape&SWADD) && (o==NAME||o==OREG))
137                 if (BYTEOFF(p->n_lval))
138                         return SRNOPE;
ragge
1.1
139
ragge
1.28
140         switch (o) {
ragge
1.1
141
142         case NAME:
ragge
1.28
143                 if (shape & SNAME)
144                         return SRDIR;
145                 break;
146
ragge
1.1
147         case ICON:
ragge
1.77
148         case FCON:
ragge
1.28
149                 if (shape & SCON)
150                         return SRDIR;
151                 break;
ragge
1.1
152
153         case FLD:
ragge
1.73
154                 if (shape & SFLD)
155                         return flshape(p->n_left);
ragge
1.28
156                 break;
ragge
1.1
157
158         case CCODES:
ragge
1.28
159                 if (shape & SCC)
160                         return SRDIR;
161                 break;
ragge
1.1
162
163         case REG:
ragge
1.60
164         case TEMP:
ragge
1.34
165                 mask = PCLASS(p);
ragge
1.28
166                 if (shape & mask)
167                         return SRDIR;
ragge
1.62
168                 break;
ragge
1.60
169
ragge
1.1
170         case OREG:
ragge
1.28
171                 if (shape & SOREG)
172                         return SRDIR;
173                 break;
ragge
1.1
174
ragge
1.22
175         case UMUL:
ragge
1.81
176 #if 0
ragge
1.62
177                 if (shumul(p->n_left) & shape)
ragge
1.67
178                         return SROREG;  /* Calls offstar to traverse down */
ragge
1.28
179                 break;
ragge
1.81
180 #else
181                 return shumul(p->n_leftshape);
182 #endif
ragge
1.1
183
ragge
1.28
184         }
185         return SRNOPE;
186 }
ragge
1.1
187
ragge
1.2
188 /*
189  * does the type t match tword
190  */
191 int
192 ttype(TWORD tint tword)
193 {
194         if (tword & TANY)
195                 return(1);
ragge
1.1
196
ragge
1.13
197 #ifdef PCC_DEBUG
ragge
1.5
198         if (t2debug)
199                 printf("ttype(%o, %o)\n"ttword);
ragge
1.13
200 #endif
ragge
1.31
201         if (ISPTR(t) && ISFTN(DECREF(t)) && (tword & TFTN)) {
202                 /* For funny function pointers */
203                 return 1;
204         }
ragge
1.5
205         if (ISPTR(t) && (tword&TPTRTO)) {
ragge
1.1
206                 do {
207                         t = DECREF(t);
ragge
1.5
208                 } while (ISARY(t));
ragge
1.1
209                         /* arrays that are left are usually only
ragge
1.5
210                          * in structure references...
211                          */
212                 return (ttype(ttword&(~TPTRTO)));
213         }
214         if (t != BTYPE(t))
215                 return (tword & TPOINT); /* TPOINT means not simple! */
216         if (tword & TPTRTO)
217                 return(0);
ragge
1.1
218
ragge
1.5
219         switch (t) {
ragge
1.1
220         case CHAR:
221                 returntword & TCHAR );
222         case SHORT:
223                 returntword & TSHORT );
224         case STRTY:
225         case UNIONTY:
226                 returntword & TSTRUCT );
227         case INT:
228                 returntword & TINT );
229         case UNSIGNED:
230                 returntword & TUNSIGNED );
231         case USHORT:
232                 returntword & TUSHORT );
233         case UCHAR:
234                 returntword & TUCHAR );
235         case ULONG:
236                 returntword & TULONG );
237         case LONG:
238                 returntword & TLONG );
ragge
1.3
239         case LONGLONG:
240                 returntword & TLONGLONG );
241         case ULONGLONG:
242                 returntword & TULONGLONG );
ragge
1.1
243         case FLOAT:
244                 returntword & TFLOAT );
245         case DOUBLE:
246                 returntword & TDOUBLE );
ragge
1.30
247         case LDOUBLE:
248                 returntword & TLDOUBLE );
ragge
1.3
249         }
ragge
1.1
250
251         return(0);
ragge
1.5
252 }
ragge
1.1
253
ragge
1.81
254 #define FLDSZ(x)        UPKFSZ(x)
ragge
1.95
255 #if TARGET_ENDIAN == TARGET_LE
ragge
1.73
256 #define FLDSHF(x)       UPKFOFF(x)
257 #else
258 #define FLDSHF(x)       (SZINT - FLDSZ(x) - UPKFOFF(x))
259 #endif
260
ragge
1.2
261 /*
262  * generate code by interpreting table entry
263  */
264 void
265 expand(NODE *pint cookiechar *cp)
266 {
ragge
1.1
267         CONSZ val;
268
gmcgarry
1.90
269 #if 0
270         printf("expand\n");
271         fwalk(pe2print0);
272 #endif
ragge
1.81
273
ragge
1.1
274         for( ; *cp; ++cp ){
275                 switch( *cp ){
276
277                 default:
plunky
1.99
278                         putchar(*cp);
ragge
1.1
279                         continue;  /* this is the usual case... */
280
281                 case 'Z':  /* special machine dependent operations */
282                         zzzcodep, *++cp );
283                         continue;
284
285                 case 'F':  /* this line deleted if FOREFF is active */
stefan
1.76
286                         if (cookie & FOREFF) {
ragge
1.78
287                                 while (*cp && *cp != '\n')
288                                         cp++;
289                                 if (*cp == 0)
290                                         return;
stefan
1.76
291                         }
ragge
1.1
292                         continue;
293
294                 case 'S':  /* field size */
stefan
1.76
295                         if (fldexpand(pcookie, &cp))
296                                 continue;
ragge
1.73
297                         printf("%d"FLDSZ(p->n_rval));
ragge
1.1
298                         continue;
299
300                 case 'H':  /* field shift */
stefan
1.76
301                         if (fldexpand(pcookie, &cp))
302                                 continue;
ragge
1.73
303                         printf("%d"FLDSHF(p->n_rval));
ragge
1.1
304                         continue;
305
306                 case 'M':  /* field mask */
307                 case 'N':  /* complement of field mask */
stefan
1.76
308                         if (fldexpand(pcookie, &cp))
309                                 continue;
ragge
1.1
310                         val = 1;
ragge
1.73
311                         val <<= FLDSZ(p->n_rval);
ragge
1.1
312                         --val;
ragge
1.73
313                         val <<= FLDSHF(p->n_rval);
ragge
1.1
314                         adrcon( *cp=='M' ? val : ~val );
315                         continue;
316
317                 case 'L':  /* output special label field */
ragge
1.11
318                         if (*++cp == 'C')
319                                 printf(LABFMTp->n_label);
320                         else
321                                 printf(LABFMT, (int)getlr(p,*cp)->n_lval);
ragge
1.1
322                         continue;
323
324                 case 'O':  /* opcode string */
ragge
1.87
325 #ifdef FINDMOPS
326                         if (p->n_op == ASSIGN)
327                                 hopcode(*++cpp->n_right->n_op);
328                         else
329 #endif
ragge
1.10
330                         hopcode( *++cpp->n_op );
ragge
1.1
331                         continue;
332
333                 case 'B':  /* byte offset in word */
ragge
1.10
334                         val = getlr(p,*++cp)->n_lval;
ragge
1.1
335                         val = BYTEOFF(val);
336                         printfCONFMTval );
337                         continue;
338
339                 case 'C'/* for constant value only */
ragge
1.27
340                         conput(stdoutgetlrp, *++cp ) );
ragge
1.1
341                         continue;
342
343                 case 'I'/* in instruction */
344                         insputgetlrp, *++cp ) );
345                         continue;
346
347                 case 'A'/* address of */
ragge
1.24
348                         adrput(stdoutgetlrp, *++cp ) );
ragge
1.1
349                         continue;
350
351                 case 'U'/* for upper half of address, only */
ragge
1.15
352                         upput(getlr(p, *++cp), SZLONG);
ragge
1.1
353                         continue;
354
355                         }
356
357                 }
358
359         }
ragge
1.26
360
ragge
1.94
361 NODE resc[NRESC];
ragge
1.1
362
363 NODE *
ragge
1.2
364 getlr(NODE *pint c)
365 {
ragge
1.1
366         /* return the pointer to the left or right side of p, or p itself,
367            depending on the optype of p */
368
ragge
1.2
369         switch (c) {
ragge
1.1
370
371         case '1':
372         case '2':
373         case '3':
ragge
1.41
374         case 'D':
375                 if (c == 'D')
376                         c = 0;
377                 else
378                         c -= '0';
ragge
1.94
379                 if (resc[c].n_op == FREE)
380                         comperr("getlr: free node");
381                 return &resc[c];
ragge
1.1
382
383         case 'L':
ragge
1.10
384                 returnoptypep->n_op ) == LTYPE ? p : p->n_left );
ragge
1.1
385
386         case 'R':
ragge
1.10
387                 returnoptypep->n_op ) != BITYPE ? p : p->n_right );
ragge
1.1
388
ragge
1.2
389         }
ragge
1.1
390         cerror"bad getlr: %c"c );
391         /* NOTREACHED */
ragge
1.2
392         return NULL;
393 }
ragge
1.7
394
ragge
1.36
395 #ifdef PCC_DEBUG
396 #define F2DEBUG(x)      if (f2debug) printf x
397 #define F2WALK(x)       if (f2debug) fwalk(x, e2print, 0)
398 #else
399 #define F2DEBUG(x)
400 #define F2WALK(x)
401 #endif
402
ragge
1.38
403 /*
404  * Convert a node to REG or OREG.
ragge
1.62
405  * Shape is register class where we want the result.
ragge
1.61
406  * Returns register class if register nodes.
ragge
1.64
407  * If w is: (should be shapes)
ragge
1.85
408  *      - SRREG - result in register, call geninsn().
409  *      - SROREG - create OREG; call offstar().
ragge
1.64
410  *      - 0 - clear su, walk down.
ragge
1.38
411  */
ragge
1.36
412 static int
413 swmatch(NODE *pint shapeint w)
414 {
ragge
1.65
415         int rv = 0;
ragge
1.67
416
gmcgarry
1.74
417         F2DEBUG(("swmatch: p=%p, shape=%s, w=%s\n"pprcook(shape), srtyp[w]));
418
ragge
1.64
419         switch (w) {
ragge
1.85
420         case SRREG:
ragge
1.65
421                 rv = geninsn(pshape);
422                 break;
423
ragge
1.85
424         case SROREG:
ragge
1.64
425                 /* should be here only if op == UMUL */
426                 if (p->n_op != UMUL && p->n_op != FLD)
427                         comperr("swmatch %p"p);
428                 if (p->n_op == FLD) {
ragge
1.67
429                         offstar(p->n_left->n_leftshape);
ragge
1.64
430                         p->n_left->n_su = 0;
431                 } else
ragge
1.67
432                         offstar(p->n_leftshape);
ragge
1.64
433                 p->n_su = 0;
ragge
1.65
434                 rv = ffs(shape)-1;
435                 break;
436
ragge
1.64
437         case 0:
438                 if (optype(p->n_op) == BITYPE)
439                         swmatch(p->n_right00);
440                 if (optype(p->n_op) != LTYPE)
441                         swmatch(p->n_left00);
442                 p->n_su = 0;
443         }
ragge
1.65
444         return rv;
ragge
1.64
445
ragge
1.36
446 }
447
ragge
1.34
448 /*
ragge
1.61
449  * Help routines for find*() functions.
ragge
1.62
450  * If the node will be a REG node and it will be rewritten in the
451  * instruction, ask for it to be put in a register.
ragge
1.61
452  */
453 static int
454 chcheck(NODE *pint shapeint rew)
455 {
ragge
1.72
456         int shsha;
ragge
1.67
457
ragge
1.72
458         sha = shape;
ragge
1.68
459         if (shape & SPECIAL)
460                 shape = 0;
461
ragge
1.72
462         switch ((sh = tshape(psha))) {
ragge
1.67
463         case SRNOPE:
464                 if (shape & INREGS)
465                         sh = SRREG;
466                 break;
ragge
1.69
467
ragge
1.67
468         case SROREG:
469         case SRDIR:
470                 if (rew == 0)
471                         break;
472                 if (shape & INREGS)
473                         sh = SRREG;
474                 else
475                         sh = SRNOPE;
476                 break;
477         }
478         return sh;
ragge
1.61
479 }
480
481 /*
ragge
1.65
482  * Check how to walk further down.
483  * Merge with swmatch()?
484  *      sh - shape for return value (register class).
485  *      p - node (for this leg)
486  *      shape - given shape for this leg
487  *      cookie - cookie given for parent node
gmcgarry
1.74
488  *      rew - 
489  *      go - switch key for traversing down
ragge
1.65
490  *      returns register class.
491  */
492 static int
493 shswitch(int shNODE *pint shapeint cookieint rewint go)
494 {
495         int lsh;
496
ragge
1.81
497         F2DEBUG(("shswitch: p=%p, shape=%s, "pprcook(shape)));
498         F2DEBUG(("cookie=%s, rew=0x%x, go=%s\n"prcook(cookie), rewsrtyp[go]));
gmcgarry
1.74
499
ragge
1.65
500         switch (go) {
ragge
1.69
501         case SRDIR/* direct match, just clear su */
ragge
1.65
502                 (void)swmatch(p00);
503                 break;
504
505         case SROREG/* call offstar to prepare for OREG conversion */
ragge
1.85
506                 (void)swmatch(pshapeSROREG);
ragge
1.65
507                 break;
508
509         case SRREG/* call geninsn() to get value into register */
gmcgarry
1.74
510                 lsh = shape & (FORCC | INREGS);
ragge
1.65
511                 if (rew && cookie != FOREFF)
gmcgarry
1.74
512                         lsh &= (cookie & (FORCC | INREGS));
ragge
1.85
513                 lsh = swmatch(plshSRREG);
ragge
1.65
514                 if (rew)
515                         sh = lsh;
516                 break;
517         }
518         return sh;
519 }
520
521 /*
ragge
1.56
522  * Find the best instruction to evaluate the given tree.
523  * Best is to match both subnodes directly, second-best is if
524  * subnodes must be evaluated into OREGs, thereafter if nodes 
525  * must be put into registers.
526  * Whether 2-op instructions or 3-op is preferred is depending on in
527  * which order they are found in the table.
528  * mtchno is set to the count of regs needed for its legs.
529  */
530 int
531 findops(NODE *pint cookie)
532 {
533         extern int *qtable[];
ragge
1.66
534         struct optab *q, *qq = NULL;
ragge
1.56
535         int ishlshr, *ixpsh;
ragge
1.66
536         int lvl = 10idx = 0gol = 0gor = 0;
ragge
1.56
537         NODE *l, *r;
538
539         F2DEBUG(("findops node %p (%s)\n"pprcook(cookie)));
540         F2WALK(p);
541
542         ixp = qtable[p->n_op];
ragge
1.62
543         l = getlr(p'L');
544         r = getlr(p'R');
ragge
1.56
545         for (i = 0ixp[i] >= 0i++) {
546                 q = &table[ixp[i]];
547
ragge
1.86
548                 F2DEBUG(("findop: ixp %d str %s\n"ixp[i], q->cstring));
gmcgarry
1.75
549                 if (!acceptable(q))             /* target-dependent filter */
550                         continue;
551
ragge
1.56
552                 if (ttype(l->n_typeq->ltype) == 0 ||
553                     ttype(r->n_typeq->rtype) == 0)
554                         continue/* Types must be correct */
555
556                 if ((cookie & q->visit) == 0)
557                         continue/* must get a result */
558
559                 F2DEBUG(("findop got types\n"));
ragge
1.67
560
ragge
1.61
561                 if ((shl = chcheck(lq->lshapeq->rewrite & RLEFT)) == SRNOPE)
562                         continue;
ragge
1.56
563
ragge
1.92
564                 F2DEBUG(("findop lshape %s\n"srtyp[shl]));
ragge
1.56
565                 F2WALK(l);
ragge
1.61
566
gmcgarry
1.75
567                 if ((shr = chcheck(rq->rshapeq->rewrite & RRIGHT)) == SRNOPE)
568                         continue;
ragge
1.56
569
ragge
1.92
570                 F2DEBUG(("findop rshape %s\n"srtyp[shr]));
ragge
1.56
571                 F2WALK(r);
572
ragge
1.92
573                 /* Help register assignment after SSA by preferring */
574                 /* 2-op insns instead of 3-ops */
plunky
1.97
575                 if (xssa && (q->rewrite & RLEFT) == 0 && shl == SRDIR)
ragge
1.92
576                         shl = SRREG;
577
ragge
1.56
578                 if (q->needs & REWRITE)
579                         break;  /* Done here */
580
ragge
1.66
581                 if (lvl <= (shl + shr))
582                         continue;
583                 lvl = shl + shr;
584                 qq = q;
585                 idx = ixp[i];
586                 gol = shl;
587                 gor = shr;
ragge
1.56
588         }
ragge
1.66
589         if (lvl == 10) {
ragge
1.56
590                 F2DEBUG(("findops failed\n"));
591                 if (setbin(p))
592                         return FRETRY;
593                 return FFAIL;
594         }
595
ragge
1.66
596         F2DEBUG(("findops entry %d(%s,%s)\n"idxsrtyp[gol], srtyp[gor]));
ragge
1.56
597
598         sh = -1;
ragge
1.67
599
ragge
1.81
600 #ifdef mach_pdp11
ragge
1.84
601         if (cookie == FORCC && p->n_op != AND)  /* XXX - fix */
ragge
1.81
602                 cookie = INREGS;
ragge
1.88
603 #else
604         if (cookie == FORCC)
605                 cookie = INREGS;
ragge
1.81
606 #endif
607
ragge
1.65
608         sh = shswitch(shp->n_leftqq->lshapecookie,
609             qq->rewrite & RLEFTgol);
610         sh = shswitch(shp->n_rightqq->rshapecookie,
611             qq->rewrite & RRIGHTgor);
ragge
1.67
612
ragge
1.70
613         if (sh == -1) {
gmcgarry
1.74
614                 if (cookie == FOREFF || cookie == FORCC)
ragge
1.70
615                         sh = 0;
616                 else
617                         sh = ffs(cookie & qq->visit & INREGS)-1;
618         }
ragge
1.81
619         F2DEBUG(("findops: node %p sh %d (%s)\n"pshprcook(1 << sh)));
ragge
1.66
620         p->n_su = MKIDX(idx0);
621         SCLASS(p->n_sush);
ragge
1.56
622         return sh;
623 }
624
ragge
1.34
625 /*
626  * Find the best relation op for matching the two trees it has.
627  * This is a sub-version of the function findops() above.
628  * The instruction with the lowest grading is emitted.
629  *
630  * Level assignment for priority:
631  *      left    right   prio
632  *      -       -       -
633  *      direct  direct  1
634  *      direct  OREG    2       # make oreg
635  *      OREG    direct  2       # make oreg
636  *      OREG    OREG    2       # make both oreg
637  *      direct  REG     3       # put in reg
638  *      OREG    REG     3       # put in reg, make oreg
639  *      REG     direct  3       # put in reg
640  *      REG     OREG    3       # put in reg, make oreg
641  *      REG     REG     4       # put both in reg
642  */
643 int
644 relops(NODE *p)
645 {
646         extern int *qtable[];
647         struct optab *q;
ragge
1.67
648         int ishl = 0shr = 0;
ragge
1.34
649         NODE *l, *r;
ragge
1.67
650         int *ixpidx = 0;
651         int lvl = 10gol = 0gor = 0;
ragge
1.34
652
ragge
1.47
653         F2DEBUG(("relops tree:\n"));
654         F2WALK(p);
ragge
1.34
655
ragge
1.67
656         l = getlr(p'L');
657         r = getlr(p'R');
ragge
1.34
658         ixp = qtable[p->n_op];
659         for (i = 0ixp[i] >= 0i++) {
660                 q = &table[ixp[i]];
661
ragge
1.47
662                 F2DEBUG(("relops: ixp %d\n"ixp[i]));
gmcgarry
1.75
663                 if (!acceptable(q))             /* target-dependent filter */
664                         continue;
665
ragge
1.34
666                 if (ttype(l->n_typeq->ltype) == 0 ||
667                     ttype(r->n_typeq->rtype) == 0)
668                         continue/* Types must be correct */
669
ragge
1.47
670                 F2DEBUG(("relops got types\n"));
ragge
1.64
671                 if ((shl = chcheck(lq->lshape0)) == SRNOPE)
672                         continue;
ragge
1.47
673                 F2DEBUG(("relops lshape %d\n"shl));
674                 F2WALK(p);
ragge
1.64
675                 if ((shr = chcheck(rq->rshape0)) == SRNOPE)
676                         continue;
ragge
1.47
677                 F2DEBUG(("relops rshape %d\n"shr));
678                 F2WALK(p);
ragge
1.34
679                 if (q->needs & REWRITE)
680                         break;  /* Done here */
681
ragge
1.67
682                 if (lvl <= (shl + shr))
683                         continue;
684                 lvl = shl + shr;
685                 idx = ixp[i];
686                 gol = shl;
687                 gor = shr;
ragge
1.34
688         }
ragge
1.67
689         if (lvl == 10) {
ragge
1.47
690                 F2DEBUG(("relops failed\n"));
691                 if (setbin(p))
692                         return FRETRY;
693                 return FFAIL;
694         }
ragge
1.67
695         F2DEBUG(("relops entry %d(%s %s)\n"idxsrtyp[gol], srtyp[gor]));
ragge
1.47
696
ragge
1.67
697         q = &table[idx];
698
699         (void)shswitch(-1p->n_leftq->lshapeFORCC,
700             q->rewrite & RLEFTgol);
701
702         (void)shswitch(-1p->n_rightq->rshapeFORCC,
703             q->rewrite & RRIGHTgor);
704         
gmcgarry
1.74
705         F2DEBUG(("relops: node %p\n"p));
ragge
1.67
706         p->n_su = MKIDX(idx0);
707         SCLASS(p->n_suCLASSA); /* XXX */
ragge
1.47
708         return 0;
ragge
1.34
709 }
710
711 /*
712  * Find a matching assign op.
713  *
714  * Level assignment for priority:
ragge
1.47
715  *      left    right   prio
ragge
1.34
716  *      -       -       -
717  *      direct  direct  1
718  *      direct  REG     2
719  *      direct  OREG    3
720  *      OREG    direct  4
721  *      OREG    REG     5
722  *      OREG    OREG    6
723  */
724 int
725 findasg(NODE *pint cookie)
726 {
727         extern int *qtable[];
728         struct optab *q;
ragge
1.65
729         int ishshlshrlvl = 10;
ragge
1.34
730         NODE *l, *r;
731         int *ixp;
ragge
1.36
732         struct optab *qq = NULL/* XXX gcc */
ragge
1.65
733         int idx = 0gol = 0gor = 0;
734
735         shl = shr = 0;
ragge
1.34
736
ragge
1.36
737         F2DEBUG(("findasg tree: %s\n"prcook(cookie)));
738         F2WALK(p);
ragge
1.34
739
740         ixp = qtable[p->n_op];
ragge
1.62
741         l = getlr(p'L');
742         r = getlr(p'R');
ragge
1.34
743         for (i = 0ixp[i] >= 0i++) {
744                 q = &table[ixp[i]];
745
gmcgarry
1.74
746                 F2DEBUG(("findasg: ixp %d\n"ixp[i]));
gmcgarry
1.75
747                 if (!acceptable(q))             /* target-dependent filter */
748                         continue;
749
ragge
1.34
750                 if (ttype(l->n_typeq->ltype) == 0 ||
751                     ttype(r->n_typeq->rtype) == 0)
752                         continue/* Types must be correct */
753
ragge
1.36
754                 if ((cookie & q->visit) == 0)
755                         continue/* must get a result */
ragge
1.34
756
gmcgarry
1.74
757                 F2DEBUG(("findasg got types\n"));
ragge
1.81
758 #ifdef mach_pdp11 /* XXX - check for other targets too */
759                 if (p->n_op == STASG && ISPTR(l->n_type)) {
760                         /* Accept lvalue to be in register */
761                         /* if struct assignment is given a pointer */
762                         if ((shl = chcheck(lq->lshape,
763                             q->rewrite & RLEFT)) == SRNOPE)
764                                 continue;
765                 } else
766 #endif
767                 {
768                         if ((shl = tshape(lq->lshape)) == SRNOPE)
769                                 continue;
770                         if (shl == SRREG)
771                                 continue;
772                 }
ragge
1.34
773
gmcgarry
1.74
774                 F2DEBUG(("findasg lshape %d\n"shl));
ragge
1.36
775                 F2WALK(l);
ragge
1.34
776
gmcgarry
1.75
777                 if ((shr = chcheck(rq->rshapeq->rewrite & RRIGHT)) == SRNOPE)
ragge
1.62
778                         continue;
ragge
1.34
779
gmcgarry
1.74
780                 F2DEBUG(("findasg rshape %d\n"shr));
ragge
1.36
781                 F2WALK(r);
ragge
1.34
782                 if (q->needs & REWRITE)
783                         break;  /* Done here */
784
785                 if (lvl <= (shl + shr))
786                         continue;
ragge
1.67
787
ragge
1.34
788                 lvl = shl + shr;
ragge
1.36
789                 qq = q;
ragge
1.65
790                 idx = ixp[i];
791                 gol = shl;
792                 gor = shr;
ragge
1.34
793         }
ragge
1.36
794
ragge
1.65
795         if (lvl == 10) {
ragge
1.36
796                 F2DEBUG(("findasg failed\n"));
797                 if (setasg(pcookie))
798                         return FRETRY;
799                 return FFAIL;
800         }
ragge
1.65
801         F2DEBUG(("findasg entry %d(%s,%s)\n"idxsrtyp[gol], srtyp[gor]));
ragge
1.46
802
ragge
1.36
803         sh = -1;
ragge
1.65
804         sh = shswitch(shp->n_leftqq->lshapecookie,
805             qq->rewrite & RLEFTgol);
ragge
1.64
806
ragge
1.65
807         sh = shswitch(shp->n_rightqq->rshapecookie,
808             qq->rewrite & RRIGHTgor);
ragge
1.67
809
ragge
1.81
810 #ifdef mach_pdp11 /* XXX all targets? */
ragge
1.85
811         lvl = 0;
812         if (cookie == FOREFF)
813                 lvl = RVEFFsh = 0;
814         else if (cookie == FORCC)
815                 lvl = RVCCsh = 0;
816         else if (sh == -1) {
817                 sh = ffs(cookie & qq->visit & INREGS)-1;
818 #ifdef PCC_DEBUG
819                 if (sh == -1)
820                         comperr("findasg bad shape");
821 #endif
822                 SCLASS(lvl,sh);
823         } else
824                 SCLASS(lvl,sh);
825         p->n_su = MKIDX(idxlvl);
ragge
1.81
826 #else
ragge
1.85
827         if (sh == -1) {
ragge
1.36
828                 if (cookie == FOREFF)
ragge
1.48
829                         sh = 0;
830                 else
831                         sh = ffs(cookie & qq->visit & INREGS)-1;
ragge
1.36
832         }
ragge
1.38
833         F2DEBUG(("findasg: node %p class %d\n"psh));
ragge
1.67
834
ragge
1.65
835         p->n_su = MKIDX(idx0);
836         SCLASS(p->n_sush);
ragge
1.85
837 #endif /* mach_pdp11 */
ragge
1.81
838 #ifdef FINDMOPS
839         p->n_flags &= ~1;
840 #endif
ragge
1.39
841         return sh;
ragge
1.34
842 }
843
844 /*
ragge
1.57
845  * Search for an UMUL table entry that can turn an indirect node into
846  * a move from an OREG.
847  */
848 int
849 findumul(NODE *pint cookie)
850 {
851         extern int *qtable[];
852         struct optab *q = NULL/* XXX gcc */
ragge
1.67
853         int ishl = 0shr = 0sh;
ragge
1.57
854         int *ixp;
855
856         F2DEBUG(("findumul p %p (%s)\n"pprcook(cookie)));
857         F2WALK(p);
858
859         ixp = qtable[p->n_op];
860         for (i = 0ixp[i] >= 0i++) {
861                 q = &table[ixp[i]];
862
863                 F2DEBUG(("findumul: ixp %d\n"ixp[i]));
gmcgarry
1.75
864                 if (!acceptable(q))             /* target-dependent filter */
865                         continue;
866
ragge
1.57
867                 if ((q->visit & cookie) == 0)
868                         continue/* wrong registers */
869
ragge
1.60
870                 if (ttype(p->n_typeq->rtype) == 0)
ragge
1.57
871                         continue/* Types must be correct */
ragge
1.60
872                 
ragge
1.57
873
874                 F2DEBUG(("findumul got types, rshape %s\n"prcook(q->rshape)));
875                 /*
876                  * Try to create an OREG of the node.
877                  * Fake left even though it's right node,
878                  * to be sure of conversion if going down left.
879                  */
ragge
1.67
880                 if ((shl = chcheck(pq->rshape0)) == SRNOPE)
ragge
1.63
881                         continue;
ragge
1.57
882                 
883                 shr = 0;
884
885                 if (q->needs & REWRITE)
886                         break;  /* Done here */
887
ragge
1.67
888                 F2DEBUG(("findumul got shape %s\n"srtyp[shl]));
ragge
1.57
889
ragge
1.67
890                 break/* XXX search better matches */
ragge
1.57
891         }
ragge
1.67
892         if (ixp[i] < 0) {
ragge
1.57
893                 F2DEBUG(("findumul failed\n"));
894                 if (setuni(pcookie))
895                         return FRETRY;
896                 return FFAIL;
897         }
ragge
1.67
898         F2DEBUG(("findumul entry %d(%s %s)\n"ixp[i], srtyp[shl], srtyp[shr]));
ragge
1.57
899
ragge
1.67
900         sh = shswitch(-1pq->rshapecookieq->rewrite & RLEFTshl);
901         if (sh == -1)
ragge
1.57
902                 sh = ffs(cookie & q->visit & INREGS)-1;
903
904         F2DEBUG(("findumul: node %p (%s)\n"pprcook(1 << sh)));
ragge
1.67
905         p->n_su = MKIDX(ixp[i], 0);
906         SCLASS(p->n_sush);
ragge
1.57
907         return sh;
908 }
909
910 /*
ragge
1.52
911  * Find a leaf type node that puts the value into a register.
ragge
1.34
912  */
913 int
914 findleaf(NODE *pint cookie)
915 {
916         extern int *qtable[];
ragge
1.39
917         struct optab *q = NULL/* XXX gcc */
ragge
1.67
918         int ish;
ragge
1.34
919         int *ixp;
920
ragge
1.52
921         F2DEBUG(("findleaf p %p (%s)\n"pprcook(cookie)));
ragge
1.39
922         F2WALK(p);
ragge
1.34
923
924         ixp = qtable[p->n_op];
925         for (i = 0ixp[i] >= 0i++) {
926                 q = &table[ixp[i]];
927
ragge
1.39
928                 F2DEBUG(("findleaf: ixp %d\n"ixp[i]));
gmcgarry
1.75
929                 if (!acceptable(q))             /* target-dependent filter */
930                         continue;
ragge
1.57
931                 if ((q->visit & cookie) == 0)
932                         continue/* wrong registers */
933
934                 if (ttype(p->n_typeq->rtype) == 0 ||
935                     ttype(p->n_typeq->ltype) == 0)
936                         continue/* Types must be correct */
ragge
1.34
937
ragge
1.57
938                 F2DEBUG(("findleaf got types, rshape %s\n"prcook(q->rshape)));
ragge
1.67
939
940                 if (chcheck(pq->rshape0) != SRDIR)
941                         continue;
ragge