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