1 /*        Id: pass2.h,v 1.142 2015/08/13 11:56:03 ragge Exp           */
2 /*        $NetBSD: pass2.h,v 1.1.1.7 2016/02/09 20:29:17 plunky Exp $ */
3 /*
4  * Copyright(C) Caldera International Inc. 2001-2002. 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  *
10  * Redistributions of source code and documentation must retain the above
11  * copyright notice, this list of conditions and the following disclaimer.
12  * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditionsand the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  * All advertising materials mentioning features or use of this software
16  * must display the following acknowledgement:
17  *        This product includes software developed or owned by Caldera
18  *        International, Inc.
19  * Neither the name of Caldera International, Inc. nor the names of other
20  * contributors may be used to endorse or promote products derived from
21  * this software without specific prior written permission.
22  *
23  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
24  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
25  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
28  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
32  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
33  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  */
36 #include <sys/types.h>
37 
38 #ifndef MKEXT
39 #include "external.h"
40 #else
41 typedef unsigned int bittype; /* XXX - for basicblock */
42 #define   BIT2BYTE(a)         (((a) + 31) / 32)
43 #endif
44 #include "manifest.h"
45 
46 /* cookies, used as arguments to codgen */
47 #define FOREFF      01                  /* compute for effects only */
48 #define INAREG      02                  /* compute into a register */
49 #define INBREG      04                  /* compute into a register */
50 #define INCREG      010                 /* compute into a register */
51 #define INDREG      020                 /* compute into a register */
52 #define   INREGS    (INAREG|INBREG|INCREG|INDREG)
53 #define FORCC       040                 /* compute for condition codes only */
54 #define QUIET       0100                /* tell geninsn() to not complain if fail */
55 #define INTEMP      010000              /* compute into a temporary location */
56 #define FORREW      040000              /* search the table for a rewrite rule */
57 #define INEREG      0x10000             /* compute into a register, > 16 bits */
58 #define INFREG      0x20000             /* compute into a register, > 16 bits */
59 #define INGREG      0x40000             /* compute into a register, > 16 bits */
60 
61 /*
62  * OP descriptors,
63  * the ASG operator may be used on some of these
64  */
65 #define OPSIMP      010000              /* +, -, &, |, ^ */
66 #define OPCOMM      010002              /* +, &, |, ^ */
67 #define OPMUL       010004              /* *, / */
68 #define OPDIV       010006              /* /, % */
69 #define OPUNARY     010010              /* unary ops */
70 #define OPLEAF      010012              /* leaves */
71 #define OPANY       010014              /* any op... */
72 #define OPLOG       010016              /* logical ops */
73 #define OPFLOAT     010020              /* +, -, *, or / (for floats) */
74 #define OPSHFT      010022              /* <<, >> */
75 #define OPLTYPE     010024              /* leaf type nodes (e.g, NAME, ICON, etc.) */
76 
77 /* shapes */
78 #define SANY        01                  /* same as FOREFF */
79 #define SAREG       02                  /* same as INAREG */
80 #define SBREG       04                  /* same as INBREG */
81 #define SCREG       010                 /* same as INCREG */
82 #define SDREG       020                 /* same as INDREG */
83 #define SCC         040                 /* same as FORCC */
84 #define SNAME       0100
85 #define SCON        0200
86 #define SFLD        0400
87 #define SOREG       01000
88 #define STARNM      02000
89 #define STARREG     04000
90 #define SWADD       040000
91 #define SPECIAL     0100000
92 #define SZERO       SPECIAL
93 #define SONE        (SPECIAL|1)
94 #define SMONE       (SPECIAL|2)
95 #define SCCON       (SPECIAL|3)         /* -256 <= constant < 256 */
96 #define SSCON       (SPECIAL|4)         /* -32768 <= constant < 32768 */
97 #define SSOREG      (SPECIAL|5)         /* non-indexed OREG */
98 #define   MAXSPECIAL          (SPECIAL|5)
99 #define SEREG       0x10000             /* same as INEREG */
100 #define SFREG       0x20000             /* same as INFREG */
101 #define SGREG       0x40000             /* same as INGREG */
102 
103 /* These are used in rstatus[] in conjunction with SxREG */
104 #define   TEMPREG   01000
105 #define   PERMREG   02000
106 
107 /* tshape() return values */
108 #define   SRNOPE    0                   /* Cannot match any shape */
109 #define   SRDIR     1                   /* Direct match */
110 #define   SROREG    2                   /* Can convert into OREG */
111 #define   SRREG     3                   /* Must put into REG */
112 
113 /* find*() return values */
114 #define   FRETRY    -2
115 #define   FFAIL     -1
116 
117 /* INTEMP is carefully not conflicting with shapes */
118 
119 /* types */
120 #define TCHAR                 01        /* char */
121 #define TSHORT                02        /* short */
122 #define TINT                  04        /* int */
123 #define TLONG                 010       /* long */
124 #define TFLOAT                020       /* float */
125 #define TDOUBLE               040       /* double */
126 #define TPOINT                0100      /* pointer to something */
127 #define TUCHAR                0200      /* unsigned char */
128 #define TUSHORT               0400      /* unsigned short */
129 #define TUNSIGNED   01000     /* unsigned int */
130 #define TULONG                02000     /* unsigned long */
131 #define TPTRTO                04000     /* pointer to one of the above */
132 #define TANY                  010000    /* matches anything within reason */
133 #define TSTRUCT               020000    /* structure or union */
134 #define   TLONGLONG 040000    /* long long */
135 #define   TULONGLONG          0100000   /* unsigned long long */
136 #define   TLDOUBLE  0200000   /* long double; exceeds 16 bit */
137 #define   TFTN                0400000   /* function pointer; exceeds 16 bit */
138 
139 /* reclamation cookies */
140 #define RNULL                 0         /* clobber result */
141 #define RLEFT                 01
142 #define RRIGHT                02
143 #define RESC1                 04
144 #define RESC2                 010
145 #define RESC3                 020
146 #define RDEST                 040
147 #define RESCC                 04000
148 #define RNOP                  010000    /* DANGER: can cause loops.. */
149 
150 /* needs */
151 #define NASL                  0x0001    /* may share left register */
152 #define NASR                  0x0002    /* may share right register */
153 #define NAREG                 0x0004
154 #define NACOUNT               0x000c
155 #define NBSL                  0x0010
156 #define NBSR                  0x0020
157 #define NBREG                 0x0040
158 #define NBCOUNT               0x00c0
159 #define   NCSL                0x0100
160 #define   NCSR                0x0200
161 #define   NCREG               0x0400
162 #define   NCCOUNT             0x0c00
163 #define NTEMP                 0x1000
164 #define NTMASK                0x3000
165 #define NSPECIAL    0x4000    /* need special register treatment */
166 #define REWRITE               0x8000
167 #define   NDSL                0x00010000          /* Above 16 bit */
168 #define   NDSR                0x00020000          /* Above 16 bit */
169 #define   NDREG               0x00040000          /* Above 16 bit */
170 #define   NDCOUNT             0x000c0000
171 #define   NESL                0x00100000          /* Above 16 bit */
172 #define   NESR                0x00200000          /* Above 16 bit */
173 #define   NEREG               0x00400000          /* Above 16 bit */
174 #define   NECOUNT             0x00c00000
175 #define   NFSL                0x01000000          /* Above 16 bit */
176 #define   NFSR                0x02000000          /* Above 16 bit */
177 #define   NFREG               0x04000000          /* Above 16 bit */
178 #define   NFCOUNT             0x0c000000
179 #define   NGSL                0x10000000          /* Above 16 bit */
180 #define   NGSR                0x20000000          /* Above 16 bit */
181 #undef    NGREG     /* XXX - linux exposes NGREG to public */
182 #define   NGREG               0x40000000          /* Above 16 bit */
183 #define   NGCOUNT             0xc0000000
184 
185 /* special treatment */
186 #define   NLEFT               (0001)    /* left leg register (moveadd) */
187 #define   NOLEFT              (0002)    /* avoid regs for left (addedge) */
188 #define   NRIGHT              (0004)    /* right leg register */
189 #define   NORIGHT             (0010)    /* avoid reg for right */
190 #define   NEVER               (0020)    /* registers trashed (addalledges) */
191 #define   NRES                (0040)    /* result register (moveadd) */
192 #define   NMOVTO              (0100)    /* move between classes */
193 
194 
195 #define MUSTDO                010000    /* force register requirements */
196 #define NOPREF                020000    /* no preference for register assignment */
197 
198 #define   isreg(p)  (p->n_op == REG || p->n_op == TEMP)
199 
200 extern    int fregs;
201 
202 /* code tables */
203 extern    struct optab {
204           int       op;
205           int       visit;
206           int       lshape;
207           int       ltype;
208           int       rshape;
209           int       rtype;
210           int       needs;
211           int       rewrite;
212           char      *cstring;
213 } table[];
214 
215 /* Special needs for register allocations */
216 struct rspecial {
217           int op, num;
218 #if 0
219           int left; /* left leg register */
220           int noleft;         /* avoid regs for left */
221           int right;          /* right leg register */
222           int noright;        /* avoid right leg register */
223           int *rmask;         /* array of destroyed registers */
224           int res;  /* Result ends up here */
225 //        void (*rew)(struct optab *, NODE *);    /* special rewrite */
226 #endif
227 };
228 
229 struct p2env;
230 #define   NRESC 4
231 extern    NODE resc[];
232 extern    int p2autooff, p2maxautooff;
233 
234 extern    NODE
235           *talloc(void),
236           *eread(void),
237           *mklnode(int, CONSZ, int, TWORD),
238           *mkbinode(int, NODE *, NODE *, TWORD),
239           *mkunode(int, NODE *, int, TWORD),
240           *getlr(NODE *p, int);
241 
242 void eoftn(struct interpass_prolog *);
243 void prologue(struct interpass_prolog *);
244 void e2print(NODE *p, int down, int *a, int *b);
245 void myoptim(struct interpass *);
246 void cbgen(int op, int label);
247 int match(NODE *p, int cookie);
248 int acceptable(struct optab *);
249 int special(NODE *, int);
250 int setasg(NODE *, int);
251 int setuni(NODE *, int);
252 int sucomp(NODE *);
253 int nsucomp(NODE *);
254 int setorder(NODE *);
255 int geninsn(NODE *, int cookie);
256 void adrput(FILE *, NODE *);
257 void comperr(char *str, ...);
258 void genregs(NODE *p);
259 void ngenregs(struct p2env *);
260 NODE *store(NODE *);
261 struct interpass *ipnode(NODE *);
262 void deflab(int);
263 void rmove(int, int, TWORD);
264 int rspecial(struct optab *, int);
265 struct rspecial *nspecial(struct optab *q);
266 void printip(struct interpass *pole);
267 int findops(NODE *p, int);
268 int findasg(NODE *p, int);
269 int finduni(NODE *p, int);
270 int findumul(NODE *p, int);
271 int findleaf(NODE *p, int);
272 int relops(NODE *p);
273 #ifdef FINDMOPS
274 int findmops(NODE *p, int);
275 int treecmp(NODE *p1, NODE *p2);
276 #endif
277 void offstar(NODE *p, int shape);
278 int gclass(TWORD);
279 void lastcall(NODE *);
280 void myreader(struct interpass *pole);
281 int oregok(NODE *p, int sharp);
282 void myormake(NODE *);
283 int *livecall(NODE *);
284 void prtreg(NODE *);
285 char *prcook(int);
286 int myxasm(struct interpass *ip, NODE *p);
287 int xasmcode(char *s);
288 int freetemp(int k);
289 NODE *storenode(TWORD t, int k);
290 void storemod(NODE *, int k, int reg);
291 int rewfld(NODE *p);
292 void canon(NODE *);
293 void mycanon(NODE *);
294 void oreg2(NODE *p, void *);
295 int shumul(NODE *p, int);
296 NODE *deluseless(NODE *p);
297 int getlab2(void);
298 int tshape(NODE *, int);
299 void conput(FILE *, NODE *);
300 int shtemp(NODE *p);
301 int ttype(TWORD t, int tword);
302 void expand(NODE *, int, char *);
303 void hopcode(int, int);
304 void adrcon(CONSZ);
305 void zzzcode(NODE *, int);
306 void insput(NODE *);
307 void upput(NODE *, int);
308 int tlen(NODE *p);
309 int setbin(NODE *);
310 int notoff(TWORD, int, CONSZ, char *);
311 int fldexpand(NODE *, int, char **);
312 int flshape(NODE *p);
313 int ncnt(int needs);
314 void mainp2(void);
315 
316 extern    char *rnames[];
317 
318 extern int classmask(int), tclassmask(int);
319 extern void cmapinit(void);
320 extern int aliasmap(int adjclass, int regnum);
321 extern int regK[];
322 #define   CLASSA    1
323 #define   CLASSB    2
324 #define   CLASSC    3
325 #define   CLASSD    4
326 #define   CLASSE    5
327 #define   CLASSF    6
328 #define   CLASSG    7
329 
330 /* used when parsing xasm codes */
331 #define   XASMVAL(x)          ((x) & 0377)                  /* get val from codeword */
332 #define   XASMVAL1(x)         (((x) >> 16) & 0377)          /* get val from codeword */
333 #define   XASMVAL2(x)         (((x) >> 24) & 0377)          /* get val from codeword */
334 #define   XASMASG             0x100     /* = */
335 #define   XASMCONSTR          0x200     /* & */
336 #define   XASMINOUT 0x400     /* + */
337 #define XASMALL               (XASMASG|XASMCONSTR|XASMINOUT)
338 #define   XASMISINP(cw)       (((cw) & XASMASG) == 0)                 /* input operand */
339 #define   XASMISOUT(cw)       ((cw) & (XASMASG|XASMINOUT))  /* output operand */
340 
341 /* routines to handle double indirection */
342 #ifdef R2REGS
343 void makeor2(NODE *p, NODE *q, int, int);
344 int base(NODE *);
345 int offset(NODE *p, int);
346 #endif
347 
348 extern    int lineno;
349 extern    int ndebug;
350 extern    int b2debug, c2debug, e2debug, f2debug, g2debug, o2debug;
351 extern    int r2debug, s2debug, t2debug, u2debug, x2debug;
352 
353 extern    int dope[];         /* a vector containing operator information */
354 extern    char *opst[];       /* a vector containing names for ops */
355 
356 #ifdef PCC_DEBUG
357 
358 static inline int
optype(int o)359 optype(int o)
360 {
361           if (o >= MAXOP+1)
362                     cerror("optype");
363           return (dope[o]&TYFLG);
364 }
365 
366 static inline int
asgop(int o)367 asgop(int o)
368 {
369           if (o >= MAXOP+1)
370                     cerror("asgop");
371           return (dope[o]&ASGFLG);
372 }
373 
374 static inline int
logop(int o)375 logop(int o)
376 {
377           if (o >= MAXOP+1)
378                     cerror("logop");
379           return (dope[o]&LOGFLG);
380 }
381 
382 static inline int
callop(int o)383 callop(int o)
384 {
385           if (o >= MAXOP+1)
386                     cerror("callop");
387           return (dope[o]&CALLFLG);
388 }
389 
390 #else
391 
392 #define optype(o)   (dope[o]&TYFLG)
393 #define asgop(o)    (dope[o]&ASGFLG)
394 #define logop(o)    (dope[o]&LOGFLG)
395 #define callop(o)   (dope[o]&CALLFLG)
396 
397 #endif
398 
399           /* macros for doing double indexing */
400 #define R2PACK(x,y,z)         (0200*((x)+1)+y+040000*z)
401 #define R2UPK1(x)   ((((x)>>7)-1)&0177)
402 #define R2UPK2(x)   ((x)&0177)
403 #define R2UPK3(x)   (x>>14)
404 #define R2TEST(x)   ((x)>=0200)
405 
406 /*
407  * Layout of findops() return value:
408  *      bit 0 whether left shall go into a register.
409  *      bit 1 whether right shall go into a register.
410  *      bit 2 entry is only used for side effects.
411  *      bit 3 if condition codes are used.
412  *
413  * These values should be synced with FOREFF/FORCC.
414  */
415 #define ISMOPS                001
416 #define RREG                  002
417 #define   RVEFF               004
418 #define   RVCC                010
419 #define DORIGHT               020
420 #define   SCLASS(v,x)         ((v) |= ((x) << 5))
421 #define   TCLASS(x) (((x) >> 5) & 7)
422 #define   TBSH                8
423 #define TBLIDX(idx) ((idx) >> TBSH)
424 #define MKIDX(tbl,mod)        (((tbl) << TBSH) | (mod))
425 
426 #ifndef   BREGS
427 #define   BREGS     0
428 #define   TBREGS    0
429 #endif
430 #define   REGBIT(x) (1 << (x))
431 #ifndef PERMTYPE
432 #define   PERMTYPE(a)         (INT)
433 #endif
434 
435 /* Flags for the dataflow code */
436 /* do the live/dead analysis */
437 #define DO_LIVEDEAD  0x01
438 /* compute avail expressions */
439 #define DO_AVAILEXPR 0x02
440 /* Do an update on the live/dead. One variable only */
441 #define DO_UPDATELD  0x04
442 /* Do an update on available expressions, one variable has changed */
443 #define DO_UPDATEEX  0x08
444 
445 void emit(struct interpass *);
446 void optimize(struct p2env *);
447 
448 struct basicblock {
449           DLIST_ENTRY(basicblock) bbelem;
450           SLIST_HEAD(, cfgnode) parents;          /* CFG - parents to this node */
451           SLIST_HEAD(, cfgnode) child;  /* Children, usually max 2 of them */
452           int bbnum;          /* this basic block number */
453           unsigned int dfnum; /* DFS-number */
454           unsigned int dfparent; /* Parent in DFS */
455           unsigned int semi;
456           unsigned int ancestor;
457           unsigned int idom;
458           unsigned int samedom;
459           bittype *bucket;
460           bittype *df;
461           bittype *dfchildren;
462           bittype *Aorig;
463           bittype *Aphi;
464           SLIST_HEAD(, phiinfo) phi;
465 
466           bittype *gen, *killed, *in, *out;       /* Liveness analysis */
467 
468           struct interpass *first; /* first element of basic block */
469           struct interpass *last;  /* last element of basic block */
470 };
471 
472 struct labelinfo {
473           struct basicblock **arr;
474           int size;
475           unsigned int low;
476 };
477 
478 struct bblockinfo {
479           int size;
480           struct basicblock **arr;
481 };
482 
483 struct varinfo {
484           struct pvarinfo **arr;
485           SLIST_HEAD(, varstack) *stack;
486           int size;
487           int low;
488 };
489 
490 struct pvarinfo {
491           struct pvarinfo *next;
492           struct basicblock *bb;
493           TWORD n_type;
494 };
495 
496 struct varstack {
497           SLIST_ENTRY(varstack) varstackelem;
498           int tmpregno;
499 };
500 
501 
502 struct cfgnode {
503           SLIST_ENTRY(cfgnode) cfgelem;
504           SLIST_ENTRY(cfgnode) chld;
505           struct basicblock *bblock;
506 };
507 
508 struct phiinfo {
509           SLIST_ENTRY(phiinfo) phielem;
510           int tmpregno;
511           int newtmpregno;
512           TWORD n_type;
513           int size;
514           int *intmpregno;
515 };
516 
517 /*
518  * Description of the pass2 environment.
519  * There will be only one of these structs.  It is used to keep
520  * all state descriptions during the compilation of a function
521  * in one place.
522  */
523 struct p2env {
524           struct interpass ipole;                           /* all statements */
525           struct interpass_prolog *ipp, *epp;     /* quick references */
526           struct bblockinfo bbinfo;
527           struct labelinfo labinfo;
528           struct basicblock bblocks;
529           int nbblocks;
530 };
531 
532 extern struct p2env p2env;
533 
534 /*
535  * C compiler second pass extra defines.
536  */
537 #define PHI (MAXOP + 1)                 /* Used in SSA trees */
538 
539 enum {
540           ATTR_P2_FIRST = ATTR_MI_MAX + 1,
541           ATTR_P2STRUCT,
542 #ifdef ATTR_P2_TARGET
543           ATTR_P2_TARGET,
544 #endif
545           ATTR_P2_MAX
546 };
547