1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
|
/* $OpenBSD: pass2.h,v 1.3 2007/10/01 18:51:02 otto Exp $ */
/*
* Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code and documentation must retain the above
* copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditionsand the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed or owned by Caldera
* International, Inc.
* Neither the name of Caldera International, Inc. nor the names of other
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
* INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
* FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include "manifest.h"
#include "protos.h"
#ifndef MKEXT
#include "external.h"
#else
typedef int bittype; /* XXX - for basicblock */
#endif
/* cookies, used as arguments to codgen */
#define FOREFF 01 /* compute for effects only */
#define INAREG 02 /* compute into a register */
#define INBREG 04 /* compute into a register */
#define INCREG 010 /* compute into a register */
#define INDREG 020 /* compute into a register */
#define INREGS (INAREG|INBREG|INCREG|INDREG)
#define FORCC 040 /* compute for condition codes only */
#define INTEMP 010000 /* compute into a temporary location */
#define FORREW 040000 /* search the table for a rewrite rule */
/*
* OP descriptors,
* the ASG operator may be used on some of these
*/
#define OPSIMP 010000 /* +, -, &, |, ^ */
#define OPCOMM 010002 /* +, &, |, ^ */
#define OPMUL 010004 /* *, / */
#define OPDIV 010006 /* /, % */
#define OPUNARY 010010 /* unary ops */
#define OPLEAF 010012 /* leaves */
#define OPANY 010014 /* any op... */
#define OPLOG 010016 /* logical ops */
#define OPFLOAT 010020 /* +, -, *, or / (for floats) */
#define OPSHFT 010022 /* <<, >> */
#define OPLTYPE 010024 /* leaf type nodes (e.g, NAME, ICON, etc.) */
/* shapes */
#define SANY 01 /* same as FOREFF */
#define SAREG 02 /* same as INAREG */
#define SBREG 04 /* same as INBREG */
#define SCREG 010 /* same as INCREG */
#define SDREG 020 /* same as INDREG */
#define SCC 040 /* same as FORCC */
#define SNAME 0100
#define SCON 0200
#define SFLD 0400
#define SOREG 01000
#define STARNM 02000
#define STARREG 04000
#define SWADD 040000
#define SPECIAL 0100000
#define SZERO SPECIAL
#define SONE (SPECIAL|1)
#define SMONE (SPECIAL|2)
#define SCCON (SPECIAL|3) /* -256 <= constant < 256 */
#define SSCON (SPECIAL|4) /* -32768 <= constant < 32768 */
#define SSOREG (SPECIAL|5) /* non-indexed OREG */
#define MAXSPECIAL (SPECIAL|5)
/* These are used in rstatus[] in conjunction with SxREG */
#define TEMPREG 0100
#define PERMREG 0200
/* tshape() return values */
#define SRNOPE 0 /* Cannot match any shape */
#define SRDIR 1 /* Direct match */
#define SROREG 2 /* Can convert into OREG */
#define SRREG 3 /* Must put into REG */
/* find*() return values */
#define FRETRY -2
#define FFAIL -1
/* INTEMP is carefully not conflicting with shapes */
/* types */
#define TCHAR 01 /* char */
#define TSHORT 02 /* short */
#define TINT 04 /* int */
#define TLONG 010 /* long */
#define TFLOAT 020 /* float */
#define TDOUBLE 040 /* double */
#define TPOINT 0100 /* pointer to something */
#define TUCHAR 0200 /* unsigned char */
#define TUSHORT 0400 /* unsigned short */
#define TUNSIGNED 01000 /* unsigned int */
#define TULONG 02000 /* unsigned long */
#define TPTRTO 04000 /* pointer to one of the above */
#define TANY 010000 /* matches anything within reason */
#define TSTRUCT 020000 /* structure or union */
#define TLONGLONG 040000 /* long long */
#define TULONGLONG 0100000 /* unsigned long long */
#define TLDOUBLE 0200000 /* long double; exceeds 16 bit */
#define TFTN 0400000 /* function pointer; exceeds 16 bit */
/* reclamation cookies */
#define RNULL 0 /* clobber result */
#define RLEFT 01
#define RRIGHT 02
#define RESC1 04
#define RESC2 010
#define RESC3 020
#define RDEST 040
#define RESCC 04000
#define RNOP 010000 /* DANGER: can cause loops.. */
/* needs */
#define NAREG 0000001
#define NACOUNT 0000003
#define NAMASK 0000017
#define NASL 0000004 /* may share left register */
#define NASR 0000010 /* may share right register */
#define NBREG 0000020
#define NBCOUNT 0000060
#define NBMASK 0000360
#define NBSL 0000100
#define NBSR 0000200
#define NTEMP 0000400
#define NTMASK 0001400
#define NSPECIAL 0040000 /* need special register treatment */
#define REWRITE 0100000
#define NCSL 0x10000 /* Above 16 bit */
#define NCSR 0x20000 /* Above 16 bit */
#define NCREG 0x40000 /* Above 16 bit */
#define NCCOUNT 0xc0000
#define NDSL 0x100000 /* Above 16 bit */
#define NDSR 0x200000 /* Above 16 bit */
#define NDREG 0x400000 /* Above 16 bit */
#define NDCOUNT 0xc00000
/* special treatment */
#define NLEFT (0001) /* left leg register (moveadd) */
#define NOLEFT (0002) /* avoid regs for left (addedge) */
#define NRIGHT (0004) /* right leg register */
#define NORIGHT (0010) /* avoid reg for right */
#define NEVER (0020) /* registers trashed (addalledges) */
#define NRES (0040) /* result register (moveadd) */
#define NMOVTO (0100) /* move between classes */
#define MUSTDO 010000 /* force register requirements */
#define NOPREF 020000 /* no preference for register assignment */
#define isreg(p) (p->n_op == REG || p->n_op == TEMP)
#define TBUSY 01000
#define SETSTO(x,y) (stotree = (x), stocook = (y))
extern int stocook;
extern NODE *stotree;
extern int callflag;
extern int fregs;
/* code tables */
extern struct optab {
int op;
int visit;
int lshape;
int ltype;
int rshape;
int rtype;
int needs;
int rewrite;
char *cstring;
} table[];
/* Special needs for register allocations */
struct rspecial {
int op, num;
#if 0
int left; /* left leg register */
int noleft; /* avoid regs for left */
int right; /* right leg register */
int noright; /* avoid right leg register */
int *rmask; /* array of destroyed registers */
int res; /* Result ends up here */
// void (*rew)(struct optab *, NODE *); /* special rewrite */
#endif
};
extern NODE resc[];
extern int p2autooff, p2maxautooff;
extern NODE
*talloc(void),
*eread(void),
*mklnode(int, CONSZ, int, TWORD),
*mkbinode(int, NODE *, NODE *, TWORD),
*mkunode(int, NODE *, int, TWORD),
*getlr(NODE *p, int);
void eoftn(struct interpass_prolog *);
void prologue(struct interpass_prolog *);
void setlocc(int locctr);
void e2print(NODE *p, int down, int *a, int *b);
void myoptim(struct interpass *);
void cbgen(int op, int label);
struct optab *nxtmatch(struct optab *);
int chkmatch(NODE *, int, int, int);
int match(NODE *p, int cookie);
int nmatch(NODE *p, int what);
#ifndef special
int special(NODE *, int);
#endif
int setasg(NODE *, int);
int setuni(NODE *, int);
int sucomp(NODE *);
int nsucomp(NODE *);
int setorder(NODE *);
int geninsn(NODE *, int cookie);
void adrput(FILE *, NODE *);
void comperr(char *str, ...);
void genregs(NODE *p);
void ngenregs(struct interpass *);
NODE *store(NODE *);
void gencall(NODE *, NODE *prev);
struct interpass *ipnode(NODE *);
void deflab(int);
void rmove(int, int, TWORD);
int rspecial(struct optab *, int);
struct rspecial *nspecial(struct optab *q);
void printip(struct interpass *pole);
int findops(NODE *p, int);
int findasg(NODE *p, int);
int finduni(NODE *p, int);
int findumul(NODE *p, int);
int findleaf(NODE *p, int);
int relops(NODE *p);
void offstar(NODE *p, int shape);
int gclass(TWORD);
void lastcall(NODE *);
void myreader(struct interpass *pole);
int oregok(NODE *p, int sharp);
void myormake(NODE *);
char *prcook(int);
void conput(FILE *, NODE *);
extern char *rnames[];
extern int rstatus[];
extern int roverlap[MAXREGS][MAXREGS];
extern int classmask(int), tclassmask(int);
extern void cmapinit(void);
extern int aliasmap(int adjclass, int regnum);
extern int regK[];
#define CLASSA 1
#define CLASSB 2
#define CLASSC 3
#define CLASSD 4
#define CLASSE 5
/* routines to handle double indirection */
#ifdef R2REGS
void makeor2(NODE *p, NODE *q, int, int);
int base(NODE *);
int offset(NODE *p, int);
#endif
extern int lineno;
extern int fldshf, fldsz;
extern int lflag, x2debug, udebug, e2debug, odebug, mdebug;
extern int rdebug, radebug, t2debug, s2debug, b2debug, c2debug;
extern int kflag;
#ifdef FORT
extern int Oflag;
#endif
#ifndef callchk
#define callchk(x) allchk()
#endif
#ifndef PUTCHAR
#define PUTCHAR(x) putchar(x)
#endif
#define optype(o) (dope[o]&TYFLG)
#define asgop(o) (dope[o]&ASGFLG)
#define logop(o) (dope[o]&LOGFLG)
#define callop(o) (dope[o]&CALLFLG)
extern int dope[]; /* a vector containing operator information */
extern char *opst[]; /* a vector containing names for ops */
/* macros for doing double indexing */
#define R2PACK(x,y,z) (0200*((x)+1)+y+040000*z)
#define R2UPK1(x) ((((x)>>7)-1)&0177)
#define R2UPK2(x) ((x)&0177)
#define R2UPK3(x) (x>>14)
#define R2TEST(x) ((x)>=0200)
/*
* Layout of findops() return value:
* bit 0-1 where to store left node.
* bit 2-3 where to store right node.
* bit 4 set if right leg should be evaluated first
* bit 5- table index
*
* LOREG means: walk down left node, after code emission call canon() to
* convert the tree to an OREG.
*/
#define LREG 001
#define LOREG 002
#define LTEMP 003
#define LDIR 003
#define LMASK 003
#define RREG 004
#define ROREG 010
#define RTEMP 014
#define RDIR 014
#define RMASK 014
#define DORIGHT 020
#define SCLASS(v,x) ((v) |= ((x) << 5))
#define TCLASS(x) (((x) >> 5) & 7)
#define TBSH 8
#define TBLIDX(idx) ((idx) >> TBSH)
#define MKIDX(tbl,mod) (((tbl) << TBSH) | (mod))
#ifndef BREGS
#define BREGS 0
#define TBREGS 0
#endif
#define REGBIT(x) (1 << (x))
void emit(struct interpass *);
void optimize(struct interpass *);
struct basicblock {
DLIST_ENTRY(basicblock) bbelem;
SLIST_HEAD(, cfgnode) children; /* CFG - children to this node */
SLIST_HEAD(, cfgnode) parents; /* CFG - parents to this node */
int bbnum; /* this basic block number */
unsigned int dfnum; /* DFS-number */
unsigned int dfparent; /* Parent in DFS */
unsigned int semi;
unsigned int ancestor;
unsigned int idom;
unsigned int samedom;
bittype *bucket;
bittype *df;
bittype *dfchildren;
bittype *Aorig;
bittype *Aphi;
struct interpass *first; /* first element of basic block */
struct interpass *last; /* last element of basic block */
};
struct labelinfo {
struct basicblock **arr;
unsigned int size;
unsigned int low;
};
struct bblockinfo {
unsigned int size;
struct basicblock **arr;
};
struct varinfo {
struct pvarinfo **arr;
int size;
int low;
};
struct pvarinfo {
struct pvarinfo *next;
struct basicblock *bb;
NODE *top, *n;
};
struct cfgnode {
SLIST_ENTRY(cfgnode) cfgelem;
struct basicblock *bblock;
};
/*
* C compiler second pass extra defines.
*/
#define PHI (MAXOP + 1) /* Used in SSA trees */
|