blob: c487566d0a762e3bb787b10d331200464ce8c37d [file] [log] [blame]
Eric Biederman90089602004-05-28 14:11:54 +00001#undef VERSION_MAJOR
2#undef VERSION_MINOR
3#undef RELEASE_DATE
4#undef VERSION
5#define VERSION_MAJOR "0"
6#define VERSION_MINOR "63"
7#define RELEASE_DATE "28 May 2004"
8#define VERSION VERSION_MAJOR "." VERSION_MINOR
9
Eric Biedermanb138ac82003-04-22 18:44:01 +000010#include <stdarg.h>
11#include <errno.h>
12#include <stdint.h>
13#include <stdlib.h>
14#include <stdio.h>
15#include <sys/types.h>
16#include <sys/stat.h>
17#include <fcntl.h>
18#include <unistd.h>
19#include <stdio.h>
20#include <string.h>
Eric Biedermanb138ac82003-04-22 18:44:01 +000021#include <limits.h>
Eric Biederman90089602004-05-28 14:11:54 +000022#include <locale.h>
23#include <time.h>
Eric Biedermanb138ac82003-04-22 18:44:01 +000024
Eric Biederman90089602004-05-28 14:11:54 +000025#define MAX_CWD_SIZE 4096
Eric Biederman5ade04a2003-10-22 04:03:46 +000026#define MAX_ALLOCATION_PASSES 100
27
Eric Biedermana4aef6d2003-12-05 06:16:19 +000028#define DEBUG_CONSISTENCY 1
Eric Biederman530b5192003-07-01 10:05:30 +000029#define DEBUG_SDP_BLOCKS 0
30#define DEBUG_TRIPLE_COLOR 0
Eric Biedermanb138ac82003-04-22 18:44:01 +000031
Eric Biederman90089602004-05-28 14:11:54 +000032#define DEBUG_DISPLAY_USES 1
33#define DEBUG_DISPLAY_TYPES 1
34#define DEBUG_REPLACE_CLOSURE_TYPE_HIRES 0
35#define DEBUG_DECOMPOSE_PRINT_TUPLES 0
36#define DEBUG_DECOMPOSE_HIRES 0
37#define DEBUG_INITIALIZER 0
38#define DEBUG_UPDATE_CLOSURE_TYPE 0
39#define DEBUG_LOCAL_TRIPLE 0
40#define DEBUG_BASIC_BLOCKS_VERBOSE 0
41#define DEBUG_CPS_RENAME_VARIABLES_HIRES 0
42#define DEBUG_SIMPLIFY_HIRES 0
43#define DEBUG_SHRINKING 0
44#define DEBUG_COALESCE_HITCHES 0
45#define DEBUG_CODE_ELIMINATION 0
46
47#define DEBUG_EXPLICIT_CLOSURES 0
48
Eric Biederman8d9c1232003-06-17 08:42:17 +000049#warning "FIXME give clear error messages about unused variables"
Eric Biederman530b5192003-07-01 10:05:30 +000050#warning "FIXME properly handle multi dimensional arrays"
Eric Biederman90089602004-05-28 14:11:54 +000051#warning "FIXME handle multiple register sizes"
Eric Biederman05f26fc2003-06-11 21:55:00 +000052
Eric Biedermanb138ac82003-04-22 18:44:01 +000053/* Control flow graph of a loop without goto.
54 *
55 * AAA
56 * +---/
57 * /
58 * / +--->CCC
59 * | | / \
60 * | | DDD EEE break;
61 * | | \ \
62 * | | FFF \
63 * \| / \ \
64 * |\ GGG HHH | continue;
65 * | \ \ | |
66 * | \ III | /
67 * | \ | / /
68 * | vvv /
69 * +----BBB /
70 * | /
71 * vv
72 * JJJ
73 *
74 *
75 * AAA
76 * +-----+ | +----+
77 * | \ | / |
78 * | BBB +-+ |
79 * | / \ / | |
80 * | CCC JJJ / /
81 * | / \ / /
82 * | DDD EEE / /
83 * | | +-/ /
84 * | FFF /
85 * | / \ /
86 * | GGG HHH /
87 * | | +-/
88 * | III
89 * +--+
90 *
91 *
92 * DFlocal(X) = { Y <- Succ(X) | idom(Y) != X }
93 * DFup(Z) = { Y <- DF(Z) | idom(Y) != X }
94 *
95 *
96 * [] == DFlocal(X) U DF(X)
97 * () == DFup(X)
98 *
99 * Dominator graph of the same nodes.
100 *
101 * AAA AAA: [ ] ()
102 * / \
103 * BBB JJJ BBB: [ JJJ ] ( JJJ ) JJJ: [ ] ()
104 * |
105 * CCC CCC: [ ] ( BBB, JJJ )
106 * / \
107 * DDD EEE DDD: [ ] ( BBB ) EEE: [ JJJ ] ()
108 * |
109 * FFF FFF: [ ] ( BBB )
110 * / \
111 * GGG HHH GGG: [ ] ( BBB ) HHH: [ BBB ] ()
112 * |
113 * III III: [ BBB ] ()
114 *
115 *
116 * BBB and JJJ are definitely the dominance frontier.
117 * Where do I place phi functions and how do I make that decision.
118 *
119 */
120static void die(char *fmt, ...)
121{
122 va_list args;
123
124 va_start(args, fmt);
125 vfprintf(stderr, fmt, args);
126 va_end(args);
127 fflush(stdout);
128 fflush(stderr);
129 exit(1);
130}
131
Eric Biedermanb138ac82003-04-22 18:44:01 +0000132static void *xmalloc(size_t size, const char *name)
133{
134 void *buf;
135 buf = malloc(size);
136 if (!buf) {
137 die("Cannot malloc %ld bytes to hold %s: %s\n",
138 size + 0UL, name, strerror(errno));
139 }
140 return buf;
141}
142
143static void *xcmalloc(size_t size, const char *name)
144{
145 void *buf;
146 buf = xmalloc(size, name);
147 memset(buf, 0, size);
148 return buf;
149}
150
Eric Biederman90089602004-05-28 14:11:54 +0000151static void *xrealloc(void *ptr, size_t size, const char *name)
152{
153 void *buf;
154 buf = realloc(ptr, size);
155 if (!buf) {
156 die("Cannot realloc %ld bytes to hold %s: %s\n",
157 size + 0UL, name, strerror(errno));
158 }
159 return buf;
160}
161
Eric Biedermanb138ac82003-04-22 18:44:01 +0000162static void xfree(const void *ptr)
163{
164 free((void *)ptr);
165}
166
167static char *xstrdup(const char *str)
168{
169 char *new;
170 int len;
171 len = strlen(str);
172 new = xmalloc(len + 1, "xstrdup string");
173 memcpy(new, str, len);
174 new[len] = '\0';
175 return new;
176}
177
178static void xchdir(const char *path)
179{
180 if (chdir(path) != 0) {
Eric Biederman90089602004-05-28 14:11:54 +0000181 die("chdir to `%s' failed: %s\n",
Eric Biedermanb138ac82003-04-22 18:44:01 +0000182 path, strerror(errno));
183 }
184}
185
186static int exists(const char *dirname, const char *filename)
187{
Eric Biederman90089602004-05-28 14:11:54 +0000188 char cwd[MAX_CWD_SIZE];
189 int does_exist;
190
191 if (getcwd(cwd, sizeof(cwd)) == 0) {
192 die("cwd buffer to small");
193 }
194
195 does_exist = 1;
196 if (chdir(dirname) != 0) {
197 does_exist = 0;
198 }
199 if (does_exist && (access(filename, O_RDONLY) < 0)) {
Eric Biedermanb138ac82003-04-22 18:44:01 +0000200 if ((errno != EACCES) && (errno != EROFS)) {
201 does_exist = 0;
202 }
203 }
Eric Biederman90089602004-05-28 14:11:54 +0000204 xchdir(cwd);
Eric Biedermanb138ac82003-04-22 18:44:01 +0000205 return does_exist;
206}
207
208
209static char *slurp_file(const char *dirname, const char *filename, off_t *r_size)
210{
Eric Biederman90089602004-05-28 14:11:54 +0000211 char cwd[MAX_CWD_SIZE];
Eric Biedermanb138ac82003-04-22 18:44:01 +0000212 int fd;
213 char *buf;
214 off_t size, progress;
215 ssize_t result;
216 struct stat stats;
217
218 if (!filename) {
219 *r_size = 0;
220 return 0;
221 }
Eric Biederman90089602004-05-28 14:11:54 +0000222 if (getcwd(cwd, sizeof(cwd)) == 0) {
223 die("cwd buffer to small");
224 }
Eric Biedermanb138ac82003-04-22 18:44:01 +0000225 xchdir(dirname);
226 fd = open(filename, O_RDONLY);
Eric Biederman90089602004-05-28 14:11:54 +0000227 xchdir(cwd);
Eric Biedermanb138ac82003-04-22 18:44:01 +0000228 if (fd < 0) {
229 die("Cannot open '%s' : %s\n",
230 filename, strerror(errno));
231 }
232 result = fstat(fd, &stats);
233 if (result < 0) {
234 die("Cannot stat: %s: %s\n",
235 filename, strerror(errno));
236 }
237 size = stats.st_size;
238 *r_size = size +1;
239 buf = xmalloc(size +2, filename);
240 buf[size] = '\n'; /* Make certain the file is newline terminated */
241 buf[size+1] = '\0'; /* Null terminate the file for good measure */
242 progress = 0;
243 while(progress < size) {
244 result = read(fd, buf + progress, size - progress);
245 if (result < 0) {
246 if ((errno == EINTR) || (errno == EAGAIN))
247 continue;
248 die("read on %s of %ld bytes failed: %s\n",
249 filename, (size - progress)+ 0UL, strerror(errno));
250 }
251 progress += result;
252 }
253 result = close(fd);
254 if (result < 0) {
255 die("Close of %s failed: %s\n",
256 filename, strerror(errno));
257 }
258 return buf;
259}
260
Eric Biederman83b991a2003-10-11 06:20:25 +0000261/* Types on the destination platform */
262#warning "FIXME this assumes 32bit x86 is the destination"
263typedef int8_t schar_t;
264typedef uint8_t uchar_t;
265typedef int8_t char_t;
266typedef int16_t short_t;
267typedef uint16_t ushort_t;
268typedef int32_t int_t;
269typedef uint32_t uint_t;
270typedef int32_t long_t;
271typedef uint32_t ulong_t;
272
273#define SCHAR_T_MIN (-128)
274#define SCHAR_T_MAX 127
275#define UCHAR_T_MAX 255
276#define CHAR_T_MIN SCHAR_T_MIN
277#define CHAR_T_MAX SCHAR_T_MAX
278#define SHRT_T_MIN (-32768)
279#define SHRT_T_MAX 32767
280#define USHRT_T_MAX 65535
281#define INT_T_MIN (-LONG_T_MAX - 1)
282#define INT_T_MAX 2147483647
283#define UINT_T_MAX 4294967295U
284#define LONG_T_MIN (-LONG_T_MAX - 1)
285#define LONG_T_MAX 2147483647
286#define ULONG_T_MAX 4294967295U
Eric Biedermanb138ac82003-04-22 18:44:01 +0000287
Eric Biederman90089602004-05-28 14:11:54 +0000288#define SIZEOF_I8 8
289#define SIZEOF_I16 16
290#define SIZEOF_I32 32
291#define SIZEOF_I64 64
292
293#define SIZEOF_CHAR 8
294#define SIZEOF_SHORT 16
295#define SIZEOF_INT 32
296#define SIZEOF_LONG (sizeof(long_t)*SIZEOF_CHAR)
297
298
299#define ALIGNOF_CHAR 8
300#define ALIGNOF_SHORT 16
301#define ALIGNOF_INT 32
302#define ALIGNOF_LONG (sizeof(long_t)*SIZEOF_CHAR)
303
304#define REG_SIZEOF_REG 32
305#define REG_SIZEOF_CHAR REG_SIZEOF_REG
306#define REG_SIZEOF_SHORT REG_SIZEOF_REG
307#define REG_SIZEOF_INT REG_SIZEOF_REG
308#define REG_SIZEOF_LONG REG_SIZEOF_REG
309
310#define REG_ALIGNOF_REG REG_SIZEOF_REG
311#define REG_ALIGNOF_CHAR REG_SIZEOF_REG
312#define REG_ALIGNOF_SHORT REG_SIZEOF_REG
313#define REG_ALIGNOF_INT REG_SIZEOF_REG
314#define REG_ALIGNOF_LONG REG_SIZEOF_REG
315
316/* Additional definitions for clarity.
317 * I currently assume a long is the largest native
318 * machine word and that a pointer fits into it.
319 */
320#define SIZEOF_WORD SIZEOF_LONG
321#define SIZEOF_POINTER SIZEOF_LONG
322#define ALIGNOF_WORD ALIGNOF_LONG
323#define ALIGNOF_POINTER ALIGNOF_LONG
324#define REG_SIZEOF_POINTER REG_SIZEOF_LONG
325#define REG_ALIGNOF_POINTER REG_ALIGNOF_LONG
326
Eric Biedermanb138ac82003-04-22 18:44:01 +0000327struct file_state {
328 struct file_state *prev;
329 const char *basename;
330 char *dirname;
331 char *buf;
332 off_t size;
Eric Biederman90089602004-05-28 14:11:54 +0000333 const char *pos;
Eric Biedermanb138ac82003-04-22 18:44:01 +0000334 int line;
Eric Biederman90089602004-05-28 14:11:54 +0000335 const char *line_start;
Eric Biedermanf7a0ba82003-06-19 15:14:52 +0000336 int report_line;
337 const char *report_name;
338 const char *report_dir;
Eric Biedermanb138ac82003-04-22 18:44:01 +0000339};
340struct hash_entry;
341struct token {
342 int tok;
343 struct hash_entry *ident;
344 int str_len;
345 union {
346 ulong_t integer;
347 const char *str;
Eric Biederman90089602004-05-28 14:11:54 +0000348 int notmacro;
Eric Biedermanb138ac82003-04-22 18:44:01 +0000349 } val;
350};
351
352/* I have two classes of types:
353 * Operational types.
354 * Logical types. (The type the C standard says the operation is of)
355 *
356 * The operational types are:
357 * chars
358 * shorts
359 * ints
360 * longs
361 *
362 * floats
363 * doubles
364 * long doubles
365 *
366 * pointer
367 */
368
369
370/* Machine model.
371 * No memory is useable by the compiler.
372 * There is no floating point support.
373 * All operations take place in general purpose registers.
374 * There is one type of general purpose register.
375 * Unsigned longs are stored in that general purpose register.
376 */
377
378/* Operations on general purpose registers.
379 */
380
Eric Biederman530b5192003-07-01 10:05:30 +0000381#define OP_SDIVT 0
382#define OP_UDIVT 1
383#define OP_SMUL 2
384#define OP_UMUL 3
385#define OP_SDIV 4
386#define OP_UDIV 5
387#define OP_SMOD 6
388#define OP_UMOD 7
389#define OP_ADD 8
390#define OP_SUB 9
391#define OP_SL 10
392#define OP_USR 11
393#define OP_SSR 12
394#define OP_AND 13
395#define OP_XOR 14
396#define OP_OR 15
397#define OP_POS 16 /* Dummy positive operator don't use it */
398#define OP_NEG 17
399#define OP_INVERT 18
Eric Biedermanb138ac82003-04-22 18:44:01 +0000400
401#define OP_EQ 20
402#define OP_NOTEQ 21
403#define OP_SLESS 22
404#define OP_ULESS 23
405#define OP_SMORE 24
406#define OP_UMORE 25
407#define OP_SLESSEQ 26
408#define OP_ULESSEQ 27
409#define OP_SMOREEQ 28
410#define OP_UMOREEQ 29
411
412#define OP_LFALSE 30 /* Test if the expression is logically false */
413#define OP_LTRUE 31 /* Test if the expression is logcially true */
414
415#define OP_LOAD 32
416#define OP_STORE 33
Eric Biederman530b5192003-07-01 10:05:30 +0000417/* For OP_STORE ->type holds the type
418 * RHS(0) holds the destination address
419 * RHS(1) holds the value to store.
420 */
Eric Biedermanb138ac82003-04-22 18:44:01 +0000421
Eric Biederman90089602004-05-28 14:11:54 +0000422#define OP_UEXTRACT 34
423/* OP_UEXTRACT extracts an unsigned bitfield from a pseudo register
424 * RHS(0) holds the psuedo register to extract from
425 * ->type holds the size of the bitfield.
426 * ->u.bitfield.size holds the size of the bitfield.
427 * ->u.bitfield.offset holds the offset to extract from
428 */
429#define OP_SEXTRACT 35
430/* OP_SEXTRACT extracts a signed bitfield from a pseudo register
431 * RHS(0) holds the psuedo register to extract from
432 * ->type holds the size of the bitfield.
433 * ->u.bitfield.size holds the size of the bitfield.
434 * ->u.bitfield.offset holds the offset to extract from
435 */
436#define OP_DEPOSIT 36
437/* OP_DEPOSIT replaces a bitfield with a new value.
438 * RHS(0) holds the value to replace a bitifield in.
439 * RHS(1) holds the replacement value
440 * ->u.bitfield.size holds the size of the bitfield.
441 * ->u.bitfield.offset holds the deposit into
442 */
443
444#define OP_NOOP 37
Eric Biedermanb138ac82003-04-22 18:44:01 +0000445
446#define OP_MIN_CONST 50
Eric Biederman90089602004-05-28 14:11:54 +0000447#define OP_MAX_CONST 58
Eric Biedermanb138ac82003-04-22 18:44:01 +0000448#define IS_CONST_OP(X) (((X) >= OP_MIN_CONST) && ((X) <= OP_MAX_CONST))
449#define OP_INTCONST 50
Eric Biedermand1ea5392003-06-28 06:49:45 +0000450/* For OP_INTCONST ->type holds the type.
451 * ->u.cval holds the constant value.
452 */
Eric Biedermanb138ac82003-04-22 18:44:01 +0000453#define OP_BLOBCONST 51
Eric Biederman0babc1c2003-05-09 02:39:00 +0000454/* For OP_BLOBCONST ->type holds the layout and size
Eric Biedermanb138ac82003-04-22 18:44:01 +0000455 * information. u.blob holds a pointer to the raw binary
456 * data for the constant initializer.
457 */
458#define OP_ADDRCONST 52
Eric Biederman0babc1c2003-05-09 02:39:00 +0000459/* For OP_ADDRCONST ->type holds the type.
Eric Biederman6aa31cc2003-06-10 21:22:07 +0000460 * MISC(0) holds the reference to the static variable.
Eric Biederman0babc1c2003-05-09 02:39:00 +0000461 * ->u.cval holds an offset from that value.
Eric Biedermanb138ac82003-04-22 18:44:01 +0000462 */
Eric Biederman90089602004-05-28 14:11:54 +0000463#define OP_UNKNOWNVAL 59
464/* For OP_UNKNOWNAL ->type holds the type.
465 * For some reason we don't know what value this type has.
466 * This allows for variables that have don't have values
467 * assigned yet, or variables whose value we simply do not know.
468 */
Eric Biedermanb138ac82003-04-22 18:44:01 +0000469
470#define OP_WRITE 60
471/* OP_WRITE moves one pseudo register to another.
Eric Biederman90089602004-05-28 14:11:54 +0000472 * MISC(0) holds the destination pseudo register, which must be an OP_DECL.
473 * RHS(0) holds the psuedo to move.
Eric Biedermanb138ac82003-04-22 18:44:01 +0000474 */
475
476#define OP_READ 61
477/* OP_READ reads the value of a variable and makes
478 * it available for the pseudo operation.
479 * Useful for things like def-use chains.
Eric Biederman0babc1c2003-05-09 02:39:00 +0000480 * RHS(0) holds points to the triple to read from.
Eric Biedermanb138ac82003-04-22 18:44:01 +0000481 */
482#define OP_COPY 62
Eric Biederman90089602004-05-28 14:11:54 +0000483/* OP_COPY makes a copy of the pseudo register or constant in RHS(0).
Eric Biederman0babc1c2003-05-09 02:39:00 +0000484 */
Eric Biederman90089602004-05-28 14:11:54 +0000485#define OP_CONVERT 63
486/* OP_CONVERT makes a copy of the pseudo register or constant in RHS(0).
487 * And then the type is converted appropriately.
488 */
489#define OP_PIECE 64
Eric Biederman0babc1c2003-05-09 02:39:00 +0000490/* OP_PIECE returns one piece of a instruction that returns a structure.
Eric Biederman6aa31cc2003-06-10 21:22:07 +0000491 * MISC(0) is the instruction
Eric Biederman0babc1c2003-05-09 02:39:00 +0000492 * u.cval is the LHS piece of the instruction to return.
Eric Biedermanb138ac82003-04-22 18:44:01 +0000493 */
Eric Biederman90089602004-05-28 14:11:54 +0000494#define OP_ASM 65
Eric Biederman6aa31cc2003-06-10 21:22:07 +0000495/* OP_ASM holds a sequence of assembly instructions, the result
496 * of a C asm directive.
497 * RHS(x) holds input value x to the assembly sequence.
498 * LHS(x) holds the output value x from the assembly sequence.
499 * u.blob holds the string of assembly instructions.
500 */
Eric Biedermanb138ac82003-04-22 18:44:01 +0000501
Eric Biederman90089602004-05-28 14:11:54 +0000502#define OP_DEREF 66
Eric Biedermanb138ac82003-04-22 18:44:01 +0000503/* OP_DEREF generates an lvalue from a pointer.
Eric Biederman0babc1c2003-05-09 02:39:00 +0000504 * RHS(0) holds the pointer value.
Eric Biedermanb138ac82003-04-22 18:44:01 +0000505 * OP_DEREF serves as a place holder to indicate all necessary
506 * checks have been done to indicate a value is an lvalue.
507 */
Eric Biederman90089602004-05-28 14:11:54 +0000508#define OP_DOT 67
Eric Biederman0babc1c2003-05-09 02:39:00 +0000509/* OP_DOT references a submember of a structure lvalue.
Eric Biederman90089602004-05-28 14:11:54 +0000510 * MISC(0) holds the lvalue.
Eric Biederman0babc1c2003-05-09 02:39:00 +0000511 * ->u.field holds the name of the field we want.
512 *
Eric Biederman90089602004-05-28 14:11:54 +0000513 * Not seen after structures are flattened.
Eric Biederman0babc1c2003-05-09 02:39:00 +0000514 */
Eric Biederman90089602004-05-28 14:11:54 +0000515#define OP_INDEX 68
516/* OP_INDEX references a submember of a tuple or array lvalue.
517 * MISC(0) holds the lvalue.
518 * ->u.cval holds the index into the lvalue.
519 *
520 * Not seen after structures are flattened.
521 */
522#define OP_VAL 69
Eric Biedermanb138ac82003-04-22 18:44:01 +0000523/* OP_VAL returns the value of a subexpression of the current expression.
524 * Useful for operators that have side effects.
Eric Biederman0babc1c2003-05-09 02:39:00 +0000525 * RHS(0) holds the expression.
526 * MISC(0) holds the subexpression of RHS(0) that is the
Eric Biedermanb138ac82003-04-22 18:44:01 +0000527 * value of the expression.
528 *
529 * Not seen outside of expressions.
530 */
Eric Biederman90089602004-05-28 14:11:54 +0000531
532#define OP_TUPLE 70
533/* OP_TUPLE is an array of triples that are either variable
534 * or values for a structure or an array. It is used as
535 * a place holder when flattening compound types.
536 * The value represented by an OP_TUPLE is held in N registers.
537 * LHS(0..N-1) refer to those registers.
538 * ->use is a list of statements that use the value.
539 *
540 * Although OP_TUPLE always has register sized pieces they are not
541 * used until structures are flattened/decomposed into their register
542 * components.
543 * ???? registers ????
Eric Biedermanb138ac82003-04-22 18:44:01 +0000544 */
545
Eric Biederman90089602004-05-28 14:11:54 +0000546#define OP_BITREF 71
547/* OP_BITREF describes a bitfield as an lvalue.
548 * RHS(0) holds the register value.
549 * ->type holds the type of the bitfield.
550 * ->u.bitfield.size holds the size of the bitfield.
551 * ->u.bitfield.offset holds the offset of the bitfield in the register
552 */
553
554
555#define OP_FCALL 72
Eric Biederman5ade04a2003-10-22 04:03:46 +0000556/* OP_FCALL performs a procedure call.
Eric Biederman0babc1c2003-05-09 02:39:00 +0000557 * MISC(0) holds a pointer to the OP_LIST of a function
558 * RHS(x) holds argument x of a function
559 *
Eric Biedermanb138ac82003-04-22 18:44:01 +0000560 * Currently not seen outside of expressions.
561 */
Eric Biederman90089602004-05-28 14:11:54 +0000562#define OP_PROG 73
563/* OP_PROG is an expression that holds a list of statements, or
564 * expressions. The final expression is the value of the expression.
565 * RHS(0) holds the start of the list.
Eric Biedermanb138ac82003-04-22 18:44:01 +0000566 */
567
568/* statements */
569#define OP_LIST 80
Eric Biederman5ade04a2003-10-22 04:03:46 +0000570/* OP_LIST Holds a list of statements that compose a function, and a result value.
Eric Biederman0babc1c2003-05-09 02:39:00 +0000571 * RHS(0) holds the list of statements.
Eric Biederman5ade04a2003-10-22 04:03:46 +0000572 * A list of all functions is maintained.
Eric Biedermanb138ac82003-04-22 18:44:01 +0000573 */
574
Eric Biederman5ade04a2003-10-22 04:03:46 +0000575#define OP_BRANCH 81 /* an unconditional branch */
Eric Biedermanb138ac82003-04-22 18:44:01 +0000576/* For branch instructions
Eric Biederman0babc1c2003-05-09 02:39:00 +0000577 * TARG(0) holds the branch target.
Eric Biederman0babc1c2003-05-09 02:39:00 +0000578 * ->next holds where to branch to if the branch is not taken.
Eric Biederman5ade04a2003-10-22 04:03:46 +0000579 * The branch target can only be a label
Eric Biedermanb138ac82003-04-22 18:44:01 +0000580 */
581
Eric Biederman5ade04a2003-10-22 04:03:46 +0000582#define OP_CBRANCH 82 /* a conditional branch */
583/* For conditional branch instructions
584 * RHS(0) holds the branch condition.
585 * TARG(1) holds the branch target.
586 * ->next holds where to branch to if the branch is not taken.
587 * The branch target can only be a label
588 */
589
590#define OP_CALL 83 /* an uncontional branch that will return */
591/* For call instructions
592 * MISC(0) holds the OP_RET that returns from the branch
593 * TARG(0) holds the branch target.
594 * ->next holds where to branch to if the branch is not taken.
595 * The branch target can only be a label
596 */
597
598#define OP_RET 84 /* an uncontinonal branch through a variable back to an OP_CALL */
599/* For call instructions
600 * RHS(0) holds the variable with the return address
601 * The branch target can only be a label
602 */
603
604#define OP_LABEL 86
Eric Biedermanb138ac82003-04-22 18:44:01 +0000605/* OP_LABEL is a triple that establishes an target for branches.
Eric Biederman0babc1c2003-05-09 02:39:00 +0000606 * ->use is the list of all branches that use this label.
Eric Biedermanb138ac82003-04-22 18:44:01 +0000607 */
608
Eric Biederman5ade04a2003-10-22 04:03:46 +0000609#define OP_ADECL 87
610/* OP_ADECL is a triple that establishes an lvalue for assignments.
Eric Biederman90089602004-05-28 14:11:54 +0000611 * A variable takes N registers to contain.
612 * LHS(0..N-1) refer to an OP_PIECE triple that represents
613 * the Xth register that the variable is stored in.
Eric Biederman0babc1c2003-05-09 02:39:00 +0000614 * ->use is a list of statements that use the variable.
Eric Biederman90089602004-05-28 14:11:54 +0000615 *
616 * Although OP_ADECL always has register sized pieces they are not
617 * used until structures are flattened/decomposed into their register
618 * components.
Eric Biedermanb138ac82003-04-22 18:44:01 +0000619 */
620
Eric Biederman5ade04a2003-10-22 04:03:46 +0000621#define OP_SDECL 88
Eric Biederman6aa31cc2003-06-10 21:22:07 +0000622/* OP_SDECL is a triple that establishes a variable of static
Eric Biedermanb138ac82003-04-22 18:44:01 +0000623 * storage duration.
Eric Biederman0babc1c2003-05-09 02:39:00 +0000624 * ->use is a list of statements that use the variable.
625 * MISC(0) holds the initializer expression.
Eric Biedermanb138ac82003-04-22 18:44:01 +0000626 */
627
628
Eric Biederman5ade04a2003-10-22 04:03:46 +0000629#define OP_PHI 89
Eric Biedermanb138ac82003-04-22 18:44:01 +0000630/* OP_PHI is a triple used in SSA form code.
631 * It is used when multiple code paths merge and a variable needs
632 * a single assignment from any of those code paths.
633 * The operation is a cross between OP_DECL and OP_WRITE, which
Eric Biederman5ade04a2003-10-22 04:03:46 +0000634 * is what OP_PHI is generated from.
Eric Biedermanb138ac82003-04-22 18:44:01 +0000635 *
Eric Biederman0babc1c2003-05-09 02:39:00 +0000636 * RHS(x) points to the value from code path x
637 * The number of RHS entries is the number of control paths into the block
Eric Biedermanb138ac82003-04-22 18:44:01 +0000638 * in which OP_PHI resides. The elements of the array point to point
639 * to the variables OP_PHI is derived from.
640 *
Eric Biederman0babc1c2003-05-09 02:39:00 +0000641 * MISC(0) holds a pointer to the orginal OP_DECL node.
Eric Biedermanb138ac82003-04-22 18:44:01 +0000642 */
643
Eric Biederman90089602004-05-28 14:11:54 +0000644#if 0
645/* continuation helpers
646 */
647#define OP_CPS_BRANCH 90 /* an unconditional branch */
648/* OP_CPS_BRANCH calls a continuation
649 * RHS(x) holds argument x of the function
650 * TARG(0) holds OP_CPS_START target
651 */
652#define OP_CPS_CBRANCH 91 /* a conditional branch */
653/* OP_CPS_CBRANCH conditionally calls one of two continuations
654 * RHS(0) holds the branch condition
655 * RHS(x + 1) holds argument x of the function
656 * TARG(0) holds the OP_CPS_START to jump to when true
657 * ->next holds the OP_CPS_START to jump to when false
658 */
659#define OP_CPS_CALL 92 /* an uncontional branch that will return */
660/* For OP_CPS_CALL instructions
661 * RHS(x) holds argument x of the function
662 * MISC(0) holds the OP_CPS_RET that returns from the branch
663 * TARG(0) holds the branch target.
664 * ->next holds where the OP_CPS_RET will return to.
665 */
666#define OP_CPS_RET 93
667/* OP_CPS_RET conditionally calls one of two continuations
668 * RHS(0) holds the variable with the return function address
669 * RHS(x + 1) holds argument x of the function
670 * The branch target may be any OP_CPS_START
671 */
672#define OP_CPS_END 94
673/* OP_CPS_END is the triple at the end of the program.
674 * For most practical purposes it is a branch.
675 */
676#define OP_CPS_START 95
677/* OP_CPS_START is a triple at the start of a continuation
678 * The arguments variables takes N registers to contain.
679 * LHS(0..N-1) refer to an OP_PIECE triple that represents
680 * the Xth register that the arguments are stored in.
681 */
682#endif
683
Eric Biedermanb138ac82003-04-22 18:44:01 +0000684/* Architecture specific instructions */
685#define OP_CMP 100
686#define OP_TEST 101
687#define OP_SET_EQ 102
688#define OP_SET_NOTEQ 103
689#define OP_SET_SLESS 104
690#define OP_SET_ULESS 105
691#define OP_SET_SMORE 106
692#define OP_SET_UMORE 107
693#define OP_SET_SLESSEQ 108
694#define OP_SET_ULESSEQ 109
695#define OP_SET_SMOREEQ 110
696#define OP_SET_UMOREEQ 111
697
698#define OP_JMP 112
699#define OP_JMP_EQ 113
700#define OP_JMP_NOTEQ 114
701#define OP_JMP_SLESS 115
702#define OP_JMP_ULESS 116
703#define OP_JMP_SMORE 117
704#define OP_JMP_UMORE 118
705#define OP_JMP_SLESSEQ 119
706#define OP_JMP_ULESSEQ 120
707#define OP_JMP_SMOREEQ 121
708#define OP_JMP_UMOREEQ 122
709
710/* Builtin operators that it is just simpler to use the compiler for */
711#define OP_INB 130
712#define OP_INW 131
713#define OP_INL 132
714#define OP_OUTB 133
715#define OP_OUTW 134
716#define OP_OUTL 135
717#define OP_BSF 136
718#define OP_BSR 137
Eric Biedermanb138ac82003-04-22 18:44:01 +0000719#define OP_RDMSR 138
720#define OP_WRMSR 139
Eric Biedermanb138ac82003-04-22 18:44:01 +0000721#define OP_HLT 140
722
Eric Biederman0babc1c2003-05-09 02:39:00 +0000723struct op_info {
724 const char *name;
725 unsigned flags;
Eric Biederman90089602004-05-28 14:11:54 +0000726#define PURE 0x001 /* Triple has no side effects */
727#define IMPURE 0x002 /* Triple has side effects */
Eric Biederman0babc1c2003-05-09 02:39:00 +0000728#define PURE_BITS(FLAGS) ((FLAGS) & 0x3)
Eric Biederman90089602004-05-28 14:11:54 +0000729#define DEF 0x004 /* Triple is a variable definition */
730#define BLOCK 0x008 /* Triple stores the current block */
731#define STRUCTURAL 0x010 /* Triple does not generate a machine instruction */
732#define BRANCH_BITS(FLAGS) ((FLAGS) & 0xe0 )
733#define UBRANCH 0x020 /* Triple is an unconditional branch instruction */
734#define CBRANCH 0x040 /* Triple is a conditional branch instruction */
735#define RETBRANCH 0x060 /* Triple is a return instruction */
736#define CALLBRANCH 0x080 /* Triple is a call instruction */
737#define ENDBRANCH 0x0a0 /* Triple is an end instruction */
738#define PART 0x100 /* Triple is really part of another triple */
739#define BITFIELD 0x200 /* Triple manipulates a bitfield */
740 signed char lhs, rhs, misc, targ;
Eric Biedermanb138ac82003-04-22 18:44:01 +0000741};
742
Eric Biederman0babc1c2003-05-09 02:39:00 +0000743#define OP(LHS, RHS, MISC, TARG, FLAGS, NAME) { \
744 .name = (NAME), \
745 .flags = (FLAGS), \
746 .lhs = (LHS), \
747 .rhs = (RHS), \
748 .misc = (MISC), \
749 .targ = (TARG), \
750 }
751static const struct op_info table_ops[] = {
Eric Biederman530b5192003-07-01 10:05:30 +0000752[OP_SDIVT ] = OP( 2, 2, 0, 0, PURE | BLOCK , "sdivt"),
753[OP_UDIVT ] = OP( 2, 2, 0, 0, PURE | BLOCK , "udivt"),
Eric Biederman6aa31cc2003-06-10 21:22:07 +0000754[OP_SMUL ] = OP( 0, 2, 0, 0, PURE | DEF | BLOCK , "smul"),
755[OP_UMUL ] = OP( 0, 2, 0, 0, PURE | DEF | BLOCK , "umul"),
756[OP_SDIV ] = OP( 0, 2, 0, 0, PURE | DEF | BLOCK , "sdiv"),
757[OP_UDIV ] = OP( 0, 2, 0, 0, PURE | DEF | BLOCK , "udiv"),
758[OP_SMOD ] = OP( 0, 2, 0, 0, PURE | DEF | BLOCK , "smod"),
759[OP_UMOD ] = OP( 0, 2, 0, 0, PURE | DEF | BLOCK , "umod"),
760[OP_ADD ] = OP( 0, 2, 0, 0, PURE | DEF | BLOCK , "add"),
761[OP_SUB ] = OP( 0, 2, 0, 0, PURE | DEF | BLOCK , "sub"),
762[OP_SL ] = OP( 0, 2, 0, 0, PURE | DEF | BLOCK , "sl"),
763[OP_USR ] = OP( 0, 2, 0, 0, PURE | DEF | BLOCK , "usr"),
764[OP_SSR ] = OP( 0, 2, 0, 0, PURE | DEF | BLOCK , "ssr"),
765[OP_AND ] = OP( 0, 2, 0, 0, PURE | DEF | BLOCK , "and"),
766[OP_XOR ] = OP( 0, 2, 0, 0, PURE | DEF | BLOCK , "xor"),
767[OP_OR ] = OP( 0, 2, 0, 0, PURE | DEF | BLOCK , "or"),
768[OP_POS ] = OP( 0, 1, 0, 0, PURE | DEF | BLOCK , "pos"),
769[OP_NEG ] = OP( 0, 1, 0, 0, PURE | DEF | BLOCK , "neg"),
770[OP_INVERT ] = OP( 0, 1, 0, 0, PURE | DEF | BLOCK , "invert"),
Eric Biedermanb138ac82003-04-22 18:44:01 +0000771
Eric Biederman6aa31cc2003-06-10 21:22:07 +0000772[OP_EQ ] = OP( 0, 2, 0, 0, PURE | DEF | BLOCK , "eq"),
773[OP_NOTEQ ] = OP( 0, 2, 0, 0, PURE | DEF | BLOCK , "noteq"),
774[OP_SLESS ] = OP( 0, 2, 0, 0, PURE | DEF | BLOCK , "sless"),
775[OP_ULESS ] = OP( 0, 2, 0, 0, PURE | DEF | BLOCK , "uless"),
776[OP_SMORE ] = OP( 0, 2, 0, 0, PURE | DEF | BLOCK , "smore"),
777[OP_UMORE ] = OP( 0, 2, 0, 0, PURE | DEF | BLOCK , "umore"),
778[OP_SLESSEQ ] = OP( 0, 2, 0, 0, PURE | DEF | BLOCK , "slesseq"),
779[OP_ULESSEQ ] = OP( 0, 2, 0, 0, PURE | DEF | BLOCK , "ulesseq"),
780[OP_SMOREEQ ] = OP( 0, 2, 0, 0, PURE | DEF | BLOCK , "smoreeq"),
781[OP_UMOREEQ ] = OP( 0, 2, 0, 0, PURE | DEF | BLOCK , "umoreeq"),
782[OP_LFALSE ] = OP( 0, 1, 0, 0, PURE | DEF | BLOCK , "lfalse"),
783[OP_LTRUE ] = OP( 0, 1, 0, 0, PURE | DEF | BLOCK , "ltrue"),
Eric Biederman0babc1c2003-05-09 02:39:00 +0000784
Eric Biederman90089602004-05-28 14:11:54 +0000785[OP_LOAD ] = OP( 0, 1, 0, 0, PURE | DEF | BLOCK, "load"),
786[OP_STORE ] = OP( 0, 2, 0, 0, PURE | BLOCK , "store"),
787
788[OP_UEXTRACT ] = OP( 0, 1, 0, 0, PURE | DEF | BITFIELD, "uextract"),
789[OP_SEXTRACT ] = OP( 0, 1, 0, 0, PURE | DEF | BITFIELD, "sextract"),
790[OP_DEPOSIT ] = OP( 0, 2, 0, 0, PURE | DEF | BITFIELD, "deposit"),
Eric Biederman0babc1c2003-05-09 02:39:00 +0000791
Eric Biederman83b991a2003-10-11 06:20:25 +0000792[OP_NOOP ] = OP( 0, 0, 0, 0, PURE | BLOCK | STRUCTURAL, "noop"),
Eric Biederman0babc1c2003-05-09 02:39:00 +0000793
Eric Biederman6aa31cc2003-06-10 21:22:07 +0000794[OP_INTCONST ] = OP( 0, 0, 0, 0, PURE | DEF, "intconst"),
Eric Biederman83b991a2003-10-11 06:20:25 +0000795[OP_BLOBCONST ] = OP( 0, 0, 0, 0, PURE , "blobconst"),
Eric Biederman6aa31cc2003-06-10 21:22:07 +0000796[OP_ADDRCONST ] = OP( 0, 0, 1, 0, PURE | DEF, "addrconst"),
Eric Biederman90089602004-05-28 14:11:54 +0000797[OP_UNKNOWNVAL ] = OP( 0, 0, 0, 0, PURE | DEF, "unknown"),
Eric Biederman0babc1c2003-05-09 02:39:00 +0000798
Eric Biederman90089602004-05-28 14:11:54 +0000799#warning "FIXME is it correct for OP_WRITE to be a def? I currently use it as one..."
800[OP_WRITE ] = OP( 0, 1, 1, 0, PURE | DEF | BLOCK, "write"),
Eric Biederman6aa31cc2003-06-10 21:22:07 +0000801[OP_READ ] = OP( 0, 1, 0, 0, PURE | DEF | BLOCK, "read"),
802[OP_COPY ] = OP( 0, 1, 0, 0, PURE | DEF | BLOCK, "copy"),
Eric Biederman90089602004-05-28 14:11:54 +0000803[OP_CONVERT ] = OP( 0, 1, 0, 0, PURE | DEF | BLOCK, "convert"),
804[OP_PIECE ] = OP( 0, 0, 1, 0, PURE | DEF | STRUCTURAL | PART, "piece"),
805[OP_ASM ] = OP(-1, -1, 0, 0, PURE, "asm"),
Eric Biederman6aa31cc2003-06-10 21:22:07 +0000806[OP_DEREF ] = OP( 0, 1, 0, 0, 0 | DEF | BLOCK, "deref"),
Eric Biederman90089602004-05-28 14:11:54 +0000807[OP_DOT ] = OP( 0, 0, 1, 0, PURE | DEF | PART, "dot"),
808[OP_INDEX ] = OP( 0, 0, 1, 0, PURE | DEF | PART, "index"),
Eric Biederman0babc1c2003-05-09 02:39:00 +0000809
Eric Biederman6aa31cc2003-06-10 21:22:07 +0000810[OP_VAL ] = OP( 0, 1, 1, 0, 0 | DEF | BLOCK, "val"),
Eric Biederman90089602004-05-28 14:11:54 +0000811[OP_TUPLE ] = OP(-1, 0, 0, 0, 0 | PURE | BLOCK | STRUCTURAL, "tuple"),
812[OP_BITREF ] = OP( 0, 1, 0, 0, 0 | DEF | PURE | STRUCTURAL | BITFIELD, "bitref"),
Eric Biederman0babc1c2003-05-09 02:39:00 +0000813/* Call is special most it can stand in for anything so it depends on context */
Eric Biederman90089602004-05-28 14:11:54 +0000814[OP_FCALL ] = OP( 0, -1, 1, 0, 0 | BLOCK | CALLBRANCH, "fcall"),
815[OP_PROG ] = OP( 0, 1, 0, 0, 0 | IMPURE | BLOCK | STRUCTURAL, "prog"),
816/* The sizes of OP_FCALL depends upon context */
Eric Biederman0babc1c2003-05-09 02:39:00 +0000817
Eric Biederman83b991a2003-10-11 06:20:25 +0000818[OP_LIST ] = OP( 0, 1, 1, 0, 0 | DEF | STRUCTURAL, "list"),
Eric Biederman90089602004-05-28 14:11:54 +0000819[OP_BRANCH ] = OP( 0, 0, 0, 1, PURE | BLOCK | UBRANCH, "branch"),
820[OP_CBRANCH ] = OP( 0, 1, 0, 1, PURE | BLOCK | CBRANCH, "cbranch"),
821[OP_CALL ] = OP( 0, 0, 1, 1, PURE | BLOCK | CALLBRANCH, "call"),
822[OP_RET ] = OP( 0, 1, 0, 0, PURE | BLOCK | RETBRANCH, "ret"),
Eric Biederman83b991a2003-10-11 06:20:25 +0000823[OP_LABEL ] = OP( 0, 0, 0, 0, PURE | BLOCK | STRUCTURAL, "label"),
824[OP_ADECL ] = OP( 0, 0, 0, 0, PURE | BLOCK | STRUCTURAL, "adecl"),
825[OP_SDECL ] = OP( 0, 0, 1, 0, PURE | BLOCK | STRUCTURAL, "sdecl"),
Eric Biederman0babc1c2003-05-09 02:39:00 +0000826/* The number of RHS elements of OP_PHI depend upon context */
Eric Biederman6aa31cc2003-06-10 21:22:07 +0000827[OP_PHI ] = OP( 0, -1, 1, 0, PURE | DEF | BLOCK, "phi"),
Eric Biederman0babc1c2003-05-09 02:39:00 +0000828
Eric Biederman90089602004-05-28 14:11:54 +0000829#if 0
830[OP_CPS_BRANCH ] = OP( 0, -1, 0, 1, PURE | BLOCK | UBRANCH, "cps_branch"),
831[OP_CPS_CBRANCH] = OP( 0, -1, 0, 1, PURE | BLOCK | CBRANCH, "cps_cbranch"),
832[OP_CPS_CALL ] = OP( 0, -1, 1, 1, PURE | BLOCK | CALLBRANCH, "cps_call"),
833[OP_CPS_RET ] = OP( 0, -1, 0, 0, PURE | BLOCK | RETBRANCH, "cps_ret"),
834[OP_CPS_END ] = OP( 0, -1, 0, 0, IMPURE | BLOCK | ENDBRANCH, "cps_end"),
835[OP_CPS_START ] = OP( -1, 0, 0, 0, PURE | BLOCK | STRUCTURAL, "cps_start"),
836#endif
837
Eric Biederman6aa31cc2003-06-10 21:22:07 +0000838[OP_CMP ] = OP( 0, 2, 0, 0, PURE | DEF | BLOCK, "cmp"),
839[OP_TEST ] = OP( 0, 1, 0, 0, PURE | DEF | BLOCK, "test"),
840[OP_SET_EQ ] = OP( 0, 1, 0, 0, PURE | DEF | BLOCK, "set_eq"),
841[OP_SET_NOTEQ ] = OP( 0, 1, 0, 0, PURE | DEF | BLOCK, "set_noteq"),
842[OP_SET_SLESS ] = OP( 0, 1, 0, 0, PURE | DEF | BLOCK, "set_sless"),
843[OP_SET_ULESS ] = OP( 0, 1, 0, 0, PURE | DEF | BLOCK, "set_uless"),
844[OP_SET_SMORE ] = OP( 0, 1, 0, 0, PURE | DEF | BLOCK, "set_smore"),
845[OP_SET_UMORE ] = OP( 0, 1, 0, 0, PURE | DEF | BLOCK, "set_umore"),
846[OP_SET_SLESSEQ] = OP( 0, 1, 0, 0, PURE | DEF | BLOCK, "set_slesseq"),
847[OP_SET_ULESSEQ] = OP( 0, 1, 0, 0, PURE | DEF | BLOCK, "set_ulesseq"),
848[OP_SET_SMOREEQ] = OP( 0, 1, 0, 0, PURE | DEF | BLOCK, "set_smoreq"),
849[OP_SET_UMOREEQ] = OP( 0, 1, 0, 0, PURE | DEF | BLOCK, "set_umoreq"),
Eric Biederman90089602004-05-28 14:11:54 +0000850[OP_JMP ] = OP( 0, 0, 0, 1, PURE | BLOCK | UBRANCH, "jmp"),
851[OP_JMP_EQ ] = OP( 0, 1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_eq"),
852[OP_JMP_NOTEQ ] = OP( 0, 1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_noteq"),
853[OP_JMP_SLESS ] = OP( 0, 1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_sless"),
854[OP_JMP_ULESS ] = OP( 0, 1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_uless"),
855[OP_JMP_SMORE ] = OP( 0, 1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_smore"),
856[OP_JMP_UMORE ] = OP( 0, 1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_umore"),
857[OP_JMP_SLESSEQ] = OP( 0, 1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_slesseq"),
858[OP_JMP_ULESSEQ] = OP( 0, 1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_ulesseq"),
859[OP_JMP_SMOREEQ] = OP( 0, 1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_smoreq"),
860[OP_JMP_UMOREEQ] = OP( 0, 1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_umoreq"),
Eric Biederman0babc1c2003-05-09 02:39:00 +0000861
Eric Biederman6aa31cc2003-06-10 21:22:07 +0000862[OP_INB ] = OP( 0, 1, 0, 0, IMPURE | DEF | BLOCK, "__inb"),
863[OP_INW ] = OP( 0, 1, 0, 0, IMPURE | DEF | BLOCK, "__inw"),
864[OP_INL ] = OP( 0, 1, 0, 0, IMPURE | DEF | BLOCK, "__inl"),
865[OP_OUTB ] = OP( 0, 2, 0, 0, IMPURE| BLOCK, "__outb"),
866[OP_OUTW ] = OP( 0, 2, 0, 0, IMPURE| BLOCK, "__outw"),
867[OP_OUTL ] = OP( 0, 2, 0, 0, IMPURE| BLOCK, "__outl"),
868[OP_BSF ] = OP( 0, 1, 0, 0, PURE | DEF | BLOCK, "__bsf"),
869[OP_BSR ] = OP( 0, 1, 0, 0, PURE | DEF | BLOCK, "__bsr"),
870[OP_RDMSR ] = OP( 2, 1, 0, 0, IMPURE | BLOCK, "__rdmsr"),
871[OP_WRMSR ] = OP( 0, 3, 0, 0, IMPURE | BLOCK, "__wrmsr"),
872[OP_HLT ] = OP( 0, 0, 0, 0, IMPURE | BLOCK, "__hlt"),
Eric Biederman0babc1c2003-05-09 02:39:00 +0000873};
874#undef OP
875#define OP_MAX (sizeof(table_ops)/sizeof(table_ops[0]))
Eric Biedermanb138ac82003-04-22 18:44:01 +0000876
877static const char *tops(int index)
878{
879 static const char unknown[] = "unknown op";
880 if (index < 0) {
881 return unknown;
882 }
883 if (index > OP_MAX) {
884 return unknown;
885 }
Eric Biederman0babc1c2003-05-09 02:39:00 +0000886 return table_ops[index].name;
Eric Biedermanb138ac82003-04-22 18:44:01 +0000887}
888
Eric Biederman6aa31cc2003-06-10 21:22:07 +0000889struct asm_info;
Eric Biedermanb138ac82003-04-22 18:44:01 +0000890struct triple;
891struct block;
892struct triple_set {
893 struct triple_set *next;
894 struct triple *member;
895};
896
Eric Biederman90089602004-05-28 14:11:54 +0000897#define MAX_LHS 63
898#define MAX_RHS 127
Eric Biederman678d8162003-07-03 03:59:38 +0000899#define MAX_MISC 3
Eric Biederman90089602004-05-28 14:11:54 +0000900#define MAX_TARG 1
Eric Biederman0babc1c2003-05-09 02:39:00 +0000901
Eric Biedermanf7a0ba82003-06-19 15:14:52 +0000902struct occurance {
903 int count;
904 const char *filename;
905 const char *function;
906 int line;
907 int col;
908 struct occurance *parent;
909};
Eric Biederman90089602004-05-28 14:11:54 +0000910struct bitfield {
911 ulong_t size : 8;
912 ulong_t offset : 24;
913};
Eric Biedermanb138ac82003-04-22 18:44:01 +0000914struct triple {
915 struct triple *next, *prev;
916 struct triple_set *use;
917 struct type *type;
Eric Biederman90089602004-05-28 14:11:54 +0000918 unsigned int op : 8;
919 unsigned int template_id : 7;
920 unsigned int lhs : 6;
921 unsigned int rhs : 7;
922 unsigned int misc : 2;
923 unsigned int targ : 1;
924#define TRIPLE_SIZE(TRIPLE) \
925 ((TRIPLE)->lhs + (TRIPLE)->rhs + (TRIPLE)->misc + (TRIPLE)->targ)
926#define TRIPLE_LHS_OFF(PTR) (0)
927#define TRIPLE_RHS_OFF(PTR) (TRIPLE_LHS_OFF(PTR) + (PTR)->lhs)
928#define TRIPLE_MISC_OFF(PTR) (TRIPLE_RHS_OFF(PTR) + (PTR)->rhs)
929#define TRIPLE_TARG_OFF(PTR) (TRIPLE_MISC_OFF(PTR) + (PTR)->misc)
930#define LHS(PTR,INDEX) ((PTR)->param[TRIPLE_LHS_OFF(PTR) + (INDEX)])
931#define RHS(PTR,INDEX) ((PTR)->param[TRIPLE_RHS_OFF(PTR) + (INDEX)])
932#define TARG(PTR,INDEX) ((PTR)->param[TRIPLE_TARG_OFF(PTR) + (INDEX)])
933#define MISC(PTR,INDEX) ((PTR)->param[TRIPLE_MISC_OFF(PTR) + (INDEX)])
Eric Biedermanb138ac82003-04-22 18:44:01 +0000934 unsigned id; /* A scratch value and finally the register */
Eric Biederman6aa31cc2003-06-10 21:22:07 +0000935#define TRIPLE_FLAG_FLATTENED (1 << 31)
936#define TRIPLE_FLAG_PRE_SPLIT (1 << 30)
937#define TRIPLE_FLAG_POST_SPLIT (1 << 29)
Eric Biederman83b991a2003-10-11 06:20:25 +0000938#define TRIPLE_FLAG_VOLATILE (1 << 28)
Eric Biederman90089602004-05-28 14:11:54 +0000939#define TRIPLE_FLAG_INLINE (1 << 27) /* ???? */
940#define TRIPLE_FLAG_LOCAL (1 << 26)
941
942#define TRIPLE_FLAG_COPY TRIPLE_FLAG_VOLATILE
Eric Biedermanf7a0ba82003-06-19 15:14:52 +0000943 struct occurance *occurance;
Eric Biedermanb138ac82003-04-22 18:44:01 +0000944 union {
945 ulong_t cval;
Eric Biederman90089602004-05-28 14:11:54 +0000946 struct bitfield bitfield;
Eric Biedermanb138ac82003-04-22 18:44:01 +0000947 struct block *block;
948 void *blob;
Eric Biederman0babc1c2003-05-09 02:39:00 +0000949 struct hash_entry *field;
Eric Biederman6aa31cc2003-06-10 21:22:07 +0000950 struct asm_info *ainfo;
Eric Biederman90089602004-05-28 14:11:54 +0000951 struct triple *func;
952 struct symbol *symbol;
Eric Biedermanb138ac82003-04-22 18:44:01 +0000953 } u;
Eric Biederman0babc1c2003-05-09 02:39:00 +0000954 struct triple *param[2];
Eric Biedermanb138ac82003-04-22 18:44:01 +0000955};
956
Eric Biederman6aa31cc2003-06-10 21:22:07 +0000957struct reg_info {
958 unsigned reg;
959 unsigned regcm;
960};
961struct ins_template {
962 struct reg_info lhs[MAX_LHS + 1], rhs[MAX_RHS + 1];
963};
964
965struct asm_info {
966 struct ins_template tmpl;
967 char *str;
968};
969
Eric Biedermanb138ac82003-04-22 18:44:01 +0000970struct block_set {
971 struct block_set *next;
972 struct block *member;
973};
974struct block {
975 struct block *work_next;
Eric Biedermanb138ac82003-04-22 18:44:01 +0000976 struct triple *first, *last;
Eric Biederman5ade04a2003-10-22 04:03:46 +0000977 int edge_count;
978 struct block_set *edges;
Eric Biedermanb138ac82003-04-22 18:44:01 +0000979 int users;
980 struct block_set *use;
981 struct block_set *idominates;
982 struct block_set *domfrontier;
983 struct block *idom;
984 struct block_set *ipdominates;
985 struct block_set *ipdomfrontier;
986 struct block *ipdom;
987 int vertex;
988
989};
990
991struct symbol {
992 struct symbol *next;
993 struct hash_entry *ident;
994 struct triple *def;
995 struct type *type;
996 int scope_depth;
997};
998
Eric Biederman90089602004-05-28 14:11:54 +0000999struct macro_arg {
1000 struct macro_arg *next;
1001 struct hash_entry *ident;
1002};
Eric Biedermanb138ac82003-04-22 18:44:01 +00001003struct macro {
1004 struct hash_entry *ident;
1005 char *buf;
1006 int buf_len;
Eric Biederman90089602004-05-28 14:11:54 +00001007 int buf_off;
1008 struct macro_arg *args;
1009 int argc;
Eric Biedermanb138ac82003-04-22 18:44:01 +00001010};
1011
1012struct hash_entry {
1013 struct hash_entry *next;
1014 const char *name;
1015 int name_len;
1016 int tok;
1017 struct macro *sym_define;
1018 struct symbol *sym_label;
Eric Biederman83b991a2003-10-11 06:20:25 +00001019 struct symbol *sym_tag;
Eric Biedermanb138ac82003-04-22 18:44:01 +00001020 struct symbol *sym_ident;
1021};
1022
1023#define HASH_TABLE_SIZE 2048
1024
Eric Biederman5ade04a2003-10-22 04:03:46 +00001025struct compiler_state {
Eric Biederman05f26fc2003-06-11 21:55:00 +00001026 const char *label_prefix;
Eric Biederman6aa31cc2003-06-10 21:22:07 +00001027 const char *ofilename;
Eric Biederman5ade04a2003-10-22 04:03:46 +00001028 unsigned long flags;
1029 unsigned long debug;
1030 unsigned long max_allocation_passes;
Eric Biederman90089602004-05-28 14:11:54 +00001031
1032 size_t include_path_count;
1033 const char **include_paths;
1034
1035 size_t define_count;
1036 const char **defines;
1037
1038 size_t undef_count;
1039 const char **undefs;
Eric Biederman5ade04a2003-10-22 04:03:46 +00001040};
1041struct arch_state {
1042 unsigned long features;
1043};
Eric Biederman90089602004-05-28 14:11:54 +00001044struct basic_blocks {
1045 struct triple *func;
1046 struct triple *first;
1047 struct block *first_block, *last_block;
1048 int last_vertex;
1049};
1050#define MAX_CPP_IF_DEPTH 63
Eric Biederman5ade04a2003-10-22 04:03:46 +00001051struct compile_state {
1052 struct compiler_state *compiler;
1053 struct arch_state *arch;
Eric Biederman6aa31cc2003-06-10 21:22:07 +00001054 FILE *output;
Eric Biederman90089602004-05-28 14:11:54 +00001055 FILE *errout;
1056 FILE *dbgout;
Eric Biedermanb138ac82003-04-22 18:44:01 +00001057 struct file_state *file;
Eric Biedermanf7a0ba82003-06-19 15:14:52 +00001058 struct occurance *last_occurance;
1059 const char *function;
Eric Biedermanb138ac82003-04-22 18:44:01 +00001060 struct token token[4];
1061 struct hash_entry *hash_table[HASH_TABLE_SIZE];
Eric Biederman83b991a2003-10-11 06:20:25 +00001062 struct hash_entry *i_switch;
1063 struct hash_entry *i_case;
Eric Biedermanb138ac82003-04-22 18:44:01 +00001064 struct hash_entry *i_continue;
1065 struct hash_entry *i_break;
Eric Biederman83b991a2003-10-11 06:20:25 +00001066 struct hash_entry *i_default;
Eric Biederman5ade04a2003-10-22 04:03:46 +00001067 struct hash_entry *i_return;
Eric Biederman90089602004-05-28 14:11:54 +00001068 /* Additional hash entries for predefined macros */
1069 struct hash_entry *i_defined;
1070 struct hash_entry *i___VA_ARGS__;
1071 struct hash_entry *i___FILE__;
1072 struct hash_entry *i___LINE__;
1073 /* Additional hash entries for predefined identifiers */
1074 struct hash_entry *i___func__;
1075 /* Additional hash entries for attributes */
1076 struct hash_entry *i_noinline;
1077 struct hash_entry *i_always_inline;
Eric Biedermanb138ac82003-04-22 18:44:01 +00001078 int scope_depth;
Eric Biederman90089602004-05-28 14:11:54 +00001079 unsigned char if_bytes[(MAX_CPP_IF_DEPTH + CHAR_BIT -1)/CHAR_BIT];
1080 int if_depth;
1081 int eat_depth, eat_targ;
Eric Biedermanb138ac82003-04-22 18:44:01 +00001082 int macro_line;
1083 struct file_state *macro_file;
Eric Biederman5ade04a2003-10-22 04:03:46 +00001084 struct triple *functions;
Eric Biedermanb138ac82003-04-22 18:44:01 +00001085 struct triple *main_function;
Eric Biederman83b991a2003-10-11 06:20:25 +00001086 struct triple *first;
Eric Biederman5ade04a2003-10-22 04:03:46 +00001087 struct triple *global_pool;
Eric Biederman90089602004-05-28 14:11:54 +00001088 struct basic_blocks bb;
1089 int functions_joined;
Eric Biedermanb138ac82003-04-22 18:44:01 +00001090};
1091
Eric Biederman0babc1c2003-05-09 02:39:00 +00001092/* visibility global/local */
1093/* static/auto duration */
1094/* typedef, register, inline */
1095#define STOR_SHIFT 0
Eric Biederman5ade04a2003-10-22 04:03:46 +00001096#define STOR_MASK 0x001f
Eric Biederman0babc1c2003-05-09 02:39:00 +00001097/* Visibility */
1098#define STOR_GLOBAL 0x0001
1099/* Duration */
1100#define STOR_PERM 0x0002
Eric Biederman5ade04a2003-10-22 04:03:46 +00001101/* Definition locality */
1102#define STOR_NONLOCAL 0x0004 /* The definition is not in this translation unit */
Eric Biederman0babc1c2003-05-09 02:39:00 +00001103/* Storage specifiers */
1104#define STOR_AUTO 0x0000
1105#define STOR_STATIC 0x0002
Eric Biederman5ade04a2003-10-22 04:03:46 +00001106#define STOR_LOCAL 0x0003
1107#define STOR_EXTERN 0x0007
1108#define STOR_INLINE 0x0008
1109#define STOR_REGISTER 0x0010
1110#define STOR_TYPEDEF 0x0018
Eric Biederman0babc1c2003-05-09 02:39:00 +00001111
Eric Biederman5ade04a2003-10-22 04:03:46 +00001112#define QUAL_SHIFT 5
1113#define QUAL_MASK 0x00e0
Eric Biederman0babc1c2003-05-09 02:39:00 +00001114#define QUAL_NONE 0x0000
Eric Biederman5ade04a2003-10-22 04:03:46 +00001115#define QUAL_CONST 0x0020
1116#define QUAL_VOLATILE 0x0040
1117#define QUAL_RESTRICT 0x0080
Eric Biederman0babc1c2003-05-09 02:39:00 +00001118
1119#define TYPE_SHIFT 8
1120#define TYPE_MASK 0x1f00
Eric Biederman90089602004-05-28 14:11:54 +00001121#define TYPE_INTEGER(TYPE) ((((TYPE) >= TYPE_CHAR) && ((TYPE) <= TYPE_ULLONG)) || ((TYPE) == TYPE_ENUM) || ((TYPE) == TYPE_BITFIELD))
1122#define TYPE_ARITHMETIC(TYPE) ((((TYPE) >= TYPE_CHAR) && ((TYPE) <= TYPE_LDOUBLE)) || ((TYPE) == TYPE_ENUM) || ((TYPE) == TYPE_BITFIELD))
Eric Biederman0babc1c2003-05-09 02:39:00 +00001123#define TYPE_UNSIGNED(TYPE) ((TYPE) & 0x0100)
1124#define TYPE_SIGNED(TYPE) (!TYPE_UNSIGNED(TYPE))
Eric Biederman83b991a2003-10-11 06:20:25 +00001125#define TYPE_MKUNSIGNED(TYPE) (((TYPE) & ~0xF000) | 0x0100)
1126#define TYPE_RANK(TYPE) ((TYPE) & ~0xF1FF)
Eric Biederman0babc1c2003-05-09 02:39:00 +00001127#define TYPE_PTR(TYPE) (((TYPE) & TYPE_MASK) == TYPE_POINTER)
1128#define TYPE_DEFAULT 0x0000
1129#define TYPE_VOID 0x0100
1130#define TYPE_CHAR 0x0200
1131#define TYPE_UCHAR 0x0300
1132#define TYPE_SHORT 0x0400
1133#define TYPE_USHORT 0x0500
1134#define TYPE_INT 0x0600
1135#define TYPE_UINT 0x0700
1136#define TYPE_LONG 0x0800
1137#define TYPE_ULONG 0x0900
1138#define TYPE_LLONG 0x0a00 /* long long */
1139#define TYPE_ULLONG 0x0b00
1140#define TYPE_FLOAT 0x0c00
1141#define TYPE_DOUBLE 0x0d00
1142#define TYPE_LDOUBLE 0x0e00 /* long double */
Eric Biederman83b991a2003-10-11 06:20:25 +00001143
1144/* Note: TYPE_ENUM is chosen very carefully so TYPE_RANK works */
1145#define TYPE_ENUM 0x1600
1146#define TYPE_LIST 0x1700
1147/* TYPE_LIST is a basic building block when defining enumerations
1148 * type->field_ident holds the name of this enumeration entry.
1149 * type->right holds the entry in the list.
1150 */
1151
Eric Biederman0babc1c2003-05-09 02:39:00 +00001152#define TYPE_STRUCT 0x1000
Eric Biederman90089602004-05-28 14:11:54 +00001153/* For TYPE_STRUCT
1154 * type->left holds the link list of TYPE_PRODUCT entries that
1155 * make up the structure.
1156 * type->elements hold the length of the linked list
1157 */
Eric Biederman83b991a2003-10-11 06:20:25 +00001158#define TYPE_UNION 0x1100
Eric Biederman90089602004-05-28 14:11:54 +00001159/* For TYPE_UNION
1160 * type->left holds the link list of TYPE_OVERLAP entries that
1161 * make up the union.
1162 * type->elements hold the length of the linked list
1163 */
Eric Biederman0babc1c2003-05-09 02:39:00 +00001164#define TYPE_POINTER 0x1200
1165/* For TYPE_POINTER:
1166 * type->left holds the type pointed to.
1167 */
1168#define TYPE_FUNCTION 0x1300
1169/* For TYPE_FUNCTION:
1170 * type->left holds the return type.
Eric Biederman90089602004-05-28 14:11:54 +00001171 * type->right holds the type of the arguments
1172 * type->elements holds the count of the arguments
Eric Biederman0babc1c2003-05-09 02:39:00 +00001173 */
1174#define TYPE_PRODUCT 0x1400
1175/* TYPE_PRODUCT is a basic building block when defining structures
1176 * type->left holds the type that appears first in memory.
1177 * type->right holds the type that appears next in memory.
1178 */
1179#define TYPE_OVERLAP 0x1500
1180/* TYPE_OVERLAP is a basic building block when defining unions
1181 * type->left and type->right holds to types that overlap
1182 * each other in memory.
1183 */
Eric Biederman83b991a2003-10-11 06:20:25 +00001184#define TYPE_ARRAY 0x1800
Eric Biederman0babc1c2003-05-09 02:39:00 +00001185/* TYPE_ARRAY is a basic building block when definitng arrays.
1186 * type->left holds the type we are an array of.
Eric Biederman90089602004-05-28 14:11:54 +00001187 * type->elements holds the number of elements.
Eric Biederman0babc1c2003-05-09 02:39:00 +00001188 */
Eric Biederman90089602004-05-28 14:11:54 +00001189#define TYPE_TUPLE 0x1900
1190/* TYPE_TUPLE is a basic building block when defining
1191 * positionally reference type conglomerations. (i.e. closures)
1192 * In essence it is a wrapper for TYPE_PRODUCT, like TYPE_STRUCT
1193 * except it has no field names.
1194 * type->left holds the liked list of TYPE_PRODUCT entries that
1195 * make up the closure type.
1196 * type->elements hold the number of elements in the closure.
1197 */
1198#define TYPE_JOIN 0x1a00
1199/* TYPE_JOIN is a basic building block when defining
1200 * positionally reference type conglomerations. (i.e. closures)
1201 * In essence it is a wrapper for TYPE_OVERLAP, like TYPE_UNION
1202 * except it has no field names.
1203 * type->left holds the liked list of TYPE_OVERLAP entries that
1204 * make up the closure type.
1205 * type->elements hold the number of elements in the closure.
1206 */
1207#define TYPE_BITFIELD 0x1b00
1208/* TYPE_BITFIED is the type of a bitfield.
1209 * type->left holds the type basic type TYPE_BITFIELD is derived from.
1210 * type->elements holds the number of bits in the bitfield.
1211 */
1212#define TYPE_UNKNOWN 0x1c00
1213/* TYPE_UNKNOWN is the type of an unknown value.
1214 * Used on unknown consts and other places where I don't know the type.
1215 */
1216
1217#define ATTRIB_SHIFT 16
1218#define ATTRIB_MASK 0xffff0000
1219#define ATTRIB_NOINLINE 0x00010000
1220#define ATTRIB_ALWAYS_INLINE 0x00020000
Eric Biederman0babc1c2003-05-09 02:39:00 +00001221
Eric Biederman83b991a2003-10-11 06:20:25 +00001222#define ELEMENT_COUNT_UNSPECIFIED ULONG_T_MAX
Eric Biederman0babc1c2003-05-09 02:39:00 +00001223
1224struct type {
1225 unsigned int type;
1226 struct type *left, *right;
1227 ulong_t elements;
1228 struct hash_entry *field_ident;
1229 struct hash_entry *type_ident;
1230};
1231
Eric Biederman530b5192003-07-01 10:05:30 +00001232#define TEMPLATE_BITS 7
Eric Biederman6aa31cc2003-06-10 21:22:07 +00001233#define MAX_TEMPLATES (1<<TEMPLATE_BITS)
Eric Biederman83b991a2003-10-11 06:20:25 +00001234#define MAX_REG_EQUIVS 16
Eric Biederman530b5192003-07-01 10:05:30 +00001235#define MAX_REGC 14
Eric Biederman83b991a2003-10-11 06:20:25 +00001236#define MAX_REGISTERS 75
1237#define REGISTER_BITS 7
1238#define MAX_VIRT_REGISTERS (1<<REGISTER_BITS)
Eric Biederman90089602004-05-28 14:11:54 +00001239#define REG_ERROR 0
1240#define REG_UNSET 1
1241#define REG_UNNEEDED 2
Eric Biederman6aa31cc2003-06-10 21:22:07 +00001242#define REG_VIRT0 (MAX_REGISTERS + 0)
1243#define REG_VIRT1 (MAX_REGISTERS + 1)
1244#define REG_VIRT2 (MAX_REGISTERS + 2)
1245#define REG_VIRT3 (MAX_REGISTERS + 3)
1246#define REG_VIRT4 (MAX_REGISTERS + 4)
1247#define REG_VIRT5 (MAX_REGISTERS + 5)
Eric Biederman83b991a2003-10-11 06:20:25 +00001248#define REG_VIRT6 (MAX_REGISTERS + 6)
1249#define REG_VIRT7 (MAX_REGISTERS + 7)
1250#define REG_VIRT8 (MAX_REGISTERS + 8)
1251#define REG_VIRT9 (MAX_REGISTERS + 9)
1252
1253#if (MAX_REGISTERS + 9) > MAX_VIRT_REGISTERS
1254#error "MAX_VIRT_REGISTERS to small"
1255#endif
Eric Biederman90089602004-05-28 14:11:54 +00001256#if (MAX_REGC + REGISTER_BITS) >= 26
Eric Biederman83b991a2003-10-11 06:20:25 +00001257#error "Too many id bits used"
1258#endif
Eric Biedermanb138ac82003-04-22 18:44:01 +00001259
1260/* Provision for 8 register classes */
Eric Biedermanf96a8102003-06-16 16:57:34 +00001261#define REG_SHIFT 0
1262#define REGC_SHIFT REGISTER_BITS
1263#define REGC_MASK (((1 << MAX_REGC) - 1) << REGISTER_BITS)
Eric Biederman6aa31cc2003-06-10 21:22:07 +00001264#define REG_MASK (MAX_VIRT_REGISTERS -1)
1265#define ID_REG(ID) ((ID) & REG_MASK)
1266#define SET_REG(ID, REG) ((ID) = (((ID) & ~REG_MASK) | ((REG) & REG_MASK)))
Eric Biedermanf96a8102003-06-16 16:57:34 +00001267#define ID_REGCM(ID) (((ID) & REGC_MASK) >> REGC_SHIFT)
1268#define SET_REGCM(ID, REGCM) ((ID) = (((ID) & ~REGC_MASK) | (((REGCM) << REGC_SHIFT) & REGC_MASK)))
1269#define SET_INFO(ID, INFO) ((ID) = (((ID) & ~(REG_MASK | REGC_MASK)) | \
1270 (((INFO).reg) & REG_MASK) | ((((INFO).regcm) << REGC_SHIFT) & REGC_MASK)))
Eric Biedermanb138ac82003-04-22 18:44:01 +00001271
Eric Biederman90089602004-05-28 14:11:54 +00001272#define ARCH_INPUT_REGS 4
1273#define ARCH_OUTPUT_REGS 4
1274
1275static const struct reg_info arch_input_regs[ARCH_INPUT_REGS];
1276static const struct reg_info arch_output_regs[ARCH_OUTPUT_REGS];
Eric Biedermanb138ac82003-04-22 18:44:01 +00001277static unsigned arch_reg_regcm(struct compile_state *state, int reg);
Eric Biederman6aa31cc2003-06-10 21:22:07 +00001278static unsigned arch_regcm_normalize(struct compile_state *state, unsigned regcm);
Eric Biedermand1ea5392003-06-28 06:49:45 +00001279static unsigned arch_regcm_reg_normalize(struct compile_state *state, unsigned regcm);
Eric Biedermanb138ac82003-04-22 18:44:01 +00001280static void arch_reg_equivs(
1281 struct compile_state *state, unsigned *equiv, int reg);
1282static int arch_select_free_register(
1283 struct compile_state *state, char *used, int classes);
1284static unsigned arch_regc_size(struct compile_state *state, int class);
1285static int arch_regcm_intersect(unsigned regcm1, unsigned regcm2);
1286static unsigned arch_type_to_regcm(struct compile_state *state, struct type *type);
1287static const char *arch_reg_str(int reg);
Eric Biederman6aa31cc2003-06-10 21:22:07 +00001288static struct reg_info arch_reg_constraint(
1289 struct compile_state *state, struct type *type, const char *constraint);
1290static struct reg_info arch_reg_clobber(
1291 struct compile_state *state, const char *clobber);
1292static struct reg_info arch_reg_lhs(struct compile_state *state,
1293 struct triple *ins, int index);
1294static struct reg_info arch_reg_rhs(struct compile_state *state,
1295 struct triple *ins, int index);
Eric Biederman90089602004-05-28 14:11:54 +00001296static int arch_reg_size(int reg);
Eric Biederman6aa31cc2003-06-10 21:22:07 +00001297static struct triple *transform_to_arch_instruction(
1298 struct compile_state *state, struct triple *ins);
Eric Biederman90089602004-05-28 14:11:54 +00001299static struct triple *flatten(
1300 struct compile_state *state, struct triple *first, struct triple *ptr);
1301
Eric Biederman6aa31cc2003-06-10 21:22:07 +00001302
1303
Eric Biedermanb138ac82003-04-22 18:44:01 +00001304
Eric Biederman5ade04a2003-10-22 04:03:46 +00001305#define DEBUG_ABORT_ON_ERROR 0x00000001
1306#define DEBUG_BASIC_BLOCKS 0x00000002
1307#define DEBUG_FDOMINATORS 0x00000004
1308#define DEBUG_RDOMINATORS 0x00000008
1309#define DEBUG_TRIPLES 0x00000010
1310#define DEBUG_INTERFERENCE 0x00000020
1311#define DEBUG_SCC_TRANSFORM 0x00000040
1312#define DEBUG_SCC_TRANSFORM2 0x00000080
1313#define DEBUG_REBUILD_SSA_FORM 0x00000100
1314#define DEBUG_INLINE 0x00000200
1315#define DEBUG_RANGE_CONFLICTS 0x00000400
1316#define DEBUG_RANGE_CONFLICTS2 0x00000800
1317#define DEBUG_COLOR_GRAPH 0x00001000
1318#define DEBUG_COLOR_GRAPH2 0x00002000
1319#define DEBUG_COALESCING 0x00004000
1320#define DEBUG_COALESCING2 0x00008000
Eric Biederman90089602004-05-28 14:11:54 +00001321#define DEBUG_VERIFICATION 0x00010000
1322#define DEBUG_CALLS 0x00020000
1323#define DEBUG_CALLS2 0x00040000
1324#define DEBUG_TOKENS 0x80000000
Eric Biederman5ade04a2003-10-22 04:03:46 +00001325
1326#define DEBUG_DEFAULT ( \
1327 DEBUG_ABORT_ON_ERROR | \
1328 DEBUG_BASIC_BLOCKS | \
1329 DEBUG_FDOMINATORS | \
1330 DEBUG_RDOMINATORS | \
1331 DEBUG_TRIPLES | \
1332 0 )
1333
Eric Biederman90089602004-05-28 14:11:54 +00001334#define DEBUG_ALL ( \
1335 DEBUG_ABORT_ON_ERROR | \
1336 DEBUG_BASIC_BLOCKS | \
1337 DEBUG_FDOMINATORS | \
1338 DEBUG_RDOMINATORS | \
1339 DEBUG_TRIPLES | \
1340 DEBUG_INTERFERENCE | \
1341 DEBUG_SCC_TRANSFORM | \
1342 DEBUG_SCC_TRANSFORM2 | \
1343 DEBUG_REBUILD_SSA_FORM | \
1344 DEBUG_INLINE | \
1345 DEBUG_RANGE_CONFLICTS | \
1346 DEBUG_RANGE_CONFLICTS2 | \
1347 DEBUG_COLOR_GRAPH | \
1348 DEBUG_COLOR_GRAPH2 | \
1349 DEBUG_COALESCING | \
1350 DEBUG_COALESCING2 | \
1351 DEBUG_VERIFICATION | \
1352 DEBUG_CALLS | \
1353 DEBUG_CALLS2 | \
1354 DEBUG_TOKENS | \
1355 0 )
1356
1357#define COMPILER_INLINE_MASK 0x00000007
1358#define COMPILER_INLINE_ALWAYS 0x00000000
1359#define COMPILER_INLINE_NEVER 0x00000001
1360#define COMPILER_INLINE_DEFAULTON 0x00000002
1361#define COMPILER_INLINE_DEFAULTOFF 0x00000003
1362#define COMPILER_INLINE_NOPENALTY 0x00000004
1363#define COMPILER_ELIMINATE_INEFECTUAL_CODE 0x00000008
1364#define COMPILER_SIMPLIFY 0x00000010
1365#define COMPILER_SCC_TRANSFORM 0x00000020
1366#define COMPILER_SIMPLIFY_OP 0x00000040
1367#define COMPILER_SIMPLIFY_PHI 0x00000080
1368#define COMPILER_SIMPLIFY_LABEL 0x00000100
1369#define COMPILER_SIMPLIFY_BRANCH 0x00000200
1370#define COMPILER_SIMPLIFY_COPY 0x00000400
1371#define COMPILER_SIMPLIFY_ARITH 0x00000800
1372#define COMPILER_SIMPLIFY_SHIFT 0x00001000
1373#define COMPILER_SIMPLIFY_BITWISE 0x00002000
1374#define COMPILER_SIMPLIFY_LOGICAL 0x00004000
1375#define COMPILER_SIMPLIFY_BITFIELD 0x00008000
1376
1377#define COMPILER_CPP_ONLY 0x80000000
Eric Biederman5ade04a2003-10-22 04:03:46 +00001378
1379#define COMPILER_DEFAULT_FLAGS ( \
1380 COMPILER_ELIMINATE_INEFECTUAL_CODE | \
Eric Biederman90089602004-05-28 14:11:54 +00001381 COMPILER_INLINE_DEFAULTON | \
Eric Biederman5ade04a2003-10-22 04:03:46 +00001382 COMPILER_SIMPLIFY_OP | \
1383 COMPILER_SIMPLIFY_PHI | \
1384 COMPILER_SIMPLIFY_LABEL | \
1385 COMPILER_SIMPLIFY_BRANCH | \
1386 COMPILER_SIMPLIFY_COPY | \
1387 COMPILER_SIMPLIFY_ARITH | \
1388 COMPILER_SIMPLIFY_SHIFT | \
1389 COMPILER_SIMPLIFY_BITWISE | \
1390 COMPILER_SIMPLIFY_LOGICAL | \
Eric Biederman90089602004-05-28 14:11:54 +00001391 COMPILER_SIMPLIFY_BITFIELD | \
Eric Biederman5ade04a2003-10-22 04:03:46 +00001392 0 )
Eric Biedermanb138ac82003-04-22 18:44:01 +00001393
Eric Biederman153ea352003-06-20 14:43:20 +00001394#define GLOBAL_SCOPE_DEPTH 1
1395#define FUNCTION_SCOPE_DEPTH (GLOBAL_SCOPE_DEPTH + 1)
Eric Biedermanb138ac82003-04-22 18:44:01 +00001396
Eric Biederman6aa31cc2003-06-10 21:22:07 +00001397static void compile_file(struct compile_state *old_state, const char *filename, int local);
1398
Eric Biederman5ade04a2003-10-22 04:03:46 +00001399
1400
1401static void init_compiler_state(struct compiler_state *compiler)
1402{
1403 memset(compiler, 0, sizeof(*compiler));
1404 compiler->label_prefix = "";
1405 compiler->ofilename = "auto.inc";
1406 compiler->flags = COMPILER_DEFAULT_FLAGS;
1407 compiler->debug = 0;
1408 compiler->max_allocation_passes = MAX_ALLOCATION_PASSES;
Eric Biederman90089602004-05-28 14:11:54 +00001409 compiler->include_path_count = 1;
1410 compiler->include_paths = xcmalloc(sizeof(char *), "include_paths");
1411 compiler->define_count = 1;
1412 compiler->defines = xcmalloc(sizeof(char *), "defines");
1413 compiler->undef_count = 1;
1414 compiler->undefs = xcmalloc(sizeof(char *), "undefs");
Eric Biederman5ade04a2003-10-22 04:03:46 +00001415}
1416
1417struct compiler_flag {
1418 const char *name;
1419 unsigned long flag;
1420};
Eric Biederman90089602004-05-28 14:11:54 +00001421
1422struct compiler_arg {
1423 const char *name;
1424 unsigned long mask;
1425 struct compiler_flag flags[16];
1426};
1427
Eric Biederman5ade04a2003-10-22 04:03:46 +00001428static int set_flag(
1429 const struct compiler_flag *ptr, unsigned long *flags,
1430 int act, const char *flag)
1431{
1432 int result = -1;
1433 for(; ptr->name; ptr++) {
1434 if (strcmp(ptr->name, flag) == 0) {
1435 break;
1436 }
1437 }
1438 if (ptr->name) {
1439 result = 0;
1440 *flags &= ~(ptr->flag);
1441 if (act) {
1442 *flags |= ptr->flag;
1443 }
1444 }
1445 return result;
1446}
1447
Eric Biederman90089602004-05-28 14:11:54 +00001448static int set_arg(
1449 const struct compiler_arg *ptr, unsigned long *flags, const char *arg)
1450{
1451 const char *val;
1452 int result = -1;
1453 int len;
1454 val = strchr(arg, '=');
1455 if (val) {
1456 len = val - arg;
1457 val++;
1458 for(; ptr->name; ptr++) {
1459 if (strncmp(ptr->name, arg, len) == 0) {
1460 break;
1461 }
1462 }
1463 if (ptr->name) {
1464 *flags &= ~ptr->mask;
1465 result = set_flag(&ptr->flags[0], flags, 1, val);
1466 }
1467 }
1468 return result;
1469}
1470
1471
1472static void flag_usage(FILE *fp, const struct compiler_flag *ptr,
1473 const char *prefix, const char *invert_prefix)
1474{
1475 for(;ptr->name; ptr++) {
1476 fprintf(fp, "%s%s\n", prefix, ptr->name);
1477 if (invert_prefix) {
1478 fprintf(fp, "%s%s\n", invert_prefix, ptr->name);
1479 }
1480 }
1481}
1482
1483static void arg_usage(FILE *fp, const struct compiler_arg *ptr,
1484 const char *prefix)
1485{
1486 for(;ptr->name; ptr++) {
1487 const struct compiler_flag *flag;
1488 for(flag = &ptr->flags[0]; flag->name; flag++) {
1489 fprintf(fp, "%s%s=%s\n",
1490 prefix, ptr->name, flag->name);
1491 }
1492 }
1493}
1494
1495static int append_string(size_t *max, const char ***vec, const char *str,
1496 const char *name)
1497{
1498 size_t count;
1499 count = ++(*max);
1500 *vec = xrealloc(*vec, sizeof(char *)*count, "name");
1501 (*vec)[count -1] = 0;
1502 (*vec)[count -2] = str;
1503 return 0;
1504}
1505
1506static void arg_error(char *fmt, ...);
1507static const char *identifier(const char *str, const char *end);
1508
1509static int append_include_path(struct compiler_state *compiler, const char *str)
1510{
1511 int result;
1512 if (!exists(str, ".")) {
1513 arg_error("Nonexistent include path: `%s'\n",
1514 str);
1515 }
1516 result = append_string(&compiler->include_path_count,
1517 &compiler->include_paths, str, "include_paths");
1518 return result;
1519}
1520
1521static int append_define(struct compiler_state *compiler, const char *str)
1522{
1523 const char *end, *rest;
1524 int result;
1525
1526 end = strchr(str, '=');
1527 if (!end) {
1528 end = str + strlen(str);
1529 }
1530 rest = identifier(str, end);
1531 if (rest != end) {
1532 int len = end - str - 1;
1533 arg_error("Invalid name cannot define macro: `%*.*s'\n",
1534 len, len, str);
1535 }
1536 result = append_string(&compiler->define_count,
1537 &compiler->defines, str, "defines");
1538 return result;
1539}
1540
1541static int append_undef(struct compiler_state *compiler, const char *str)
1542{
1543 const char *end, *rest;
1544 int result;
1545
1546 end = str + strlen(str);
1547 rest = identifier(str, end);
1548 if (rest != end) {
1549 int len = end - str - 1;
1550 arg_error("Invalid name cannot undefine macro: `%*.*s'\n",
1551 len, len, str);
1552 }
1553 result = append_string(&compiler->undef_count,
1554 &compiler->undefs, str, "undefs");
1555 return result;
1556}
1557
1558static const struct compiler_flag romcc_flags[] = {
1559 { "cpp-only", COMPILER_CPP_ONLY },
1560 { "eliminate-inefectual-code", COMPILER_ELIMINATE_INEFECTUAL_CODE },
1561 { "simplify", COMPILER_SIMPLIFY },
1562 { "scc-transform", COMPILER_SCC_TRANSFORM },
1563 { "simplify-op", COMPILER_SIMPLIFY_OP },
1564 { "simplify-phi", COMPILER_SIMPLIFY_PHI },
1565 { "simplify-label", COMPILER_SIMPLIFY_LABEL },
1566 { "simplify-branch", COMPILER_SIMPLIFY_BRANCH },
1567 { "simplify-copy", COMPILER_SIMPLIFY_COPY },
1568 { "simplify-arith", COMPILER_SIMPLIFY_ARITH },
1569 { "simplify-shift", COMPILER_SIMPLIFY_SHIFT },
1570 { "simplify-bitwise", COMPILER_SIMPLIFY_BITWISE },
1571 { "simplify-logical", COMPILER_SIMPLIFY_LOGICAL },
1572 { "simplify-bitfield", COMPILER_SIMPLIFY_BITFIELD },
1573 { 0, 0 },
1574};
1575static const struct compiler_arg romcc_args[] = {
1576 { "inline-policy", COMPILER_INLINE_MASK,
1577 {
1578 { "always", COMPILER_INLINE_ALWAYS, },
1579 { "never", COMPILER_INLINE_NEVER, },
1580 { "defaulton", COMPILER_INLINE_DEFAULTON, },
1581 { "defaultoff", COMPILER_INLINE_DEFAULTOFF, },
1582 { "nopenalty", COMPILER_INLINE_NOPENALTY, },
1583 { 0, 0 },
1584 },
1585 },
1586 { 0, 0 },
1587};
1588static const struct compiler_flag romcc_opt_flags[] = {
1589 { "-O", COMPILER_SIMPLIFY },
1590 { "-O2", COMPILER_SIMPLIFY | COMPILER_SCC_TRANSFORM },
1591 { "-E", COMPILER_CPP_ONLY },
1592 { 0, 0, },
1593};
1594static const struct compiler_flag romcc_debug_flags[] = {
1595 { "all", DEBUG_ALL },
1596 { "abort-on-error", DEBUG_ABORT_ON_ERROR },
1597 { "basic-blocks", DEBUG_BASIC_BLOCKS },
1598 { "fdominators", DEBUG_FDOMINATORS },
1599 { "rdominators", DEBUG_RDOMINATORS },
1600 { "triples", DEBUG_TRIPLES },
1601 { "interference", DEBUG_INTERFERENCE },
1602 { "scc-transform", DEBUG_SCC_TRANSFORM },
1603 { "scc-transform2", DEBUG_SCC_TRANSFORM2 },
1604 { "rebuild-ssa-form", DEBUG_REBUILD_SSA_FORM },
1605 { "inline", DEBUG_INLINE },
1606 { "live-range-conflicts", DEBUG_RANGE_CONFLICTS },
1607 { "live-range-conflicts2", DEBUG_RANGE_CONFLICTS2 },
1608 { "color-graph", DEBUG_COLOR_GRAPH },
1609 { "color-graph2", DEBUG_COLOR_GRAPH2 },
1610 { "coalescing", DEBUG_COALESCING },
1611 { "coalescing2", DEBUG_COALESCING2 },
1612 { "verification", DEBUG_VERIFICATION },
1613 { "calls", DEBUG_CALLS },
1614 { "calls2", DEBUG_CALLS2 },
1615 { "tokens", DEBUG_TOKENS },
1616 { 0, 0 },
1617};
1618
Eric Biederman5ade04a2003-10-22 04:03:46 +00001619static int compiler_encode_flag(
1620 struct compiler_state *compiler, const char *flag)
1621{
Eric Biederman5ade04a2003-10-22 04:03:46 +00001622 int act;
1623 int result;
1624
1625 act = 1;
1626 result = -1;
1627 if (strncmp(flag, "no-", 3) == 0) {
1628 flag += 3;
1629 act = 0;
1630 }
1631 if (strncmp(flag, "-O", 2) == 0) {
Eric Biederman90089602004-05-28 14:11:54 +00001632 result = set_flag(romcc_opt_flags, &compiler->flags, act, flag);
1633 }
1634 else if (strncmp(flag, "-E", 2) == 0) {
1635 result = set_flag(romcc_opt_flags, &compiler->flags, act, flag);
1636 }
1637 else if (strncmp(flag, "-I", 2) == 0) {
1638 result = append_include_path(compiler, flag + 2);
1639 }
1640 else if (strncmp(flag, "-D", 2) == 0) {
1641 result = append_define(compiler, flag + 2);
1642 }
1643 else if (strncmp(flag, "-U", 2) == 0) {
1644 result = append_undef(compiler, flag + 2);
Eric Biederman5ade04a2003-10-22 04:03:46 +00001645 }
1646 else if (act && strncmp(flag, "label-prefix=", 13) == 0) {
1647 result = 0;
1648 compiler->label_prefix = flag + 13;
1649 }
1650 else if (act && strncmp(flag, "max-allocation-passes=", 22) == 0) {
1651 unsigned long max_passes;
1652 char *end;
1653 max_passes = strtoul(flag + 22, &end, 10);
1654 if (end[0] == '\0') {
1655 result = 0;
1656 compiler->max_allocation_passes = max_passes;
1657 }
1658 }
1659 else if (act && strcmp(flag, "debug") == 0) {
1660 result = 0;
1661 compiler->debug |= DEBUG_DEFAULT;
1662 }
1663 else if (strncmp(flag, "debug-", 6) == 0) {
1664 flag += 6;
Eric Biederman90089602004-05-28 14:11:54 +00001665 result = set_flag(romcc_debug_flags, &compiler->debug, act, flag);
Eric Biederman5ade04a2003-10-22 04:03:46 +00001666 }
1667 else {
Eric Biederman90089602004-05-28 14:11:54 +00001668 result = set_flag(romcc_flags, &compiler->flags, act, flag);
1669 if (result < 0) {
1670 result = set_arg(romcc_args, &compiler->flags, flag);
1671 }
Eric Biederman5ade04a2003-10-22 04:03:46 +00001672 }
1673 return result;
1674}
1675
Eric Biederman90089602004-05-28 14:11:54 +00001676static void compiler_usage(FILE *fp)
1677{
1678 flag_usage(fp, romcc_opt_flags, "", 0);
1679 flag_usage(fp, romcc_flags, "-f", "-fno-");
1680 arg_usage(fp, romcc_args, "-f");
1681 flag_usage(fp, romcc_debug_flags, "-fdebug-", "-fno-debug-");
1682 fprintf(fp, "-flabel-prefix=<prefix for assembly language labels>\n");
1683 fprintf(fp, "--label-prefix=<prefix for assembly language labels>\n");
1684 fprintf(fp, "-I<include path>\n");
1685 fprintf(fp, "-D<macro>[=defn]\n");
1686 fprintf(fp, "-U<macro>\n");
1687}
1688
Eric Biederman6aa31cc2003-06-10 21:22:07 +00001689static void do_cleanup(struct compile_state *state)
1690{
1691 if (state->output) {
1692 fclose(state->output);
Eric Biederman5ade04a2003-10-22 04:03:46 +00001693 unlink(state->compiler->ofilename);
Eric Biederman90089602004-05-28 14:11:54 +00001694 state->output = 0;
1695 }
1696 if (state->dbgout) {
1697 fflush(state->dbgout);
1698 }
1699 if (state->errout) {
1700 fflush(state->errout);
1701 }
1702}
1703
1704static struct compile_state *exit_state;
1705static void exit_cleanup(void)
1706{
1707 if (exit_state) {
1708 do_cleanup(exit_state);
Eric Biederman6aa31cc2003-06-10 21:22:07 +00001709 }
1710}
Eric Biedermanb138ac82003-04-22 18:44:01 +00001711
1712static int get_col(struct file_state *file)
1713{
1714 int col;
Eric Biederman90089602004-05-28 14:11:54 +00001715 const char *ptr, *end;
Eric Biedermanb138ac82003-04-22 18:44:01 +00001716 ptr = file->line_start;
1717 end = file->pos;
1718 for(col = 0; ptr < end; ptr++) {
1719 if (*ptr != '\t') {
1720 col++;
1721 }
1722 else {
1723 col = (col & ~7) + 8;
1724 }
1725 }
1726 return col;
1727}
1728
1729static void loc(FILE *fp, struct compile_state *state, struct triple *triple)
1730{
1731 int col;
Eric Biederman530b5192003-07-01 10:05:30 +00001732 if (triple && triple->occurance) {
Eric Biederman00443072003-06-24 12:34:45 +00001733 struct occurance *spot;
Eric Biederman5ade04a2003-10-22 04:03:46 +00001734 for(spot = triple->occurance; spot; spot = spot->parent) {
1735 fprintf(fp, "%s:%d.%d: ",
1736 spot->filename, spot->line, spot->col);
Eric Biederman00443072003-06-24 12:34:45 +00001737 }
Eric Biedermanb138ac82003-04-22 18:44:01 +00001738 return;
1739 }
1740 if (!state->file) {
1741 return;
1742 }
1743 col = get_col(state->file);
1744 fprintf(fp, "%s:%d.%d: ",
Eric Biedermanf7a0ba82003-06-19 15:14:52 +00001745 state->file->report_name, state->file->report_line, col);
Eric Biedermanb138ac82003-04-22 18:44:01 +00001746}
1747
Eric Biederman5ade04a2003-10-22 04:03:46 +00001748static void internal_error(struct compile_state *state, struct triple *ptr,
Eric Biederman90089602004-05-28 14:11:54 +00001749 const char *fmt, ...)
Eric Biedermanb138ac82003-04-22 18:44:01 +00001750{
Eric Biederman90089602004-05-28 14:11:54 +00001751 FILE *fp = state->errout;
Eric Biedermanb138ac82003-04-22 18:44:01 +00001752 va_list args;
1753 va_start(args, fmt);
Eric Biederman90089602004-05-28 14:11:54 +00001754 loc(fp, state, ptr);
1755 fputc('\n', fp);
Eric Biederman6aa31cc2003-06-10 21:22:07 +00001756 if (ptr) {
Eric Biederman90089602004-05-28 14:11:54 +00001757 fprintf(fp, "%p %-10s ", ptr, tops(ptr->op));
Eric Biederman6aa31cc2003-06-10 21:22:07 +00001758 }
Eric Biederman90089602004-05-28 14:11:54 +00001759 fprintf(fp, "Internal compiler error: ");
1760 vfprintf(fp, fmt, args);
1761 fprintf(fp, "\n");
Eric Biedermanb138ac82003-04-22 18:44:01 +00001762 va_end(args);
Eric Biederman6aa31cc2003-06-10 21:22:07 +00001763 do_cleanup(state);
Eric Biedermanb138ac82003-04-22 18:44:01 +00001764 abort();
1765}
1766
1767
Eric Biederman5ade04a2003-10-22 04:03:46 +00001768static void internal_warning(struct compile_state *state, struct triple *ptr,
Eric Biederman90089602004-05-28 14:11:54 +00001769 const char *fmt, ...)
Eric Biedermanb138ac82003-04-22 18:44:01 +00001770{
Eric Biederman90089602004-05-28 14:11:54 +00001771 FILE *fp = state->errout;
Eric Biedermanb138ac82003-04-22 18:44:01 +00001772 va_list args;
1773 va_start(args, fmt);
Eric Biederman90089602004-05-28 14:11:54 +00001774 loc(fp, state, ptr);
Eric Biederman66fe2222003-07-04 15:14:04 +00001775 if (ptr) {
Eric Biederman90089602004-05-28 14:11:54 +00001776 fprintf(fp, "%p %-10s ", ptr, tops(ptr->op));
Eric Biederman66fe2222003-07-04 15:14:04 +00001777 }
Eric Biederman90089602004-05-28 14:11:54 +00001778 fprintf(fp, "Internal compiler warning: ");
1779 vfprintf(fp, fmt, args);
1780 fprintf(fp, "\n");
Eric Biedermanb138ac82003-04-22 18:44:01 +00001781 va_end(args);
1782}
1783
1784
1785
Eric Biederman5ade04a2003-10-22 04:03:46 +00001786static void error(struct compile_state *state, struct triple *ptr,
Eric Biederman90089602004-05-28 14:11:54 +00001787 const char *fmt, ...)
Eric Biedermanb138ac82003-04-22 18:44:01 +00001788{
Eric Biederman90089602004-05-28 14:11:54 +00001789 FILE *fp = state->errout;
Eric Biedermanb138ac82003-04-22 18:44:01 +00001790 va_list args;
1791 va_start(args, fmt);
Eric Biederman90089602004-05-28 14:11:54 +00001792 loc(fp, state, ptr);
1793 fputc('\n', fp);
Eric Biederman5ade04a2003-10-22 04:03:46 +00001794 if (ptr && (state->compiler->debug & DEBUG_ABORT_ON_ERROR)) {
Eric Biederman90089602004-05-28 14:11:54 +00001795 fprintf(fp, "%p %-10s ", ptr, tops(ptr->op));
Eric Biederman83b991a2003-10-11 06:20:25 +00001796 }
Eric Biederman90089602004-05-28 14:11:54 +00001797 vfprintf(fp, fmt, args);
Eric Biedermanb138ac82003-04-22 18:44:01 +00001798 va_end(args);
Eric Biederman90089602004-05-28 14:11:54 +00001799 fprintf(fp, "\n");
Eric Biederman6aa31cc2003-06-10 21:22:07 +00001800 do_cleanup(state);
Eric Biederman5ade04a2003-10-22 04:03:46 +00001801 if (state->compiler->debug & DEBUG_ABORT_ON_ERROR) {
Eric Biederman0babc1c2003-05-09 02:39:00 +00001802 abort();
1803 }
Eric Biedermanb138ac82003-04-22 18:44:01 +00001804 exit(1);
1805}
1806
Eric Biederman5ade04a2003-10-22 04:03:46 +00001807static void warning(struct compile_state *state, struct triple *ptr,
Eric Biederman90089602004-05-28 14:11:54 +00001808 const char *fmt, ...)
Eric Biedermanb138ac82003-04-22 18:44:01 +00001809{
Eric Biederman90089602004-05-28 14:11:54 +00001810 FILE *fp = state->errout;
Eric Biedermanb138ac82003-04-22 18:44:01 +00001811 va_list args;
1812 va_start(args, fmt);
Eric Biederman90089602004-05-28 14:11:54 +00001813 loc(fp, state, ptr);
1814 fprintf(fp, "warning: ");
1815 if (ptr && (state->compiler->debug & DEBUG_ABORT_ON_ERROR)) {
1816 fprintf(fp, "%p %-10s ", ptr, tops(ptr->op));
1817 }
1818 vfprintf(fp, fmt, args);
1819 fprintf(fp, "\n");
Eric Biedermanb138ac82003-04-22 18:44:01 +00001820 va_end(args);
1821}
1822
Eric Biedermanb138ac82003-04-22 18:44:01 +00001823#define FINISHME() warning(state, 0, "FINISHME @ %s.%s:%d", __FILE__, __func__, __LINE__)
1824
Eric Biederman0babc1c2003-05-09 02:39:00 +00001825static void valid_op(struct compile_state *state, int op)
Eric Biedermanb138ac82003-04-22 18:44:01 +00001826{
1827 char *fmt = "invalid op: %d";
Eric Biederman0babc1c2003-05-09 02:39:00 +00001828 if (op >= OP_MAX) {
1829 internal_error(state, 0, fmt, op);
Eric Biedermanb138ac82003-04-22 18:44:01 +00001830 }
Eric Biederman0babc1c2003-05-09 02:39:00 +00001831 if (op < 0) {
1832 internal_error(state, 0, fmt, op);
Eric Biedermanb138ac82003-04-22 18:44:01 +00001833 }
1834}
1835
Eric Biederman0babc1c2003-05-09 02:39:00 +00001836static void valid_ins(struct compile_state *state, struct triple *ptr)
1837{
1838 valid_op(state, ptr->op);
1839}
1840
Eric Biederman90089602004-05-28 14:11:54 +00001841static void valid_param_count(struct compile_state *state, struct triple *ins)
1842{
1843 int lhs, rhs, misc, targ;
1844 valid_ins(state, ins);
1845 lhs = table_ops[ins->op].lhs;
1846 rhs = table_ops[ins->op].rhs;
1847 misc = table_ops[ins->op].misc;
1848 targ = table_ops[ins->op].targ;
1849
1850 if ((lhs >= 0) && (ins->lhs != lhs)) {
1851 internal_error(state, ins, "Bad lhs count");
1852 }
1853 if ((rhs >= 0) && (ins->rhs != rhs)) {
1854 internal_error(state, ins, "Bad rhs count");
1855 }
1856 if ((misc >= 0) && (ins->misc != misc)) {
1857 internal_error(state, ins, "Bad misc count");
1858 }
1859 if ((targ >= 0) && (ins->targ != targ)) {
1860 internal_error(state, ins, "Bad targ count");
1861 }
1862}
1863
Eric Biedermanb138ac82003-04-22 18:44:01 +00001864static void process_trigraphs(struct compile_state *state)
1865{
1866 char *src, *dest, *end;
1867 struct file_state *file;
1868 file = state->file;
1869 src = dest = file->buf;
1870 end = file->buf + file->size;
1871 while((end - src) >= 3) {
1872 if ((src[0] == '?') && (src[1] == '?')) {
1873 int c = -1;
1874 switch(src[2]) {
1875 case '=': c = '#'; break;
1876 case '/': c = '\\'; break;
1877 case '\'': c = '^'; break;
1878 case '(': c = '['; break;
1879 case ')': c = ']'; break;
1880 case '!': c = '!'; break;
1881 case '<': c = '{'; break;
1882 case '>': c = '}'; break;
1883 case '-': c = '~'; break;
1884 }
1885 if (c != -1) {
1886 *dest++ = c;
1887 src += 3;
1888 }
1889 else {
1890 *dest++ = *src++;
1891 }
1892 }
1893 else {
1894 *dest++ = *src++;
1895 }
1896 }
1897 while(src != end) {
1898 *dest++ = *src++;
1899 }
1900 file->size = dest - file->buf;
1901}
1902
1903static void splice_lines(struct compile_state *state)
1904{
1905 char *src, *dest, *end;
1906 struct file_state *file;
1907 file = state->file;
1908 src = dest = file->buf;
1909 end = file->buf + file->size;
1910 while((end - src) >= 2) {
1911 if ((src[0] == '\\') && (src[1] == '\n')) {
1912 src += 2;
1913 }
1914 else {
1915 *dest++ = *src++;
1916 }
1917 }
1918 while(src != end) {
1919 *dest++ = *src++;
1920 }
1921 file->size = dest - file->buf;
1922}
1923
1924static struct type void_type;
Eric Biederman90089602004-05-28 14:11:54 +00001925static struct type unknown_type;
Eric Biedermanb138ac82003-04-22 18:44:01 +00001926static void use_triple(struct triple *used, struct triple *user)
1927{
1928 struct triple_set **ptr, *new;
1929 if (!used)
1930 return;
1931 if (!user)
1932 return;
1933 ptr = &used->use;
1934 while(*ptr) {
1935 if ((*ptr)->member == user) {
1936 return;
1937 }
1938 ptr = &(*ptr)->next;
1939 }
1940 /* Append new to the head of the list,
1941 * copy_func and rename_block_variables
1942 * depends on this.
1943 */
1944 new = xcmalloc(sizeof(*new), "triple_set");
1945 new->member = user;
1946 new->next = used->use;
1947 used->use = new;
1948}
1949
1950static void unuse_triple(struct triple *used, struct triple *unuser)
1951{
1952 struct triple_set *use, **ptr;
Eric Biederman6aa31cc2003-06-10 21:22:07 +00001953 if (!used) {
1954 return;
1955 }
Eric Biedermanb138ac82003-04-22 18:44:01 +00001956 ptr = &used->use;
1957 while(*ptr) {
1958 use = *ptr;
1959 if (use->member == unuser) {
1960 *ptr = use->next;
1961 xfree(use);
1962 }
1963 else {
1964 ptr = &use->next;
1965 }
1966 }
1967}
1968
Eric Biedermanf7a0ba82003-06-19 15:14:52 +00001969static void put_occurance(struct occurance *occurance)
1970{
Eric Biederman5ade04a2003-10-22 04:03:46 +00001971 if (occurance) {
1972 occurance->count -= 1;
1973 if (occurance->count <= 0) {
1974 if (occurance->parent) {
1975 put_occurance(occurance->parent);
1976 }
1977 xfree(occurance);
Eric Biedermanf7a0ba82003-06-19 15:14:52 +00001978 }
Eric Biedermanf7a0ba82003-06-19 15:14:52 +00001979 }
1980}
1981
1982static void get_occurance(struct occurance *occurance)
1983{
Eric Biederman5ade04a2003-10-22 04:03:46 +00001984 if (occurance) {
1985 occurance->count += 1;
1986 }
Eric Biedermanf7a0ba82003-06-19 15:14:52 +00001987}
1988
1989
1990static struct occurance *new_occurance(struct compile_state *state)
1991{
1992 struct occurance *result, *last;
1993 const char *filename;
1994 const char *function;
1995 int line, col;
1996
1997 function = "";
1998 filename = 0;
1999 line = 0;
2000 col = 0;
2001 if (state->file) {
2002 filename = state->file->report_name;
2003 line = state->file->report_line;
2004 col = get_col(state->file);
2005 }
2006 if (state->function) {
2007 function = state->function;
2008 }
2009 last = state->last_occurance;
2010 if (last &&
2011 (last->col == col) &&
2012 (last->line == line) &&
2013 (last->function == function) &&
Eric Biederman83b991a2003-10-11 06:20:25 +00002014 ((last->filename == filename) ||
2015 (strcmp(last->filename, filename) == 0)))
2016 {
Eric Biedermanf7a0ba82003-06-19 15:14:52 +00002017 get_occurance(last);
2018 return last;
2019 }
2020 if (last) {
2021 state->last_occurance = 0;
2022 put_occurance(last);
2023 }
2024 result = xmalloc(sizeof(*result), "occurance");
2025 result->count = 2;
2026 result->filename = filename;
2027 result->function = function;
2028 result->line = line;
2029 result->col = col;
2030 result->parent = 0;
2031 state->last_occurance = result;
2032 return result;
2033}
2034
2035static struct occurance *inline_occurance(struct compile_state *state,
Eric Biederman5ade04a2003-10-22 04:03:46 +00002036 struct occurance *base, struct occurance *top)
Eric Biedermanf7a0ba82003-06-19 15:14:52 +00002037{
2038 struct occurance *result, *last;
Eric Biederman5ade04a2003-10-22 04:03:46 +00002039 if (top->parent) {
2040 internal_error(state, 0, "inlining an already inlined function?");
2041 }
2042 /* If I have a null base treat it that way */
2043 if ((base->parent == 0) &&
2044 (base->col == 0) &&
2045 (base->line == 0) &&
2046 (base->function[0] == '\0') &&
2047 (base->filename[0] == '\0')) {
2048 base = 0;
2049 }
2050 /* See if I can reuse the last occurance I had */
Eric Biedermanf7a0ba82003-06-19 15:14:52 +00002051 last = state->last_occurance;
2052 if (last &&
Eric Biederman5ade04a2003-10-22 04:03:46 +00002053 (last->parent == base) &&
2054 (last->col == top->col) &&
2055 (last->line == top->line) &&
2056 (last->function == top->function) &&
2057 (last->filename == top->filename)) {
Eric Biedermanf7a0ba82003-06-19 15:14:52 +00002058 get_occurance(last);
2059 return last;
2060 }
Eric Biederman5ade04a2003-10-22 04:03:46 +00002061 /* I can't reuse the last occurance so free it */
Eric Biedermanf7a0ba82003-06-19 15:14:52 +00002062 if (last) {
2063 state->last_occurance = 0;
2064 put_occurance(last);
2065 }
Eric Biederman5ade04a2003-10-22 04:03:46 +00002066 /* Generate a new occurance structure */
2067 get_occurance(base);
Eric Biedermanf7a0ba82003-06-19 15:14:52 +00002068 result = xmalloc(sizeof(*result), "occurance");
2069 result->count = 2;
Eric Biederman5ade04a2003-10-22 04:03:46 +00002070 result->filename = top->filename;
2071 result->function = top->function;
2072 result->line = top->line;
2073 result->col = top->col;
2074 result->parent = base;
Eric Biedermanf7a0ba82003-06-19 15:14:52 +00002075 state->last_occurance = result;
2076 return result;
2077}
Eric Biedermanf7a0ba82003-06-19 15:14:52 +00002078
2079static struct occurance dummy_occurance = {
2080 .count = 2,
2081 .filename = __FILE__,
2082 .function = "",
2083 .line = __LINE__,
2084 .col = 0,
2085 .parent = 0,
2086};
Eric Biedermanb138ac82003-04-22 18:44:01 +00002087
Eric Biederman90089602004-05-28 14:11:54 +00002088/* The undef triple is used as a place holder when we are removing pointers
Eric Biedermanb138ac82003-04-22 18:44:01 +00002089 * from a triple. Having allows certain sanity checks to pass even
2090 * when the original triple that was pointed to is gone.
2091 */
Eric Biederman90089602004-05-28 14:11:54 +00002092static struct triple unknown_triple = {
2093 .next = &unknown_triple,
2094 .prev = &unknown_triple,
Eric Biedermanf7a0ba82003-06-19 15:14:52 +00002095 .use = 0,
Eric Biederman90089602004-05-28 14:11:54 +00002096 .op = OP_UNKNOWNVAL,
2097 .lhs = 0,
2098 .rhs = 0,
2099 .misc = 0,
2100 .targ = 0,
2101 .type = &unknown_type,
Eric Biedermanf7a0ba82003-06-19 15:14:52 +00002102 .id = -1, /* An invalid id */
Eric Biederman830c9882003-07-04 00:27:33 +00002103 .u = { .cval = 0, },
Eric Biedermanf7a0ba82003-06-19 15:14:52 +00002104 .occurance = &dummy_occurance,
Eric Biederman830c9882003-07-04 00:27:33 +00002105 .param = { [0] = 0, [1] = 0, },
Eric Biedermanb138ac82003-04-22 18:44:01 +0000