- Update romcc to version 0.27 and add more tests.
[coreboot.git] / util / romcc / romcc.c
1 #include <stdarg.h>
2 #include <errno.h>
3 #include <stdint.h>
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <fcntl.h>
9 #include <unistd.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <ctype.h>
13 #include <limits.h>
14
15 #define DEBUG_ERROR_MESSAGES 0
16 #define DEBUG_COLOR_GRAPH 0
17 #define DEBUG_SCC 0
18 #define DEBUG_CONSISTENCY 1
19
20 /*  Control flow graph of a loop without goto.
21  * 
22  *        AAA
23  *   +---/
24  *  /
25  * / +--->CCC
26  * | |    / \
27  * | |  DDD EEE    break;
28  * | |    \    \
29  * | |    FFF   \
30  *  \|    / \    \
31  *   |\ GGG HHH   |   continue;
32  *   | \  \   |   |
33  *   |  \ III |  /
34  *   |   \ | /  / 
35  *   |    vvv  /  
36  *   +----BBB /   
37  *         | /
38  *         vv
39  *        JJJ
40  *
41  * 
42  *             AAA
43  *     +-----+  |  +----+
44  *     |      \ | /     |
45  *     |       BBB  +-+ |
46  *     |       / \ /  | |
47  *     |     CCC JJJ / /
48  *     |     / \    / / 
49  *     |   DDD EEE / /  
50  *     |    |   +-/ /
51  *     |   FFF     /    
52  *     |   / \    /     
53  *     | GGG HHH /      
54  *     |  |   +-/
55  *     | III
56  *     +--+ 
57  *
58  * 
59  * DFlocal(X) = { Y <- Succ(X) | idom(Y) != X }
60  * DFup(Z)    = { Y <- DF(Z) | idom(Y) != X }
61  *
62  *
63  * [] == DFlocal(X) U DF(X)
64  * () == DFup(X)
65  *
66  * Dominator graph of the same nodes.
67  *
68  *           AAA     AAA: [ ] ()
69  *          /   \
70  *        BBB    JJJ BBB: [ JJJ ] ( JJJ )  JJJ: [ ] ()
71  *         |
72  *        CCC        CCC: [ ] ( BBB, JJJ )
73  *        / \
74  *     DDD   EEE     DDD: [ ] ( BBB ) EEE: [ JJJ ] ()
75  *      |
76  *     FFF           FFF: [ ] ( BBB )
77  *     / \         
78  *  GGG   HHH        GGG: [ ] ( BBB ) HHH: [ BBB ] ()
79  *   |
80  *  III              III: [ BBB ] ()
81  *
82  *
83  * BBB and JJJ are definitely the dominance frontier.
84  * Where do I place phi functions and how do I make that decision.
85  *   
86  */
87 static void die(char *fmt, ...)
88 {
89         va_list args;
90
91         va_start(args, fmt);
92         vfprintf(stderr, fmt, args);
93         va_end(args);
94         fflush(stdout);
95         fflush(stderr);
96         exit(1);
97 }
98
99 #define MALLOC_STRONG_DEBUG
100 static void *xmalloc(size_t size, const char *name)
101 {
102         void *buf;
103         buf = malloc(size);
104         if (!buf) {
105                 die("Cannot malloc %ld bytes to hold %s: %s\n",
106                         size + 0UL, name, strerror(errno));
107         }
108         return buf;
109 }
110
111 static void *xcmalloc(size_t size, const char *name)
112 {
113         void *buf;
114         buf = xmalloc(size, name);
115         memset(buf, 0, size);
116         return buf;
117 }
118
119 static void xfree(const void *ptr)
120 {
121         free((void *)ptr);
122 }
123
124 static char *xstrdup(const char *str)
125 {
126         char *new;
127         int len;
128         len = strlen(str);
129         new = xmalloc(len + 1, "xstrdup string");
130         memcpy(new, str, len);
131         new[len] = '\0';
132         return new;
133 }
134
135 static void xchdir(const char *path)
136 {
137         if (chdir(path) != 0) {
138                 die("chdir to %s failed: %s\n",
139                         path, strerror(errno));
140         }
141 }
142
143 static int exists(const char *dirname, const char *filename)
144 {
145         int does_exist = 1;
146         xchdir(dirname);
147         if (access(filename, O_RDONLY) < 0) {
148                 if ((errno != EACCES) && (errno != EROFS)) {
149                         does_exist = 0;
150                 }
151         }
152         return does_exist;
153 }
154
155
156 static char *slurp_file(const char *dirname, const char *filename, off_t *r_size)
157 {
158         int fd;
159         char *buf;
160         off_t size, progress;
161         ssize_t result;
162         struct stat stats;
163         
164         if (!filename) {
165                 *r_size = 0;
166                 return 0;
167         }
168         xchdir(dirname);
169         fd = open(filename, O_RDONLY);
170         if (fd < 0) {
171                 die("Cannot open '%s' : %s\n",
172                         filename, strerror(errno));
173         }
174         result = fstat(fd, &stats);
175         if (result < 0) {
176                 die("Cannot stat: %s: %s\n",
177                         filename, strerror(errno));
178         }
179         size = stats.st_size;
180         *r_size = size +1;
181         buf = xmalloc(size +2, filename);
182         buf[size] = '\n'; /* Make certain the file is newline terminated */
183         buf[size+1] = '\0'; /* Null terminate the file for good measure */
184         progress = 0;
185         while(progress < size) {
186                 result = read(fd, buf + progress, size - progress);
187                 if (result < 0) {
188                         if ((errno == EINTR) || (errno == EAGAIN))
189                                 continue;
190                         die("read on %s of %ld bytes failed: %s\n",
191                                 filename, (size - progress)+ 0UL, strerror(errno));
192                 }
193                 progress += result;
194         }
195         result = close(fd);
196         if (result < 0) {
197                 die("Close of %s failed: %s\n",
198                         filename, strerror(errno));
199         }
200         return buf;
201 }
202
203 /* Long on the destination platform */
204 typedef unsigned long ulong_t;
205 typedef long long_t;
206
207 struct file_state {
208         struct file_state *prev;
209         const char *basename;
210         char *dirname;
211         char *buf;
212         off_t size;
213         char *pos;
214         int line;
215         char *line_start;
216 };
217 struct hash_entry;
218 struct token {
219         int tok;
220         struct hash_entry *ident;
221         int str_len;
222         union {
223                 ulong_t integer;
224                 const char *str;
225         } val;
226 };
227
228 /* I have two classes of types:
229  * Operational types.
230  * Logical types.  (The type the C standard says the operation is of)
231  *
232  * The operational types are:
233  * chars
234  * shorts
235  * ints
236  * longs
237  *
238  * floats
239  * doubles
240  * long doubles
241  *
242  * pointer
243  */
244
245
246 /* Machine model.
247  * No memory is useable by the compiler.
248  * There is no floating point support.
249  * All operations take place in general purpose registers.
250  * There is one type of general purpose register.
251  * Unsigned longs are stored in that general purpose register.
252  */
253
254 /* Operations on general purpose registers.
255  */
256
257 #define OP_SMUL       0
258 #define OP_UMUL       1
259 #define OP_SDIV       2
260 #define OP_UDIV       3
261 #define OP_SMOD       4
262 #define OP_UMOD       5
263 #define OP_ADD        6
264 #define OP_SUB        7
265 #define OP_SL         8
266 #define OP_USR        9
267 #define OP_SSR       10 
268 #define OP_AND       11 
269 #define OP_XOR       12
270 #define OP_OR        13
271 #define OP_POS       14 /* Dummy positive operator don't use it */
272 #define OP_NEG       15
273 #define OP_INVERT    16
274                      
275 #define OP_EQ        20
276 #define OP_NOTEQ     21
277 #define OP_SLESS     22
278 #define OP_ULESS     23
279 #define OP_SMORE     24
280 #define OP_UMORE     25
281 #define OP_SLESSEQ   26
282 #define OP_ULESSEQ   27
283 #define OP_SMOREEQ   28
284 #define OP_UMOREEQ   29
285                      
286 #define OP_LFALSE    30  /* Test if the expression is logically false */
287 #define OP_LTRUE     31  /* Test if the expression is logcially true */
288
289 #define OP_LOAD      32
290 #define OP_STORE     33
291
292 #define OP_NOOP      34
293
294 #define OP_MIN_CONST 50
295 #define OP_MAX_CONST 59
296 #define IS_CONST_OP(X) (((X) >= OP_MIN_CONST) && ((X) <= OP_MAX_CONST))
297 #define OP_INTCONST  50
298 #define OP_BLOBCONST 51
299 /* For OP_BLOBCONST ->type holds the layout and size
300  * information.  u.blob holds a pointer to the raw binary
301  * data for the constant initializer.
302  */
303 #define OP_ADDRCONST 52
304 /* For OP_ADDRCONST ->type holds the type.
305  * MISC(0) holds the reference to the static variable.
306  * ->u.cval holds an offset from that value.
307  */
308
309 #define OP_WRITE     60 
310 /* OP_WRITE moves one pseudo register to another.
311  * LHS(0) holds the destination pseudo register, which must be an OP_DECL.
312  * RHS(0) holds the psuedo to move.
313  */
314
315 #define OP_READ      61
316 /* OP_READ reads the value of a variable and makes
317  * it available for the pseudo operation.
318  * Useful for things like def-use chains.
319  * RHS(0) holds points to the triple to read from.
320  */
321 #define OP_COPY      62
322 /* OP_COPY makes a copy of the psedo register or constant in RHS(0).
323  */
324 #define OP_PIECE     63
325 /* OP_PIECE returns one piece of a instruction that returns a structure.
326  * MISC(0) is the instruction
327  * u.cval is the LHS piece of the instruction to return.
328  */
329 #define OP_ASM       64
330 /* OP_ASM holds a sequence of assembly instructions, the result
331  * of a C asm directive.
332  * RHS(x) holds input value x to the assembly sequence.
333  * LHS(x) holds the output value x from the assembly sequence.
334  * u.blob holds the string of assembly instructions.
335  */
336
337 #define OP_DEREF     65
338 /* OP_DEREF generates an lvalue from a pointer.
339  * RHS(0) holds the pointer value.
340  * OP_DEREF serves as a place holder to indicate all necessary
341  * checks have been done to indicate a value is an lvalue.
342  */
343 #define OP_DOT       66
344 /* OP_DOT references a submember of a structure lvalue.
345  * RHS(0) holds the lvalue.
346  * ->u.field holds the name of the field we want.
347  *
348  * Not seen outside of expressions.
349  */
350 #define OP_VAL       67
351 /* OP_VAL returns the value of a subexpression of the current expression.
352  * Useful for operators that have side effects.
353  * RHS(0) holds the expression.
354  * MISC(0) holds the subexpression of RHS(0) that is the
355  * value of the expression.
356  *
357  * Not seen outside of expressions.
358  */
359 #define OP_LAND      68
360 /* OP_LAND performs a C logical and between RHS(0) and RHS(1).
361  * Not seen outside of expressions.
362  */
363 #define OP_LOR       69
364 /* OP_LOR performs a C logical or between RHS(0) and RHS(1).
365  * Not seen outside of expressions.
366  */
367 #define OP_COND      70
368 /* OP_CODE performas a C ? : operation. 
369  * RHS(0) holds the test.
370  * RHS(1) holds the expression to evaluate if the test returns true.
371  * RHS(2) holds the expression to evaluate if the test returns false.
372  * Not seen outside of expressions.
373  */
374 #define OP_COMMA     71
375 /* OP_COMMA performacs a C comma operation.
376  * That is RHS(0) is evaluated, then RHS(1)
377  * and the value of RHS(1) is returned.
378  * Not seen outside of expressions.
379  */
380
381 #define OP_CALL      72
382 /* OP_CALL performs a procedure call. 
383  * MISC(0) holds a pointer to the OP_LIST of a function
384  * RHS(x) holds argument x of a function
385  * 
386  * Currently not seen outside of expressions.
387  */
388 #define OP_VAL_VEC   74
389 /* OP_VAL_VEC is an array of triples that are either variable
390  * or values for a structure or an array.
391  * RHS(x) holds element x of the vector.
392  * triple->type->elements holds the size of the vector.
393  */
394
395 /* statements */
396 #define OP_LIST      80
397 /* OP_LIST Holds a list of statements, and a result value.
398  * RHS(0) holds the list of statements.
399  * MISC(0) holds the value of the statements.
400  */
401
402 #define OP_BRANCH    81 /* branch */
403 /* For branch instructions
404  * TARG(0) holds the branch target.
405  * RHS(0) if present holds the branch condition.
406  * ->next holds where to branch to if the branch is not taken.
407  * The branch target can only be a decl...
408  */
409
410 #define OP_LABEL     83
411 /* OP_LABEL is a triple that establishes an target for branches.
412  * ->use is the list of all branches that use this label.
413  */
414
415 #define OP_ADECL     84 
416 /* OP_DECL is a triple that establishes an lvalue for assignments.
417  * ->use is a list of statements that use the variable.
418  */
419
420 #define OP_SDECL     85
421 /* OP_SDECL is a triple that establishes a variable of static
422  * storage duration.
423  * ->use is a list of statements that use the variable.
424  * MISC(0) holds the initializer expression.
425  */
426
427
428 #define OP_PHI       86
429 /* OP_PHI is a triple used in SSA form code.  
430  * It is used when multiple code paths merge and a variable needs
431  * a single assignment from any of those code paths.
432  * The operation is a cross between OP_DECL and OP_WRITE, which
433  * is what OP_PHI is geneared from.
434  * 
435  * RHS(x) points to the value from code path x
436  * The number of RHS entries is the number of control paths into the block
437  * in which OP_PHI resides.  The elements of the array point to point
438  * to the variables OP_PHI is derived from.
439  *
440  * MISC(0) holds a pointer to the orginal OP_DECL node.
441  */
442
443 /* Architecture specific instructions */
444 #define OP_CMP         100
445 #define OP_TEST        101
446 #define OP_SET_EQ      102
447 #define OP_SET_NOTEQ   103
448 #define OP_SET_SLESS   104
449 #define OP_SET_ULESS   105
450 #define OP_SET_SMORE   106
451 #define OP_SET_UMORE   107
452 #define OP_SET_SLESSEQ 108
453 #define OP_SET_ULESSEQ 109
454 #define OP_SET_SMOREEQ 110
455 #define OP_SET_UMOREEQ 111
456
457 #define OP_JMP         112
458 #define OP_JMP_EQ      113
459 #define OP_JMP_NOTEQ   114
460 #define OP_JMP_SLESS   115
461 #define OP_JMP_ULESS   116
462 #define OP_JMP_SMORE   117
463 #define OP_JMP_UMORE   118
464 #define OP_JMP_SLESSEQ 119
465 #define OP_JMP_ULESSEQ 120
466 #define OP_JMP_SMOREEQ 121
467 #define OP_JMP_UMOREEQ 122
468
469 /* Builtin operators that it is just simpler to use the compiler for */
470 #define OP_INB         130
471 #define OP_INW         131
472 #define OP_INL         132
473 #define OP_OUTB        133
474 #define OP_OUTW        134
475 #define OP_OUTL        135
476 #define OP_BSF         136
477 #define OP_BSR         137
478 #define OP_RDMSR       138
479 #define OP_WRMSR       139
480 #define OP_HLT         140
481
482 struct op_info {
483         const char *name;
484         unsigned flags;
485 #define PURE   1
486 #define IMPURE 2
487 #define PURE_BITS(FLAGS) ((FLAGS) & 0x3)
488 #define DEF    4
489 #define BLOCK  8 /* Triple stores the current block */
490         unsigned char lhs, rhs, misc, targ;
491 };
492
493 #define OP(LHS, RHS, MISC, TARG, FLAGS, NAME) { \
494         .name = (NAME), \
495         .flags = (FLAGS), \
496         .lhs = (LHS), \
497         .rhs = (RHS), \
498         .misc = (MISC), \
499         .targ = (TARG), \
500          }
501 static const struct op_info table_ops[] = {
502 [OP_SMUL       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "smul"),
503 [OP_UMUL       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "umul"),
504 [OP_SDIV       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "sdiv"),
505 [OP_UDIV       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "udiv"),
506 [OP_SMOD       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "smod"),
507 [OP_UMOD       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "umod"),
508 [OP_ADD        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "add"),
509 [OP_SUB        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "sub"),
510 [OP_SL         ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "sl"),
511 [OP_USR        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "usr"),
512 [OP_SSR        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "ssr"),
513 [OP_AND        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "and"),
514 [OP_XOR        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "xor"),
515 [OP_OR         ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "or"),
516 [OP_POS        ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "pos"),
517 [OP_NEG        ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "neg"),
518 [OP_INVERT     ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "invert"),
519
520 [OP_EQ         ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "eq"),
521 [OP_NOTEQ      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "noteq"),
522 [OP_SLESS      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "sless"),
523 [OP_ULESS      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "uless"),
524 [OP_SMORE      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "smore"),
525 [OP_UMORE      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "umore"),
526 [OP_SLESSEQ    ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "slesseq"),
527 [OP_ULESSEQ    ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "ulesseq"),
528 [OP_SMOREEQ    ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "smoreeq"),
529 [OP_UMOREEQ    ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "umoreeq"),
530 [OP_LFALSE     ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "lfalse"),
531 [OP_LTRUE      ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "ltrue"),
532
533 [OP_LOAD       ] = OP( 0,  1, 0, 0, IMPURE | DEF | BLOCK, "load"),
534 [OP_STORE      ] = OP( 1,  1, 0, 0, IMPURE | BLOCK , "store"),
535
536 [OP_NOOP       ] = OP( 0,  0, 0, 0, PURE | BLOCK, "noop"),
537
538 [OP_INTCONST   ] = OP( 0,  0, 0, 0, PURE | DEF, "intconst"),
539 [OP_BLOBCONST  ] = OP( 0,  0, 0, 0, PURE, "blobconst"),
540 [OP_ADDRCONST  ] = OP( 0,  0, 1, 0, PURE | DEF, "addrconst"),
541
542 [OP_WRITE      ] = OP( 1,  1, 0, 0, PURE | BLOCK, "write"),
543 [OP_READ       ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "read"),
544 [OP_COPY       ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "copy"),
545 [OP_PIECE      ] = OP( 0,  0, 1, 0, PURE | DEF, "piece"),
546 [OP_ASM        ] = OP(-1, -1, 0, 0, IMPURE, "asm"),
547 [OP_DEREF      ] = OP( 0,  1, 0, 0, 0 | DEF | BLOCK, "deref"), 
548 [OP_DOT        ] = OP( 0,  1, 0, 0, 0 | DEF | BLOCK, "dot"),
549
550 [OP_VAL        ] = OP( 0,  1, 1, 0, 0 | DEF | BLOCK, "val"),
551 [OP_LAND       ] = OP( 0,  2, 0, 0, 0 | DEF | BLOCK, "land"),
552 [OP_LOR        ] = OP( 0,  2, 0, 0, 0 | DEF | BLOCK, "lor"),
553 [OP_COND       ] = OP( 0,  3, 0, 0, 0 | DEF | BLOCK, "cond"),
554 [OP_COMMA      ] = OP( 0,  2, 0, 0, 0 | DEF | BLOCK, "comma"),
555 /* Call is special most it can stand in for anything so it depends on context */
556 [OP_CALL       ] = OP(-1, -1, 1, 0, 0 | BLOCK, "call"),
557 /* The sizes of OP_CALL and OP_VAL_VEC depend upon context */
558 [OP_VAL_VEC    ] = OP( 0, -1, 0, 0, 0 | BLOCK, "valvec"),
559
560 [OP_LIST       ] = OP( 0,  1, 1, 0, 0 | DEF, "list"),
561 /* The number of targets for OP_BRANCH depends on context */
562 [OP_BRANCH     ] = OP( 0, -1, 0, 1, PURE | BLOCK, "branch"),
563 [OP_LABEL      ] = OP( 0,  0, 0, 0, PURE | BLOCK, "label"),
564 [OP_ADECL      ] = OP( 0,  0, 0, 0, PURE | BLOCK, "adecl"),
565 [OP_SDECL      ] = OP( 0,  0, 1, 0, PURE | BLOCK, "sdecl"),
566 /* The number of RHS elements of OP_PHI depend upon context */
567 [OP_PHI        ] = OP( 0, -1, 1, 0, PURE | DEF | BLOCK, "phi"),
568
569 [OP_CMP        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK, "cmp"),
570 [OP_TEST       ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "test"),
571 [OP_SET_EQ     ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_eq"),
572 [OP_SET_NOTEQ  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_noteq"),
573 [OP_SET_SLESS  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_sless"),
574 [OP_SET_ULESS  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_uless"),
575 [OP_SET_SMORE  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_smore"),
576 [OP_SET_UMORE  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_umore"),
577 [OP_SET_SLESSEQ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_slesseq"),
578 [OP_SET_ULESSEQ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_ulesseq"),
579 [OP_SET_SMOREEQ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_smoreq"),
580 [OP_SET_UMOREEQ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_umoreq"),
581 [OP_JMP        ] = OP( 0,  0, 0, 1, PURE | BLOCK, "jmp"),
582 [OP_JMP_EQ     ] = OP( 0,  1, 0, 1, PURE | BLOCK, "jmp_eq"),
583 [OP_JMP_NOTEQ  ] = OP( 0,  1, 0, 1, PURE | BLOCK, "jmp_noteq"),
584 [OP_JMP_SLESS  ] = OP( 0,  1, 0, 1, PURE | BLOCK, "jmp_sless"),
585 [OP_JMP_ULESS  ] = OP( 0,  1, 0, 1, PURE | BLOCK, "jmp_uless"),
586 [OP_JMP_SMORE  ] = OP( 0,  1, 0, 1, PURE | BLOCK, "jmp_smore"),
587 [OP_JMP_UMORE  ] = OP( 0,  1, 0, 1, PURE | BLOCK, "jmp_umore"),
588 [OP_JMP_SLESSEQ] = OP( 0,  1, 0, 1, PURE | BLOCK, "jmp_slesseq"),
589 [OP_JMP_ULESSEQ] = OP( 0,  1, 0, 1, PURE | BLOCK, "jmp_ulesseq"),
590 [OP_JMP_SMOREEQ] = OP( 0,  1, 0, 1, PURE | BLOCK, "jmp_smoreq"),
591 [OP_JMP_UMOREEQ] = OP( 0,  1, 0, 1, PURE | BLOCK, "jmp_umoreq"),
592
593 [OP_INB        ] = OP( 0,  1, 0, 0, IMPURE | DEF | BLOCK, "__inb"),
594 [OP_INW        ] = OP( 0,  1, 0, 0, IMPURE | DEF | BLOCK, "__inw"),
595 [OP_INL        ] = OP( 0,  1, 0, 0, IMPURE | DEF | BLOCK, "__inl"),
596 [OP_OUTB       ] = OP( 0,  2, 0, 0, IMPURE| BLOCK, "__outb"),
597 [OP_OUTW       ] = OP( 0,  2, 0, 0, IMPURE| BLOCK, "__outw"),
598 [OP_OUTL       ] = OP( 0,  2, 0, 0, IMPURE| BLOCK, "__outl"),
599 [OP_BSF        ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "__bsf"),
600 [OP_BSR        ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "__bsr"),
601 [OP_RDMSR      ] = OP( 2,  1, 0, 0, IMPURE | BLOCK, "__rdmsr"),
602 [OP_WRMSR      ] = OP( 0,  3, 0, 0, IMPURE | BLOCK, "__wrmsr"),
603 [OP_HLT        ] = OP( 0,  0, 0, 0, IMPURE | BLOCK, "__hlt"),
604 };
605 #undef OP
606 #define OP_MAX      (sizeof(table_ops)/sizeof(table_ops[0]))
607
608 static const char *tops(int index) 
609 {
610         static const char unknown[] = "unknown op";
611         if (index < 0) {
612                 return unknown;
613         }
614         if (index > OP_MAX) {
615                 return unknown;
616         }
617         return table_ops[index].name;
618 }
619
620 struct asm_info;
621 struct triple;
622 struct block;
623 struct triple_set {
624         struct triple_set *next;
625         struct triple *member;
626 };
627
628 #define MAX_LHS  15
629 #define MAX_RHS  15
630 #define MAX_MISC 15
631 #define MAX_TARG 15
632
633 struct triple {
634         struct triple *next, *prev;
635         struct triple_set *use;
636         struct type *type;
637         unsigned char op;
638         unsigned char template_id;
639         unsigned short sizes;
640 #define TRIPLE_LHS(SIZES)  (((SIZES) >>  0) & 0x0f)
641 #define TRIPLE_RHS(SIZES)  (((SIZES) >>  4) & 0x0f)
642 #define TRIPLE_MISC(SIZES) (((SIZES) >>  8) & 0x0f)
643 #define TRIPLE_TARG(SIZES) (((SIZES) >> 12) & 0x0f)
644 #define TRIPLE_SIZE(SIZES) \
645         ((((SIZES) >> 0) & 0x0f) + \
646         (((SIZES) >>  4) & 0x0f) + \
647         (((SIZES) >>  8) & 0x0f) + \
648         (((SIZES) >> 12) & 0x0f))
649 #define TRIPLE_SIZES(LHS, RHS, MISC, TARG) \
650         ((((LHS) & 0x0f) <<  0) | \
651         (((RHS) & 0x0f)  <<  4) | \
652         (((MISC) & 0x0f) <<  8) | \
653         (((TARG) & 0x0f) << 12))
654 #define TRIPLE_LHS_OFF(SIZES)  (0)
655 #define TRIPLE_RHS_OFF(SIZES)  (TRIPLE_LHS_OFF(SIZES) + TRIPLE_LHS(SIZES))
656 #define TRIPLE_MISC_OFF(SIZES) (TRIPLE_RHS_OFF(SIZES) + TRIPLE_RHS(SIZES))
657 #define TRIPLE_TARG_OFF(SIZES) (TRIPLE_MISC_OFF(SIZES) + TRIPLE_MISC(SIZES))
658 #define LHS(PTR,INDEX) ((PTR)->param[TRIPLE_LHS_OFF((PTR)->sizes) + (INDEX)])
659 #define RHS(PTR,INDEX) ((PTR)->param[TRIPLE_RHS_OFF((PTR)->sizes) + (INDEX)])
660 #define TARG(PTR,INDEX) ((PTR)->param[TRIPLE_TARG_OFF((PTR)->sizes) + (INDEX)])
661 #define MISC(PTR,INDEX) ((PTR)->param[TRIPLE_MISC_OFF((PTR)->sizes) + (INDEX)])
662         unsigned id; /* A scratch value and finally the register */
663 #define TRIPLE_FLAG_FLATTENED   (1 << 31)
664 #define TRIPLE_FLAG_PRE_SPLIT   (1 << 30)
665 #define TRIPLE_FLAG_POST_SPLIT  (1 << 29)
666         const char *filename;
667         int line;
668         int col;
669         union {
670                 ulong_t cval;
671                 struct block  *block;
672                 void *blob;
673                 struct hash_entry *field;
674                 struct asm_info *ainfo;
675         } u;
676         struct triple *param[2];
677 };
678
679 struct reg_info {
680         unsigned reg;
681         unsigned regcm;
682 };
683 struct ins_template {
684         struct reg_info lhs[MAX_LHS + 1], rhs[MAX_RHS + 1];
685 };
686
687 struct asm_info {
688         struct ins_template tmpl;
689         char *str;
690 };
691
692 struct block_set {
693         struct block_set *next;
694         struct block *member;
695 };
696 struct block {
697         struct block *work_next;
698         struct block *left, *right;
699         struct triple *first, *last;
700         int users;
701         struct block_set *use;
702         struct block_set *idominates;
703         struct block_set *domfrontier;
704         struct block *idom;
705         struct block_set *ipdominates;
706         struct block_set *ipdomfrontier;
707         struct block *ipdom;
708         int vertex;
709         
710 };
711
712 struct symbol {
713         struct symbol *next;
714         struct hash_entry *ident;
715         struct triple *def;
716         struct type *type;
717         int scope_depth;
718 };
719
720 struct macro {
721         struct hash_entry *ident;
722         char *buf;
723         int buf_len;
724 };
725
726 struct hash_entry {
727         struct hash_entry *next;
728         const char *name;
729         int name_len;
730         int tok;
731         struct macro *sym_define;
732         struct symbol *sym_label;
733         struct symbol *sym_struct;
734         struct symbol *sym_ident;
735 };
736
737 #define HASH_TABLE_SIZE 2048
738
739 struct compile_state {
740         const char *ofilename;
741         FILE *output;
742         struct triple *vars;
743         struct file_state *file;
744         struct token token[4];
745         struct hash_entry *hash_table[HASH_TABLE_SIZE];
746         struct hash_entry *i_continue;
747         struct hash_entry *i_break;
748         int scope_depth;
749         int if_depth, if_value;
750         int macro_line;
751         struct file_state *macro_file;
752         struct triple *main_function;
753         struct block *first_block, *last_block;
754         int last_vertex;
755         int cpu;
756         int debug;
757         int optimize;
758 };
759
760 /* visibility global/local */
761 /* static/auto duration */
762 /* typedef, register, inline */
763 #define STOR_SHIFT         0
764 #define STOR_MASK     0x000f
765 /* Visibility */
766 #define STOR_GLOBAL   0x0001
767 /* Duration */
768 #define STOR_PERM     0x0002
769 /* Storage specifiers */
770 #define STOR_AUTO     0x0000
771 #define STOR_STATIC   0x0002
772 #define STOR_EXTERN   0x0003
773 #define STOR_REGISTER 0x0004
774 #define STOR_TYPEDEF  0x0008
775 #define STOR_INLINE   0x000c
776
777 #define QUAL_SHIFT         4
778 #define QUAL_MASK     0x0070
779 #define QUAL_NONE     0x0000
780 #define QUAL_CONST    0x0010
781 #define QUAL_VOLATILE 0x0020
782 #define QUAL_RESTRICT 0x0040
783
784 #define TYPE_SHIFT         8
785 #define TYPE_MASK     0x1f00
786 #define TYPE_INTEGER(TYPE)    (((TYPE) >= TYPE_CHAR) && ((TYPE) <= TYPE_ULLONG))
787 #define TYPE_ARITHMETIC(TYPE) (((TYPE) >= TYPE_CHAR) && ((TYPE) <= TYPE_LDOUBLE))
788 #define TYPE_UNSIGNED(TYPE)   ((TYPE) & 0x0100)
789 #define TYPE_SIGNED(TYPE)     (!TYPE_UNSIGNED(TYPE))
790 #define TYPE_MKUNSIGNED(TYPE) ((TYPE) | 0x0100)
791 #define TYPE_RANK(TYPE)       ((TYPE) & ~0x0100)
792 #define TYPE_PTR(TYPE)        (((TYPE) & TYPE_MASK) == TYPE_POINTER)
793 #define TYPE_DEFAULT  0x0000
794 #define TYPE_VOID     0x0100
795 #define TYPE_CHAR     0x0200
796 #define TYPE_UCHAR    0x0300
797 #define TYPE_SHORT    0x0400
798 #define TYPE_USHORT   0x0500
799 #define TYPE_INT      0x0600
800 #define TYPE_UINT     0x0700
801 #define TYPE_LONG     0x0800
802 #define TYPE_ULONG    0x0900
803 #define TYPE_LLONG    0x0a00 /* long long */
804 #define TYPE_ULLONG   0x0b00
805 #define TYPE_FLOAT    0x0c00
806 #define TYPE_DOUBLE   0x0d00
807 #define TYPE_LDOUBLE  0x0e00 /* long double */
808 #define TYPE_STRUCT   0x1000
809 #define TYPE_ENUM     0x1100
810 #define TYPE_POINTER  0x1200 
811 /* For TYPE_POINTER:
812  * type->left holds the type pointed to.
813  */
814 #define TYPE_FUNCTION 0x1300 
815 /* For TYPE_FUNCTION:
816  * type->left holds the return type.
817  * type->right holds the...
818  */
819 #define TYPE_PRODUCT  0x1400
820 /* TYPE_PRODUCT is a basic building block when defining structures
821  * type->left holds the type that appears first in memory.
822  * type->right holds the type that appears next in memory.
823  */
824 #define TYPE_OVERLAP  0x1500
825 /* TYPE_OVERLAP is a basic building block when defining unions
826  * type->left and type->right holds to types that overlap
827  * each other in memory.
828  */
829 #define TYPE_ARRAY    0x1600
830 /* TYPE_ARRAY is a basic building block when definitng arrays.
831  * type->left holds the type we are an array of.
832  * type-> holds the number of elements.
833  */
834
835 #define ELEMENT_COUNT_UNSPECIFIED (~0UL)
836
837 struct type {
838         unsigned int type;
839         struct type *left, *right;
840         ulong_t elements;
841         struct hash_entry *field_ident;
842         struct hash_entry *type_ident;
843 };
844
845 #define MAX_REGISTERS      75
846 #define MAX_REG_EQUIVS     16
847 #define REGISTER_BITS      28
848 #define MAX_VIRT_REGISTERS (1<<REGISTER_BITS)
849 #define TEMPLATE_BITS      6
850 #define MAX_TEMPLATES      (1<<TEMPLATE_BITS)
851 #define MAX_REGC           12
852 #define REG_UNSET          0
853 #define REG_UNNEEDED       1
854 #define REG_VIRT0          (MAX_REGISTERS + 0)
855 #define REG_VIRT1          (MAX_REGISTERS + 1)
856 #define REG_VIRT2          (MAX_REGISTERS + 2)
857 #define REG_VIRT3          (MAX_REGISTERS + 3)
858 #define REG_VIRT4          (MAX_REGISTERS + 4)
859 #define REG_VIRT5          (MAX_REGISTERS + 5)
860
861 /* Provision for 8 register classes */
862 #define REG_MASK (MAX_VIRT_REGISTERS -1)
863 #define ID_REG(ID)              ((ID) & REG_MASK)
864 #define SET_REG(ID, REG)        ((ID) = (((ID) & ~REG_MASK) | ((REG) & REG_MASK)))
865
866 static unsigned arch_reg_regcm(struct compile_state *state, int reg);
867 static unsigned arch_regcm_normalize(struct compile_state *state, unsigned regcm);
868 static void arch_reg_equivs(
869         struct compile_state *state, unsigned *equiv, int reg);
870 static int arch_select_free_register(
871         struct compile_state *state, char *used, int classes);
872 static unsigned arch_regc_size(struct compile_state *state, int class);
873 static int arch_regcm_intersect(unsigned regcm1, unsigned regcm2);
874 static unsigned arch_type_to_regcm(struct compile_state *state, struct type *type);
875 static const char *arch_reg_str(int reg);
876 static struct reg_info arch_reg_constraint(
877         struct compile_state *state, struct type *type, const char *constraint);
878 static struct reg_info arch_reg_clobber(
879         struct compile_state *state, const char *clobber);
880 static struct reg_info arch_reg_lhs(struct compile_state *state, 
881         struct triple *ins, int index);
882 static struct reg_info arch_reg_rhs(struct compile_state *state, 
883         struct triple *ins, int index);
884 static struct triple *transform_to_arch_instruction(
885         struct compile_state *state, struct triple *ins);
886
887
888
889 #define DEBUG_ABORT_ON_ERROR    0x0001
890 #define DEBUG_INTERMEDIATE_CODE 0x0002
891 #define DEBUG_CONTROL_FLOW      0x0004
892 #define DEBUG_BASIC_BLOCKS      0x0008
893 #define DEBUG_FDOMINATORS       0x0010
894 #define DEBUG_RDOMINATORS       0x0020
895 #define DEBUG_TRIPLES           0x0040
896 #define DEBUG_INTERFERENCE      0x0080
897 #define DEBUG_ARCH_CODE         0x0100
898 #define DEBUG_CODE_ELIMINATION  0x0200
899 #define DEBUG_INSERTED_COPIES   0x0400
900
901 #define GLOBAL_SCOPE_DEPTH 1
902
903 static void compile_file(struct compile_state *old_state, const char *filename, int local);
904
905 static void do_cleanup(struct compile_state *state)
906 {
907         if (state->output) {
908                 fclose(state->output);
909                 unlink(state->ofilename);
910         }
911 }
912
913 static int get_col(struct file_state *file)
914 {
915         int col;
916         char *ptr, *end;
917         ptr = file->line_start;
918         end = file->pos;
919         for(col = 0; ptr < end; ptr++) {
920                 if (*ptr != '\t') {
921                         col++;
922                 } 
923                 else {
924                         col = (col & ~7) + 8;
925                 }
926         }
927         return col;
928 }
929
930 static void loc(FILE *fp, struct compile_state *state, struct triple *triple)
931 {
932         int col;
933         if (triple) {
934                 fprintf(fp, "%s:%d.%d: ", 
935                         triple->filename, triple->line, triple->col);
936                 return;
937         }
938         if (!state->file) {
939                 return;
940         }
941         col = get_col(state->file);
942         fprintf(fp, "%s:%d.%d: ", 
943                 state->file->basename, state->file->line, col);
944 }
945
946 static void __internal_error(struct compile_state *state, struct triple *ptr, 
947         char *fmt, ...)
948 {
949         va_list args;
950         va_start(args, fmt);
951         loc(stderr, state, ptr);
952         if (ptr) {
953                 fprintf(stderr, "%p %s ", ptr, tops(ptr->op));
954         }
955         fprintf(stderr, "Internal compiler error: ");
956         vfprintf(stderr, fmt, args);
957         fprintf(stderr, "\n");
958         va_end(args);
959         do_cleanup(state);
960         abort();
961 }
962
963
964 static void __internal_warning(struct compile_state *state, struct triple *ptr, 
965         char *fmt, ...)
966 {
967         va_list args;
968         va_start(args, fmt);
969         loc(stderr, state, ptr);
970         fprintf(stderr, "Internal compiler warning: ");
971         vfprintf(stderr, fmt, args);
972         fprintf(stderr, "\n");
973         va_end(args);
974 }
975
976
977
978 static void __error(struct compile_state *state, struct triple *ptr, 
979         char *fmt, ...)
980 {
981         va_list args;
982         va_start(args, fmt);
983         loc(stderr, state, ptr);
984         vfprintf(stderr, fmt, args);
985         va_end(args);
986         fprintf(stderr, "\n");
987         do_cleanup(state);
988         if (state->debug & DEBUG_ABORT_ON_ERROR) {
989                 abort();
990         }
991         exit(1);
992 }
993
994 static void __warning(struct compile_state *state, struct triple *ptr, 
995         char *fmt, ...)
996 {
997         va_list args;
998         va_start(args, fmt);
999         loc(stderr, state, ptr);
1000         fprintf(stderr, "warning: "); 
1001         vfprintf(stderr, fmt, args);
1002         fprintf(stderr, "\n");
1003         va_end(args);
1004 }
1005
1006 #if DEBUG_ERROR_MESSAGES 
1007 #  define internal_error fprintf(stderr,  "@ %s.%s:%d \t", __FILE__, __func__, __LINE__),__internal_error
1008 #  define internal_warning fprintf(stderr,  "@ %s.%s:%d \t", __FILE__, __func__, __LINE__),__internal_warning
1009 #  define error fprintf(stderr, "@ %s.%s:%d \t", __FILE__, __func__, __LINE__),__error
1010 #  define warning fprintf(stderr, "@ %s.%s:%d \t", __FILE__, __func__, __LINE__),__warning
1011 #else
1012 #  define internal_error __internal_error
1013 #  define internal_warning __internal_warning
1014 #  define error __error
1015 #  define warning __warning
1016 #endif
1017 #define FINISHME() warning(state, 0, "FINISHME @ %s.%s:%d", __FILE__, __func__, __LINE__)
1018
1019 static void valid_op(struct compile_state *state, int op)
1020 {
1021         char *fmt = "invalid op: %d";
1022         if (op >= OP_MAX) {
1023                 internal_error(state, 0, fmt, op);
1024         }
1025         if (op < 0) {
1026                 internal_error(state, 0, fmt, op);
1027         }
1028 }
1029
1030 static void valid_ins(struct compile_state *state, struct triple *ptr)
1031 {
1032         valid_op(state, ptr->op);
1033 }
1034
1035 static void process_trigraphs(struct compile_state *state)
1036 {
1037         char *src, *dest, *end;
1038         struct file_state *file;
1039         file = state->file;
1040         src = dest = file->buf;
1041         end = file->buf + file->size;
1042         while((end - src) >= 3) {
1043                 if ((src[0] == '?') && (src[1] == '?')) {
1044                         int c = -1;
1045                         switch(src[2]) {
1046                         case '=': c = '#'; break;
1047                         case '/': c = '\\'; break;
1048                         case '\'': c = '^'; break;
1049                         case '(': c = '['; break;
1050                         case ')': c = ']'; break;
1051                         case '!': c = '!'; break;
1052                         case '<': c = '{'; break;
1053                         case '>': c = '}'; break;
1054                         case '-': c = '~'; break;
1055                         }
1056                         if (c != -1) {
1057                                 *dest++ = c;
1058                                 src += 3;
1059                         }
1060                         else {
1061                                 *dest++ = *src++;
1062                         }
1063                 }
1064                 else {
1065                         *dest++ = *src++;
1066                 }
1067         }
1068         while(src != end) {
1069                 *dest++ = *src++;
1070         }
1071         file->size = dest - file->buf;
1072 }
1073
1074 static void splice_lines(struct compile_state *state)
1075 {
1076         char *src, *dest, *end;
1077         struct file_state *file;
1078         file = state->file;
1079         src = dest = file->buf;
1080         end = file->buf + file->size;
1081         while((end - src) >= 2) {
1082                 if ((src[0] == '\\') && (src[1] == '\n')) {
1083                         src += 2;
1084                 }
1085                 else {
1086                         *dest++ = *src++;
1087                 }
1088         }
1089         while(src != end) {
1090                 *dest++ = *src++;
1091         }
1092         file->size = dest - file->buf;
1093 }
1094
1095 static struct type void_type;
1096 static void use_triple(struct triple *used, struct triple *user)
1097 {
1098         struct triple_set **ptr, *new;
1099         if (!used)
1100                 return;
1101         if (!user)
1102                 return;
1103         ptr = &used->use;
1104         while(*ptr) {
1105                 if ((*ptr)->member == user) {
1106                         return;
1107                 }
1108                 ptr = &(*ptr)->next;
1109         }
1110         /* Append new to the head of the list, 
1111          * copy_func and rename_block_variables
1112          * depends on this.
1113          */
1114         new = xcmalloc(sizeof(*new), "triple_set");
1115         new->member = user;
1116         new->next   = used->use;
1117         used->use   = new;
1118 }
1119
1120 static void unuse_triple(struct triple *used, struct triple *unuser)
1121 {
1122         struct triple_set *use, **ptr;
1123         if (!used) {
1124                 return;
1125         }
1126         ptr = &used->use;
1127         while(*ptr) {
1128                 use = *ptr;
1129                 if (use->member == unuser) {
1130                         *ptr = use->next;
1131                         xfree(use);
1132                 }
1133                 else {
1134                         ptr = &use->next;
1135                 }
1136         }
1137 }
1138
1139 static void push_triple(struct triple *used, struct triple *user)
1140 {
1141         struct triple_set *new;
1142         if (!used)
1143                 return;
1144         if (!user)
1145                 return;
1146         /* Append new to the head of the list,
1147          * it's the only sensible behavoir for a stack.
1148          */
1149         new = xcmalloc(sizeof(*new), "triple_set");
1150         new->member = user;
1151         new->next   = used->use;
1152         used->use   = new;
1153 }
1154
1155 static void pop_triple(struct triple *used, struct triple *unuser)
1156 {
1157         struct triple_set *use, **ptr;
1158         ptr = &used->use;
1159         while(*ptr) {
1160                 use = *ptr;
1161                 if (use->member == unuser) {
1162                         *ptr = use->next;
1163                         xfree(use);
1164                         /* Only free one occurance from the stack */
1165                         return;
1166                 }
1167                 else {
1168                         ptr = &use->next;
1169                 }
1170         }
1171 }
1172
1173
1174 /* The zero triple is used as a place holder when we are removing pointers
1175  * from a triple.  Having allows certain sanity checks to pass even
1176  * when the original triple that was pointed to is gone.
1177  */
1178 static struct triple zero_triple = {
1179         .next     = &zero_triple,
1180         .prev     = &zero_triple,
1181         .use      = 0,
1182         .op       = OP_INTCONST,
1183         .sizes    = TRIPLE_SIZES(0, 0, 0, 0),
1184         .id       = -1, /* An invalid id */
1185         .u = { .cval   = 0, },
1186         .filename = __FILE__,
1187         .line     = __LINE__,
1188         .col      = 0,
1189         .param { [0] = 0, [1] = 0, },
1190 };
1191
1192
1193 static unsigned short triple_sizes(struct compile_state *state,
1194         int op, struct type *type, int lhs_wanted, int rhs_wanted)
1195 {
1196         int lhs, rhs, misc, targ;
1197         valid_op(state, op);
1198         lhs = table_ops[op].lhs;
1199         rhs = table_ops[op].rhs;
1200         misc = table_ops[op].misc;
1201         targ = table_ops[op].targ;
1202         
1203         
1204         if (op == OP_CALL) {
1205                 struct type *param;
1206                 rhs = 0;
1207                 param = type->right;
1208                 while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
1209                         rhs++;
1210                         param = param->right;
1211                 }
1212                 if ((param->type & TYPE_MASK) != TYPE_VOID) {
1213                         rhs++;
1214                 }
1215                 lhs = 0;
1216                 if ((type->left->type & TYPE_MASK) == TYPE_STRUCT) {
1217                         lhs = type->left->elements;
1218                 }
1219         }
1220         else if (op == OP_VAL_VEC) {
1221                 rhs = type->elements;
1222         }
1223         else if ((op == OP_BRANCH) || (op == OP_PHI)) {
1224                 rhs = rhs_wanted;
1225         }
1226         else if (op == OP_ASM) {
1227                 rhs = rhs_wanted;
1228                 lhs = lhs_wanted;
1229         }
1230         if ((rhs < 0) || (rhs > MAX_RHS)) {
1231                 internal_error(state, 0, "bad rhs");
1232         }
1233         if ((lhs < 0) || (lhs > MAX_LHS)) {
1234                 internal_error(state, 0, "bad lhs");
1235         }
1236         if ((misc < 0) || (misc > MAX_MISC)) {
1237                 internal_error(state, 0, "bad misc");
1238         }
1239         if ((targ < 0) || (targ > MAX_TARG)) {
1240                 internal_error(state, 0, "bad targs");
1241         }
1242         return TRIPLE_SIZES(lhs, rhs, misc, targ);
1243 }
1244
1245 static struct triple *alloc_triple(struct compile_state *state, 
1246         int op, struct type *type, int lhs, int rhs,
1247         const char *filename, int line, int col)
1248 {
1249         size_t size, sizes, extra_count, min_count;
1250         struct triple *ret;
1251         sizes = triple_sizes(state, op, type, lhs, rhs);
1252
1253         min_count = sizeof(ret->param)/sizeof(ret->param[0]);
1254         extra_count = TRIPLE_SIZE(sizes);
1255         extra_count = (extra_count < min_count)? 0 : extra_count - min_count;
1256
1257         size = sizeof(*ret) + sizeof(ret->param[0]) * extra_count;
1258         ret = xcmalloc(size, "tripple");
1259         ret->op       = op;
1260         ret->sizes    = sizes;
1261         ret->type     = type;
1262         ret->next     = ret;
1263         ret->prev     = ret;
1264         ret->filename = filename;
1265         ret->line     = line;
1266         ret->col      = col;
1267         return ret;
1268 }
1269
1270 struct triple *dup_triple(struct compile_state *state, struct triple *src)
1271 {
1272         struct triple *dup;
1273         int src_lhs, src_rhs, src_size;
1274         src_lhs = TRIPLE_LHS(src->sizes);
1275         src_rhs = TRIPLE_RHS(src->sizes);
1276         src_size = TRIPLE_SIZE(src->sizes);
1277         dup = alloc_triple(state, src->op, src->type, src_lhs, src_rhs,
1278                 src->filename, src->line, src->col);
1279         memcpy(dup, src, sizeof(*src));
1280         memcpy(dup->param, src->param, src_size * sizeof(src->param[0]));
1281         return dup;
1282 }
1283
1284 static struct triple *new_triple(struct compile_state *state, 
1285         int op, struct type *type, int lhs, int rhs)
1286 {
1287         struct triple *ret;
1288         const char *filename;
1289         int line, col;
1290         filename = 0;
1291         line = 0;
1292         col  = 0;
1293         if (state->file) {
1294                 filename = state->file->basename;
1295                 line     = state->file->line;
1296                 col      = get_col(state->file);
1297         }
1298         ret = alloc_triple(state, op, type, lhs, rhs,
1299                 filename, line, col);
1300         return ret;
1301 }
1302
1303 static struct triple *build_triple(struct compile_state *state, 
1304         int op, struct type *type, struct triple *left, struct triple *right,
1305         const char *filename, int line, int col)
1306 {
1307         struct triple *ret;
1308         size_t count;
1309         ret = alloc_triple(state, op, type, -1, -1, filename, line, col);
1310         count = TRIPLE_SIZE(ret->sizes);
1311         if (count > 0) {
1312                 ret->param[0] = left;
1313         }
1314         if (count > 1) {
1315                 ret->param[1] = right;
1316         }
1317         return ret;
1318 }
1319
1320 static struct triple *triple(struct compile_state *state, 
1321         int op, struct type *type, struct triple *left, struct triple *right)
1322 {
1323         struct triple *ret;
1324         size_t count;
1325         ret = new_triple(state, op, type, -1, -1);
1326         count = TRIPLE_SIZE(ret->sizes);
1327         if (count >= 1) {
1328                 ret->param[0] = left;
1329         }
1330         if (count >= 2) {
1331                 ret->param[1] = right;
1332         }
1333         return ret;
1334 }
1335
1336 static struct triple *branch(struct compile_state *state, 
1337         struct triple *targ, struct triple *test)
1338 {
1339         struct triple *ret;
1340         ret = new_triple(state, OP_BRANCH, &void_type, -1, test?1:0);
1341         if (test) {
1342                 RHS(ret, 0) = test;
1343         }
1344         TARG(ret, 0) = targ;
1345         /* record the branch target was used */
1346         if (!targ || (targ->op != OP_LABEL)) {
1347                 internal_error(state, 0, "branch not to label");
1348                 use_triple(targ, ret);
1349         }
1350         return ret;
1351 }
1352
1353
1354 static void insert_triple(struct compile_state *state,
1355         struct triple *first, struct triple *ptr)
1356 {
1357         if (ptr) {
1358                 if ((ptr->id & TRIPLE_FLAG_FLATTENED) || (ptr->next != ptr)) {
1359                         internal_error(state, ptr, "expression already used");
1360                 }
1361                 ptr->next       = first;
1362                 ptr->prev       = first->prev;
1363                 ptr->prev->next = ptr;
1364                 ptr->next->prev = ptr;
1365                 if ((ptr->prev->op == OP_BRANCH) && 
1366                         TRIPLE_RHS(ptr->prev->sizes)) {
1367                         unuse_triple(first, ptr->prev);
1368                         use_triple(ptr, ptr->prev);
1369                 }
1370         }
1371 }
1372
1373 static int triple_stores_block(struct compile_state *state, struct triple *ins)
1374 {
1375         /* This function is used to determine if u.block 
1376          * is utilized to store the current block number.
1377          */
1378         int stores_block;
1379         valid_ins(state, ins);
1380         stores_block = (table_ops[ins->op].flags & BLOCK) == BLOCK;
1381         return stores_block;
1382 }
1383
1384 static struct block *block_of_triple(struct compile_state *state, 
1385         struct triple *ins)
1386 {
1387         struct triple *first;
1388         first = RHS(state->main_function, 0);
1389         while(ins != first && !triple_stores_block(state, ins)) {
1390                 if (ins == ins->prev) {
1391                         internal_error(state, 0, "ins == ins->prev?");
1392                 }
1393                 ins = ins->prev;
1394         }
1395         if (!triple_stores_block(state, ins)) {
1396                 internal_error(state, ins, "Cannot find block");
1397         }
1398         return ins->u.block;
1399 }
1400
1401 static struct triple *pre_triple(struct compile_state *state,
1402         struct triple *base,
1403         int op, struct type *type, struct triple *left, struct triple *right)
1404 {
1405         struct block *block;
1406         struct triple *ret;
1407         block = block_of_triple(state, base);
1408         ret = build_triple(state, op, type, left, right, 
1409                 base->filename, base->line, base->col);
1410         if (triple_stores_block(state, ret)) {
1411                 ret->u.block = block;
1412         }
1413         insert_triple(state, base, ret);
1414         if (block->first == base) {
1415                 block->first = ret;
1416         }
1417         return ret;
1418 }
1419
1420 static struct triple *post_triple(struct compile_state *state,
1421         struct triple *base,
1422         int op, struct type *type, struct triple *left, struct triple *right)
1423 {
1424         struct block *block;
1425         struct triple *ret;
1426         block = block_of_triple(state, base);
1427         ret = build_triple(state, op, type, left, right, 
1428                 base->filename, base->line, base->col);
1429         if (triple_stores_block(state, ret)) {
1430                 ret->u.block = block;
1431         }
1432         insert_triple(state, base->next, ret);
1433         if (block->last == base) {
1434                 block->last = ret;
1435         }
1436         return ret;
1437 }
1438
1439 static struct triple *label(struct compile_state *state)
1440 {
1441         /* Labels don't get a type */
1442         struct triple *result;
1443         result = triple(state, OP_LABEL, &void_type, 0, 0);
1444         return result;
1445 }
1446
1447 static void display_triple(FILE *fp, struct triple *ins)
1448 {
1449         if (ins->op == OP_INTCONST) {
1450                 fprintf(fp, "(%p) %3d %-2d %-10s <0x%08lx>          @ %s:%d.%d\n",
1451                         ins, ID_REG(ins->id), ins->template_id, tops(ins->op), 
1452                         ins->u.cval,
1453                         ins->filename, ins->line, ins->col);
1454         }
1455         else if (ins->op == OP_ADDRCONST) {
1456                 fprintf(fp, "(%p) %3d %-2d %-10s %-10p <0x%08lx> @ %s:%d.%d\n",
1457                         ins, ID_REG(ins->id), ins->template_id, tops(ins->op), 
1458                         MISC(ins, 0), ins->u.cval,
1459                         ins->filename, ins->line, ins->col);
1460         }
1461         else {
1462                 int i, count;
1463                 fprintf(fp, "(%p) %3d %-2d %-10s", 
1464                         ins, ID_REG(ins->id), ins->template_id, tops(ins->op));
1465                 count = TRIPLE_SIZE(ins->sizes);
1466                 for(i = 0; i < count; i++) {
1467                         fprintf(fp, " %-10p", ins->param[i]);
1468                 }
1469                 for(; i < 2; i++) {
1470                         printf("           ");
1471                 }
1472                 fprintf(fp, " @ %s:%d.%d\n", 
1473                         ins->filename, ins->line, ins->col);
1474         }
1475         fflush(fp);
1476 }
1477
1478 static int triple_is_pure(struct compile_state *state, struct triple *ins)
1479 {
1480         /* Does the triple have no side effects.
1481          * I.e. Rexecuting the triple with the same arguments 
1482          * gives the same value.
1483          */
1484         unsigned pure;
1485         valid_ins(state, ins);
1486         pure = PURE_BITS(table_ops[ins->op].flags);
1487         if ((pure != PURE) && (pure != IMPURE)) {
1488                 internal_error(state, 0, "Purity of %s not known\n",
1489                         tops(ins->op));
1490         }
1491         return pure == PURE;
1492 }
1493
1494 static int triple_is_branch(struct compile_state *state, struct triple *ins)
1495 {
1496         /* This function is used to determine which triples need
1497          * a register.
1498          */
1499         int is_branch;
1500         valid_ins(state, ins);
1501         is_branch = (table_ops[ins->op].targ != 0);
1502         return is_branch;
1503 }
1504
1505 static int triple_is_def(struct compile_state *state, struct triple *ins)
1506 {
1507         /* This function is used to determine which triples need
1508          * a register.
1509          */
1510         int is_def;
1511         valid_ins(state, ins);
1512         is_def = (table_ops[ins->op].flags & DEF) == DEF;
1513         return is_def;
1514 }
1515
1516 static struct triple **triple_iter(struct compile_state *state,
1517         size_t count, struct triple **vector,
1518         struct triple *ins, struct triple **last)
1519 {
1520         struct triple **ret;
1521         ret = 0;
1522         if (count) {
1523                 if (!last) {
1524                         ret = vector;
1525                 }
1526                 else if ((last >= vector) && (last < (vector + count - 1))) {
1527                         ret = last + 1;
1528                 }
1529         }
1530         return ret;
1531         
1532 }
1533
1534 static struct triple **triple_lhs(struct compile_state *state,
1535         struct triple *ins, struct triple **last)
1536 {
1537         return triple_iter(state, TRIPLE_LHS(ins->sizes), &LHS(ins,0), 
1538                 ins, last);
1539 }
1540
1541 static struct triple **triple_rhs(struct compile_state *state,
1542         struct triple *ins, struct triple **last)
1543 {
1544         return triple_iter(state, TRIPLE_RHS(ins->sizes), &RHS(ins,0), 
1545                 ins, last);
1546 }
1547
1548 static struct triple **triple_misc(struct compile_state *state,
1549         struct triple *ins, struct triple **last)
1550 {
1551         return triple_iter(state, TRIPLE_MISC(ins->sizes), &MISC(ins,0), 
1552                 ins, last);
1553 }
1554
1555 static struct triple **triple_targ(struct compile_state *state,
1556         struct triple *ins, struct triple **last)
1557 {
1558         size_t count;
1559         struct triple **ret, **vector;
1560         ret = 0;
1561         count = TRIPLE_TARG(ins->sizes);
1562         vector = &TARG(ins, 0);
1563         if (count) {
1564                 if (!last) {
1565                         ret = vector;
1566                 }
1567                 else if ((last >= vector) && (last < (vector + count - 1))) {
1568                         ret = last + 1;
1569                 }
1570                 else if ((last == (vector + count - 1)) && 
1571                         TRIPLE_RHS(ins->sizes)) {
1572                         ret = &ins->next;
1573                 }
1574         }
1575         return ret;
1576 }
1577
1578
1579 static void verify_use(struct compile_state *state,
1580         struct triple *user, struct triple *used)
1581 {
1582         int size, i;
1583         size = TRIPLE_SIZE(user->sizes);
1584         for(i = 0; i < size; i++) {
1585                 if (user->param[i] == used) {
1586                         break;
1587                 }
1588         }
1589         if (triple_is_branch(state, user)) {
1590                 if (user->next == used) {
1591                         i = -1;
1592                 }
1593         }
1594         if (i == size) {
1595                 internal_error(state, user, "%s(%p) does not use %s(%p)",
1596                         tops(user->op), user, tops(used->op), used);
1597         }
1598 }
1599
1600 static int find_rhs_use(struct compile_state *state, 
1601         struct triple *user, struct triple *used)
1602 {
1603         struct triple **param;
1604         int size, i;
1605         verify_use(state, user, used);
1606         size = TRIPLE_RHS(user->sizes);
1607         param = &RHS(user, 0);
1608         for(i = 0; i < size; i++) {
1609                 if (param[i] == used) {
1610                         return i;
1611                 }
1612         }
1613         return -1;
1614 }
1615
1616 static void free_triple(struct compile_state *state, struct triple *ptr)
1617 {
1618         size_t size;
1619         size = sizeof(*ptr) - sizeof(ptr->param) +
1620                 (sizeof(ptr->param[0])*TRIPLE_SIZE(ptr->sizes));
1621         ptr->prev->next = ptr->next;
1622         ptr->next->prev = ptr->prev;
1623         if (ptr->use) {
1624                 internal_error(state, ptr, "ptr->use != 0");
1625         }
1626         memset(ptr, -1, size);
1627         xfree(ptr);
1628 }
1629
1630 static void release_triple(struct compile_state *state, struct triple *ptr)
1631 {
1632         struct triple_set *set, *next;
1633         struct triple **expr;
1634         /* Remove ptr from use chains where it is the user */
1635         expr = triple_rhs(state, ptr, 0);
1636         for(; expr; expr = triple_rhs(state, ptr, expr)) {
1637                 if (*expr) {
1638                         unuse_triple(*expr, ptr);
1639                 }
1640         }
1641         expr = triple_lhs(state, ptr, 0);
1642         for(; expr; expr = triple_lhs(state, ptr, expr)) {
1643                 if (*expr) {
1644                         unuse_triple(*expr, ptr);
1645                 }
1646         }
1647         expr = triple_misc(state, ptr, 0);
1648         for(; expr; expr = triple_misc(state, ptr, expr)) {
1649                 if (*expr) {
1650                         unuse_triple(*expr, ptr);
1651                 }
1652         }
1653         expr = triple_targ(state, ptr, 0);
1654         for(; expr; expr = triple_targ(state, ptr, expr)) {
1655                 if (*expr) {
1656                         unuse_triple(*expr, ptr);
1657                 }
1658         }
1659         /* Reomve ptr from use chains where it is used */
1660         for(set = ptr->use; set; set = next) {
1661                 next = set->next;
1662                 expr = triple_rhs(state, set->member, 0);
1663                 for(; expr; expr = triple_rhs(state, set->member, expr)) {
1664                         if (*expr == ptr) {
1665                                 *expr = &zero_triple;
1666                         }
1667                 }
1668                 expr = triple_lhs(state, set->member, 0);
1669                 for(; expr; expr = triple_lhs(state, set->member, expr)) {
1670                         if (*expr == ptr) {
1671                                 *expr = &zero_triple;
1672                         }
1673                 }
1674                 expr = triple_misc(state, set->member, 0);
1675                 for(; expr; expr = triple_misc(state, set->member, expr)) {
1676                         if (*expr == ptr) {
1677                                 *expr = &zero_triple;
1678                         }
1679                 }
1680                 expr = triple_targ(state, set->member, 0);
1681                 for(; expr; expr = triple_targ(state, set->member, expr)) {
1682                         if (*expr == ptr) {
1683                                 *expr = &zero_triple;
1684                         }
1685                 }
1686                 unuse_triple(ptr, set->member);
1687         }
1688         free_triple(state, ptr);
1689 }
1690
1691 static void print_triple(struct compile_state *state, struct triple *ptr);
1692
1693 #define TOK_UNKNOWN     0
1694 #define TOK_SPACE       1
1695 #define TOK_SEMI        2
1696 #define TOK_LBRACE      3
1697 #define TOK_RBRACE      4
1698 #define TOK_COMMA       5
1699 #define TOK_EQ          6
1700 #define TOK_COLON       7
1701 #define TOK_LBRACKET    8
1702 #define TOK_RBRACKET    9
1703 #define TOK_LPAREN      10
1704 #define TOK_RPAREN      11
1705 #define TOK_STAR        12
1706 #define TOK_DOTS        13
1707 #define TOK_MORE        14
1708 #define TOK_LESS        15
1709 #define TOK_TIMESEQ     16
1710 #define TOK_DIVEQ       17
1711 #define TOK_MODEQ       18
1712 #define TOK_PLUSEQ      19
1713 #define TOK_MINUSEQ     20
1714 #define TOK_SLEQ        21
1715 #define TOK_SREQ        22
1716 #define TOK_ANDEQ       23
1717 #define TOK_XOREQ       24
1718 #define TOK_OREQ        25
1719 #define TOK_EQEQ        26
1720 #define TOK_NOTEQ       27
1721 #define TOK_QUEST       28
1722 #define TOK_LOGOR       29
1723 #define TOK_LOGAND      30
1724 #define TOK_OR          31
1725 #define TOK_AND         32
1726 #define TOK_XOR         33
1727 #define TOK_LESSEQ      34
1728 #define TOK_MOREEQ      35
1729 #define TOK_SL          36
1730 #define TOK_SR          37
1731 #define TOK_PLUS        38
1732 #define TOK_MINUS       39
1733 #define TOK_DIV         40
1734 #define TOK_MOD         41
1735 #define TOK_PLUSPLUS    42
1736 #define TOK_MINUSMINUS  43
1737 #define TOK_BANG        44
1738 #define TOK_ARROW       45
1739 #define TOK_DOT         46
1740 #define TOK_TILDE       47
1741 #define TOK_LIT_STRING  48
1742 #define TOK_LIT_CHAR    49
1743 #define TOK_LIT_INT     50
1744 #define TOK_LIT_FLOAT   51
1745 #define TOK_MACRO       52
1746 #define TOK_CONCATENATE 53
1747
1748 #define TOK_IDENT       54
1749 #define TOK_STRUCT_NAME 55
1750 #define TOK_ENUM_CONST  56
1751 #define TOK_TYPE_NAME   57
1752
1753 #define TOK_AUTO        58
1754 #define TOK_BREAK       59
1755 #define TOK_CASE        60
1756 #define TOK_CHAR        61
1757 #define TOK_CONST       62
1758 #define TOK_CONTINUE    63
1759 #define TOK_DEFAULT     64
1760 #define TOK_DO          65
1761 #define TOK_DOUBLE      66
1762 #define TOK_ELSE        67
1763 #define TOK_ENUM        68
1764 #define TOK_EXTERN      69
1765 #define TOK_FLOAT       70
1766 #define TOK_FOR         71
1767 #define TOK_GOTO        72
1768 #define TOK_IF          73
1769 #define TOK_INLINE      74
1770 #define TOK_INT         75
1771 #define TOK_LONG        76
1772 #define TOK_REGISTER    77
1773 #define TOK_RESTRICT    78
1774 #define TOK_RETURN      79
1775 #define TOK_SHORT       80
1776 #define TOK_SIGNED      81
1777 #define TOK_SIZEOF      82
1778 #define TOK_STATIC      83
1779 #define TOK_STRUCT      84
1780 #define TOK_SWITCH      85
1781 #define TOK_TYPEDEF     86
1782 #define TOK_UNION       87
1783 #define TOK_UNSIGNED    88
1784 #define TOK_VOID        89
1785 #define TOK_VOLATILE    90
1786 #define TOK_WHILE       91
1787 #define TOK_ASM         92
1788 #define TOK_ATTRIBUTE   93
1789 #define TOK_ALIGNOF     94
1790 #define TOK_FIRST_KEYWORD TOK_AUTO
1791 #define TOK_LAST_KEYWORD  TOK_ALIGNOF
1792
1793 #define TOK_DEFINE      100
1794 #define TOK_UNDEF       101
1795 #define TOK_INCLUDE     102
1796 #define TOK_LINE        103
1797 #define TOK_ERROR       104
1798 #define TOK_WARNING     105
1799 #define TOK_PRAGMA      106
1800 #define TOK_IFDEF       107
1801 #define TOK_IFNDEF      108
1802 #define TOK_ELIF        109
1803 #define TOK_ENDIF       110
1804
1805 #define TOK_FIRST_MACRO TOK_DEFINE
1806 #define TOK_LAST_MACRO  TOK_ENDIF
1807          
1808 #define TOK_EOF         111
1809
1810 static const char *tokens[] = {
1811 [TOK_UNKNOWN     ] = "unknown",
1812 [TOK_SPACE       ] = ":space:",
1813 [TOK_SEMI        ] = ";",
1814 [TOK_LBRACE      ] = "{",
1815 [TOK_RBRACE      ] = "}",
1816 [TOK_COMMA       ] = ",",
1817 [TOK_EQ          ] = "=",
1818 [TOK_COLON       ] = ":",
1819 [TOK_LBRACKET    ] = "[",
1820 [TOK_RBRACKET    ] = "]",
1821 [TOK_LPAREN      ] = "(",
1822 [TOK_RPAREN      ] = ")",
1823 [TOK_STAR        ] = "*",
1824 [TOK_DOTS        ] = "...",
1825 [TOK_MORE        ] = ">",
1826 [TOK_LESS        ] = "<",
1827 [TOK_TIMESEQ     ] = "*=",
1828 [TOK_DIVEQ       ] = "/=",
1829 [TOK_MODEQ       ] = "%=",
1830 [TOK_PLUSEQ      ] = "+=",
1831 [TOK_MINUSEQ     ] = "-=",
1832 [TOK_SLEQ        ] = "<<=",
1833 [TOK_SREQ        ] = ">>=",
1834 [TOK_ANDEQ       ] = "&=",
1835 [TOK_XOREQ       ] = "^=",
1836 [TOK_OREQ        ] = "|=",
1837 [TOK_EQEQ        ] = "==",
1838 [TOK_NOTEQ       ] = "!=",
1839 [TOK_QUEST       ] = "?",
1840 [TOK_LOGOR       ] = "||",
1841 [TOK_LOGAND      ] = "&&",
1842 [TOK_OR          ] = "|",
1843 [TOK_AND         ] = "&",
1844 [TOK_XOR         ] = "^",
1845 [TOK_LESSEQ      ] = "<=",
1846 [TOK_MOREEQ      ] = ">=",
1847 [TOK_SL          ] = "<<",
1848 [TOK_SR          ] = ">>",
1849 [TOK_PLUS        ] = "+",
1850 [TOK_MINUS       ] = "-",
1851 [TOK_DIV         ] = "/",
1852 [TOK_MOD         ] = "%",
1853 [TOK_PLUSPLUS    ] = "++",
1854 [TOK_MINUSMINUS  ] = "--",
1855 [TOK_BANG        ] = "!",
1856 [TOK_ARROW       ] = "->",
1857 [TOK_DOT         ] = ".",
1858 [TOK_TILDE       ] = "~",
1859 [TOK_LIT_STRING  ] = ":string:",
1860 [TOK_IDENT       ] = ":ident:",
1861 [TOK_TYPE_NAME   ] = ":typename:",
1862 [TOK_LIT_CHAR    ] = ":char:",
1863 [TOK_LIT_INT     ] = ":integer:",
1864 [TOK_LIT_FLOAT   ] = ":float:",
1865 [TOK_MACRO       ] = "#",
1866 [TOK_CONCATENATE ] = "##",
1867
1868 [TOK_AUTO        ] = "auto",
1869 [TOK_BREAK       ] = "break",
1870 [TOK_CASE        ] = "case",
1871 [TOK_CHAR        ] = "char",
1872 [TOK_CONST       ] = "const",
1873 [TOK_CONTINUE    ] = "continue",
1874 [TOK_DEFAULT     ] = "default",
1875 [TOK_DO          ] = "do",
1876 [TOK_DOUBLE      ] = "double",
1877 [TOK_ELSE        ] = "else",
1878 [TOK_ENUM        ] = "enum",
1879 [TOK_EXTERN      ] = "extern",
1880 [TOK_FLOAT       ] = "float",
1881 [TOK_FOR         ] = "for",
1882 [TOK_GOTO        ] = "goto",
1883 [TOK_IF          ] = "if",
1884 [TOK_INLINE      ] = "inline",
1885 [TOK_INT         ] = "int",
1886 [TOK_LONG        ] = "long",
1887 [TOK_REGISTER    ] = "register",
1888 [TOK_RESTRICT    ] = "restrict",
1889 [TOK_RETURN      ] = "return",
1890 [TOK_SHORT       ] = "short",
1891 [TOK_SIGNED      ] = "signed",
1892 [TOK_SIZEOF      ] = "sizeof",
1893 [TOK_STATIC      ] = "static",
1894 [TOK_STRUCT      ] = "struct",
1895 [TOK_SWITCH      ] = "switch",
1896 [TOK_TYPEDEF     ] = "typedef",
1897 [TOK_UNION       ] = "union",
1898 [TOK_UNSIGNED    ] = "unsigned",
1899 [TOK_VOID        ] = "void",
1900 [TOK_VOLATILE    ] = "volatile",
1901 [TOK_WHILE       ] = "while",
1902 [TOK_ASM         ] = "asm",
1903 [TOK_ATTRIBUTE   ] = "__attribute__",
1904 [TOK_ALIGNOF     ] = "__alignof__",
1905
1906 [TOK_DEFINE      ] = "define",
1907 [TOK_UNDEF       ] = "undef",
1908 [TOK_INCLUDE     ] = "include",
1909 [TOK_LINE        ] = "line",
1910 [TOK_ERROR       ] = "error",
1911 [TOK_WARNING     ] = "warning",
1912 [TOK_PRAGMA      ] = "pragma",
1913 [TOK_IFDEF       ] = "ifdef",
1914 [TOK_IFNDEF      ] = "ifndef",
1915 [TOK_ELIF        ] = "elif",
1916 [TOK_ENDIF       ] = "endif",
1917
1918 [TOK_EOF         ] = "EOF",
1919 };
1920
1921 static unsigned int hash(const char *str, int str_len)
1922 {
1923         unsigned int hash;
1924         const char *end;
1925         end = str + str_len;
1926         hash = 0;
1927         for(; str < end; str++) {
1928                 hash = (hash *263) + *str;
1929         }
1930         hash = hash & (HASH_TABLE_SIZE -1);
1931         return hash;
1932 }
1933
1934 static struct hash_entry *lookup(
1935         struct compile_state *state, const char *name, int name_len)
1936 {
1937         struct hash_entry *entry;
1938         unsigned int index;
1939         index = hash(name, name_len);
1940         entry = state->hash_table[index];
1941         while(entry && 
1942                 ((entry->name_len != name_len) ||
1943                         (memcmp(entry->name, name, name_len) != 0))) {
1944                 entry = entry->next;
1945         }
1946         if (!entry) {
1947                 char *new_name;
1948                 /* Get a private copy of the name */
1949                 new_name = xmalloc(name_len + 1, "hash_name");
1950                 memcpy(new_name, name, name_len);
1951                 new_name[name_len] = '\0';
1952
1953                 /* Create a new hash entry */
1954                 entry = xcmalloc(sizeof(*entry), "hash_entry");
1955                 entry->next = state->hash_table[index];
1956                 entry->name = new_name;
1957                 entry->name_len = name_len;
1958
1959                 /* Place the new entry in the hash table */
1960                 state->hash_table[index] = entry;
1961         }
1962         return entry;
1963 }
1964
1965 static void ident_to_keyword(struct compile_state *state, struct token *tk)
1966 {
1967         struct hash_entry *entry;
1968         entry = tk->ident;
1969         if (entry && ((entry->tok == TOK_TYPE_NAME) ||
1970                 (entry->tok == TOK_ENUM_CONST) ||
1971                 ((entry->tok >= TOK_FIRST_KEYWORD) && 
1972                         (entry->tok <= TOK_LAST_KEYWORD)))) {
1973                 tk->tok = entry->tok;
1974         }
1975 }
1976
1977 static void ident_to_macro(struct compile_state *state, struct token *tk)
1978 {
1979         struct hash_entry *entry;
1980         entry = tk->ident;
1981         if (entry && 
1982                 (entry->tok >= TOK_FIRST_MACRO) &&
1983                 (entry->tok <= TOK_LAST_MACRO)) {
1984                 tk->tok = entry->tok;
1985         }
1986 }
1987
1988 static void hash_keyword(
1989         struct compile_state *state, const char *keyword, int tok)
1990 {
1991         struct hash_entry *entry;
1992         entry = lookup(state, keyword, strlen(keyword));
1993         if (entry && entry->tok != TOK_UNKNOWN) {
1994                 die("keyword %s already hashed", keyword);
1995         }
1996         entry->tok  = tok;
1997 }
1998
1999 static void symbol(
2000         struct compile_state *state, struct hash_entry *ident,
2001         struct symbol **chain, struct triple *def, struct type *type)
2002 {
2003         struct symbol *sym;
2004         if (*chain && ((*chain)->scope_depth == state->scope_depth)) {
2005                 error(state, 0, "%s already defined", ident->name);
2006         }
2007         sym = xcmalloc(sizeof(*sym), "symbol");
2008         sym->ident = ident;
2009         sym->def   = def;
2010         sym->type  = type;
2011         sym->scope_depth = state->scope_depth;
2012         sym->next = *chain;
2013         *chain    = sym;
2014 }
2015
2016 static void start_scope(struct compile_state *state)
2017 {
2018         state->scope_depth++;
2019 }
2020
2021 static void end_scope_syms(struct symbol **chain, int depth)
2022 {
2023         struct symbol *sym, *next;
2024         sym = *chain;
2025         while(sym && (sym->scope_depth == depth)) {
2026                 next = sym->next;
2027                 xfree(sym);
2028                 sym = next;
2029         }
2030         *chain = sym;
2031 }
2032
2033 static void end_scope(struct compile_state *state)
2034 {
2035         int i;
2036         int depth;
2037         /* Walk through the hash table and remove all symbols
2038          * in the current scope. 
2039          */
2040         depth = state->scope_depth;
2041         for(i = 0; i < HASH_TABLE_SIZE; i++) {
2042                 struct hash_entry *entry;
2043                 entry = state->hash_table[i];
2044                 while(entry) {
2045                         end_scope_syms(&entry->sym_label,  depth);
2046                         end_scope_syms(&entry->sym_struct, depth);
2047                         end_scope_syms(&entry->sym_ident,  depth);
2048                         entry = entry->next;
2049                 }
2050         }
2051         state->scope_depth = depth - 1;
2052 }
2053
2054 static void register_keywords(struct compile_state *state)
2055 {
2056         hash_keyword(state, "auto",          TOK_AUTO);
2057         hash_keyword(state, "break",         TOK_BREAK);
2058         hash_keyword(state, "case",          TOK_CASE);
2059         hash_keyword(state, "char",          TOK_CHAR);
2060         hash_keyword(state, "const",         TOK_CONST);
2061         hash_keyword(state, "continue",      TOK_CONTINUE);
2062         hash_keyword(state, "default",       TOK_DEFAULT);
2063         hash_keyword(state, "do",            TOK_DO);
2064         hash_keyword(state, "double",        TOK_DOUBLE);
2065         hash_keyword(state, "else",          TOK_ELSE);
2066         hash_keyword(state, "enum",          TOK_ENUM);
2067         hash_keyword(state, "extern",        TOK_EXTERN);
2068         hash_keyword(state, "float",         TOK_FLOAT);
2069         hash_keyword(state, "for",           TOK_FOR);
2070         hash_keyword(state, "goto",          TOK_GOTO);
2071         hash_keyword(state, "if",            TOK_IF);
2072         hash_keyword(state, "inline",        TOK_INLINE);
2073         hash_keyword(state, "int",           TOK_INT);
2074         hash_keyword(state, "long",          TOK_LONG);
2075         hash_keyword(state, "register",      TOK_REGISTER);
2076         hash_keyword(state, "restrict",      TOK_RESTRICT);
2077         hash_keyword(state, "return",        TOK_RETURN);
2078         hash_keyword(state, "short",         TOK_SHORT);
2079         hash_keyword(state, "signed",        TOK_SIGNED);
2080         hash_keyword(state, "sizeof",        TOK_SIZEOF);
2081         hash_keyword(state, "static",        TOK_STATIC);
2082         hash_keyword(state, "struct",        TOK_STRUCT);
2083         hash_keyword(state, "switch",        TOK_SWITCH);
2084         hash_keyword(state, "typedef",       TOK_TYPEDEF);
2085         hash_keyword(state, "union",         TOK_UNION);
2086         hash_keyword(state, "unsigned",      TOK_UNSIGNED);
2087         hash_keyword(state, "void",          TOK_VOID);
2088         hash_keyword(state, "volatile",      TOK_VOLATILE);
2089         hash_keyword(state, "__volatile__",  TOK_VOLATILE);
2090         hash_keyword(state, "while",         TOK_WHILE);
2091         hash_keyword(state, "asm",           TOK_ASM);
2092         hash_keyword(state, "__asm__",       TOK_ASM);
2093         hash_keyword(state, "__attribute__", TOK_ATTRIBUTE);
2094         hash_keyword(state, "__alignof__",   TOK_ALIGNOF);
2095 }
2096
2097 static void register_macro_keywords(struct compile_state *state)
2098 {
2099         hash_keyword(state, "define",        TOK_DEFINE);
2100         hash_keyword(state, "undef",         TOK_UNDEF);
2101         hash_keyword(state, "include",       TOK_INCLUDE);
2102         hash_keyword(state, "line",          TOK_LINE);
2103         hash_keyword(state, "error",         TOK_ERROR);
2104         hash_keyword(state, "warning",       TOK_WARNING);
2105         hash_keyword(state, "pragma",        TOK_PRAGMA);
2106         hash_keyword(state, "ifdef",         TOK_IFDEF);
2107         hash_keyword(state, "ifndef",        TOK_IFNDEF);
2108         hash_keyword(state, "elif",          TOK_ELIF);
2109         hash_keyword(state, "endif",         TOK_ENDIF);
2110 }
2111
2112 static int spacep(int c)
2113 {
2114         int ret = 0;
2115         switch(c) {
2116         case ' ':
2117         case '\t':
2118         case '\f':
2119         case '\v':
2120         case '\r':
2121         case '\n':
2122                 ret = 1;
2123                 break;
2124         }
2125         return ret;
2126 }
2127
2128 static int digitp(int c)
2129 {
2130         int ret = 0;
2131         switch(c) {
2132         case '0': case '1': case '2': case '3': case '4': 
2133         case '5': case '6': case '7': case '8': case '9':
2134                 ret = 1;
2135                 break;
2136         }
2137         return ret;
2138 }
2139
2140 static int hexdigitp(int c)
2141 {
2142         int ret = 0;
2143         switch(c) {
2144         case '0': case '1': case '2': case '3': case '4': 
2145         case '5': case '6': case '7': case '8': case '9':
2146         case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
2147         case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
2148                 ret = 1;
2149                 break;
2150         }
2151         return ret;
2152 }
2153 static int hexdigval(int c) 
2154 {
2155         int val = -1;
2156         if ((c >= '0') && (c <= '9')) {
2157                 val = c - '0';
2158         }
2159         else if ((c >= 'A') && (c <= 'F')) {
2160                 val = 10 + (c - 'A');
2161         }
2162         else if ((c >= 'a') && (c <= 'f')) {
2163                 val = 10 + (c - 'a');
2164         }
2165         return val;
2166 }
2167
2168 static int octdigitp(int c)
2169 {
2170         int ret = 0;
2171         switch(c) {
2172         case '0': case '1': case '2': case '3': 
2173         case '4': case '5': case '6': case '7':
2174                 ret = 1;
2175                 break;
2176         }
2177         return ret;
2178 }
2179 static int octdigval(int c)
2180 {
2181         int val = -1;
2182         if ((c >= '0') && (c <= '7')) {
2183                 val = c - '0';
2184         }
2185         return val;
2186 }
2187
2188 static int letterp(int c)
2189 {
2190         int ret = 0;
2191         switch(c) {
2192         case 'a': case 'b': case 'c': case 'd': case 'e':
2193         case 'f': case 'g': case 'h': case 'i': case 'j':
2194         case 'k': case 'l': case 'm': case 'n': case 'o':
2195         case 'p': case 'q': case 'r': case 's': case 't':
2196         case 'u': case 'v': case 'w': case 'x': case 'y':
2197         case 'z':
2198         case 'A': case 'B': case 'C': case 'D': case 'E':
2199         case 'F': case 'G': case 'H': case 'I': case 'J':
2200         case 'K': case 'L': case 'M': case 'N': case 'O':
2201         case 'P': case 'Q': case 'R': case 'S': case 'T':
2202         case 'U': case 'V': case 'W': case 'X': case 'Y':
2203         case 'Z':
2204         case '_':
2205                 ret = 1;
2206                 break;
2207         }
2208         return ret;
2209 }
2210
2211 static int char_value(struct compile_state *state,
2212         const signed char **strp, const signed char *end)
2213 {
2214         const signed char *str;
2215         int c;
2216         str = *strp;
2217         c = *str++;
2218         if ((c == '\\') && (str < end)) {
2219                 switch(*str) {
2220                 case 'n':  c = '\n'; str++; break;
2221                 case 't':  c = '\t'; str++; break;
2222                 case 'v':  c = '\v'; str++; break;
2223                 case 'b':  c = '\b'; str++; break;
2224                 case 'r':  c = '\r'; str++; break;
2225                 case 'f':  c = '\f'; str++; break;
2226                 case 'a':  c = '\a'; str++; break;
2227                 case '\\': c = '\\'; str++; break;
2228                 case '?':  c = '?';  str++; break;
2229                 case '\'': c = '\''; str++; break;
2230                 case '"':  c = '"';  break;
2231                 case 'x': 
2232                         c = 0;
2233                         str++;
2234                         while((str < end) && hexdigitp(*str)) {
2235                                 c <<= 4;
2236                                 c += hexdigval(*str);
2237                                 str++;
2238                         }
2239                         break;
2240                 case '0': case '1': case '2': case '3': 
2241                 case '4': case '5': case '6': case '7':
2242                         c = 0;
2243                         while((str < end) && octdigitp(*str)) {
2244                                 c <<= 3;
2245                                 c += octdigval(*str);
2246                                 str++;
2247                         }
2248                         break;
2249                 default:
2250                         error(state, 0, "Invalid character constant");
2251                         break;
2252                 }
2253         }
2254         *strp = str;
2255         return c;
2256 }
2257
2258 static char *after_digits(char *ptr, char *end)
2259 {
2260         while((ptr < end) && digitp(*ptr)) {
2261                 ptr++;
2262         }
2263         return ptr;
2264 }
2265
2266 static char *after_octdigits(char *ptr, char *end)
2267 {
2268         while((ptr < end) && octdigitp(*ptr)) {
2269                 ptr++;
2270         }
2271         return ptr;
2272 }
2273
2274 static char *after_hexdigits(char *ptr, char *end)
2275 {
2276         while((ptr < end) && hexdigitp(*ptr)) {
2277                 ptr++;
2278         }
2279         return ptr;
2280 }
2281
2282 static void save_string(struct compile_state *state, 
2283         struct token *tk, char *start, char *end, const char *id)
2284 {
2285         char *str;
2286         int str_len;
2287         /* Create a private copy of the string */
2288         str_len = end - start + 1;
2289         str = xmalloc(str_len + 1, id);
2290         memcpy(str, start, str_len);
2291         str[str_len] = '\0';
2292
2293         /* Store the copy in the token */
2294         tk->val.str = str;
2295         tk->str_len = str_len;
2296 }
2297 static void next_token(struct compile_state *state, int index)
2298 {
2299         struct file_state *file;
2300         struct token *tk;
2301         char *token;
2302         int c, c1, c2, c3;
2303         char *tokp, *end;
2304         int tok;
2305 next_token:
2306         file = state->file;
2307         tk = &state->token[index];
2308         tk->str_len = 0;
2309         tk->ident = 0;
2310         token = tokp = file->pos;
2311         end = file->buf + file->size;
2312         tok = TOK_UNKNOWN;
2313         c = -1;
2314         if (tokp < end) {
2315                 c = *tokp;
2316         }
2317         c1 = -1;
2318         if ((tokp + 1) < end) {
2319                 c1 = tokp[1];
2320         }
2321         c2 = -1;
2322         if ((tokp + 2) < end) {
2323                 c2 = tokp[2];
2324         }
2325         c3 = -1;
2326         if ((tokp + 3) < end) {
2327                 c3 = tokp[3];
2328         }
2329         if (tokp >= end) {
2330                 tok = TOK_EOF;
2331                 tokp = end;
2332         }
2333         /* Whitespace */
2334         else if (spacep(c)) {
2335                 tok = TOK_SPACE;
2336                 while ((tokp < end) && spacep(c)) {
2337                         if (c == '\n') {
2338                                 file->line++;
2339                                 file->line_start = tokp + 1;
2340                         }
2341                         c = *(++tokp);
2342                 }
2343                 if (!spacep(c)) {
2344                         tokp--;
2345                 }
2346         }
2347         /* EOL Comments */
2348         else if ((c == '/') && (c1 == '/')) {
2349                 tok = TOK_SPACE;
2350                 for(tokp += 2; tokp < end; tokp++) {
2351                         c = *tokp;
2352                         if (c == '\n') {
2353                                 file->line++;
2354                                 file->line_start = tokp +1;
2355                                 break;
2356                         }
2357                 }
2358         }
2359         /* Comments */
2360         else if ((c == '/') && (c1 == '*')) {
2361                 int line;
2362                 char *line_start;
2363                 line = file->line;
2364                 line_start = file->line_start;
2365                 for(tokp += 2; (end - tokp) >= 2; tokp++) {
2366                         c = *tokp;
2367                         if (c == '\n') {
2368                                 line++;
2369                                 line_start = tokp +1;
2370                         }
2371                         else if ((c == '*') && (tokp[1] == '/')) {
2372                                 tok = TOK_SPACE;
2373                                 tokp += 1;
2374                                 break;
2375                         }
2376                 }
2377                 if (tok == TOK_UNKNOWN) {
2378                         error(state, 0, "unterminated comment");
2379                 }
2380                 file->line = line;
2381                 file->line_start = line_start;
2382         }
2383         /* string constants */
2384         else if ((c == '"') ||
2385                 ((c == 'L') && (c1 == '"'))) {
2386                 int line;
2387                 char *line_start;
2388                 int wchar;
2389                 line = file->line;
2390                 line_start = file->line_start;
2391                 wchar = 0;
2392                 if (c == 'L') {
2393                         wchar = 1;
2394                         tokp++;
2395                 }
2396                 for(tokp += 1; tokp < end; tokp++) {
2397                         c = *tokp;
2398                         if (c == '\n') {
2399                                 line++;
2400                                 line_start = tokp + 1;
2401                         }
2402                         else if ((c == '\\') && (tokp +1 < end)) {
2403                                 tokp++;
2404                         }
2405                         else if (c == '"') {
2406                                 tok = TOK_LIT_STRING;
2407                                 break;
2408                         }
2409                 }
2410                 if (tok == TOK_UNKNOWN) {
2411                         error(state, 0, "unterminated string constant");
2412                 }
2413                 if (line != file->line) {
2414                         warning(state, 0, "multiline string constant");
2415                 }
2416                 file->line = line;
2417                 file->line_start = line_start;
2418
2419                 /* Save the string value */
2420                 save_string(state, tk, token, tokp, "literal string");
2421         }
2422         /* character constants */
2423         else if ((c == '\'') ||
2424                 ((c == 'L') && (c1 == '\''))) {
2425                 int line;
2426                 char *line_start;
2427                 int wchar;
2428                 line = file->line;
2429                 line_start = file->line_start;
2430                 wchar = 0;
2431                 if (c == 'L') {
2432                         wchar = 1;
2433                         tokp++;
2434                 }
2435                 for(tokp += 1; tokp < end; tokp++) {
2436                         c = *tokp;
2437                         if (c == '\n') {
2438                                 line++;
2439                                 line_start = tokp + 1;
2440                         }
2441                         else if ((c == '\\') && (tokp +1 < end)) {
2442                                 tokp++;
2443                         }
2444                         else if (c == '\'') {
2445                                 tok = TOK_LIT_CHAR;
2446                                 break;
2447                         }
2448                 }
2449                 if (tok == TOK_UNKNOWN) {
2450                         error(state, 0, "unterminated character constant");
2451                 }
2452                 if (line != file->line) {
2453                         warning(state, 0, "multiline character constant");
2454                 }
2455                 file->line = line;
2456                 file->line_start = line_start;
2457
2458                 /* Save the character value */
2459                 save_string(state, tk, token, tokp, "literal character");
2460         }
2461         /* integer and floating constants 
2462          * Integer Constants
2463          * {digits}
2464          * 0[Xx]{hexdigits}
2465          * 0{octdigit}+
2466          * 
2467          * Floating constants
2468          * {digits}.{digits}[Ee][+-]?{digits}
2469          * {digits}.{digits}
2470          * {digits}[Ee][+-]?{digits}
2471          * .{digits}[Ee][+-]?{digits}
2472          * .{digits}
2473          */
2474         
2475         else if (digitp(c) || ((c == '.') && (digitp(c1)))) {
2476                 char *next, *new;
2477                 int is_float;
2478                 is_float = 0;
2479                 if (c != '.') {
2480                         next = after_digits(tokp, end);
2481                 }
2482                 else {
2483                         next = tokp;
2484                 }
2485                 if (next[0] == '.') {
2486                         new = after_digits(next, end);
2487                         is_float = (new != next);
2488                         next = new;
2489                 }
2490                 if ((next[0] == 'e') || (next[0] == 'E')) {
2491                         if (((next + 1) < end) && 
2492                                 ((next[1] == '+') || (next[1] == '-'))) {
2493                                 next++;
2494                         }
2495                         new = after_digits(next, end);
2496                         is_float = (new != next);
2497                         next = new;
2498                 }
2499                 if (is_float) {
2500                         tok = TOK_LIT_FLOAT;
2501                         if ((next < end) && (
2502                                 (next[0] == 'f') ||
2503                                 (next[0] == 'F') ||
2504                                 (next[0] == 'l') ||
2505                                 (next[0] == 'L'))
2506                                 ) {
2507                                 next++;
2508                         }
2509                 }
2510                 if (!is_float && digitp(c)) {
2511                         tok = TOK_LIT_INT;
2512                         if ((c == '0') && ((c1 == 'x') || (c1 == 'X'))) {
2513                                 next = after_hexdigits(tokp + 2, end);
2514                         }
2515                         else if (c == '0') {
2516                                 next = after_octdigits(tokp, end);
2517                         }
2518                         else {
2519                                 next = after_digits(tokp, end);
2520                         }
2521                         /* crazy integer suffixes */
2522                         if ((next < end) && 
2523                                 ((next[0] == 'u') || (next[0] == 'U'))) { 
2524                                 next++;
2525                                 if ((next < end) &&
2526                                         ((next[0] == 'l') || (next[0] == 'L'))) {
2527                                         next++;
2528                                 }
2529                         }
2530                         else if ((next < end) &&
2531                                 ((next[0] == 'l') || (next[0] == 'L'))) {
2532                                 next++;
2533                                 if ((next < end) && 
2534                                         ((next[0] == 'u') || (next[0] == 'U'))) { 
2535                                         next++;
2536                                 }
2537                         }
2538                 }
2539                 tokp = next - 1;
2540
2541                 /* Save the integer/floating point value */
2542                 save_string(state, tk, token, tokp, "literal number");
2543         }
2544         /* identifiers */
2545         else if (letterp(c)) {
2546                 tok = TOK_IDENT;
2547                 for(tokp += 1; tokp < end; tokp++) {
2548                         c = *tokp;
2549                         if (!letterp(c) && !digitp(c)) {
2550                                 break;
2551                         }
2552                 }
2553                 tokp -= 1;
2554                 tk->ident = lookup(state, token, tokp +1 - token);
2555         }
2556         /* C99 alternate macro characters */
2557         else if ((c == '%') && (c1 == ':') && (c2 == '%') && (c3 == ':')) { 
2558                 tokp += 3; 
2559                 tok = TOK_CONCATENATE; 
2560         }
2561         else if ((c == '.') && (c1 == '.') && (c2 == '.')) { tokp += 2; tok = TOK_DOTS; }
2562         else if ((c == '<') && (c1 == '<') && (c2 == '=')) { tokp += 2; tok = TOK_SLEQ; }
2563         else if ((c == '>') && (c1 == '>') && (c2 == '=')) { tokp += 2; tok = TOK_SREQ; }
2564         else if ((c == '*') && (c1 == '=')) { tokp += 1; tok = TOK_TIMESEQ; }
2565         else if ((c == '/') && (c1 == '=')) { tokp += 1; tok = TOK_DIVEQ; }
2566         else if ((c == '%') && (c1 == '=')) { tokp += 1; tok = TOK_MODEQ; }
2567         else if ((c == '+') && (c1 == '=')) { tokp += 1; tok = TOK_PLUSEQ; }
2568         else if ((c == '-') && (c1 == '=')) { tokp += 1; tok = TOK_MINUSEQ; }
2569         else if ((c == '&') && (c1 == '=')) { tokp += 1; tok = TOK_ANDEQ; }
2570         else if ((c == '^') && (c1 == '=')) { tokp += 1; tok = TOK_XOREQ; }
2571         else if ((c == '|') && (c1 == '=')) { tokp += 1; tok = TOK_OREQ; }
2572         else if ((c == '=') && (c1 == '=')) { tokp += 1; tok = TOK_EQEQ; }
2573         else if ((c == '!') && (c1 == '=')) { tokp += 1; tok = TOK_NOTEQ; }
2574         else if ((c == '|') && (c1 == '|')) { tokp += 1; tok = TOK_LOGOR; }
2575         else if ((c == '&') && (c1 == '&')) { tokp += 1; tok = TOK_LOGAND; }
2576         else if ((c == '<') && (c1 == '=')) { tokp += 1; tok = TOK_LESSEQ; }
2577         else if ((c == '>') && (c1 == '=')) { tokp += 1; tok = TOK_MOREEQ; }
2578         else if ((c == '<') && (c1 == '<')) { tokp += 1; tok = TOK_SL; }
2579         else if ((c == '>') && (c1 == '>')) { tokp += 1; tok = TOK_SR; }
2580         else if ((c == '+') && (c1 == '+')) { tokp += 1; tok = TOK_PLUSPLUS; }
2581         else if ((c == '-') && (c1 == '-')) { tokp += 1; tok = TOK_MINUSMINUS; }
2582         else if ((c == '-') && (c1 == '>')) { tokp += 1; tok = TOK_ARROW; }
2583         else if ((c == '<') && (c1 == ':')) { tokp += 1; tok = TOK_LBRACKET; }
2584         else if ((c == ':') && (c1 == '>')) { tokp += 1; tok = TOK_RBRACKET; }
2585         else if ((c == '<') && (c1 == '%')) { tokp += 1; tok = TOK_LBRACE; }
2586         else if ((c == '%') && (c1 == '>')) { tokp += 1; tok = TOK_RBRACE; }
2587         else if ((c == '%') && (c1 == ':')) { tokp += 1; tok = TOK_MACRO; }
2588         else if ((c == '#') && (c1 == '#')) { tokp += 1; tok = TOK_CONCATENATE; }
2589         else if (c == ';') { tok = TOK_SEMI; }
2590         else if (c == '{') { tok = TOK_LBRACE; }
2591         else if (c == '}') { tok = TOK_RBRACE; }
2592         else if (c == ',') { tok = TOK_COMMA; }
2593         else if (c == '=') { tok = TOK_EQ; }
2594         else if (c == ':') { tok = TOK_COLON; }
2595         else if (c == '[') { tok = TOK_LBRACKET; }
2596         else if (c == ']') { tok = TOK_RBRACKET; }
2597         else if (c == '(') { tok = TOK_LPAREN; }
2598         else if (c == ')') { tok = TOK_RPAREN; }
2599         else if (c == '*') { tok = TOK_STAR; }
2600         else if (c == '>') { tok = TOK_MORE; }
2601         else if (c == '<') { tok = TOK_LESS; }
2602         else if (c == '?') { tok = TOK_QUEST; }
2603         else if (c == '|') { tok = TOK_OR; }
2604         else if (c == '&') { tok = TOK_AND; }
2605         else if (c == '^') { tok = TOK_XOR; }
2606         else if (c == '+') { tok = TOK_PLUS; }
2607         else if (c == '-') { tok = TOK_MINUS; }
2608         else if (c == '/') { tok = TOK_DIV; }
2609         else if (c == '%') { tok = TOK_MOD; }
2610         else if (c == '!') { tok = TOK_BANG; }
2611         else if (c == '.') { tok = TOK_DOT; }
2612         else if (c == '~') { tok = TOK_TILDE; }
2613         else if (c == '#') { tok = TOK_MACRO; }
2614         if (tok == TOK_MACRO) {
2615                 /* Only match preprocessor directives at the start of a line */
2616                 char *ptr;
2617                 for(ptr = file->line_start; spacep(*ptr); ptr++)
2618                         ;
2619                 if (ptr != tokp) {
2620                         tok = TOK_UNKNOWN;
2621                 }
2622         }
2623         if (tok == TOK_UNKNOWN) {
2624                 error(state, 0, "unknown token");
2625         }
2626
2627         file->pos = tokp + 1;
2628         tk->tok = tok;
2629         if (tok == TOK_IDENT) {
2630                 ident_to_keyword(state, tk);
2631         }
2632         /* Don't return space tokens. */
2633         if (tok == TOK_SPACE) {
2634                 goto next_token;
2635         }
2636 }
2637
2638 static void compile_macro(struct compile_state *state, struct token *tk)
2639 {
2640         struct file_state *file;
2641         struct hash_entry *ident;
2642         ident = tk->ident;
2643         file = xmalloc(sizeof(*file), "file_state");
2644         file->basename = xstrdup(tk->ident->name);
2645         file->dirname = xstrdup("");
2646         file->size = ident->sym_define->buf_len;
2647         file->buf = xmalloc(file->size +2,  file->basename);
2648         memcpy(file->buf, ident->sym_define->buf, file->size);
2649         file->buf[file->size] = '\n';
2650         file->buf[file->size + 1] = '\0';
2651         file->pos = file->buf;
2652         file->line_start = file->pos;
2653         file->line = 1;
2654         file->prev = state->file;
2655         state->file = file;
2656 }
2657
2658
2659 static int mpeek(struct compile_state *state, int index)
2660 {
2661         struct token *tk;
2662         int rescan;
2663         tk = &state->token[index + 1];
2664         if (tk->tok == -1) {
2665                 next_token(state, index + 1);
2666         }
2667         do {
2668                 rescan = 0;
2669                 if ((tk->tok == TOK_EOF) && 
2670                         (state->file != state->macro_file) &&
2671                         (state->file->prev)) {
2672                         struct file_state *file = state->file;
2673                         state->file = file->prev;
2674                         /* file->basename is used keep it */
2675                         xfree(file->dirname);
2676                         xfree(file->buf);
2677                         xfree(file);
2678                         next_token(state, index + 1);
2679                         rescan = 1;
2680                 }
2681                 else if (tk->ident && tk->ident->sym_define) {
2682                         compile_macro(state, tk);
2683                         next_token(state, index + 1);
2684                         rescan = 1;
2685                 }
2686         } while(rescan);
2687         /* Don't show the token on the next line */
2688         if (state->macro_line < state->macro_file->line) {
2689                 return TOK_EOF;
2690         }
2691         return state->token[index +1].tok;
2692 }
2693
2694 static void meat(struct compile_state *state, int index, int tok)
2695 {
2696         int next_tok;
2697         int i;
2698         next_tok = mpeek(state, index);
2699         if (next_tok != tok) {
2700                 const char *name1, *name2;
2701                 name1 = tokens[next_tok];
2702                 name2 = "";
2703                 if (next_tok == TOK_IDENT) {
2704                         name2 = state->token[index + 1].ident->name;
2705                 }
2706                 error(state, 0, "found %s %s expected %s", 
2707                         name1, name2, tokens[tok]);
2708         }
2709         /* Free the old token value */
2710         if (state->token[index].str_len) {
2711                 memset((void *)(state->token[index].val.str), -1, 
2712                         state->token[index].str_len);
2713                 xfree(state->token[index].val.str);
2714         }
2715         for(i = index; i < sizeof(state->token)/sizeof(state->token[0]) - 1; i++) {
2716                 state->token[i] = state->token[i + 1];
2717         }
2718         memset(&state->token[i], 0, sizeof(state->token[i]));
2719         state->token[i].tok = -1;
2720 }
2721
2722 static long_t mcexpr(struct compile_state *state, int index);
2723
2724 static long_t mprimary_expr(struct compile_state *state, int index)
2725 {
2726         long_t val;
2727         int tok;
2728         tok = mpeek(state, index);
2729         while(state->token[index + 1].ident && 
2730                 state->token[index + 1].ident->sym_define) {
2731                 meat(state, index, tok);
2732                 compile_macro(state, &state->token[index]);
2733                 tok = mpeek(state, index);
2734         }
2735         switch(tok) {
2736         case TOK_LPAREN:
2737                 meat(state, index, TOK_LPAREN);
2738                 val = mcexpr(state, index);
2739                 meat(state, index, TOK_RPAREN);
2740                 break;
2741         case TOK_LIT_INT:
2742         {
2743                 char *end;
2744                 meat(state, index, TOK_LIT_INT);
2745                 errno = 0;
2746                 val = strtol(state->token[index].val.str, &end, 0);
2747                 if (((val == LONG_MIN) || (val == LONG_MAX)) &&
2748                         (errno == ERANGE)) {
2749                         error(state, 0, "Integer constant to large");
2750                 }
2751                 break;
2752         }
2753         default:
2754                 meat(state, index, TOK_LIT_INT);
2755                 val = 0;
2756         }
2757         return val;
2758 }
2759 static long_t munary_expr(struct compile_state *state, int index)
2760 {
2761         long_t val;
2762         switch(mpeek(state, index)) {
2763         case TOK_PLUS:
2764                 meat(state, index, TOK_PLUS);
2765                 val = munary_expr(state, index);
2766                 val = + val;
2767                 break;
2768         case TOK_MINUS:
2769                 meat(state, index, TOK_MINUS);
2770                 val = munary_expr(state, index);
2771                 val = - val;
2772                 break;
2773         case TOK_TILDE:
2774                 meat(state, index, TOK_BANG);
2775                 val = munary_expr(state, index);
2776                 val = ~ val;
2777                 break;
2778         case TOK_BANG:
2779                 meat(state, index, TOK_BANG);
2780                 val = munary_expr(state, index);
2781                 val = ! val;
2782                 break;
2783         default:
2784                 val = mprimary_expr(state, index);
2785                 break;
2786         }
2787         return val;
2788         
2789 }
2790 static long_t mmul_expr(struct compile_state *state, int index)
2791 {
2792         long_t val;
2793         int done;
2794         val = munary_expr(state, index);
2795         do {
2796                 long_t right;
2797                 done = 0;
2798                 switch(mpeek(state, index)) {
2799                 case TOK_STAR:
2800                         meat(state, index, TOK_STAR);
2801                         right = munary_expr(state, index);
2802                         val = val * right;
2803                         break;
2804                 case TOK_DIV:
2805                         meat(state, index, TOK_DIV);
2806                         right = munary_expr(state, index);
2807                         val = val / right;
2808                         break;
2809                 case TOK_MOD:
2810                         meat(state, index, TOK_MOD);
2811                         right = munary_expr(state, index);
2812                         val = val % right;
2813                         break;
2814                 default:
2815                         done = 1;
2816                         break;
2817                 }
2818         } while(!done);
2819
2820         return val;
2821 }
2822
2823 static long_t madd_expr(struct compile_state *state, int index)
2824 {
2825         long_t val;
2826         int done;
2827         val = mmul_expr(state, index);
2828         do {
2829                 long_t right;
2830                 done = 0;
2831                 switch(mpeek(state, index)) {
2832                 case TOK_PLUS:
2833                         meat(state, index, TOK_PLUS);
2834                         right = mmul_expr(state, index);
2835                         val = val + right;
2836                         break;
2837                 case TOK_MINUS:
2838                         meat(state, index, TOK_MINUS);
2839                         right = mmul_expr(state, index);
2840                         val = val - right;
2841                         break;
2842                 default:
2843                         done = 1;
2844                         break;
2845                 }
2846         } while(!done);
2847
2848         return val;
2849 }
2850
2851 static long_t mshift_expr(struct compile_state *state, int index)
2852 {
2853         long_t val;
2854         int done;
2855         val = madd_expr(state, index);
2856         do {
2857                 long_t right;
2858                 done = 0;
2859                 switch(mpeek(state, index)) {
2860                 case TOK_SL:
2861                         meat(state, index, TOK_SL);
2862                         right = madd_expr(state, index);
2863                         val = val << right;
2864                         break;
2865                 case TOK_SR:
2866                         meat(state, index, TOK_SR);
2867                         right = madd_expr(state, index);
2868                         val = val >> right;
2869                         break;
2870                 default:
2871                         done = 1;
2872                         break;
2873                 }
2874         } while(!done);
2875
2876         return val;
2877 }
2878
2879 static long_t mrel_expr(struct compile_state *state, int index)
2880 {
2881         long_t val;
2882         int done;
2883         val = mshift_expr(state, index);
2884         do {
2885                 long_t right;
2886                 done = 0;
2887                 switch(mpeek(state, index)) {
2888                 case TOK_LESS:
2889                         meat(state, index, TOK_LESS);
2890                         right = mshift_expr(state, index);
2891                         val = val < right;
2892                         break;
2893                 case TOK_MORE:
2894                         meat(state, index, TOK_MORE);
2895                         right = mshift_expr(state, index);
2896                         val = val > right;
2897                         break;
2898                 case TOK_LESSEQ:
2899                         meat(state, index, TOK_LESSEQ);
2900                         right = mshift_expr(state, index);
2901                         val = val <= right;
2902                         break;
2903                 case TOK_MOREEQ:
2904                         meat(state, index, TOK_MOREEQ);
2905                         right = mshift_expr(state, index);
2906                         val = val >= right;
2907                         break;
2908                 default:
2909                         done = 1;
2910                         break;
2911                 }
2912         } while(!done);
2913         return val;
2914 }
2915
2916 static long_t meq_expr(struct compile_state *state, int index)
2917 {
2918         long_t val;
2919         int done;
2920         val = mrel_expr(state, index);
2921         do {
2922                 long_t right;
2923                 done = 0;
2924                 switch(mpeek(state, index)) {
2925                 case TOK_EQEQ:
2926                         meat(state, index, TOK_EQEQ);
2927                         right = mrel_expr(state, index);
2928                         val = val == right;
2929                         break;
2930                 case TOK_NOTEQ:
2931                         meat(state, index, TOK_NOTEQ);
2932                         right = mrel_expr(state, index);
2933                         val = val != right;
2934                         break;
2935                 default:
2936                         done = 1;
2937                         break;
2938                 }
2939         } while(!done);
2940         return val;
2941 }
2942
2943 static long_t mand_expr(struct compile_state *state, int index)
2944 {
2945         long_t val;
2946         val = meq_expr(state, index);
2947         if (mpeek(state, index) == TOK_AND) {
2948                 long_t right;
2949                 meat(state, index, TOK_AND);
2950                 right = meq_expr(state, index);
2951                 val = val & right;
2952         }
2953         return val;
2954 }
2955
2956 static long_t mxor_expr(struct compile_state *state, int index)
2957 {
2958         long_t val;
2959         val = mand_expr(state, index);
2960         if (mpeek(state, index) == TOK_XOR) {
2961                 long_t right;
2962                 meat(state, index, TOK_XOR);
2963                 right = mand_expr(state, index);
2964                 val = val ^ right;
2965         }
2966         return val;
2967 }
2968
2969 static long_t mor_expr(struct compile_state *state, int index)
2970 {
2971         long_t val;
2972         val = mxor_expr(state, index);
2973         if (mpeek(state, index) == TOK_OR) {
2974                 long_t right;
2975                 meat(state, index, TOK_OR);
2976                 right = mxor_expr(state, index);
2977                 val = val | right;
2978         }
2979         return val;
2980 }
2981
2982 static long_t mland_expr(struct compile_state *state, int index)
2983 {
2984         long_t val;
2985         val = mor_expr(state, index);
2986         if (mpeek(state, index) == TOK_LOGAND) {
2987                 long_t right;
2988                 meat(state, index, TOK_LOGAND);
2989                 right = mor_expr(state, index);
2990                 val = val && right;
2991         }
2992         return val;
2993 }
2994 static long_t mlor_expr(struct compile_state *state, int index)
2995 {
2996         long_t val;
2997         val = mland_expr(state, index);
2998         if (mpeek(state, index) == TOK_LOGOR) {
2999                 long_t right;
3000                 meat(state, index, TOK_LOGOR);
3001                 right = mland_expr(state, index);
3002                 val = val || right;
3003         }
3004         return val;
3005 }
3006
3007 static long_t mcexpr(struct compile_state *state, int index)
3008 {
3009         return mlor_expr(state, index);
3010 }
3011 static void preprocess(struct compile_state *state, int index)
3012 {
3013         /* Doing much more with the preprocessor would require
3014          * a parser and a major restructuring.
3015          * Postpone that for later.
3016          */
3017         struct file_state *file;
3018         struct token *tk;
3019         int line;
3020         int tok;
3021         
3022         file = state->file;
3023         tk = &state->token[index];
3024         state->macro_line = line = file->line;
3025         state->macro_file = file;
3026
3027         next_token(state, index);
3028         ident_to_macro(state, tk);
3029         if (tk->tok == TOK_IDENT) {
3030                 error(state, 0, "undefined preprocessing directive `%s'",
3031                         tk->ident->name);
3032         }
3033         switch(tk->tok) {
3034         case TOK_UNDEF:
3035         case TOK_LINE:
3036         case TOK_PRAGMA:
3037                 if (state->if_value < 0) {
3038                         break;
3039                 }
3040                 warning(state, 0, "Ignoring preprocessor directive: %s", 
3041                         tk->ident->name);
3042                 break;
3043         case TOK_ELIF:
3044                 error(state, 0, "#elif not supported");
3045 #warning "FIXME multiple #elif and #else in an #if do not work properly"
3046                 if (state->if_depth == 0) {
3047                         error(state, 0, "#elif without #if");
3048                 }
3049                 /* If the #if was taken the #elif just disables the following code */
3050                 if (state->if_value >= 0) {
3051                         state->if_value = - state->if_value;
3052                 }
3053                 /* If the previous #if was not taken see if the #elif enables the 
3054                  * trailing code.
3055                  */
3056                 else if ((state->if_value < 0) && 
3057                         (state->if_depth == - state->if_value))
3058                 {
3059                         if (mcexpr(state, index) != 0) {
3060                                 state->if_value = state->if_depth;
3061                         }
3062                         else {
3063                                 state->if_value = - state->if_depth;
3064                         }
3065                 }
3066                 break;
3067         case TOK_IF:
3068                 state->if_depth++;
3069                 if (state->if_value < 0) {
3070                         break;
3071                 }
3072                 if (mcexpr(state, index) != 0) {
3073                         state->if_value = state->if_depth;
3074                 }
3075                 else {
3076                         state->if_value = - state->if_depth;
3077                 }
3078                 break;
3079         case TOK_IFNDEF:
3080                 state->if_depth++;
3081                 if (state->if_value < 0) {
3082                         break;
3083                 }
3084                 next_token(state, index);
3085                 if ((line != file->line) || (tk->tok != TOK_IDENT)) {
3086                         error(state, 0, "Invalid macro name");
3087                 }
3088                 if (tk->ident->sym_define == 0) {
3089                         state->if_value = state->if_depth;
3090                 } 
3091                 else {
3092                         state->if_value = - state->if_depth;
3093                 }
3094                 break;
3095         case TOK_IFDEF:
3096                 state->if_depth++;
3097                 if (state->if_value < 0) {
3098                         break;
3099                 }
3100                 next_token(state, index);
3101                 if ((line != file->line) || (tk->tok != TOK_IDENT)) {
3102                         error(state, 0, "Invalid macro name");
3103                 }
3104                 if (tk->ident->sym_define != 0) {
3105                         state->if_value = state->if_depth;
3106                 }
3107                 else {
3108                         state->if_value = - state->if_depth;
3109                 }
3110                 break;
3111         case TOK_ELSE:
3112                 if (state->if_depth == 0) {
3113                         error(state, 0, "#else without #if");
3114                 }
3115                 if ((state->if_value >= 0) ||
3116                         ((state->if_value < 0) && 
3117                                 (state->if_depth == -state->if_value)))
3118                 {
3119                         state->if_value = - state->if_value;
3120                 }
3121                 break;
3122         case TOK_ENDIF:
3123                 if (state->if_depth == 0) {
3124                         error(state, 0, "#endif without #if");
3125                 }
3126                 if ((state->if_value >= 0) ||
3127                         ((state->if_value < 0) &&
3128                                 (state->if_depth == -state->if_value))) 
3129                 {
3130                         state->if_value = state->if_depth - 1;
3131                 }
3132                 state->if_depth--;
3133                 break;
3134         case TOK_DEFINE:
3135         {
3136                 struct hash_entry *ident;
3137                 struct macro *macro;
3138                 char *ptr;
3139                 
3140                 if (state->if_value < 0) /* quit early when #if'd out */
3141                         break;
3142
3143                 meat(state, index, TOK_IDENT);
3144                 ident = tk->ident;
3145                 
3146
3147                 if (*file->pos == '(') {
3148 #warning "FIXME macros with arguments not supported"
3149                         error(state, 0, "Macros with arguments not supported");
3150                 }
3151
3152                 /* Find the end of the line to get an estimate of
3153                  * the macro's length.
3154                  */
3155                 for(ptr = file->pos; *ptr != '\n'; ptr++)  
3156                         ;
3157
3158                 if (ident->sym_define != 0) {
3159                         error(state, 0, "macro %s already defined\n", ident->name);
3160                 }
3161                 macro = xmalloc(sizeof(*macro), "macro");
3162                 macro->ident = ident;
3163                 macro->buf_len = ptr - file->pos +1;
3164                 macro->buf = xmalloc(macro->buf_len +2, "macro buf");
3165
3166                 memcpy(macro->buf, file->pos, macro->buf_len);
3167                 macro->buf[macro->buf_len] = '\n';
3168                 macro->buf[macro->buf_len +1] = '\0';
3169
3170                 ident->sym_define = macro;
3171                 break;
3172         }
3173         case TOK_ERROR:
3174         {
3175                 char *end;
3176                 int len;
3177                 /* Find the end of the line */
3178                 for(end = file->pos; *end != '\n'; end++)
3179                         ;
3180                 len = (end - file->pos);
3181                 if (state->if_value >= 0) {
3182                         error(state, 0, "%*.*s", len, len, file->pos);
3183                 }
3184                 file->pos = end;
3185                 break;
3186         }
3187         case TOK_WARNING:
3188         {
3189                 char *end;
3190                 int len;
3191                 /* Find the end of the line */
3192                 for(end = file->pos; *end != '\n'; end++)
3193                         ;
3194                 len = (end - file->pos);
3195                 if (state->if_value >= 0) {
3196                         warning(state, 0, "%*.*s", len, len, file->pos);
3197                 }
3198                 file->pos = end;
3199                 break;
3200         }
3201         case TOK_INCLUDE:
3202         {
3203                 char *name;
3204                 char *ptr;
3205                 int local;
3206                 local = 0;
3207                 name = 0;
3208                 next_token(state, index);
3209                 if (tk->tok == TOK_LIT_STRING) {
3210                         const char *token;
3211                         int name_len;
3212                         name = xmalloc(tk->str_len, "include");
3213                         token = tk->val.str +1;
3214                         name_len = tk->str_len -2;
3215                         if (*token == '"') {
3216                                 token++;
3217                                 name_len--;
3218                         }
3219                         memcpy(name, token, name_len);
3220                         name[name_len] = '\0';
3221                         local = 1;
3222                 }
3223                 else if (tk->tok == TOK_LESS) {
3224                         char *start, *end;
3225                         start = file->pos;
3226                         for(end = start; *end != '\n'; end++) {
3227                                 if (*end == '>') {
3228                                         break;
3229                                 }
3230                         }
3231                         if (*end == '\n') {
3232                                 error(state, 0, "Unterminated included directive");
3233                         }
3234                         name = xmalloc(end - start + 1, "include");
3235                         memcpy(name, start, end - start);
3236                         name[end - start] = '\0';
3237                         file->pos = end +1;
3238                         local = 0;
3239                 }
3240                 else {
3241                         error(state, 0, "Invalid include directive");
3242                 }
3243                 /* Error if there are any characters after the include */
3244                 for(ptr = file->pos; *ptr != '\n'; ptr++) {
3245                         if (!isspace(*ptr)) {
3246                                 error(state, 0, "garbage after include directive");
3247                         }
3248                 }
3249                 if (state->if_value >= 0) {
3250                         compile_file(state, name, local);
3251                 }
3252                 xfree(name);
3253                 next_token(state, index);
3254                 return;
3255         }
3256         default:
3257                 /* Ignore # without a following ident */
3258                 if (tk->tok == TOK_IDENT) {
3259                         error(state, 0, "Invalid preprocessor directive: %s", 
3260                                 tk->ident->name);
3261                 }
3262                 break;
3263         }
3264         /* Consume the rest of the macro line */
3265         do {
3266                 tok = mpeek(state, index);
3267                 meat(state, index, tok);
3268         } while(tok != TOK_EOF);
3269         return;
3270 }
3271
3272 static void token(struct compile_state *state, int index)
3273 {
3274         struct file_state *file;
3275         struct token *tk;
3276         int rescan;
3277
3278         tk = &state->token[index];
3279         next_token(state, index);
3280         do {
3281                 rescan = 0;
3282                 file = state->file;
3283                 if (tk->tok == TOK_EOF && file->prev) {
3284                         state->file = file->prev;
3285                         /* file->basename is used keep it */
3286                         xfree(file->dirname);
3287                         xfree(file->buf);
3288                         xfree(file);
3289                         next_token(state, index);
3290                         rescan = 1;
3291                 }
3292                 else if (tk->tok == TOK_MACRO) {
3293                         preprocess(state, index);
3294                         rescan = 1;
3295                 }
3296                 else if (tk->ident && tk->ident->sym_define) {
3297                         compile_macro(state, tk);
3298                         next_token(state, index);
3299                         rescan = 1;
3300                 }
3301                 else if (state->if_value < 0) {
3302                         next_token(state, index);
3303                         rescan = 1;
3304                 }
3305         } while(rescan);
3306 }
3307
3308 static int peek(struct compile_state *state)
3309 {
3310         if (state->token[1].tok == -1) {
3311                 token(state, 1);
3312         }
3313         return state->token[1].tok;
3314 }
3315
3316 static int peek2(struct compile_state *state)
3317 {
3318         if (state->token[1].tok == -1) {
3319                 token(state, 1);
3320         }
3321         if (state->token[2].tok == -1) {
3322                 token(state, 2);
3323         }
3324         return state->token[2].tok;
3325 }
3326
3327 static void eat(struct compile_state *state, int tok)
3328 {
3329         int next_tok;
3330         int i;
3331         next_tok = peek(state);
3332         if (next_tok != tok) {
3333                 const char *name1, *name2;
3334                 name1 = tokens[next_tok];
3335                 name2 = "";
3336                 if (next_tok == TOK_IDENT) {
3337                         name2 = state->token[1].ident->name;
3338                 }
3339                 error(state, 0, "\tfound %s %s expected %s",
3340                         name1, name2 ,tokens[tok]);
3341         }
3342         /* Free the old token value */
3343         if (state->token[0].str_len) {
3344                 xfree((void *)(state->token[0].val.str));
3345         }
3346         for(i = 0; i < sizeof(state->token)/sizeof(state->token[0]) - 1; i++) {
3347                 state->token[i] = state->token[i + 1];
3348         }
3349         memset(&state->token[i], 0, sizeof(state->token[i]));
3350         state->token[i].tok = -1;
3351 }
3352
3353 #warning "FIXME do not hardcode the include paths"
3354 static char *include_paths[] = {
3355         "/home/eric/projects/linuxbios/checkin/solo/freebios2/src/include",
3356         "/home/eric/projects/linuxbios/checkin/solo/freebios2/src/arch/i386/include",
3357         "/home/eric/projects/linuxbios/checkin/solo/freebios2/src",
3358         0
3359 };
3360
3361 static void compile_file(struct compile_state *state, const char *filename, int local)
3362 {
3363         char cwd[4096];
3364         const char *subdir, *base;
3365         int subdir_len;
3366         struct file_state *file;
3367         char *basename;
3368         file = xmalloc(sizeof(*file), "file_state");
3369
3370         base = strrchr(filename, '/');
3371         subdir = filename;
3372         if (base != 0) {
3373                 subdir_len = base - filename;
3374                 base++;
3375         }
3376         else {
3377                 base = filename;
3378                 subdir_len = 0;
3379         }
3380         basename = xmalloc(strlen(base) +1, "basename");
3381         strcpy(basename, base);
3382         file->basename = basename;
3383
3384         if (getcwd(cwd, sizeof(cwd)) == 0) {
3385                 die("cwd buffer to small");
3386         }
3387         
3388         if (subdir[0] == '/') {
3389                 file->dirname = xmalloc(subdir_len + 1, "dirname");
3390                 memcpy(file->dirname, subdir, subdir_len);
3391                 file->dirname[subdir_len] = '\0';
3392         }
3393         else {
3394                 char *dir;
3395                 int dirlen;
3396                 char **path;
3397                 /* Find the appropriate directory... */
3398                 dir = 0;
3399                 if (!state->file && exists(cwd, filename)) {
3400                         dir = cwd;
3401                 }
3402                 if (local && state->file && exists(state->file->dirname, filename)) {
3403                         dir = state->file->dirname;
3404                 }
3405                 for(path = include_paths; !dir && *path; path++) {
3406                         if (exists(*path, filename)) {
3407                                 dir = *path;
3408                         }
3409                 }
3410                 if (!dir) {
3411                         error(state, 0, "Cannot find `%s'\n", filename);
3412                 }
3413                 dirlen = strlen(dir);
3414                 file->dirname = xmalloc(dirlen + 1 + subdir_len + 1, "dirname");
3415                 memcpy(file->dirname, dir, dirlen);
3416                 file->dirname[dirlen] = '/';
3417                 memcpy(file->dirname + dirlen + 1, subdir, subdir_len);
3418                 file->dirname[dirlen + 1 + subdir_len] = '\0';
3419         }
3420         file->buf = slurp_file(file->dirname, file->basename, &file->size);
3421         xchdir(cwd);
3422
3423         file->pos = file->buf;
3424         file->line_start = file->pos;
3425         file->line = 1;
3426
3427         file->prev = state->file;
3428         state->file = file;
3429         
3430         process_trigraphs(state);
3431         splice_lines(state);
3432 }
3433
3434 /* Type helper functions */
3435
3436 static struct type *new_type(
3437         unsigned int type, struct type *left, struct type *right)
3438 {
3439         struct type *result;
3440         result = xmalloc(sizeof(*result), "type");
3441         result->type = type;
3442         result->left = left;
3443         result->right = right;
3444         result->field_ident = 0;
3445         result->type_ident = 0;
3446         return result;
3447 }
3448
3449 static struct type *clone_type(unsigned int specifiers, struct type *old)
3450 {
3451         struct type *result;
3452         result = xmalloc(sizeof(*result), "type");
3453         memcpy(result, old, sizeof(*result));
3454         result->type &= TYPE_MASK;
3455         result->type |= specifiers;
3456         return result;
3457 }
3458
3459 #define SIZEOF_SHORT 2
3460 #define SIZEOF_INT   4
3461 #define SIZEOF_LONG  (sizeof(long_t))
3462
3463 #define ALIGNOF_SHORT 2
3464 #define ALIGNOF_INT   4
3465 #define ALIGNOF_LONG  (sizeof(long_t))
3466
3467 #define MASK_UCHAR(X)    ((X) & ((ulong_t)0xff))
3468 #define MASK_USHORT(X)   ((X) & (((ulong_t)1 << (SIZEOF_SHORT*8)) - 1))
3469 static inline ulong_t mask_uint(ulong_t x)
3470 {
3471         if (SIZEOF_INT < SIZEOF_LONG) {
3472                 ulong_t mask = (((ulong_t)1) << ((ulong_t)(SIZEOF_INT*8))) -1;
3473                 x &= mask;
3474         }
3475         return x;
3476 }
3477 #define MASK_UINT(X)      (mask_uint(X))
3478 #define MASK_ULONG(X)    (X)
3479
3480 static struct type void_type   = { .type  = TYPE_VOID };
3481 static struct type char_type   = { .type  = TYPE_CHAR };
3482 static struct type uchar_type  = { .type  = TYPE_UCHAR };
3483 static struct type short_type  = { .type  = TYPE_SHORT };
3484 static struct type ushort_type = { .type  = TYPE_USHORT };
3485 static struct type int_type    = { .type  = TYPE_INT };
3486 static struct type uint_type   = { .type  = TYPE_UINT };
3487 static struct type long_type   = { .type  = TYPE_LONG };
3488 static struct type ulong_type  = { .type  = TYPE_ULONG };
3489
3490 static struct triple *variable(struct compile_state *state, struct type *type)
3491 {
3492         struct triple *result;
3493         if ((type->type & STOR_MASK) != STOR_PERM) {
3494                 if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
3495                         result = triple(state, OP_ADECL, type, 0, 0);
3496                 } else {
3497                         struct type *field;
3498                         struct triple **vector;
3499                         ulong_t index;
3500                         result = new_triple(state, OP_VAL_VEC, type, -1, -1);
3501                         vector = &result->param[0];
3502
3503                         field = type->left;
3504                         index = 0;
3505                         while((field->type & TYPE_MASK) == TYPE_PRODUCT) {
3506                                 vector[index] = variable(state, field->left);
3507                                 field = field->right;
3508                                 index++;
3509                         }
3510                         vector[index] = variable(state, field);
3511                 }
3512         }
3513         else {
3514                 result = triple(state, OP_SDECL, type, 0, 0);
3515         }
3516         return result;
3517 }
3518
3519 static void stor_of(FILE *fp, struct type *type)
3520 {
3521         switch(type->type & STOR_MASK) {
3522         case STOR_AUTO:
3523                 fprintf(fp, "auto ");
3524                 break;
3525         case STOR_STATIC:
3526                 fprintf(fp, "static ");
3527                 break;
3528         case STOR_EXTERN:
3529                 fprintf(fp, "extern ");
3530                 break;
3531         case STOR_REGISTER:
3532                 fprintf(fp, "register ");
3533                 break;
3534         case STOR_TYPEDEF:
3535                 fprintf(fp, "typedef ");
3536                 break;
3537         case STOR_INLINE:
3538                 fprintf(fp, "inline ");
3539                 break;
3540         }
3541 }
3542 static void qual_of(FILE *fp, struct type *type)
3543 {
3544         if (type->type & QUAL_CONST) {
3545                 fprintf(fp, " const");
3546         }
3547         if (type->type & QUAL_VOLATILE) {
3548                 fprintf(fp, " volatile");
3549         }
3550         if (type->type & QUAL_RESTRICT) {
3551                 fprintf(fp, " restrict");
3552         }
3553 }
3554
3555 static void name_of(FILE *fp, struct type *type)
3556 {
3557         stor_of(fp, type);
3558         switch(type->type & TYPE_MASK) {
3559         case TYPE_VOID:
3560                 fprintf(fp, "void");
3561                 qual_of(fp, type);
3562                 break;
3563         case TYPE_CHAR:
3564                 fprintf(fp, "signed char");
3565                 qual_of(fp, type);
3566                 break;
3567         case TYPE_UCHAR:
3568                 fprintf(fp, "unsigned char");
3569                 qual_of(fp, type);
3570                 break;
3571         case TYPE_SHORT:
3572                 fprintf(fp, "signed short");
3573                 qual_of(fp, type);
3574                 break;
3575         case TYPE_USHORT:
3576                 fprintf(fp, "unsigned short");
3577                 qual_of(fp, type);
3578                 break;
3579         case TYPE_INT:
3580                 fprintf(fp, "signed int");
3581                 qual_of(fp, type);
3582                 break;
3583         case TYPE_UINT:
3584                 fprintf(fp, "unsigned int");
3585                 qual_of(fp, type);
3586                 break;
3587         case TYPE_LONG:
3588                 fprintf(fp, "signed long");
3589                 qual_of(fp, type);
3590                 break;
3591         case TYPE_ULONG:
3592                 fprintf(fp, "unsigned long");
3593                 qual_of(fp, type);
3594                 break;
3595         case TYPE_POINTER:
3596                 name_of(fp, type->left);
3597                 fprintf(fp, " * ");
3598                 qual_of(fp, type);
3599                 break;
3600         case TYPE_PRODUCT:
3601         case TYPE_OVERLAP:
3602                 name_of(fp, type->left);
3603                 fprintf(fp, ", ");
3604                 name_of(fp, type->right);
3605                 break;
3606         case TYPE_ENUM:
3607                 fprintf(fp, "enum %s", type->type_ident->name);
3608                 qual_of(fp, type);
3609                 break;
3610         case TYPE_STRUCT:
3611                 fprintf(fp, "struct %s", type->type_ident->name);
3612                 qual_of(fp, type);
3613                 break;
3614         case TYPE_FUNCTION:
3615         {
3616                 name_of(fp, type->left);
3617                 fprintf(fp, " (*)(");
3618                 name_of(fp, type->right);
3619                 fprintf(fp, ")");
3620                 break;
3621         }
3622         case TYPE_ARRAY:
3623                 name_of(fp, type->left);
3624                 fprintf(fp, " [%ld]", type->elements);
3625                 break;
3626         default:
3627                 fprintf(fp, "????: %x", type->type & TYPE_MASK);
3628                 break;
3629         }
3630 }
3631
3632 static size_t align_of(struct compile_state *state, struct type *type)
3633 {
3634         size_t align;
3635         align = 0;
3636         switch(type->type & TYPE_MASK) {
3637         case TYPE_VOID:
3638                 align = 1;
3639                 break;
3640         case TYPE_CHAR:
3641         case TYPE_UCHAR:
3642                 align = 1;
3643                 break;
3644         case TYPE_SHORT:
3645         case TYPE_USHORT:
3646                 align = ALIGNOF_SHORT;
3647                 break;
3648         case TYPE_INT:
3649         case TYPE_UINT:
3650         case TYPE_ENUM:
3651                 align = ALIGNOF_INT;
3652                 break;
3653         case TYPE_LONG:
3654         case TYPE_ULONG:
3655         case TYPE_POINTER:
3656                 align = ALIGNOF_LONG;
3657                 break;
3658         case TYPE_PRODUCT:
3659         case TYPE_OVERLAP:
3660         {
3661                 size_t left_align, right_align;
3662                 left_align  = align_of(state, type->left);
3663                 right_align = align_of(state, type->right);
3664                 align = (left_align >= right_align) ? left_align : right_align;
3665                 break;
3666         }
3667         case TYPE_ARRAY:
3668                 align = align_of(state, type->left);
3669                 break;
3670         case TYPE_STRUCT:
3671                 align = align_of(state, type->left);
3672                 break;
3673         default:
3674                 error(state, 0, "alignof not yet defined for type\n");
3675                 break;
3676         }
3677         return align;
3678 }
3679
3680 static size_t size_of(struct compile_state *state, struct type *type)
3681 {
3682         size_t size;
3683         size = 0;
3684         switch(type->type & TYPE_MASK) {
3685         case TYPE_VOID:
3686                 size = 0;
3687                 break;
3688         case TYPE_CHAR:
3689         case TYPE_UCHAR:
3690                 size = 1;
3691                 break;
3692         case TYPE_SHORT:
3693         case TYPE_USHORT:
3694                 size = SIZEOF_SHORT;
3695                 break;
3696         case TYPE_INT:
3697         case TYPE_UINT:
3698         case TYPE_ENUM:
3699                 size = SIZEOF_INT;
3700                 break;
3701         case TYPE_LONG:
3702         case TYPE_ULONG:
3703         case TYPE_POINTER:
3704                 size = SIZEOF_LONG;
3705                 break;
3706         case TYPE_PRODUCT:
3707         {
3708                 size_t align, pad;
3709                 size = size_of(state, type->left);
3710                 while((type->right->type & TYPE_MASK) == TYPE_PRODUCT) {
3711                         type = type->right;
3712                         align = align_of(state, type->left);
3713                         pad = align - (size % align);
3714                         size = size + pad + size_of(state, type->left);
3715                 }
3716                 align = align_of(state, type->right);
3717                 pad = align - (size % align);
3718                 size = size + pad + sizeof(type->right);
3719                 break;
3720         }
3721         case TYPE_OVERLAP:
3722         {
3723                 size_t size_left, size_right;
3724                 size_left = size_of(state, type->left);
3725                 size_right = size_of(state, type->right);
3726                 size = (size_left >= size_right)? size_left : size_right;
3727                 break;
3728         }
3729         case TYPE_ARRAY:
3730                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
3731                         internal_error(state, 0, "Invalid array type");
3732                 } else {
3733                         size = size_of(state, type->left) * type->elements;
3734                 }
3735                 break;
3736         case TYPE_STRUCT:
3737                 size = size_of(state, type->left);
3738                 break;
3739         default:
3740                 error(state, 0, "sizeof not yet defined for type\n");
3741                 break;
3742         }
3743         return size;
3744 }
3745
3746 static size_t field_offset(struct compile_state *state, 
3747         struct type *type, struct hash_entry *field)
3748 {
3749         size_t size, align, pad;
3750         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
3751                 internal_error(state, 0, "field_offset only works on structures");
3752         }
3753         size = 0;
3754         type = type->left;
3755         while((type->type & TYPE_MASK) == TYPE_PRODUCT) {
3756                 if (type->left->field_ident == field) {
3757                         type = type->left;
3758                 }
3759                 size += size_of(state, type->left);
3760                 type = type->right;
3761                 align = align_of(state, type->left);
3762                 pad = align - (size % align);
3763                 size += pad;
3764         }
3765         if (type->field_ident != field) {
3766                 internal_error(state, 0, "field_offset: member %s not present",
3767                         field->name);
3768         }
3769         return size;
3770 }
3771
3772 static struct type *field_type(struct compile_state *state, 
3773         struct type *type, struct hash_entry *field)
3774 {
3775         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
3776                 internal_error(state, 0, "field_type only works on structures");
3777         }
3778         type = type->left;
3779         while((type->type & TYPE_MASK) == TYPE_PRODUCT) {
3780                 if (type->left->field_ident == field) {
3781                         type = type->left;
3782                         break;
3783                 }
3784                 type = type->right;
3785         }
3786         if (type->field_ident != field) {
3787                 internal_error(state, 0, "field_type: member %s not present", 
3788                         field->name);
3789         }
3790         return type;
3791 }
3792
3793 static struct triple *struct_field(struct compile_state *state,
3794         struct triple *decl, struct hash_entry *field)
3795 {
3796         struct triple **vector;
3797         struct type *type;
3798         ulong_t index;
3799         type = decl->type;
3800         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
3801                 return decl;
3802         }
3803         if (decl->op != OP_VAL_VEC) {
3804                 internal_error(state, 0, "Invalid struct variable");
3805         }
3806         if (!field) {
3807                 internal_error(state, 0, "Missing structure field");
3808         }
3809         type = type->left;
3810         vector = &RHS(decl, 0);
3811         index = 0;
3812         while((type->type & TYPE_MASK) == TYPE_PRODUCT) {
3813                 if (type->left->field_ident == field) {
3814                         type = type->left;
3815                         break;
3816                 }
3817                 index += 1;
3818                 type = type->right;
3819         }
3820         if (type->field_ident != field) {
3821                 internal_error(state, 0, "field %s not found?", field->name);
3822         }
3823         return vector[index];
3824 }
3825
3826 static void arrays_complete(struct compile_state *state, struct type *type)
3827 {
3828         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
3829                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
3830                         error(state, 0, "array size not specified");
3831                 }
3832                 arrays_complete(state, type->left);
3833         }
3834 }
3835
3836 static unsigned int do_integral_promotion(unsigned int type)
3837 {
3838         type &= TYPE_MASK;
3839         if (TYPE_INTEGER(type) && 
3840                 TYPE_RANK(type) < TYPE_RANK(TYPE_INT)) {
3841                 type = TYPE_INT;
3842         }
3843         return type;
3844 }
3845
3846 static unsigned int do_arithmetic_conversion(
3847         unsigned int left, unsigned int right)
3848 {
3849         left &= TYPE_MASK;
3850         right &= TYPE_MASK;
3851         if ((left == TYPE_LDOUBLE) || (right == TYPE_LDOUBLE)) {
3852                 return TYPE_LDOUBLE;
3853         }
3854         else if ((left == TYPE_DOUBLE) || (right == TYPE_DOUBLE)) {
3855                 return TYPE_DOUBLE;
3856         }
3857         else if ((left == TYPE_FLOAT) || (right == TYPE_FLOAT)) {
3858                 return TYPE_FLOAT;
3859         }
3860         left = do_integral_promotion(left);
3861         right = do_integral_promotion(right);
3862         /* If both operands have the same size done */
3863         if (left == right) {
3864                 return left;
3865         }
3866         /* If both operands have the same signedness pick the larger */
3867         else if (!!TYPE_UNSIGNED(left) == !!TYPE_UNSIGNED(right)) {
3868                 return (TYPE_RANK(left) >= TYPE_RANK(right)) ? left : right;
3869         }
3870         /* If the signed type can hold everything use it */
3871         else if (TYPE_SIGNED(left) && (TYPE_RANK(left) > TYPE_RANK(right))) {
3872                 return left;
3873         }
3874         else if (TYPE_SIGNED(right) && (TYPE_RANK(right) > TYPE_RANK(left))) {
3875                 return right;
3876         }
3877         /* Convert to the unsigned type with the same rank as the signed type */
3878         else if (TYPE_SIGNED(left)) {
3879                 return TYPE_MKUNSIGNED(left);
3880         }
3881         else {
3882                 return TYPE_MKUNSIGNED(right);
3883         }
3884 }
3885
3886 /* see if two types are the same except for qualifiers */
3887 static int equiv_types(struct type *left, struct type *right)
3888 {
3889         unsigned int type;
3890         /* Error if the basic types do not match */
3891         if ((left->type & TYPE_MASK) != (right->type & TYPE_MASK)) {
3892                 return 0;
3893         }
3894         type = left->type & TYPE_MASK;
3895         /* if the basic types match and it is an arithmetic type we are done */
3896         if (TYPE_ARITHMETIC(type)) {
3897                 return 1;
3898         }
3899         /* If it is a pointer type recurse and keep testing */
3900         if (type == TYPE_POINTER) {
3901                 return equiv_types(left->left, right->left);
3902         }
3903         else if (type == TYPE_ARRAY) {
3904                 return (left->elements == right->elements) &&
3905                         equiv_types(left->left, right->left);
3906         }
3907         /* test for struct/union equality */
3908         else if (type == TYPE_STRUCT) {
3909                 return left->type_ident == right->type_ident;
3910         }
3911         /* Test for equivalent functions */
3912         else if (type == TYPE_FUNCTION) {
3913                 return equiv_types(left->left, right->left) &&
3914                         equiv_types(left->right, right->right);
3915         }
3916         /* We only see TYPE_PRODUCT as part of function equivalence matching */
3917         else if (type == TYPE_PRODUCT) {
3918                 return equiv_types(left->left, right->left) &&
3919                         equiv_types(left->right, right->right);
3920         }
3921         /* We should see TYPE_OVERLAP */
3922         else {
3923                 return 0;
3924         }
3925 }
3926
3927 static int equiv_ptrs(struct type *left, struct type *right)
3928 {
3929         if (((left->type & TYPE_MASK) != TYPE_POINTER) ||
3930                 ((right->type & TYPE_MASK) != TYPE_POINTER)) {
3931                 return 0;
3932         }
3933         return equiv_types(left->left, right->left);
3934 }
3935
3936 static struct type *compatible_types(struct type *left, struct type *right)
3937 {
3938         struct type *result;
3939         unsigned int type, qual_type;
3940         /* Error if the basic types do not match */
3941         if ((left->type & TYPE_MASK) != (right->type & TYPE_MASK)) {
3942                 return 0;
3943         }
3944         type = left->type & TYPE_MASK;
3945         qual_type = (left->type & ~STOR_MASK) | (right->type & ~STOR_MASK);
3946         result = 0;
3947         /* if the basic types match and it is an arithmetic type we are done */
3948         if (TYPE_ARITHMETIC(type)) {
3949                 result = new_type(qual_type, 0, 0);
3950         }
3951         /* If it is a pointer type recurse and keep testing */
3952         else if (type == TYPE_POINTER) {
3953                 result = compatible_types(left->left, right->left);
3954                 if (result) {
3955                         result = new_type(qual_type, result, 0);
3956                 }
3957         }
3958         /* test for struct/union equality */
3959         else if (type == TYPE_STRUCT) {
3960                 if (left->type_ident == right->type_ident) {
3961                         result = left;
3962                 }
3963         }
3964         /* Test for equivalent functions */
3965         else if (type == TYPE_FUNCTION) {
3966                 struct type *lf, *rf;
3967                 lf = compatible_types(left->left, right->left);
3968                 rf = compatible_types(left->right, right->right);
3969                 if (lf && rf) {
3970                         result = new_type(qual_type, lf, rf);
3971                 }
3972         }
3973         /* We only see TYPE_PRODUCT as part of function equivalence matching */
3974         else if (type == TYPE_PRODUCT) {
3975                 struct type *lf, *rf;
3976                 lf = compatible_types(left->left, right->left);
3977                 rf = compatible_types(left->right, right->right);
3978                 if (lf && rf) {
3979                         result = new_type(qual_type, lf, rf);
3980                 }
3981         }
3982         else {
3983                 /* Nothing else is compatible */
3984         }
3985         return result;
3986 }
3987
3988 static struct type *compatible_ptrs(struct type *left, struct type *right)
3989 {
3990         struct type *result;
3991         if (((left->type & TYPE_MASK) != TYPE_POINTER) ||
3992                 ((right->type & TYPE_MASK) != TYPE_POINTER)) {
3993                 return 0;
3994         }
3995         result = compatible_types(left->left, right->left);
3996         if (result) {
3997                 unsigned int qual_type;
3998                 qual_type = (left->type & ~STOR_MASK) | (right->type & ~STOR_MASK);
3999                 result = new_type(qual_type, result, 0);
4000         }
4001         return result;
4002         
4003 }
4004 static struct triple *integral_promotion(
4005         struct compile_state *state, struct triple *def)
4006 {
4007         struct type *type;
4008         type = def->type;
4009         /* As all operations are carried out in registers
4010          * the values are converted on load I just convert
4011          * logical type of the operand.
4012          */
4013         if (TYPE_INTEGER(type->type)) {
4014                 unsigned int int_type;
4015                 int_type = type->type & ~TYPE_MASK;
4016                 int_type |= do_integral_promotion(type->type);
4017                 if (int_type != type->type) {
4018                         def->type = new_type(int_type, 0, 0);
4019                 }
4020         }
4021         return def;
4022 }
4023
4024
4025 static void arithmetic(struct compile_state *state, struct triple *def)
4026 {
4027         if (!TYPE_ARITHMETIC(def->type->type)) {
4028                 error(state, 0, "arithmetic type expexted");
4029         }
4030 }
4031
4032 static void ptr_arithmetic(struct compile_state *state, struct triple *def)
4033 {
4034         if (!TYPE_PTR(def->type->type) && !TYPE_ARITHMETIC(def->type->type)) {
4035                 error(state, def, "pointer or arithmetic type expected");
4036         }
4037 }
4038
4039 static int is_integral(struct triple *ins)
4040 {
4041         return TYPE_INTEGER(ins->type->type);
4042 }
4043
4044 static void integral(struct compile_state *state, struct triple *def)
4045 {
4046         if (!is_integral(def)) {
4047                 error(state, 0, "integral type expected");
4048         }
4049 }
4050
4051
4052 static void bool(struct compile_state *state, struct triple *def)
4053 {
4054         if (!TYPE_ARITHMETIC(def->type->type) &&
4055                 ((def->type->type & TYPE_MASK) != TYPE_POINTER)) {
4056                 error(state, 0, "arithmetic or pointer type expected");
4057         }
4058 }
4059
4060 static int is_signed(struct type *type)
4061 {
4062         return !!TYPE_SIGNED(type->type);
4063 }
4064
4065 /* Is this value located in a register otherwise it must be in memory */
4066 static int is_in_reg(struct compile_state *state, struct triple *def)
4067 {
4068         int in_reg;
4069         if (def->op == OP_ADECL) {
4070                 in_reg = 1;
4071         }
4072         else if ((def->op == OP_SDECL) || (def->op == OP_DEREF)) {
4073                 in_reg = 0;
4074         }
4075         else if (def->op == OP_VAL_VEC) {
4076                 in_reg = is_in_reg(state, RHS(def, 0));
4077         }
4078         else if (def->op == OP_DOT) {
4079                 in_reg = is_in_reg(state, RHS(def, 0));
4080         }
4081         else {
4082                 internal_error(state, 0, "unknown expr storage location");
4083                 in_reg = -1;
4084         }
4085         return in_reg;
4086 }
4087
4088 /* Is this a stable variable location otherwise it must be a temporary */
4089 static int is_stable(struct compile_state *state, struct triple *def)
4090 {
4091         int ret;
4092         ret = 0;
4093         if (!def) {
4094                 return 0;
4095         }
4096         if ((def->op == OP_ADECL) || 
4097                 (def->op == OP_SDECL) || 
4098                 (def->op == OP_DEREF) ||
4099                 (def->op == OP_BLOBCONST)) {
4100                 ret = 1;
4101         }
4102         else if (def->op == OP_DOT) {
4103                 ret = is_stable(state, RHS(def, 0));
4104         }
4105         else if (def->op == OP_VAL_VEC) {
4106                 struct triple **vector;
4107                 ulong_t i;
4108                 ret = 1;
4109                 vector = &RHS(def, 0);
4110                 for(i = 0; i < def->type->elements; i++) {
4111                         if (!is_stable(state, vector[i])) {
4112                                 ret = 0;
4113                                 break;
4114                         }
4115                 }
4116         }
4117         return ret;
4118 }
4119
4120 static int is_lvalue(struct compile_state *state, struct triple *def)
4121 {
4122         int ret;
4123         ret = 1;
4124         if (!def) {
4125                 return 0;
4126         }
4127         if (!is_stable(state, def)) {
4128                 return 0;
4129         }
4130         if (def->type->type & QUAL_CONST) {
4131                 ret = 0;
4132         }
4133         else if (def->op == OP_DOT) {
4134                 ret = is_lvalue(state, RHS(def, 0));
4135         }
4136         return ret;
4137 }
4138
4139 static void lvalue(struct compile_state *state, struct triple *def)
4140 {
4141         if (!def) {
4142                 internal_error(state, def, "nothing where lvalue expected?");
4143         }
4144         if (!is_lvalue(state, def)) { 
4145                 error(state, def, "lvalue expected");
4146         }
4147 }
4148
4149 static int is_pointer(struct triple *def)
4150 {
4151         return (def->type->type & TYPE_MASK) == TYPE_POINTER;
4152 }
4153
4154 static void pointer(struct compile_state *state, struct triple *def)
4155 {
4156         if (!is_pointer(def)) {
4157                 error(state, def, "pointer expected");
4158         }
4159 }
4160
4161 static struct triple *int_const(
4162         struct compile_state *state, struct type *type, ulong_t value)
4163 {
4164         struct triple *result;
4165         switch(type->type & TYPE_MASK) {
4166         case TYPE_CHAR:
4167         case TYPE_INT:   case TYPE_UINT:
4168         case TYPE_LONG:  case TYPE_ULONG:
4169                 break;
4170         default:
4171                 internal_error(state, 0, "constant for unkown type");
4172         }
4173         result = triple(state, OP_INTCONST, type, 0, 0);
4174         result->u.cval = value;
4175         return result;
4176 }
4177
4178
4179 static struct triple *do_mk_addr_expr(struct compile_state *state, 
4180         struct triple *expr, struct type *type, ulong_t offset)
4181 {
4182         struct triple *result;
4183         lvalue(state, expr);
4184
4185         result = 0;
4186         if (expr->op == OP_ADECL) {
4187                 error(state, expr, "address of auto variables not supported");
4188         }
4189         else if (expr->op == OP_SDECL) {
4190                 result = triple(state, OP_ADDRCONST, type, 0, 0);
4191                 MISC(result, 0) = expr;
4192                 result->u.cval = offset;
4193         }
4194         else if (expr->op == OP_DEREF) {
4195                 result = triple(state, OP_ADD, type,
4196                         RHS(expr, 0),
4197                         int_const(state, &ulong_type, offset));
4198         }
4199         return result;
4200 }
4201
4202 static struct triple *mk_addr_expr(
4203         struct compile_state *state, struct triple *expr, ulong_t offset)
4204 {
4205         struct type *type;
4206         
4207         type = new_type(
4208                 TYPE_POINTER | (expr->type->type & QUAL_MASK),
4209                 expr->type, 0);
4210
4211         return do_mk_addr_expr(state, expr, type, offset);
4212 }
4213
4214 static struct triple *mk_deref_expr(
4215         struct compile_state *state, struct triple *expr)
4216 {
4217         struct type *base_type;
4218         pointer(state, expr);
4219         base_type = expr->type->left;
4220         if (!TYPE_PTR(base_type->type) && !TYPE_ARITHMETIC(base_type->type)) {
4221                 error(state, 0, 
4222                         "Only pointer and arithmetic values can be dereferenced");
4223         }
4224         return triple(state, OP_DEREF, base_type, expr, 0);
4225 }
4226
4227 static struct triple *deref_field(
4228         struct compile_state *state, struct triple *expr, struct hash_entry *field)
4229 {
4230         struct triple *result;
4231         struct type *type, *member;
4232         if (!field) {
4233                 internal_error(state, 0, "No field passed to deref_field");
4234         }
4235         result = 0;
4236         type = expr->type;
4237         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
4238                 error(state, 0, "request for member %s in something not a struct or union",
4239                         field->name);
4240         }
4241         member = type->left;
4242         while((member->type & TYPE_MASK) == TYPE_PRODUCT) {
4243                 if (member->left->field_ident == field) {
4244                         member = member->left;
4245                         break;
4246                 }
4247                 member = member->right;
4248         }
4249         if (member->field_ident != field) {
4250                 error(state, 0, "%s is not a member", field->name);
4251         }
4252         if ((type->type & STOR_MASK) == STOR_PERM) {
4253                 /* Do the pointer arithmetic to get a deref the field */
4254                 ulong_t offset;
4255                 offset = field_offset(state, type, field);
4256                 result = do_mk_addr_expr(state, expr, member, offset);
4257                 result = mk_deref_expr(state, result);
4258         }
4259         else {
4260                 /* Find the variable for the field I want. */
4261                 result = triple(state, OP_DOT, 
4262                         field_type(state, type, field), expr, 0);
4263                 result->u.field = field;
4264         }
4265         return result;
4266 }
4267
4268 static struct triple *read_expr(struct compile_state *state, struct triple *def)
4269 {
4270         int op;
4271         if  (!def) {
4272                 return 0;
4273         }
4274         if (!is_stable(state, def)) {
4275                 return def;
4276         }
4277         /* Tranform an array to a pointer to the first element */
4278 #warning "CHECK_ME is this the right place to transform arrays to pointers?"
4279         if ((def->type->type & TYPE_MASK) == TYPE_ARRAY) {
4280                 struct type *type;
4281                 struct triple *result;
4282                 type = new_type(
4283                         TYPE_POINTER | (def->type->type & QUAL_MASK),
4284                         def->type->left, 0);
4285                 result = triple(state, OP_ADDRCONST, type, 0, 0);
4286                 MISC(result, 0) = def;
4287                 return result;
4288         }
4289         if (is_in_reg(state, def)) {
4290                 op = OP_READ;
4291         } else {
4292                 op = OP_LOAD;
4293         }
4294         return triple(state, op, def->type, def, 0);
4295 }
4296
4297 static void write_compatible(struct compile_state *state,
4298         struct type *dest, struct type *rval)
4299 {
4300         int compatible = 0;
4301         /* Both operands have arithmetic type */
4302         if (TYPE_ARITHMETIC(dest->type) && TYPE_ARITHMETIC(rval->type)) {
4303                 compatible = 1;
4304         }
4305         /* One operand is a pointer and the other is a pointer to void */
4306         else if (((dest->type & TYPE_MASK) == TYPE_POINTER) &&
4307                 ((rval->type & TYPE_MASK) == TYPE_POINTER) &&
4308                 (((dest->left->type & TYPE_MASK) == TYPE_VOID) ||
4309                         ((rval->left->type & TYPE_MASK) == TYPE_VOID))) {
4310                 compatible = 1;
4311         }
4312         /* If both types are the same without qualifiers we are good */
4313         else if (equiv_ptrs(dest, rval)) {
4314                 compatible = 1;
4315         }
4316         /* test for struct/union equality  */
4317         else if (((dest->type & TYPE_MASK) == TYPE_STRUCT) &&
4318                 ((rval->type & TYPE_MASK) == TYPE_STRUCT) &&
4319                 (dest->type_ident == rval->type_ident)) {
4320                 compatible = 1;
4321         }
4322         if (!compatible) {
4323                 error(state, 0, "Incompatible types in assignment");
4324         }
4325 }
4326
4327 static struct triple *write_expr(
4328         struct compile_state *state, struct triple *dest, struct triple *rval)
4329 {
4330         struct triple *def;
4331         int op;
4332
4333         def = 0;
4334         if (!rval) {
4335                 internal_error(state, 0, "missing rval");
4336         }
4337
4338         if (rval->op == OP_LIST) {
4339                 internal_error(state, 0, "expression of type OP_LIST?");
4340         }
4341         if (!is_lvalue(state, dest)) {
4342                 internal_error(state, 0, "writing to a non lvalue?");
4343         }
4344
4345         write_compatible(state, dest->type, rval->type);
4346
4347         /* Now figure out which assignment operator to use */
4348         op = -1;
4349         if (is_in_reg(state, dest)) {
4350                 op = OP_WRITE;
4351         } else {
4352                 op = OP_STORE;
4353         }
4354         def = triple(state, op, dest->type, dest, rval);
4355         return def;
4356 }
4357
4358 static struct triple *init_expr(
4359         struct compile_state *state, struct triple *dest, struct triple *rval)
4360 {
4361         struct triple *def;
4362
4363         def = 0;
4364         if (!rval) {
4365                 internal_error(state, 0, "missing rval");
4366         }
4367         if ((dest->type->type & STOR_MASK) != STOR_PERM) {
4368                 rval = read_expr(state, rval);
4369                 def = write_expr(state, dest, rval);
4370         }
4371         else {
4372                 /* Fill in the array size if necessary */
4373                 if (((dest->type->type & TYPE_MASK) == TYPE_ARRAY) &&
4374                         ((rval->type->type & TYPE_MASK) == TYPE_ARRAY)) {
4375                         if (dest->type->elements == ELEMENT_COUNT_UNSPECIFIED) {
4376                                 dest->type->elements = rval->type->elements;
4377                         }
4378                 }
4379                 if (!equiv_types(dest->type, rval->type)) {
4380                         error(state, 0, "Incompatible types in inializer");
4381                 }
4382                 MISC(dest, 0) = rval;
4383                 insert_triple(state, dest, rval);
4384                 rval->id |= TRIPLE_FLAG_FLATTENED;
4385                 use_triple(MISC(dest, 0), dest);
4386         }
4387         return def;
4388 }
4389
4390 struct type *arithmetic_result(
4391         struct compile_state *state, struct triple *left, struct triple *right)
4392 {
4393         struct type *type;
4394         /* Sanity checks to ensure I am working with arithmetic types */
4395         arithmetic(state, left);
4396         arithmetic(state, right);
4397         type = new_type(
4398                 do_arithmetic_conversion(
4399                         left->type->type, 
4400                         right->type->type), 0, 0);
4401         return type;
4402 }
4403
4404 struct type *ptr_arithmetic_result(
4405         struct compile_state *state, struct triple *left, struct triple *right)
4406 {
4407         struct type *type;
4408         /* Sanity checks to ensure I am working with the proper types */
4409         ptr_arithmetic(state, left);
4410         arithmetic(state, right);
4411         if (TYPE_ARITHMETIC(left->type->type) && 
4412                 TYPE_ARITHMETIC(right->type->type)) {
4413                 type = arithmetic_result(state, left, right);
4414         }
4415         else if (TYPE_PTR(left->type->type)) {
4416                 type = left->type;
4417         }
4418         else {
4419                 internal_error(state, 0, "huh?");
4420                 type = 0;
4421         }
4422         return type;
4423 }
4424
4425
4426 /* boolean helper function */
4427
4428 static struct triple *ltrue_expr(struct compile_state *state, 
4429         struct triple *expr)
4430 {
4431         switch(expr->op) {
4432         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
4433         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
4434         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
4435                 /* If the expression is already boolean do nothing */
4436                 break;
4437         default:
4438                 expr = triple(state, OP_LTRUE, &int_type, expr, 0);
4439                 break;
4440         }
4441         return expr;
4442 }
4443
4444 static struct triple *lfalse_expr(struct compile_state *state, 
4445         struct triple *expr)
4446 {
4447         return triple(state, OP_LFALSE, &int_type, expr, 0);
4448 }
4449
4450 static struct triple *cond_expr(
4451         struct compile_state *state, 
4452         struct triple *test, struct triple *left, struct triple *right)
4453 {
4454         struct triple *def;
4455         struct type *result_type;
4456         unsigned int left_type, right_type;
4457         bool(state, test);
4458         left_type = left->type->type;
4459         right_type = right->type->type;
4460         result_type = 0;
4461         /* Both operands have arithmetic type */
4462         if (TYPE_ARITHMETIC(left_type) && TYPE_ARITHMETIC(right_type)) {
4463                 result_type = arithmetic_result(state, left, right);
4464         }
4465         /* Both operands have void type */
4466         else if (((left_type & TYPE_MASK) == TYPE_VOID) &&
4467                 ((right_type & TYPE_MASK) == TYPE_VOID)) {
4468                 result_type = &void_type;
4469         }
4470         /* pointers to the same type... */
4471         else if ((result_type = compatible_ptrs(left->type, right->type))) {
4472                 ;
4473         }
4474         /* Both operands are pointers and left is a pointer to void */
4475         else if (((left_type & TYPE_MASK) == TYPE_POINTER) &&
4476                 ((right_type & TYPE_MASK) == TYPE_POINTER) &&
4477                 ((left->type->left->type & TYPE_MASK) == TYPE_VOID)) {
4478                 result_type = right->type;
4479         }
4480         /* Both operands are pointers and right is a pointer to void */
4481         else if (((left_type & TYPE_MASK) == TYPE_POINTER) &&
4482                 ((right_type & TYPE_MASK) == TYPE_POINTER) &&
4483                 ((right->type->left->type & TYPE_MASK) == TYPE_VOID)) {
4484                 result_type = left->type;
4485         }
4486         if (!result_type) {
4487                 error(state, 0, "Incompatible types in conditional expression");
4488         }
4489         /* Cleanup and invert the test */
4490         test = lfalse_expr(state, read_expr(state, test));
4491         def = new_triple(state, OP_COND, result_type, 0, 3);
4492         def->param[0] = test;
4493         def->param[1] = left;
4494         def->param[2] = right;
4495         return def;
4496 }
4497
4498
4499 static int expr_depth(struct compile_state *state, struct triple *ins)
4500 {
4501         int count;
4502         count = 0;
4503         if (!ins || (ins->id & TRIPLE_FLAG_FLATTENED)) {
4504                 count = 0;
4505         }
4506         else if (ins->op == OP_DEREF) {
4507                 count = expr_depth(state, RHS(ins, 0)) - 1;
4508         }
4509         else if (ins->op == OP_VAL) {
4510                 count = expr_depth(state, RHS(ins, 0)) - 1;
4511         }
4512         else if (ins->op == OP_COMMA) {
4513                 int ldepth, rdepth;
4514                 ldepth = expr_depth(state, RHS(ins, 0));
4515                 rdepth = expr_depth(state, RHS(ins, 1));
4516                 count = (ldepth >= rdepth)? ldepth : rdepth;
4517         }
4518         else if (ins->op == OP_CALL) {
4519                 /* Don't figure the depth of a call just guess it is huge */
4520                 count = 1000;
4521         }
4522         else {
4523                 struct triple **expr;
4524                 expr = triple_rhs(state, ins, 0);
4525                 for(;expr; expr = triple_rhs(state, ins, expr)) {
4526                         if (*expr) {
4527                                 int depth;
4528                                 depth = expr_depth(state, *expr);
4529                                 if (depth > count) {
4530                                         count = depth;
4531                                 }
4532                         }
4533                 }
4534         }
4535         return count + 1;
4536 }
4537
4538 static struct triple *flatten(
4539         struct compile_state *state, struct triple *first, struct triple *ptr);
4540
4541 static struct triple *flatten_generic(
4542         struct compile_state *state, struct triple *first, struct triple *ptr)
4543 {
4544         struct rhs_vector {
4545                 int depth;
4546                 struct triple **ins;
4547         } vector[MAX_RHS];
4548         int i, rhs, lhs;
4549         /* Only operations with just a rhs should come here */
4550         rhs = TRIPLE_RHS(ptr->sizes);
4551         lhs = TRIPLE_LHS(ptr->sizes);
4552         if (TRIPLE_SIZE(ptr->sizes) != lhs + rhs) {
4553                 internal_error(state, ptr, "unexpected args for: %d %s",
4554                         ptr->op, tops(ptr->op));
4555         }
4556         /* Find the depth of the rhs elements */
4557         for(i = 0; i < rhs; i++) {
4558                 vector[i].ins = &RHS(ptr, i);
4559                 vector[i].depth = expr_depth(state, *vector[i].ins);
4560         }
4561         /* Selection sort the rhs */
4562         for(i = 0; i < rhs; i++) {
4563                 int j, max = i;
4564                 for(j = i + 1; j < rhs; j++ ) {
4565                         if (vector[j].depth > vector[max].depth) {
4566                                 max = j;
4567                         }
4568                 }
4569                 if (max != i) {
4570                         struct rhs_vector tmp;
4571                         tmp = vector[i];
4572                         vector[i] = vector[max];
4573                         vector[max] = tmp;
4574                 }
4575         }
4576         /* Now flatten the rhs elements */
4577         for(i = 0; i < rhs; i++) {
4578                 *vector[i].ins = flatten(state, first, *vector[i].ins);
4579                 use_triple(*vector[i].ins, ptr);
4580         }
4581         
4582         /* Now flatten the lhs elements */
4583         for(i = 0; i < lhs; i++) {
4584                 struct triple **ins = &LHS(ptr, i);
4585                 *ins = flatten(state, first, *ins);
4586                 use_triple(*ins, ptr);
4587         }
4588         return ptr;
4589 }
4590
4591 static struct triple *flatten_land(
4592         struct compile_state *state, struct triple *first, struct triple *ptr)
4593 {
4594         struct triple *left, *right;
4595         struct triple *val, *test, *jmp, *label1, *end;
4596
4597         /* Find the triples */
4598         left = RHS(ptr, 0);
4599         right = RHS(ptr, 1);
4600
4601         /* Generate the needed triples */
4602         end = label(state);
4603
4604         /* Thread the triples together */
4605         val          = flatten(state, first, variable(state, ptr->type));
4606         left         = flatten(state, first, write_expr(state, val, left));
4607         test         = flatten(state, first, 
4608                 lfalse_expr(state, read_expr(state, val)));
4609         jmp          = flatten(state, first, branch(state, end, test));
4610         label1       = flatten(state, first, label(state));
4611         right        = flatten(state, first, write_expr(state, val, right));
4612         TARG(jmp, 0) = flatten(state, first, end); 
4613         
4614         /* Now give the caller something to chew on */
4615         return read_expr(state, val);
4616 }
4617
4618 static struct triple *flatten_lor(
4619         struct compile_state *state, struct triple *first, struct triple *ptr)
4620 {
4621         struct triple *left, *right;
4622         struct triple *val, *jmp, *label1, *end;
4623
4624         /* Find the triples */
4625         left = RHS(ptr, 0);
4626         right = RHS(ptr, 1);
4627
4628         /* Generate the needed triples */
4629         end = label(state);
4630
4631         /* Thread the triples together */
4632         val          = flatten(state, first, variable(state, ptr->type));
4633         left         = flatten(state, first, write_expr(state, val, left));
4634         jmp          = flatten(state, first, branch(state, end, left));
4635         label1       = flatten(state, first, label(state));
4636         right        = flatten(state, first, write_expr(state, val, right));
4637         TARG(jmp, 0) = flatten(state, first, end);
4638        
4639         
4640         /* Now give the caller something to chew on */
4641         return read_expr(state, val);
4642 }
4643
4644 static struct triple *flatten_cond(
4645         struct compile_state *state, struct triple *first, struct triple *ptr)
4646 {
4647         struct triple *test, *left, *right;
4648         struct triple *val, *mv1, *jmp1, *label1, *mv2, *middle, *jmp2, *end;
4649
4650         /* Find the triples */
4651         test = RHS(ptr, 0);
4652         left = RHS(ptr, 1);
4653         right = RHS(ptr, 2);
4654
4655         /* Generate the needed triples */
4656         end = label(state);
4657         middle = label(state);
4658
4659         /* Thread the triples together */
4660         val           = flatten(state, first, variable(state, ptr->type));
4661         test          = flatten(state, first, test);
4662         jmp1          = flatten(state, first, branch(state, middle, test));
4663         label1        = flatten(state, first, label(state));
4664         left          = flatten(state, first, left);
4665         mv1           = flatten(state, first, write_expr(state, val, left));
4666         jmp2          = flatten(state, first, branch(state, end, 0));
4667         TARG(jmp1, 0) = flatten(state, first, middle);
4668         right         = flatten(state, first, right);
4669         mv2           = flatten(state, first, write_expr(state, val, right));
4670         TARG(jmp2, 0) = flatten(state, first, end);
4671         
4672         /* Now give the caller something to chew on */
4673         return read_expr(state, val);
4674 }
4675
4676 struct triple *copy_func(struct compile_state *state, struct triple *ofunc)
4677 {
4678         struct triple *nfunc;
4679         struct triple *nfirst, *ofirst;
4680         struct triple *new, *old;
4681
4682 #if 0
4683         fprintf(stdout, "\n");
4684         loc(stdout, state, 0);
4685         fprintf(stdout, "\n__________ copy_func _________\n");
4686         print_triple(state, ofunc);
4687         fprintf(stdout, "__________ copy_func _________ done\n\n");
4688 #endif
4689
4690         /* Make a new copy of the old function */
4691         nfunc = triple(state, OP_LIST, ofunc->type, 0, 0);
4692         nfirst = 0;
4693         ofirst = old = RHS(ofunc, 0);
4694         do {
4695                 struct triple *new;
4696                 int old_lhs, old_rhs;
4697                 old_lhs = TRIPLE_LHS(old->sizes);
4698                 old_rhs = TRIPLE_RHS(old->sizes);
4699                 new = alloc_triple(state, old->op, old->type, old_lhs, old_rhs,
4700                         old->filename, old->line, old->col);
4701                 if (!triple_stores_block(state, new)) {
4702                         memcpy(&new->u, &old->u, sizeof(new->u));
4703                 }
4704                 if (!nfirst) {
4705                         RHS(nfunc, 0) = nfirst = new;
4706                 }
4707                 else {
4708                         insert_triple(state, nfirst, new);
4709                 }
4710                 new->id |= TRIPLE_FLAG_FLATTENED;
4711                 
4712                 /* During the copy remember new as user of old */
4713                 use_triple(old, new);
4714
4715                 /* Populate the return type if present */
4716                 if (old == MISC(ofunc, 0)) {
4717                         MISC(nfunc, 0) = new;
4718                 }
4719                 old = old->next;
4720         } while(old != ofirst);
4721
4722         /* Make a second pass to fix up any unresolved references */
4723         old = ofirst;
4724         new = nfirst;
4725         do {
4726                 struct triple **oexpr, **nexpr;
4727                 int count, i;
4728                 /* Lookup where the copy is, to join pointers */
4729                 count = TRIPLE_SIZE(old->sizes);
4730                 for(i = 0; i < count; i++) {
4731                         oexpr = &old->param[i];
4732                         nexpr = &new->param[i];
4733                         if (!*nexpr && *oexpr && (*oexpr)->use) {
4734                                 *nexpr = (*oexpr)->use->member;
4735                                 if (*nexpr == old) {
4736                                         internal_error(state, 0, "new == old?");
4737                                 }
4738                                 use_triple(*nexpr, new);
4739                         }
4740                         if (!*nexpr && *oexpr) {
4741                                 internal_error(state, 0, "Could not copy %d\n", i);
4742                         }
4743                 }
4744                 old = old->next;
4745                 new = new->next;
4746         } while((old != ofirst) && (new != nfirst));
4747         
4748         /* Make a third pass to cleanup the extra useses */
4749         old = ofirst;
4750         new = nfirst;
4751         do {
4752                 unuse_triple(old, new);
4753                 old = old->next;
4754                 new = new->next;
4755         } while ((old != ofirst) && (new != nfirst));
4756         return nfunc;
4757 }
4758
4759 static struct triple *flatten_call(
4760         struct compile_state *state, struct triple *first, struct triple *ptr)
4761 {
4762         /* Inline the function call */
4763         struct type *ptype;
4764         struct triple *ofunc, *nfunc, *nfirst, *param, *result;
4765         struct triple *end, *nend;
4766         int pvals, i;
4767
4768         /* Find the triples */
4769         ofunc = MISC(ptr, 0);
4770         if (ofunc->op != OP_LIST) {
4771                 internal_error(state, 0, "improper function");
4772         }
4773         nfunc = copy_func(state, ofunc);
4774         nfirst = RHS(nfunc, 0)->next;
4775         /* Prepend the parameter reading into the new function list */
4776         ptype = nfunc->type->right;
4777         param = RHS(nfunc, 0)->next;
4778         pvals = TRIPLE_RHS(ptr->sizes);
4779         for(i = 0; i < pvals; i++) {
4780                 struct type *atype;
4781                 struct triple *arg;
4782                 atype = ptype;
4783                 if ((ptype->type & TYPE_MASK) == TYPE_PRODUCT) {
4784                         atype = ptype->left;
4785                 }
4786                 while((param->type->type & TYPE_MASK) != (atype->type & TYPE_MASK)) {
4787                         param = param->next;
4788                 }
4789                 arg = RHS(ptr, i);
4790                 flatten(state, nfirst, write_expr(state, param, arg));
4791                 ptype = ptype->right;
4792                 param = param->next;
4793         }
4794         result = 0;
4795         if ((nfunc->type->left->type & TYPE_MASK) != TYPE_VOID) {
4796                 result = read_expr(state, MISC(nfunc,0));
4797         }
4798 #if 0
4799         fprintf(stdout, "\n");
4800         loc(stdout, state, 0);
4801         fprintf(stdout, "\n__________ flatten_call _________\n");
4802         print_triple(state, nfunc);
4803         fprintf(stdout, "__________ flatten_call _________ done\n\n");
4804 #endif
4805
4806         /* Get rid of the extra triples */
4807         nfirst = RHS(nfunc, 0)->next;
4808         free_triple(state, RHS(nfunc, 0));
4809         RHS(nfunc, 0) = 0;
4810         free_triple(state, nfunc);
4811
4812         /* Append the new function list onto the return list */
4813         end = first->prev;
4814         nend = nfirst->prev;
4815         end->next    = nfirst;
4816         nfirst->prev = end;
4817         nend->next   = first;
4818         first->prev  = nend;
4819
4820         return result;
4821 }
4822
4823 static struct triple *flatten(
4824         struct compile_state *state, struct triple *first, struct triple *ptr)
4825 {
4826         struct triple *orig_ptr;
4827         if (!ptr)
4828                 return 0;
4829         do {
4830                 orig_ptr = ptr;
4831                 /* Only flatten triples once */
4832                 if (ptr->id & TRIPLE_FLAG_FLATTENED) {
4833                         return ptr;
4834                 }
4835                 switch(ptr->op) {
4836                 case OP_WRITE:
4837                 case OP_STORE:
4838                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
4839                         LHS(ptr, 0) = flatten(state, first, LHS(ptr, 0));
4840                         use_triple(LHS(ptr, 0), ptr);
4841                         use_triple(RHS(ptr, 0), ptr);
4842                         break;
4843                 case OP_COMMA:
4844                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
4845                         ptr = RHS(ptr, 1);
4846                         break;
4847                 case OP_VAL:
4848                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
4849                         return MISC(ptr, 0);
4850                         break;
4851                 case OP_LAND:
4852                         ptr = flatten_land(state, first, ptr);
4853                         break;
4854                 case OP_LOR:
4855                         ptr = flatten_lor(state, first, ptr);
4856                         break;
4857                 case OP_COND:
4858                         ptr = flatten_cond(state, first, ptr);
4859                         break;
4860                 case OP_CALL:
4861                         ptr = flatten_call(state, first, ptr);
4862                         break;
4863                 case OP_READ:
4864                 case OP_LOAD:
4865                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
4866                         use_triple(RHS(ptr, 0), ptr);
4867                         break;
4868                 case OP_BRANCH:
4869                         use_triple(TARG(ptr, 0), ptr);
4870                         if (TRIPLE_RHS(ptr->sizes)) {
4871                                 use_triple(RHS(ptr, 0), ptr);
4872                                 if (ptr->next != ptr) {
4873                                         use_triple(ptr->next, ptr);
4874                                 }
4875                         }
4876                         break;
4877                 case OP_BLOBCONST:
4878                         insert_triple(state, first, ptr);
4879                         ptr->id |= TRIPLE_FLAG_FLATTENED;
4880                         ptr = triple(state, OP_SDECL, ptr->type, ptr, 0);
4881                         use_triple(MISC(ptr, 0), ptr);
4882                         break;
4883                 case OP_DEREF:
4884                         /* Since OP_DEREF is just a marker delete it when I flatten it */
4885                         ptr = RHS(ptr, 0);
4886                         RHS(orig_ptr, 0) = 0;
4887                         free_triple(state, orig_ptr);
4888                         break;
4889                 case OP_DOT:
4890                 {
4891                         struct triple *base;
4892                         base = RHS(ptr, 0);
4893                         base = flatten(state, first, base);
4894                         if (base->op == OP_VAL_VEC) {
4895                                 ptr = struct_field(state, base, ptr->u.field);
4896                         }
4897                         break;
4898                 }
4899                 case OP_ADDRCONST:
4900                 case OP_SDECL:
4901                 case OP_PIECE:
4902                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
4903                         use_triple(MISC(ptr, 0), ptr);
4904                         break;
4905                 case OP_ADECL:
4906                         break;
4907                 default:
4908                         /* Flatten the easy cases we don't override */
4909                         ptr = flatten_generic(state, first, ptr);
4910                         break;
4911                 }
4912         } while(ptr && (ptr != orig_ptr));
4913         if (ptr) {
4914                 insert_triple(state, first, ptr);
4915                 ptr->id |= TRIPLE_FLAG_FLATTENED;
4916         }
4917         return ptr;
4918 }
4919
4920 static void release_expr(struct compile_state *state, struct triple *expr)
4921 {
4922         struct triple *head;
4923         head = label(state);
4924         flatten(state, head, expr);
4925         while(head->next != head) {
4926                 release_triple(state, head->next);
4927         }
4928         free_triple(state, head);
4929 }
4930
4931 static int replace_rhs_use(struct compile_state *state,
4932         struct triple *orig, struct triple *new, struct triple *use)
4933 {
4934         struct triple **expr;
4935         int found;
4936         found = 0;
4937         expr = triple_rhs(state, use, 0);
4938         for(;expr; expr = triple_rhs(state, use, expr)) {
4939                 if (*expr == orig) {
4940                         *expr = new;
4941                         found = 1;
4942                 }
4943         }
4944         if (found) {
4945                 unuse_triple(orig, use);
4946                 use_triple(new, use);
4947         }
4948         return found;
4949 }
4950
4951 static int replace_lhs_use(struct compile_state *state,
4952         struct triple *orig, struct triple *new, struct triple *use)
4953 {
4954         struct triple **expr;
4955         int found;
4956         found = 0;
4957         expr = triple_lhs(state, use, 0);
4958         for(;expr; expr = triple_lhs(state, use, expr)) {
4959                 if (*expr == orig) {
4960                         *expr = new;
4961                         found = 1;
4962                 }
4963         }
4964         if (found) {
4965                 unuse_triple(orig, use);
4966                 use_triple(new, use);
4967         }
4968         return found;
4969 }
4970
4971 static void propogate_use(struct compile_state *state,
4972         struct triple *orig, struct triple *new)
4973 {
4974         struct triple_set *user, *next;
4975         for(user = orig->use; user; user = next) {
4976                 struct triple *use;
4977                 int found;
4978                 next = user->next;
4979                 use = user->member;
4980                 found = 0;
4981                 found |= replace_rhs_use(state, orig, new, use);
4982                 found |= replace_lhs_use(state, orig, new, use);
4983                 if (!found) {
4984                         internal_error(state, use, "use without use");
4985                 }
4986         }
4987         if (orig->use) {
4988                 internal_error(state, orig, "used after propogate_use");
4989         }
4990 }
4991
4992 /*
4993  * Code generators
4994  * ===========================
4995  */
4996
4997 static struct triple *mk_add_expr(
4998         struct compile_state *state, struct triple *left, struct triple *right)
4999 {
5000         struct type *result_type;
5001         /* Put pointer operands on the left */
5002         if (is_pointer(right)) {
5003                 struct triple *tmp;
5004                 tmp = left;
5005                 left = right;
5006                 right = tmp;
5007         }
5008         left  = read_expr(state, left);
5009         right = read_expr(state, right);
5010         result_type = ptr_arithmetic_result(state, left, right);
5011         if (is_pointer(left)) {
5012                 right = triple(state, 
5013                         is_signed(right->type)? OP_SMUL : OP_UMUL, 
5014                         &ulong_type, 
5015                         right, 
5016                         int_const(state, &ulong_type, 
5017                                 size_of(state, left->type->left)));
5018         }
5019         return triple(state, OP_ADD, result_type, left, right);
5020 }
5021
5022 static struct triple *mk_sub_expr(
5023         struct compile_state *state, struct triple *left, struct triple *right)
5024 {
5025         struct type *result_type;
5026         result_type = ptr_arithmetic_result(state, left, right);
5027         left  = read_expr(state, left);
5028         right = read_expr(state, right);
5029         if (is_pointer(left)) {
5030                 right = triple(state, 
5031                         is_signed(right->type)? OP_SMUL : OP_UMUL, 
5032                         &ulong_type, 
5033                         right, 
5034                         int_const(state, &ulong_type, 
5035                                 size_of(state, left->type->left)));
5036         }
5037         return triple(state, OP_SUB, result_type, left, right);
5038 }
5039
5040 static struct triple *mk_pre_inc_expr(
5041         struct compile_state *state, struct triple *def)
5042 {
5043         struct triple *val;
5044         lvalue(state, def);
5045         val = mk_add_expr(state, def, int_const(state, &int_type, 1));
5046         return triple(state, OP_VAL, def->type,
5047                 write_expr(state, def, val),
5048                 val);
5049 }
5050
5051 static struct triple *mk_pre_dec_expr(
5052         struct compile_state *state, struct triple *def)
5053 {
5054         struct triple *val;
5055         lvalue(state, def);
5056         val = mk_sub_expr(state, def, int_const(state, &int_type, 1));
5057         return triple(state, OP_VAL, def->type,
5058                 write_expr(state, def, val),
5059                 val);
5060 }
5061
5062 static struct triple *mk_post_inc_expr(
5063         struct compile_state *state, struct triple *def)
5064 {
5065         struct triple *val;
5066         lvalue(state, def);
5067         val = read_expr(state, def);
5068         return triple(state, OP_VAL, def->type,
5069                 write_expr(state, def,
5070                         mk_add_expr(state, val, int_const(state, &int_type, 1)))
5071                 , val);
5072 }
5073
5074 static struct triple *mk_post_dec_expr(
5075         struct compile_state *state, struct triple *def)
5076 {
5077         struct triple *val;
5078         lvalue(state, def);
5079         val = read_expr(state, def);
5080         return triple(state, OP_VAL, def->type, 
5081                 write_expr(state, def,
5082                         mk_sub_expr(state, val, int_const(state, &int_type, 1)))
5083                 , val);
5084 }
5085
5086 static struct triple *mk_subscript_expr(
5087         struct compile_state *state, struct triple *left, struct triple *right)
5088 {
5089         left  = read_expr(state, left);
5090         right = read_expr(state, right);
5091         if (!is_pointer(left) && !is_pointer(right)) {
5092                 error(state, left, "subscripted value is not a pointer");
5093         }
5094         return mk_deref_expr(state, mk_add_expr(state, left, right));
5095 }
5096
5097 /*
5098  * Compile time evaluation
5099  * ===========================
5100  */
5101 static int is_const(struct triple *ins)
5102 {
5103         return IS_CONST_OP(ins->op);
5104 }
5105
5106 static int constants_equal(struct compile_state *state, 
5107         struct triple *left, struct triple *right)
5108 {
5109         int equal;
5110         if (!is_const(left) || !is_const(right)) {
5111                 equal = 0;
5112         }
5113         else if (left->op != right->op) {
5114                 equal = 0;
5115         }
5116         else if (!equiv_types(left->type, right->type)) {
5117                 equal = 0;
5118         }
5119         else {
5120                 equal = 0;
5121                 switch(left->op) {
5122                 case OP_INTCONST:
5123                         if (left->u.cval == right->u.cval) {
5124                                 equal = 1;
5125                         }
5126                         break;
5127                 case OP_BLOBCONST:
5128                 {
5129                         size_t lsize, rsize;
5130                         lsize = size_of(state, left->type);
5131                         rsize = size_of(state, right->type);
5132                         if (lsize != rsize) {
5133                                 break;
5134                         }
5135                         if (memcmp(left->u.blob, right->u.blob, lsize) == 0) {
5136                                 equal = 1;
5137                         }
5138                         break;
5139                 }
5140                 case OP_ADDRCONST:
5141                         if ((MISC(left, 0) == MISC(right, 0)) &&
5142                                 (left->u.cval == right->u.cval)) {
5143                                 equal = 1;
5144                         }
5145                         break;
5146                 default:
5147                         internal_error(state, left, "uknown constant type");
5148                         break;
5149                 }
5150         }
5151         return equal;
5152 }
5153
5154 static int is_zero(struct triple *ins)
5155 {
5156         return is_const(ins) && (ins->u.cval == 0);
5157 }
5158
5159 static int is_one(struct triple *ins)
5160 {
5161         return is_const(ins) && (ins->u.cval == 1);
5162 }
5163
5164 static long_t bsr(ulong_t value)
5165 {
5166         int i;
5167         for(i = (sizeof(ulong_t)*8) -1; i >= 0; i--) {
5168                 ulong_t mask;
5169                 mask = 1;
5170                 mask <<= i;
5171                 if (value & mask) {
5172                         return i;
5173                 }
5174         }
5175         return -1;
5176 }
5177
5178 static long_t bsf(ulong_t value)
5179 {
5180         int i;
5181         for(i = 0; i < (sizeof(ulong_t)*8); i++) {
5182                 ulong_t mask;
5183                 mask = 1;
5184                 mask <<= 1;
5185                 if (value & mask) {
5186                         return i;
5187                 }
5188         }
5189         return -1;
5190 }
5191
5192 static long_t log2(ulong_t value)
5193 {
5194         return bsr(value);
5195 }
5196
5197 static long_t tlog2(struct triple *ins)
5198 {
5199         return log2(ins->u.cval);
5200 }
5201
5202 static int is_pow2(struct triple *ins)
5203 {
5204         ulong_t value, mask;
5205         long_t log;
5206         if (!is_const(ins)) {
5207                 return 0;
5208         }
5209         value = ins->u.cval;
5210         log = log2(value);
5211         if (log == -1) {
5212                 return 0;
5213         }
5214         mask = 1;
5215         mask <<= log;
5216         return  ((value & mask) == value);
5217 }
5218
5219 static ulong_t read_const(struct compile_state *state,
5220         struct triple *ins, struct triple **expr)
5221 {
5222         struct triple *rhs;
5223         rhs = *expr;
5224         switch(rhs->type->type &TYPE_MASK) {
5225         case TYPE_CHAR:   
5226         case TYPE_SHORT:
5227         case TYPE_INT:
5228         case TYPE_LONG:
5229         case TYPE_UCHAR:   
5230         case TYPE_USHORT:  
5231         case TYPE_UINT:
5232         case TYPE_ULONG:
5233         case TYPE_POINTER:
5234                 break;
5235         default:
5236                 internal_error(state, rhs, "bad type to read_const\n");
5237                 break;
5238         }
5239         return rhs->u.cval;
5240 }
5241
5242 static long_t read_sconst(struct triple *ins, struct triple **expr)
5243 {
5244         struct triple *rhs;
5245         rhs = *expr;
5246         return (long_t)(rhs->u.cval);
5247 }
5248
5249 static void unuse_rhs(struct compile_state *state, struct triple *ins)
5250 {
5251         struct triple **expr;
5252         expr = triple_rhs(state, ins, 0);
5253         for(;expr;expr = triple_rhs(state, ins, expr)) {
5254                 if (*expr) {
5255                         unuse_triple(*expr, ins);
5256                         *expr = 0;
5257                 }
5258         }
5259 }
5260
5261 static void unuse_lhs(struct compile_state *state, struct triple *ins)
5262 {
5263         struct triple **expr;
5264         expr = triple_lhs(state, ins, 0);
5265         for(;expr;expr = triple_lhs(state, ins, expr)) {
5266                 unuse_triple(*expr, ins);
5267                 *expr = 0;
5268         }
5269 }
5270
5271 static void check_lhs(struct compile_state *state, struct triple *ins)
5272 {
5273         struct triple **expr;
5274         expr = triple_lhs(state, ins, 0);
5275         for(;expr;expr = triple_lhs(state, ins, expr)) {
5276                 internal_error(state, ins, "unexpected lhs");
5277         }
5278         
5279 }
5280 static void check_targ(struct compile_state *state, struct triple *ins)
5281 {
5282         struct triple **expr;
5283         expr = triple_targ(state, ins, 0);
5284         for(;expr;expr = triple_targ(state, ins, expr)) {
5285                 internal_error(state, ins, "unexpected targ");
5286         }
5287 }
5288
5289 static void wipe_ins(struct compile_state *state, struct triple *ins)
5290 {
5291         /* Becareful which instructions you replace the wiped
5292          * instruction with, as there are not enough slots
5293          * in all instructions to hold all others.
5294          */
5295         check_targ(state, ins);
5296         unuse_rhs(state, ins);
5297         unuse_lhs(state, ins);
5298 }
5299
5300 static void mkcopy(struct compile_state *state, 
5301         struct triple *ins, struct triple *rhs)
5302 {
5303         wipe_ins(state, ins);
5304         ins->op = OP_COPY;
5305         ins->sizes = TRIPLE_SIZES(0, 1, 0, 0);
5306         RHS(ins, 0) = rhs;
5307         use_triple(RHS(ins, 0), ins);
5308 }
5309
5310 static void mkconst(struct compile_state *state, 
5311         struct triple *ins, ulong_t value)
5312 {
5313         if (!is_integral(ins) && !is_pointer(ins)) {
5314                 internal_error(state, ins, "unknown type to make constant\n");
5315         }
5316         wipe_ins(state, ins);
5317         ins->op = OP_INTCONST;
5318         ins->sizes = TRIPLE_SIZES(0, 0, 0, 0);
5319         ins->u.cval = value;
5320 }
5321
5322 static void mkaddr_const(struct compile_state *state,
5323         struct triple *ins, struct triple *sdecl, ulong_t value)
5324 {
5325         wipe_ins(state, ins);
5326         ins->op = OP_ADDRCONST;
5327         ins->sizes = TRIPLE_SIZES(0, 0, 1, 0);
5328         MISC(ins, 0) = sdecl;
5329         ins->u.cval = value;
5330         use_triple(sdecl, ins);
5331 }
5332
5333 /* Transform multicomponent variables into simple register variables */
5334 static void flatten_structures(struct compile_state *state)
5335 {
5336         struct triple *ins, *first;
5337         first = RHS(state->main_function, 0);
5338         ins = first;
5339         /* Pass one expand structure values into valvecs.
5340          */
5341         ins = first;
5342         do {
5343                 struct triple *next;
5344                 next = ins->next;
5345                 if ((ins->type->type & TYPE_MASK) == TYPE_STRUCT) {
5346                         if (ins->op == OP_VAL_VEC) {
5347                                 /* Do nothing */
5348                         }
5349                         else if ((ins->op == OP_LOAD) || (ins->op == OP_READ)) {
5350                                 struct triple *def, **vector;
5351                                 struct type *tptr;
5352                                 int op;
5353                                 ulong_t i;
5354
5355                                 op = ins->op;
5356                                 def = RHS(ins, 0);
5357                                 next = alloc_triple(state, OP_VAL_VEC, ins->type, -1, -1,
5358                                         ins->filename, ins->line, ins->col);
5359
5360                                 vector = &RHS(next, 0);
5361                                 tptr = next->type->left;
5362                                 for(i = 0; i < next->type->elements; i++) {
5363                                         struct triple *sfield;
5364                                         struct type *mtype;
5365                                         mtype = tptr;
5366                                         if ((mtype->type & TYPE_MASK) == TYPE_PRODUCT) {
5367                                                 mtype = mtype->left;
5368                                         }
5369                                         sfield = deref_field(state, def, mtype->field_ident);
5370                                         
5371                                         vector[i] = triple(
5372                                                 state, op, mtype, sfield, 0);
5373                                         vector[i]->filename = next->filename;
5374                                         vector[i]->line = next->line;
5375                                         vector[i]->col = next->col;
5376                                         tptr = tptr->right;
5377                                 }
5378                                 propogate_use(state, ins, next);
5379                                 flatten(state, ins, next);
5380                                 free_triple(state, ins);
5381                         }
5382                         else if ((ins->op == OP_STORE) || (ins->op == OP_WRITE)) {
5383                                 struct triple *src, *dst, **vector;
5384                                 struct type *tptr;
5385                                 int op;
5386                                 ulong_t i;
5387
5388                                 op = ins->op;
5389                                 src = RHS(ins, 0);
5390                                 dst = LHS(ins, 0);
5391                                 next = alloc_triple(state, OP_VAL_VEC, ins->type, -1, -1,
5392                                         ins->filename, ins->line, ins->col);
5393                                 
5394                                 vector = &RHS(next, 0);
5395                                 tptr = next->type->left;
5396                                 for(i = 0; i < ins->type->elements; i++) {
5397                                         struct triple *dfield, *sfield;
5398                                         struct type *mtype;
5399                                         mtype = tptr;
5400                                         if ((mtype->type & TYPE_MASK) == TYPE_PRODUCT) {
5401                                                 mtype = mtype->left;
5402                                         }
5403                                         sfield = deref_field(state, src, mtype->field_ident);
5404                                         dfield = deref_field(state, dst, mtype->field_ident);
5405                                         vector[i] = triple(
5406                                                 state, op, mtype, dfield, sfield);
5407                                         vector[i]->filename = next->filename;
5408                                         vector[i]->line = next->line;
5409                                         vector[i]->col = next->col;
5410                                         tptr = tptr->right;
5411                                 }
5412                                 propogate_use(state, ins, next);
5413                                 flatten(state, ins, next);
5414                                 free_triple(state, ins);
5415                         }
5416                 }
5417                 ins = next;
5418         } while(ins != first);
5419         /* Pass two flatten the valvecs.
5420          */
5421         ins = first;
5422         do {
5423                 struct triple *next;
5424                 next = ins->next;
5425                 if (ins->op == OP_VAL_VEC) {
5426                         release_triple(state, ins);
5427                 } 
5428                 ins = next;
5429         } while(ins != first);
5430         /* Pass three verify the state and set ->id to 0.
5431          */
5432         ins = first;
5433         do {
5434                 ins->id &= ~TRIPLE_FLAG_FLATTENED;
5435                 if ((ins->type->type & TYPE_MASK) == TYPE_STRUCT) {
5436                         internal_error(state, 0, "STRUCT_TYPE remains?");
5437                 }
5438                 if (ins->op == OP_DOT) {
5439                         internal_error(state, 0, "OP_DOT remains?");
5440                 }
5441                 if (ins->op == OP_VAL_VEC) {
5442                         internal_error(state, 0, "OP_VAL_VEC remains?");
5443                 }
5444                 ins = ins->next;
5445         } while(ins != first);
5446 }
5447
5448 /* For those operations that cannot be simplified */
5449 static void simplify_noop(struct compile_state *state, struct triple *ins)
5450 {
5451         return;
5452 }
5453
5454 static void simplify_smul(struct compile_state *state, struct triple *ins)
5455 {
5456         if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
5457                 struct triple *tmp;
5458                 tmp = RHS(ins, 0);
5459                 RHS(ins, 0) = RHS(ins, 1);
5460                 RHS(ins, 1) = tmp;
5461         }
5462         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5463                 long_t left, right;
5464                 left  = read_sconst(ins, &RHS(ins, 0));
5465                 right = read_sconst(ins, &RHS(ins, 1));
5466                 mkconst(state, ins, left * right);
5467         }
5468         else if (is_zero(RHS(ins, 1))) {
5469                 mkconst(state, ins, 0);
5470         }
5471         else if (is_one(RHS(ins, 1))) {
5472                 mkcopy(state, ins, RHS(ins, 0));
5473         }
5474         else if (is_pow2(RHS(ins, 1))) {
5475                 struct triple *val;
5476                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
5477                 ins->op = OP_SL;
5478                 insert_triple(state, ins, val);
5479                 unuse_triple(RHS(ins, 1), ins);
5480                 use_triple(val, ins);
5481                 RHS(ins, 1) = val;
5482         }
5483 }
5484
5485 static void simplify_umul(struct compile_state *state, struct triple *ins)
5486 {
5487         if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
5488                 struct triple *tmp;
5489                 tmp = RHS(ins, 0);
5490                 RHS(ins, 0) = RHS(ins, 1);
5491                 RHS(ins, 1) = tmp;
5492         }
5493         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5494                 ulong_t left, right;
5495                 left  = read_const(state, ins, &RHS(ins, 0));
5496                 right = read_const(state, ins, &RHS(ins, 1));
5497                 mkconst(state, ins, left * right);
5498         }
5499         else if (is_zero(RHS(ins, 1))) {
5500                 mkconst(state, ins, 0);
5501         }
5502         else if (is_one(RHS(ins, 1))) {
5503                 mkcopy(state, ins, RHS(ins, 0));
5504         }
5505         else if (is_pow2(RHS(ins, 1))) {
5506                 struct triple *val;
5507                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
5508                 ins->op = OP_SL;
5509                 insert_triple(state, ins, val);
5510                 unuse_triple(RHS(ins, 1), ins);
5511                 use_triple(val, ins);
5512                 RHS(ins, 1) = val;
5513         }
5514 }
5515
5516 static void simplify_sdiv(struct compile_state *state, struct triple *ins)
5517 {
5518         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5519                 long_t left, right;
5520                 left  = read_sconst(ins, &RHS(ins, 0));
5521                 right = read_sconst(ins, &RHS(ins, 1));
5522                 mkconst(state, ins, left / right);
5523         }
5524         else if (is_zero(RHS(ins, 0))) {
5525                 mkconst(state, ins, 0);
5526         }
5527         else if (is_zero(RHS(ins, 1))) {
5528                 error(state, ins, "division by zero");
5529         }
5530         else if (is_one(RHS(ins, 1))) {
5531                 mkcopy(state, ins, RHS(ins, 0));
5532         }
5533         else if (is_pow2(RHS(ins, 1))) {
5534                 struct triple *val;
5535                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
5536                 ins->op = OP_SSR;
5537                 insert_triple(state, ins, val);
5538                 unuse_triple(RHS(ins, 1), ins);
5539                 use_triple(val, ins);
5540                 RHS(ins, 1) = val;
5541         }
5542 }
5543
5544 static void simplify_udiv(struct compile_state *state, struct triple *ins)
5545 {
5546         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5547                 ulong_t left, right;
5548                 left  = read_const(state, ins, &RHS(ins, 0));
5549                 right = read_const(state, ins, &RHS(ins, 1));
5550                 mkconst(state, ins, left / right);
5551         }
5552         else if (is_zero(RHS(ins, 0))) {
5553                 mkconst(state, ins, 0);
5554         }
5555         else if (is_zero(RHS(ins, 1))) {
5556                 error(state, ins, "division by zero");
5557         }
5558         else if (is_one(RHS(ins, 1))) {
5559                 mkcopy(state, ins, RHS(ins, 0));
5560         }
5561         else if (is_pow2(RHS(ins, 1))) {
5562                 struct triple *val;
5563                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
5564                 ins->op = OP_USR;
5565                 insert_triple(state, ins, val);
5566                 unuse_triple(RHS(ins, 1), ins);
5567                 use_triple(val, ins);
5568                 RHS(ins, 1) = val;
5569         }
5570 }
5571
5572 static void simplify_smod(struct compile_state *state, struct triple *ins)
5573 {
5574         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5575                 long_t left, right;
5576                 left  = read_const(state, ins, &RHS(ins, 0));
5577                 right = read_const(state, ins, &RHS(ins, 1));
5578                 mkconst(state, ins, left % right);
5579         }
5580         else if (is_zero(RHS(ins, 0))) {
5581                 mkconst(state, ins, 0);
5582         }
5583         else if (is_zero(RHS(ins, 1))) {
5584                 error(state, ins, "division by zero");
5585         }
5586         else if (is_one(RHS(ins, 1))) {
5587                 mkconst(state, ins, 0);
5588         }
5589         else if (is_pow2(RHS(ins, 1))) {
5590                 struct triple *val;
5591                 val = int_const(state, ins->type, RHS(ins, 1)->u.cval - 1);
5592                 ins->op = OP_AND;
5593                 insert_triple(state, ins, val);
5594                 unuse_triple(RHS(ins, 1), ins);
5595                 use_triple(val, ins);
5596                 RHS(ins, 1) = val;
5597         }
5598 }
5599 static void simplify_umod(struct compile_state *state, struct triple *ins)
5600 {
5601         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5602                 ulong_t left, right;
5603                 left  = read_const(state, ins, &RHS(ins, 0));
5604                 right = read_const(state, ins, &RHS(ins, 1));
5605                 mkconst(state, ins, left % right);
5606         }
5607         else if (is_zero(RHS(ins, 0))) {
5608                 mkconst(state, ins, 0);
5609         }
5610         else if (is_zero(RHS(ins, 1))) {
5611                 error(state, ins, "division by zero");
5612         }
5613         else if (is_one(RHS(ins, 1))) {
5614                 mkconst(state, ins, 0);
5615         }
5616         else if (is_pow2(RHS(ins, 1))) {
5617                 struct triple *val;
5618                 val = int_const(state, ins->type, RHS(ins, 1)->u.cval - 1);
5619                 ins->op = OP_AND;
5620                 insert_triple(state, ins, val);
5621                 unuse_triple(RHS(ins, 1), ins);
5622                 use_triple(val, ins);
5623                 RHS(ins, 1) = val;
5624         }
5625 }
5626
5627 static void simplify_add(struct compile_state *state, struct triple *ins)
5628 {
5629         /* start with the pointer on the left */
5630         if (is_pointer(RHS(ins, 1))) {
5631                 struct triple *tmp;
5632                 tmp = RHS(ins, 0);
5633                 RHS(ins, 0) = RHS(ins, 1);
5634                 RHS(ins, 1) = tmp;
5635         }
5636         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5637                 if (!is_pointer(RHS(ins, 0))) {
5638                         ulong_t left, right;
5639                         left  = read_const(state, ins, &RHS(ins, 0));
5640                         right = read_const(state, ins, &RHS(ins, 1));
5641                         mkconst(state, ins, left + right);
5642                 }
5643                 else /* op == OP_ADDRCONST */ {
5644                         struct triple *sdecl;
5645                         ulong_t left, right;
5646                         sdecl = MISC(RHS(ins, 0), 0);
5647                         left  = RHS(ins, 0)->u.cval;
5648                         right = RHS(ins, 1)->u.cval;
5649                         mkaddr_const(state, ins, sdecl, left + right);
5650                 }
5651         }
5652         else if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
5653                 struct triple *tmp;
5654                 tmp = RHS(ins, 1);
5655                 RHS(ins, 1) = RHS(ins, 0);
5656                 RHS(ins, 0) = tmp;
5657         }
5658 }
5659
5660 static void simplify_sub(struct compile_state *state, struct triple *ins)
5661 {
5662         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5663                 if (!is_pointer(RHS(ins, 0))) {
5664                         ulong_t left, right;
5665                         left  = read_const(state, ins, &RHS(ins, 0));
5666                         right = read_const(state, ins, &RHS(ins, 1));
5667                         mkconst(state, ins, left - right);
5668                 }
5669                 else /* op == OP_ADDRCONST */ {
5670                         struct triple *sdecl;
5671                         ulong_t left, right;
5672                         sdecl = MISC(RHS(ins, 0), 0);
5673                         left  = RHS(ins, 0)->u.cval;
5674                         right = RHS(ins, 1)->u.cval;
5675                         mkaddr_const(state, ins, sdecl, left - right);
5676                 }
5677         }
5678 }
5679
5680 static void simplify_sl(struct compile_state *state, struct triple *ins)
5681 {
5682         if (is_const(RHS(ins, 1))) {
5683                 ulong_t right;
5684                 right = read_const(state, ins, &RHS(ins, 1));
5685                 if (right >= (size_of(state, ins->type)*8)) {
5686                         warning(state, ins, "left shift count >= width of type");
5687                 }
5688         }
5689         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5690                 ulong_t left, right;
5691                 left  = read_const(state, ins, &RHS(ins, 0));
5692                 right = read_const(state, ins, &RHS(ins, 1));
5693                 mkconst(state, ins,  left << right);
5694         }
5695 }
5696
5697 static void simplify_usr(struct compile_state *state, struct triple *ins)
5698 {
5699         if (is_const(RHS(ins, 1))) {
5700                 ulong_t right;
5701                 right = read_const(state, ins, &RHS(ins, 1));
5702                 if (right >= (size_of(state, ins->type)*8)) {
5703                         warning(state, ins, "right shift count >= width of type");
5704                 }
5705         }
5706         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5707                 ulong_t left, right;
5708                 left  = read_const(state, ins, &RHS(ins, 0));
5709                 right = read_const(state, ins, &RHS(ins, 1));
5710                 mkconst(state, ins, left >> right);
5711         }
5712 }
5713
5714 static void simplify_ssr(struct compile_state *state, struct triple *ins)
5715 {
5716         if (is_const(RHS(ins, 1))) {
5717                 ulong_t right;
5718                 right = read_const(state, ins, &RHS(ins, 1));
5719                 if (right >= (size_of(state, ins->type)*8)) {
5720                         warning(state, ins, "right shift count >= width of type");
5721                 }
5722         }
5723         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5724                 long_t left, right;
5725                 left  = read_sconst(ins, &RHS(ins, 0));
5726                 right = read_sconst(ins, &RHS(ins, 1));
5727                 mkconst(state, ins, left >> right);
5728         }
5729 }
5730
5731 static void simplify_and(struct compile_state *state, struct triple *ins)
5732 {
5733         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5734                 ulong_t left, right;
5735                 left  = read_const(state, ins, &RHS(ins, 0));
5736                 right = read_const(state, ins, &RHS(ins, 1));
5737                 mkconst(state, ins, left & right);
5738         }
5739 }
5740
5741 static void simplify_or(struct compile_state *state, struct triple *ins)
5742 {
5743         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5744                 ulong_t left, right;
5745                 left  = read_const(state, ins, &RHS(ins, 0));
5746                 right = read_const(state, ins, &RHS(ins, 1));
5747                 mkconst(state, ins, left | right);
5748         }
5749 }
5750
5751 static void simplify_xor(struct compile_state *state, struct triple *ins)
5752 {
5753         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5754                 ulong_t left, right;
5755                 left  = read_const(state, ins, &RHS(ins, 0));
5756                 right = read_const(state, ins, &RHS(ins, 1));
5757                 mkconst(state, ins, left ^ right);
5758         }
5759 }
5760
5761 static void simplify_pos(struct compile_state *state, struct triple *ins)
5762 {
5763         if (is_const(RHS(ins, 0))) {
5764                 mkconst(state, ins, RHS(ins, 0)->u.cval);
5765         }
5766         else {
5767                 mkcopy(state, ins, RHS(ins, 0));
5768         }
5769 }
5770
5771 static void simplify_neg(struct compile_state *state, struct triple *ins)
5772 {
5773         if (is_const(RHS(ins, 0))) {
5774                 ulong_t left;
5775                 left = read_const(state, ins, &RHS(ins, 0));
5776                 mkconst(state, ins, -left);
5777         }
5778         else if (RHS(ins, 0)->op == OP_NEG) {
5779                 mkcopy(state, ins, RHS(RHS(ins, 0), 0));
5780         }
5781 }
5782
5783 static void simplify_invert(struct compile_state *state, struct triple *ins)
5784 {
5785         if (is_const(RHS(ins, 0))) {
5786                 ulong_t left;
5787                 left = read_const(state, ins, &RHS(ins, 0));
5788                 mkconst(state, ins, ~left);
5789         }
5790 }
5791
5792 static void simplify_eq(struct compile_state *state, struct triple *ins)
5793 {
5794         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5795                 ulong_t left, right;
5796                 left  = read_const(state, ins, &RHS(ins, 0));
5797                 right = read_const(state, ins, &RHS(ins, 1));
5798                 mkconst(state, ins, left == right);
5799         }
5800         else if (RHS(ins, 0) == RHS(ins, 1)) {
5801                 mkconst(state, ins, 1);
5802         }
5803 }
5804
5805 static void simplify_noteq(struct compile_state *state, struct triple *ins)
5806 {
5807         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5808                 ulong_t left, right;
5809                 left  = read_const(state, ins, &RHS(ins, 0));
5810                 right = read_const(state, ins, &RHS(ins, 1));
5811                 mkconst(state, ins, left != right);
5812         }
5813         else if (RHS(ins, 0) == RHS(ins, 1)) {
5814                 mkconst(state, ins, 0);
5815         }
5816 }
5817
5818 static void simplify_sless(struct compile_state *state, struct triple *ins)
5819 {
5820         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5821                 long_t left, right;
5822                 left  = read_sconst(ins, &RHS(ins, 0));
5823                 right = read_sconst(ins, &RHS(ins, 1));
5824                 mkconst(state, ins, left < right);
5825         }
5826         else if (RHS(ins, 0) == RHS(ins, 1)) {
5827                 mkconst(state, ins, 0);
5828         }
5829 }
5830
5831 static void simplify_uless(struct compile_state *state, struct triple *ins)
5832 {
5833         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5834                 ulong_t left, right;
5835                 left  = read_const(state, ins, &RHS(ins, 0));
5836                 right = read_const(state, ins, &RHS(ins, 1));
5837                 mkconst(state, ins, left < right);
5838         }
5839         else if (is_zero(RHS(ins, 0))) {
5840                 mkconst(state, ins, 1);
5841         }
5842         else if (RHS(ins, 0) == RHS(ins, 1)) {
5843                 mkconst(state, ins, 0);
5844         }
5845 }
5846
5847 static void simplify_smore(struct compile_state *state, struct triple *ins)
5848 {
5849         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5850                 long_t left, right;
5851                 left  = read_sconst(ins, &RHS(ins, 0));
5852                 right = read_sconst(ins, &RHS(ins, 1));
5853                 mkconst(state, ins, left > right);
5854         }
5855         else if (RHS(ins, 0) == RHS(ins, 1)) {
5856                 mkconst(state, ins, 0);
5857         }
5858 }
5859
5860 static void simplify_umore(struct compile_state *state, struct triple *ins)
5861 {
5862         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5863                 ulong_t left, right;
5864                 left  = read_const(state, ins, &RHS(ins, 0));
5865                 right = read_const(state, ins, &RHS(ins, 1));
5866                 mkconst(state, ins, left > right);
5867         }
5868         else if (is_zero(RHS(ins, 1))) {
5869                 mkconst(state, ins, 1);
5870         }
5871         else if (RHS(ins, 0) == RHS(ins, 1)) {
5872                 mkconst(state, ins, 0);
5873         }
5874 }
5875
5876
5877 static void simplify_slesseq(struct compile_state *state, struct triple *ins)
5878 {
5879         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5880                 long_t left, right;
5881                 left  = read_sconst(ins, &RHS(ins, 0));
5882                 right = read_sconst(ins, &RHS(ins, 1));
5883                 mkconst(state, ins, left <= right);
5884         }
5885         else if (RHS(ins, 0) == RHS(ins, 1)) {
5886                 mkconst(state, ins, 1);
5887         }
5888 }
5889
5890 static void simplify_ulesseq(struct compile_state *state, struct triple *ins)
5891 {
5892         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5893                 ulong_t left, right;
5894                 left  = read_const(state, ins, &RHS(ins, 0));
5895                 right = read_const(state, ins, &RHS(ins, 1));
5896                 mkconst(state, ins, left <= right);
5897         }
5898         else if (is_zero(RHS(ins, 0))) {
5899                 mkconst(state, ins, 1);
5900         }
5901         else if (RHS(ins, 0) == RHS(ins, 1)) {
5902                 mkconst(state, ins, 1);
5903         }
5904 }
5905
5906 static void simplify_smoreeq(struct compile_state *state, struct triple *ins)
5907 {
5908         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 0))) {
5909                 long_t left, right;
5910                 left  = read_sconst(ins, &RHS(ins, 0));
5911                 right = read_sconst(ins, &RHS(ins, 1));
5912                 mkconst(state, ins, left >= right);
5913         }
5914         else if (RHS(ins, 0) == RHS(ins, 1)) {
5915                 mkconst(state, ins, 1);
5916         }
5917 }
5918
5919 static void simplify_umoreeq(struct compile_state *state, struct triple *ins)
5920 {
5921         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5922                 ulong_t left, right;
5923                 left  = read_const(state, ins, &RHS(ins, 0));
5924                 right = read_const(state, ins, &RHS(ins, 1));
5925                 mkconst(state, ins, left >= right);
5926         }
5927         else if (is_zero(RHS(ins, 1))) {
5928                 mkconst(state, ins, 1);
5929         }
5930         else if (RHS(ins, 0) == RHS(ins, 1)) {
5931                 mkconst(state, ins, 1);
5932         }
5933 }
5934
5935 static void simplify_lfalse(struct compile_state *state, struct triple *ins)
5936 {
5937         if (is_const(RHS(ins, 0))) {
5938                 ulong_t left;
5939                 left = read_const(state, ins, &RHS(ins, 0));
5940                 mkconst(state, ins, left == 0);
5941         }
5942         /* Otherwise if I am the only user... */
5943         else if ((RHS(ins, 0)->use->member == ins) && (RHS(ins, 0)->use->next == 0)) {
5944                 int need_copy = 1;
5945                 /* Invert a boolean operation */
5946                 switch(RHS(ins, 0)->op) {
5947                 case OP_LTRUE:   RHS(ins, 0)->op = OP_LFALSE;  break;
5948                 case OP_LFALSE:  RHS(ins, 0)->op = OP_LTRUE;   break;
5949                 case OP_EQ:      RHS(ins, 0)->op = OP_NOTEQ;   break;
5950                 case OP_NOTEQ:   RHS(ins, 0)->op = OP_EQ;      break;
5951                 case OP_SLESS:   RHS(ins, 0)->op = OP_SMOREEQ; break;
5952                 case OP_ULESS:   RHS(ins, 0)->op = OP_UMOREEQ; break;
5953                 case OP_SMORE:   RHS(ins, 0)->op = OP_SLESSEQ; break;
5954                 case OP_UMORE:   RHS(ins, 0)->op = OP_ULESSEQ; break;
5955                 case OP_SLESSEQ: RHS(ins, 0)->op = OP_SMORE;   break;
5956                 case OP_ULESSEQ: RHS(ins, 0)->op = OP_UMORE;   break;
5957                 case OP_SMOREEQ: RHS(ins, 0)->op = OP_SLESS;   break;
5958                 case OP_UMOREEQ: RHS(ins, 0)->op = OP_ULESS;   break;
5959                 default:
5960                         need_copy = 0;
5961                         break;
5962                 }
5963                 if (need_copy) {
5964                         mkcopy(state, ins, RHS(ins, 0));
5965                 }
5966         }
5967 }
5968
5969 static void simplify_ltrue (struct compile_state *state, struct triple *ins)
5970 {
5971         if (is_const(RHS(ins, 0))) {
5972                 ulong_t left;
5973                 left = read_const(state, ins, &RHS(ins, 0));
5974                 mkconst(state, ins, left != 0);
5975         }
5976         else switch(RHS(ins, 0)->op) {
5977         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
5978         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
5979         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
5980                 mkcopy(state, ins, RHS(ins, 0));
5981         }
5982
5983 }
5984
5985 static void simplify_copy(struct compile_state *state, struct triple *ins)
5986 {
5987         if (is_const(RHS(ins, 0))) {
5988                 switch(RHS(ins, 0)->op) {
5989                 case OP_INTCONST:
5990                 {
5991                         ulong_t left;
5992                         left = read_const(state, ins, &RHS(ins, 0));
5993                         mkconst(state, ins, left);
5994                         break;
5995                 }
5996                 case OP_ADDRCONST:
5997                 {
5998                         struct triple *sdecl;
5999                         ulong_t offset;
6000                         sdecl  = MISC(RHS(ins, 0), 0);
6001                         offset = RHS(ins, 0)->u.cval;
6002                         mkaddr_const(state, ins, sdecl, offset);
6003                         break;
6004                 }
6005                 default:
6006                         internal_error(state, ins, "uknown constant");
6007                         break;
6008                 }
6009         }
6010 }
6011
6012 static void simplify_branch(struct compile_state *state, struct triple *ins)
6013 {
6014         struct block *block;
6015         if (ins->op != OP_BRANCH) {
6016                 internal_error(state, ins, "not branch");
6017         }
6018         if (ins->use != 0) {
6019                 internal_error(state, ins, "branch use");
6020         }
6021 #warning "FIXME implement simplify branch."
6022         /* The challenge here with simplify branch is that I need to 
6023          * make modifications to the control flow graph as well
6024          * as to the branch instruction itself.
6025          */
6026         block = ins->u.block;
6027         
6028         if (TRIPLE_RHS(ins->sizes) && is_const(RHS(ins, 0))) {
6029                 struct triple *targ;
6030                 ulong_t value;
6031                 value = read_const(state, ins, &RHS(ins, 0));
6032                 unuse_triple(RHS(ins, 0), ins);
6033                 targ = TARG(ins, 0);
6034                 ins->sizes = TRIPLE_SIZES(0, 0, 0, 1);
6035                 if (value) {
6036                         unuse_triple(ins->next, ins);
6037                         TARG(ins, 0) = targ;
6038                 }
6039                 else {
6040                         unuse_triple(targ, ins);
6041                         TARG(ins, 0) = ins->next;
6042                 }
6043 #warning "FIXME handle the case of making a branch unconditional"
6044         }
6045         if (TARG(ins, 0) == ins->next) {
6046                 unuse_triple(ins->next, ins);
6047                 if (TRIPLE_RHS(ins->sizes)) {
6048                         unuse_triple(RHS(ins, 0), ins);
6049                         unuse_triple(ins->next, ins);
6050                 }
6051                 ins->sizes = TRIPLE_SIZES(0, 0, 0, 0);
6052                 ins->op = OP_NOOP;
6053                 if (ins->use) {
6054                         internal_error(state, ins, "noop use != 0");
6055                 }
6056 #warning "FIXME handle the case of killing a branch"
6057         }
6058 }
6059
6060 static void simplify_phi(struct compile_state *state, struct triple *ins)
6061 {
6062         struct triple **expr;
6063         ulong_t value;
6064         expr = triple_rhs(state, ins, 0);
6065         if (!*expr || !is_const(*expr)) {
6066                 return;
6067         }
6068         value = read_const(state, ins, expr);
6069         for(;expr;expr = triple_rhs(state, ins, expr)) {
6070                 if (!*expr || !is_const(*expr)) {
6071                         return;
6072                 }
6073                 if (value != read_const(state, ins, expr)) {
6074                         return;
6075                 }
6076         }
6077         mkconst(state, ins, value);
6078 }
6079
6080
6081 static void simplify_bsf(struct compile_state *state, struct triple *ins)
6082 {
6083         if (is_const(RHS(ins, 0))) {
6084                 ulong_t left;
6085                 left = read_const(state, ins, &RHS(ins, 0));
6086                 mkconst(state, ins, bsf(left));
6087         }
6088 }
6089
6090 static void simplify_bsr(struct compile_state *state, struct triple *ins)
6091 {
6092         if (is_const(RHS(ins, 0))) {
6093                 ulong_t left;
6094                 left = read_const(state, ins, &RHS(ins, 0));
6095                 mkconst(state, ins, bsr(left));
6096         }
6097 }
6098
6099
6100 typedef void (*simplify_t)(struct compile_state *state, struct triple *ins);
6101 static const simplify_t table_simplify[] = {
6102 #if 0
6103 #define simplify_smul     simplify_noop
6104 #define simplify_umul     simplify_noop
6105 #define simplify_sdiv     simplify_noop
6106 #define simplify_udiv     simplify_noop
6107 #define simplify_smod     simplify_noop
6108 #define simplify_umod     simplify_noop
6109 #endif
6110 #if 0
6111 #define simplify_add      simplify_noop
6112 #define simplify_sub      simplify_noop
6113 #endif
6114 #if 0
6115 #define simplify_sl       simplify_noop
6116 #define simplify_usr      simplify_noop
6117 #define simplify_ssr      simplify_noop
6118 #endif
6119 #if 0
6120 #define simplify_and      simplify_noop
6121 #define simplify_xor      simplify_noop
6122 #define simplify_or       simplify_noop
6123 #endif
6124 #if 0
6125 #define simplify_pos      simplify_noop
6126 #define simplify_neg      simplify_noop
6127 #define simplify_invert   simplify_noop
6128 #endif
6129
6130 #if 0
6131 #define simplify_eq       simplify_noop
6132 #define simplify_noteq    simplify_noop
6133 #endif
6134 #if 0
6135 #define simplify_sless    simplify_noop
6136 #define simplify_uless    simplify_noop
6137 #define simplify_smore    simplify_noop
6138 #define simplify_umore    simplify_noop
6139 #endif
6140 #if 0
6141 #define simplify_slesseq  simplify_noop
6142 #define simplify_ulesseq  simplify_noop
6143 #define simplify_smoreeq  simplify_noop
6144 #define simplify_umoreeq  simplify_noop
6145 #endif
6146 #if 0
6147 #define simplify_lfalse   simplify_noop
6148 #endif
6149 #if 0
6150 #define simplify_ltrue    simplify_noop
6151 #endif
6152
6153 #if 0
6154 #define simplify_copy     simplify_noop
6155 #endif
6156
6157 #if 0
6158 #define simplify_branch   simplify_noop
6159 #endif
6160
6161 #if 0
6162 #define simplify_phi      simplify_noop
6163 #endif
6164
6165 #if 0
6166 #define simplify_bsf      simplify_noop
6167 #define simplify_bsr      simplify_noop
6168 #endif
6169
6170 [OP_SMUL       ] = simplify_smul,
6171 [OP_UMUL       ] = simplify_umul,
6172 [OP_SDIV       ] = simplify_sdiv,
6173 [OP_UDIV       ] = simplify_udiv,
6174 [OP_SMOD       ] = simplify_smod,
6175 [OP_UMOD       ] = simplify_umod,
6176 [OP_ADD        ] = simplify_add,
6177 [OP_SUB        ] = simplify_sub,
6178 [OP_SL         ] = simplify_sl,
6179 [OP_USR        ] = simplify_usr,
6180 [OP_SSR        ] = simplify_ssr,
6181 [OP_AND        ] = simplify_and,
6182 [OP_XOR        ] = simplify_xor,
6183 [OP_OR         ] = simplify_or,
6184 [OP_POS        ] = simplify_pos,
6185 [OP_NEG        ] = simplify_neg,
6186 [OP_INVERT     ] = simplify_invert,
6187
6188 [OP_EQ         ] = simplify_eq,
6189 [OP_NOTEQ      ] = simplify_noteq,
6190 [OP_SLESS      ] = simplify_sless,
6191 [OP_ULESS      ] = simplify_uless,
6192 [OP_SMORE      ] = simplify_smore,
6193 [OP_UMORE      ] = simplify_umore,
6194 [OP_SLESSEQ    ] = simplify_slesseq,
6195 [OP_ULESSEQ    ] = simplify_ulesseq,
6196 [OP_SMOREEQ    ] = simplify_smoreeq,
6197 [OP_UMOREEQ    ] = simplify_umoreeq,
6198 [OP_LFALSE     ] = simplify_lfalse,
6199 [OP_LTRUE      ] = simplify_ltrue,
6200
6201 [OP_LOAD       ] = simplify_noop,
6202 [OP_STORE      ] = simplify_noop,
6203
6204 [OP_NOOP       ] = simplify_noop,
6205
6206 [OP_INTCONST   ] = simplify_noop,
6207 [OP_BLOBCONST  ] = simplify_noop,
6208 [OP_ADDRCONST  ] = simplify_noop,
6209
6210 [OP_WRITE      ] = simplify_noop,
6211 [OP_READ       ] = simplify_noop,
6212 [OP_COPY       ] = simplify_copy,
6213 [OP_PIECE      ] = simplify_noop,
6214 [OP_ASM        ] = simplify_noop,
6215
6216 [OP_DOT        ] = simplify_noop,
6217 [OP_VAL_VEC    ] = simplify_noop,
6218
6219 [OP_LIST       ] = simplify_noop,
6220 [OP_BRANCH     ] = simplify_branch,
6221 [OP_LABEL      ] = simplify_noop,
6222 [OP_ADECL      ] = simplify_noop,
6223 [OP_SDECL      ] = simplify_noop,
6224 [OP_PHI        ] = simplify_phi,
6225
6226 [OP_INB        ] = simplify_noop,
6227 [OP_INW        ] = simplify_noop,
6228 [OP_INL        ] = simplify_noop,
6229 [OP_OUTB       ] = simplify_noop,
6230 [OP_OUTW       ] = simplify_noop,
6231 [OP_OUTL       ] = simplify_noop,
6232 [OP_BSF        ] = simplify_bsf,
6233 [OP_BSR        ] = simplify_bsr,
6234 [OP_RDMSR      ] = simplify_noop,
6235 [OP_WRMSR      ] = simplify_noop,                    
6236 [OP_HLT        ] = simplify_noop,
6237 };
6238
6239 static void simplify(struct compile_state *state, struct triple *ins)
6240 {
6241         int op;
6242         simplify_t do_simplify;
6243         do {
6244                 op = ins->op;
6245                 do_simplify = 0;
6246                 if ((op < 0) || (op > sizeof(table_simplify)/sizeof(table_simplify[0]))) {
6247                         do_simplify = 0;
6248                 }
6249                 else {
6250                         do_simplify = table_simplify[op];
6251                 }
6252                 if (!do_simplify) {
6253                         internal_error(state, ins, "cannot simplify op: %d %s\n",
6254                                 op, tops(op));
6255                         return;
6256                 }
6257                 do_simplify(state, ins);
6258         } while(ins->op != op);
6259 }
6260
6261 static void simplify_all(struct compile_state *state)
6262 {
6263         struct triple *ins, *first;
6264         first = RHS(state->main_function, 0);
6265         ins = first;
6266         do {
6267                 simplify(state, ins);
6268                 ins = ins->next;
6269         } while(ins != first);
6270 }
6271
6272 /*
6273  * Builtins....
6274  * ============================
6275  */
6276
6277 static void register_builtin_function(struct compile_state *state,
6278         const char *name, int op, struct type *rtype, ...)
6279 {
6280         struct type *ftype, *atype, *param, **next;
6281         struct triple *def, *arg, *result, *work, *last, *first;
6282         struct hash_entry *ident;
6283         struct file_state file;
6284         int parameters;
6285         int name_len;
6286         va_list args;
6287         int i;
6288
6289         /* Dummy file state to get debug handling right */
6290         memset(&file, 0, sizeof(file));
6291         file.basename = name;
6292         file.line = 1;
6293         file.prev = state->file;
6294         state->file = &file;
6295
6296         /* Find the Parameter count */
6297         valid_op(state, op);
6298         parameters = table_ops[op].rhs;
6299         if (parameters < 0 ) {
6300                 internal_error(state, 0, "Invalid builtin parameter count");
6301         }
6302
6303         /* Find the function type */
6304         ftype = new_type(TYPE_FUNCTION, rtype, 0);
6305         next = &ftype->right;
6306         va_start(args, rtype);
6307         for(i = 0; i < parameters; i++) {
6308                 atype = va_arg(args, struct type *);
6309                 if (!*next) {
6310                         *next = atype;
6311                 } else {
6312                         *next = new_type(TYPE_PRODUCT, *next, atype);
6313                         next = &((*next)->right);
6314                 }
6315         }
6316         if (!*next) {
6317                 *next = &void_type;
6318         }
6319         va_end(args);
6320
6321         /* Generate the needed triples */
6322         def = triple(state, OP_LIST, ftype, 0, 0);
6323         first = label(state);
6324         RHS(def, 0) = first;
6325
6326         /* Now string them together */
6327         param = ftype->right;
6328         for(i = 0; i < parameters; i++) {
6329                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
6330                         atype = param->left;
6331                 } else {
6332                         atype = param;
6333                 }
6334                 arg = flatten(state, first, variable(state, atype));
6335                 param = param->right;
6336         }
6337         result = 0;
6338         if ((rtype->type & TYPE_MASK) != TYPE_VOID) {
6339                 result = flatten(state, first, variable(state, rtype));
6340         }
6341         MISC(def, 0) = result;
6342         work = new_triple(state, op, rtype, -1, parameters);
6343         for(i = 0, arg = first->next; i < parameters; i++, arg = arg->next) {
6344                 RHS(work, i) = read_expr(state, arg);
6345         }
6346         if (result && ((rtype->type & TYPE_MASK) == TYPE_STRUCT)) {
6347                 struct triple *val;
6348                 /* Populate the LHS with the target registers */
6349                 work = flatten(state, first, work);
6350                 work->type = &void_type;
6351                 param = rtype->left;
6352                 if (rtype->elements != TRIPLE_LHS(work->sizes)) {
6353                         internal_error(state, 0, "Invalid result type");
6354                 }
6355                 val = new_triple(state, OP_VAL_VEC, rtype, -1, -1);
6356                 for(i = 0; i < rtype->elements; i++) {
6357                         struct triple *piece;
6358                         atype = param;
6359                         if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
6360                                 atype = param->left;
6361                         }
6362                         if (!TYPE_ARITHMETIC(atype->type) &&
6363                                 !TYPE_PTR(atype->type)) {
6364                                 internal_error(state, 0, "Invalid lhs type");
6365                         }
6366                         piece = triple(state, OP_PIECE, atype, work, 0);
6367                         piece->u.cval = i;
6368                         LHS(work, i) = piece;
6369                         RHS(val, i) = piece;
6370                 }
6371                 work = val;
6372         }
6373         if (result) {
6374                 work = write_expr(state, result, work);
6375         }
6376         work = flatten(state, first, work);
6377         last = flatten(state, first, label(state));
6378         name_len = strlen(name);
6379         ident = lookup(state, name, name_len);
6380         symbol(state, ident, &ident->sym_ident, def, ftype);
6381         
6382         state->file = file.prev;
6383 #if 0
6384         fprintf(stdout, "\n");
6385         loc(stdout, state, 0);
6386         fprintf(stdout, "\n__________ builtin_function _________\n");
6387         print_triple(state, def);
6388         fprintf(stdout, "__________ builtin_function _________ done\n\n");
6389 #endif
6390 }
6391
6392 static struct type *partial_struct(struct compile_state *state,
6393         const char *field_name, struct type *type, struct type *rest)
6394 {
6395         struct hash_entry *field_ident;
6396         struct type *result;
6397         int field_name_len;
6398
6399         field_name_len = strlen(field_name);
6400         field_ident = lookup(state, field_name, field_name_len);
6401
6402         result = clone_type(0, type);
6403         result->field_ident = field_ident;
6404
6405         if (rest) {
6406                 result = new_type(TYPE_PRODUCT, result, rest);
6407         }
6408         return result;
6409 }
6410
6411 static struct type *register_builtin_type(struct compile_state *state,
6412         const char *name, struct type *type)
6413 {
6414         struct hash_entry *ident;
6415         int name_len;
6416
6417         name_len = strlen(name);
6418         ident = lookup(state, name, name_len);
6419         
6420         if ((type->type & TYPE_MASK) == TYPE_PRODUCT) {
6421                 ulong_t elements = 0;
6422                 struct type *field;
6423                 type = new_type(TYPE_STRUCT, type, 0);
6424                 field = type->left;
6425                 while((field->type & TYPE_MASK) == TYPE_PRODUCT) {
6426                         elements++;
6427                         field = field->right;
6428                 }
6429                 elements++;
6430                 symbol(state, ident, &ident->sym_struct, 0, type);
6431                 type->type_ident = ident;
6432                 type->elements = elements;
6433         }
6434         symbol(state, ident, &ident->sym_ident, 0, type);
6435         ident->tok = TOK_TYPE_NAME;
6436         return type;
6437 }
6438
6439
6440 static void register_builtins(struct compile_state *state)
6441 {
6442         struct type *msr_type;
6443
6444         register_builtin_function(state, "__builtin_inb", OP_INB, &uchar_type, 
6445                 &ushort_type);
6446         register_builtin_function(state, "__builtin_inw", OP_INW, &ushort_type,
6447                 &ushort_type);
6448         register_builtin_function(state, "__builtin_inl", OP_INL, &uint_type,   
6449                 &ushort_type);
6450
6451         register_builtin_function(state, "__builtin_outb", OP_OUTB, &void_type, 
6452                 &uchar_type, &ushort_type);
6453         register_builtin_function(state, "__builtin_outw", OP_OUTW, &void_type, 
6454                 &ushort_type, &ushort_type);
6455         register_builtin_function(state, "__builtin_outl", OP_OUTL, &void_type, 
6456                 &uint_type, &ushort_type);
6457         
6458         register_builtin_function(state, "__builtin_bsf", OP_BSF, &int_type, 
6459                 &int_type);
6460         register_builtin_function(state, "__builtin_bsr", OP_BSR, &int_type, 
6461                 &int_type);
6462
6463         msr_type = register_builtin_type(state, "__builtin_msr_t",
6464                 partial_struct(state, "lo", &ulong_type,
6465                 partial_struct(state, "hi", &ulong_type, 0)));
6466
6467         register_builtin_function(state, "__builtin_rdmsr", OP_RDMSR, msr_type,
6468                 &ulong_type);
6469         register_builtin_function(state, "__builtin_wrmsr", OP_WRMSR, &void_type,
6470                 &ulong_type, &ulong_type, &ulong_type);
6471         
6472         register_builtin_function(state, "__builtin_hlt", OP_HLT, &void_type, 
6473                 &void_type);
6474 }
6475
6476 static struct type *declarator(
6477         struct compile_state *state, struct type *type, 
6478         struct hash_entry **ident, int need_ident);
6479 static void decl(struct compile_state *state, struct triple *first);
6480 static struct type *specifier_qualifier_list(struct compile_state *state);
6481 static int isdecl_specifier(int tok);
6482 static struct type *decl_specifiers(struct compile_state *state);
6483 static int istype(int tok);
6484 static struct triple *expr(struct compile_state *state);
6485 static struct triple *assignment_expr(struct compile_state *state);
6486 static struct type *type_name(struct compile_state *state);
6487 static void statement(struct compile_state *state, struct triple *fist);
6488
6489 static struct triple *call_expr(
6490         struct compile_state *state, struct triple *func)
6491 {
6492         struct triple *def;
6493         struct type *param, *type;
6494         ulong_t pvals, index;
6495
6496         if ((func->type->type & TYPE_MASK) != TYPE_FUNCTION) {
6497                 error(state, 0, "Called object is not a function");
6498         }
6499         if (func->op != OP_LIST) {
6500                 internal_error(state, 0, "improper function");
6501         }
6502         eat(state, TOK_LPAREN);
6503         /* Find the return type without any specifiers */
6504         type = clone_type(0, func->type->left);
6505         def = new_triple(state, OP_CALL, func->type, -1, -1);
6506         def->type = type;
6507
6508         pvals = TRIPLE_RHS(def->sizes);
6509         MISC(def, 0) = func;
6510
6511         param = func->type->right;
6512         for(index = 0; index < pvals; index++) {
6513                 struct triple *val;
6514                 struct type *arg_type;
6515                 val = read_expr(state, assignment_expr(state));
6516                 arg_type = param;
6517                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
6518                         arg_type = param->left;
6519                 }
6520                 write_compatible(state, arg_type, val->type);
6521                 RHS(def, index) = val;
6522                 if (index != (pvals - 1)) {
6523                         eat(state, TOK_COMMA);
6524                         param = param->right;
6525                 }
6526         }
6527         eat(state, TOK_RPAREN);
6528         return def;
6529 }
6530
6531
6532 static struct triple *character_constant(struct compile_state *state)
6533 {
6534         struct triple *def;
6535         struct token *tk;
6536         const signed char *str, *end;
6537         int c;
6538         int str_len;
6539         eat(state, TOK_LIT_CHAR);
6540         tk = &state->token[0];
6541         str = tk->val.str + 1;
6542         str_len = tk->str_len - 2;
6543         if (str_len <= 0) {
6544                 error(state, 0, "empty character constant");
6545         }
6546         end = str + str_len;
6547         c = char_value(state, &str, end);
6548         if (str != end) {
6549                 error(state, 0, "multibyte character constant not supported");
6550         }
6551         def = int_const(state, &char_type, (ulong_t)((long_t)c));
6552         return def;
6553 }
6554
6555 static struct triple *string_constant(struct compile_state *state)
6556 {
6557         struct triple *def;
6558         struct token *tk;
6559         struct type *type;
6560         const signed char *str, *end;
6561         signed char *buf, *ptr;
6562         int str_len;
6563
6564         buf = 0;
6565         type = new_type(TYPE_ARRAY, &char_type, 0);
6566         type->elements = 0;
6567         /* The while loop handles string concatenation */
6568         do {
6569                 eat(state, TOK_LIT_STRING);
6570                 tk = &state->token[0];
6571                 str = tk->val.str + 1;
6572                 str_len = tk->str_len - 2;
6573                 if (str_len < 0) {
6574                         error(state, 0, "negative string constant length");
6575                 }
6576                 end = str + str_len;
6577                 ptr = buf;
6578                 buf = xmalloc(type->elements + str_len + 1, "string_constant");
6579                 memcpy(buf, ptr, type->elements);
6580                 ptr = buf + type->elements;
6581                 do {
6582                         *ptr++ = char_value(state, &str, end);
6583                 } while(str < end);
6584                 type->elements = ptr - buf;
6585         } while(peek(state) == TOK_LIT_STRING);
6586         *ptr = '\0';
6587         type->elements += 1;
6588         def = triple(state, OP_BLOBCONST, type, 0, 0);
6589         def->u.blob = buf;
6590         return def;
6591 }
6592
6593
6594 static struct triple *integer_constant(struct compile_state *state)
6595 {
6596         struct triple *def;
6597         unsigned long val;
6598         struct token *tk;
6599         char *end;
6600         int u, l, decimal;
6601         struct type *type;
6602
6603         eat(state, TOK_LIT_INT);
6604         tk = &state->token[0];
6605         errno = 0;
6606         decimal = (tk->val.str[0] != '0');
6607         val = strtoul(tk->val.str, &end, 0);
6608         if ((val == ULONG_MAX) && (errno == ERANGE)) {
6609                 error(state, 0, "Integer constant to large");
6610         }
6611         u = l = 0;
6612         if ((*end == 'u') || (*end == 'U')) {
6613                 u = 1;
6614                         end++;
6615         }
6616         if ((*end == 'l') || (*end == 'L')) {
6617                 l = 1;
6618                 end++;
6619         }
6620         if ((*end == 'u') || (*end == 'U')) {
6621                 u = 1;
6622                 end++;
6623         }
6624         if (*end) {
6625                 error(state, 0, "Junk at end of integer constant");
6626         }
6627         if (u && l)  {
6628                 type = &ulong_type;
6629         }
6630         else if (l) {
6631                 type = &long_type;
6632                 if (!decimal && (val > LONG_MAX)) {
6633                         type = &ulong_type;
6634                 }
6635         }
6636         else if (u) {
6637                 type = &uint_type;
6638                 if (val > UINT_MAX) {
6639                         type = &ulong_type;
6640                 }
6641         }
6642         else {
6643                 type = &int_type;
6644                 if (!decimal && (val > INT_MAX) && (val <= UINT_MAX)) {
6645                         type = &uint_type;
6646                 }
6647                 else if (!decimal && (val > LONG_MAX)) {
6648                         type = &ulong_type;
6649                 }
6650                 else if (val > INT_MAX) {
6651                         type = &long_type;
6652                 }
6653         }
6654         def = int_const(state, type, val);
6655         return def;
6656 }
6657
6658 static struct triple *primary_expr(struct compile_state *state)
6659 {
6660         struct triple *def;
6661         int tok;
6662         tok = peek(state);
6663         switch(tok) {
6664         case TOK_IDENT:
6665         {
6666                 struct hash_entry *ident;
6667                 /* Here ident is either:
6668                  * a varable name
6669                  * a function name
6670                  * an enumeration constant.
6671                  */
6672                 eat(state, TOK_IDENT);
6673                 ident = state->token[0].ident;
6674                 if (!ident->sym_ident) {
6675                         error(state, 0, "%s undeclared", ident->name);
6676                 }
6677                 def = ident->sym_ident->def;
6678                 break;
6679         }
6680         case TOK_ENUM_CONST:
6681                 /* Here ident is an enumeration constant */
6682                 eat(state, TOK_ENUM_CONST);
6683                 def = 0;
6684                 FINISHME();
6685                 break;
6686         case TOK_LPAREN:
6687                 eat(state, TOK_LPAREN);
6688                 def = expr(state);
6689                 eat(state, TOK_RPAREN);
6690                 break;
6691         case TOK_LIT_INT:
6692                 def = integer_constant(state);
6693                 break;
6694         case TOK_LIT_FLOAT:
6695                 eat(state, TOK_LIT_FLOAT);
6696                 error(state, 0, "Floating point constants not supported");
6697                 def = 0;
6698                 FINISHME();
6699                 break;
6700         case TOK_LIT_CHAR:
6701                 def = character_constant(state);
6702                 break;
6703         case TOK_LIT_STRING:
6704                 def = string_constant(state);
6705                 break;
6706         default:
6707                 def = 0;
6708                 error(state, 0, "Unexpected token: %s\n", tokens[tok]);
6709         }
6710         return def;
6711 }
6712
6713 static struct triple *postfix_expr(struct compile_state *state)
6714 {
6715         struct triple *def;
6716         int postfix;
6717         def = primary_expr(state);
6718         do {
6719                 struct triple *left;
6720                 int tok;
6721                 postfix = 1;
6722                 left = def;
6723                 switch((tok = peek(state))) {
6724                 case TOK_LBRACKET:
6725                         eat(state, TOK_LBRACKET);
6726                         def = mk_subscript_expr(state, left, expr(state));
6727                         eat(state, TOK_RBRACKET);
6728                         break;
6729                 case TOK_LPAREN:
6730                         def = call_expr(state, def);
6731                         break;
6732                 case TOK_DOT:
6733                 {
6734                         struct hash_entry *field;
6735                         eat(state, TOK_DOT);
6736                         eat(state, TOK_IDENT);
6737                         field = state->token[0].ident;
6738                         def = deref_field(state, def, field);
6739                         break;
6740                 }
6741                 case TOK_ARROW:
6742                 {
6743                         struct hash_entry *field;
6744                         eat(state, TOK_ARROW);
6745                         eat(state, TOK_IDENT);
6746                         field = state->token[0].ident;
6747                         def = mk_deref_expr(state, read_expr(state, def));
6748                         def = deref_field(state, def, field);
6749                         break;
6750                 }
6751                 case TOK_PLUSPLUS:
6752                         eat(state, TOK_PLUSPLUS);
6753                         def = mk_post_inc_expr(state, left);
6754                         break;
6755                 case TOK_MINUSMINUS:
6756                         eat(state, TOK_MINUSMINUS);
6757                         def = mk_post_dec_expr(state, left);
6758                         break;
6759                 default:
6760                         postfix = 0;
6761                         break;
6762                 }
6763         } while(postfix);
6764         return def;
6765 }
6766
6767 static struct triple *cast_expr(struct compile_state *state);
6768
6769 static struct triple *unary_expr(struct compile_state *state)
6770 {
6771         struct triple *def, *right;
6772         int tok;
6773         switch((tok = peek(state))) {
6774         case TOK_PLUSPLUS:
6775                 eat(state, TOK_PLUSPLUS);
6776                 def = mk_pre_inc_expr(state, unary_expr(state));
6777                 break;
6778         case TOK_MINUSMINUS:
6779                 eat(state, TOK_MINUSMINUS);
6780                 def = mk_pre_dec_expr(state, unary_expr(state));
6781                 break;
6782         case TOK_AND:
6783                 eat(state, TOK_AND);
6784                 def = mk_addr_expr(state, cast_expr(state), 0);
6785                 break;
6786         case TOK_STAR:
6787                 eat(state, TOK_STAR);
6788                 def = mk_deref_expr(state, read_expr(state, cast_expr(state)));
6789                 break;
6790         case TOK_PLUS:
6791                 eat(state, TOK_PLUS);
6792                 right = read_expr(state, cast_expr(state));
6793                 arithmetic(state, right);
6794                 def = integral_promotion(state, right);
6795                 break;
6796         case TOK_MINUS:
6797                 eat(state, TOK_MINUS);
6798                 right = read_expr(state, cast_expr(state));
6799                 arithmetic(state, right);
6800                 def = integral_promotion(state, right);
6801                 def = triple(state, OP_NEG, def->type, def, 0);
6802                 break;
6803         case TOK_TILDE:
6804                 eat(state, TOK_TILDE);
6805                 right = read_expr(state, cast_expr(state));
6806                 integral(state, right);
6807                 def = integral_promotion(state, right);
6808                 def = triple(state, OP_INVERT, def->type, def, 0);
6809                 break;
6810         case TOK_BANG:
6811                 eat(state, TOK_BANG);
6812                 right = read_expr(state, cast_expr(state));
6813                 bool(state, right);
6814                 def = lfalse_expr(state, right);
6815                 break;
6816         case TOK_SIZEOF:
6817         {
6818                 struct type *type;
6819                 int tok1, tok2;
6820                 eat(state, TOK_SIZEOF);
6821                 tok1 = peek(state);
6822                 tok2 = peek2(state);
6823                 if ((tok1 == TOK_LPAREN) && istype(tok2)) {
6824                         eat(state, TOK_LPAREN);
6825                         type = type_name(state);
6826                         eat(state, TOK_RPAREN);
6827                 }
6828                 else {
6829                         struct triple *expr;
6830                         expr = unary_expr(state);
6831                         type = expr->type;
6832                         release_expr(state, expr);
6833                 }
6834                 def = int_const(state, &ulong_type, size_of(state, type));
6835                 break;
6836         }
6837         case TOK_ALIGNOF:
6838         {
6839                 struct type *type;
6840                 int tok1, tok2;
6841                 eat(state, TOK_ALIGNOF);
6842                 tok1 = peek(state);
6843                 tok2 = peek2(state);
6844                 if ((tok1 == TOK_LPAREN) && istype(tok2)) {
6845                         eat(state, TOK_LPAREN);
6846                         type = type_name(state);
6847                         eat(state, TOK_RPAREN);
6848                 }
6849                 else {
6850                         struct triple *expr;
6851                         expr = unary_expr(state);
6852                         type = expr->type;
6853                         release_expr(state, expr);
6854                 }
6855                 def = int_const(state, &ulong_type, align_of(state, type));
6856                 break;
6857         }
6858         default:
6859                 def = postfix_expr(state);
6860                 break;
6861         }
6862         return def;
6863 }
6864
6865 static struct triple *cast_expr(struct compile_state *state)
6866 {
6867         struct triple *def;
6868         int tok1, tok2;
6869         tok1 = peek(state);
6870         tok2 = peek2(state);
6871         if ((tok1 == TOK_LPAREN) && istype(tok2)) {
6872                 struct type *type;
6873                 eat(state, TOK_LPAREN);
6874                 type = type_name(state);
6875                 eat(state, TOK_RPAREN);
6876                 def = read_expr(state, cast_expr(state));
6877                 def = triple(state, OP_COPY, type, def, 0);
6878         }
6879         else {
6880                 def = unary_expr(state);
6881         }
6882         return def;
6883 }
6884
6885 static struct triple *mult_expr(struct compile_state *state)
6886 {
6887         struct triple *def;
6888         int done;
6889         def = cast_expr(state);
6890         do {
6891                 struct triple *left, *right;
6892                 struct type *result_type;
6893                 int tok, op, sign;
6894                 done = 0;
6895                 switch(tok = (peek(state))) {
6896                 case TOK_STAR:
6897                 case TOK_DIV:
6898                 case TOK_MOD:
6899                         left = read_expr(state, def);
6900                         arithmetic(state, left);
6901
6902                         eat(state, tok);
6903
6904                         right = read_expr(state, cast_expr(state));
6905                         arithmetic(state, right);
6906
6907                         result_type = arithmetic_result(state, left, right);
6908                         sign = is_signed(result_type);
6909                         op = -1;
6910                         switch(tok) {
6911                         case TOK_STAR: op = sign? OP_SMUL : OP_UMUL; break;
6912                         case TOK_DIV:  op = sign? OP_SDIV : OP_UDIV; break;
6913                         case TOK_MOD:  op = sign? OP_SMOD : OP_UMOD; break;
6914                         }
6915                         def = triple(state, op, result_type, left, right);
6916                         break;
6917                 default:
6918                         done = 1;
6919                         break;
6920                 }
6921         } while(!done);
6922         return def;
6923 }
6924
6925 static struct triple *add_expr(struct compile_state *state)
6926 {
6927         struct triple *def;
6928         int done;
6929         def = mult_expr(state);
6930         do {
6931                 done = 0;
6932                 switch( peek(state)) {
6933                 case TOK_PLUS:
6934                         eat(state, TOK_PLUS);
6935                         def = mk_add_expr(state, def, mult_expr(state));
6936                         break;
6937                 case TOK_MINUS:
6938                         eat(state, TOK_MINUS);
6939                         def = mk_sub_expr(state, def, mult_expr(state));
6940                         break;
6941                 default:
6942                         done = 1;
6943                         break;
6944                 }
6945         } while(!done);
6946         return def;
6947 }
6948
6949 static struct triple *shift_expr(struct compile_state *state)
6950 {
6951         struct triple *def;
6952         int done;
6953         def = add_expr(state);
6954         do {
6955                 struct triple *left, *right;
6956                 int tok, op;
6957                 done = 0;
6958                 switch((tok = peek(state))) {
6959                 case TOK_SL:
6960                 case TOK_SR:
6961                         left = read_expr(state, def);
6962                         integral(state, left);
6963                         left = integral_promotion(state, left);
6964
6965                         eat(state, tok);
6966
6967                         right = read_expr(state, add_expr(state));
6968                         integral(state, right);
6969                         right = integral_promotion(state, right);
6970                         
6971                         op = (tok == TOK_SL)? OP_SL : 
6972                                 is_signed(left->type)? OP_SSR: OP_USR;
6973
6974                         def = triple(state, op, left->type, left, right);
6975                         break;
6976                 default:
6977                         done = 1;
6978                         break;
6979                 }
6980         } while(!done);
6981         return def;
6982 }
6983
6984 static struct triple *relational_expr(struct compile_state *state)
6985 {
6986 #warning "Extend relational exprs to work on more than arithmetic types"
6987         struct triple *def;
6988         int done;
6989         def = shift_expr(state);
6990         do {
6991                 struct triple *left, *right;
6992                 struct type *arg_type;
6993                 int tok, op, sign;
6994                 done = 0;
6995                 switch((tok = peek(state))) {
6996                 case TOK_LESS:
6997                 case TOK_MORE:
6998                 case TOK_LESSEQ:
6999                 case TOK_MOREEQ:
7000                         left = read_expr(state, def);
7001                         arithmetic(state, left);
7002
7003                         eat(state, tok);
7004
7005                         right = read_expr(state, shift_expr(state));
7006                         arithmetic(state, right);
7007
7008                         arg_type = arithmetic_result(state, left, right);
7009                         sign = is_signed(arg_type);
7010                         op = -1;
7011                         switch(tok) {
7012                         case TOK_LESS:   op = sign? OP_SLESS : OP_ULESS; break;
7013                         case TOK_MORE:   op = sign? OP_SMORE : OP_UMORE; break;
7014                         case TOK_LESSEQ: op = sign? OP_SLESSEQ : OP_ULESSEQ; break;
7015                         case TOK_MOREEQ: op = sign? OP_SMOREEQ : OP_UMOREEQ; break;
7016                         }
7017                         def = triple(state, op, &int_type, left, right);
7018                         break;
7019                 default:
7020                         done = 1;
7021                         break;
7022                 }
7023         } while(!done);
7024         return def;
7025 }
7026
7027 static struct triple *equality_expr(struct compile_state *state)
7028 {
7029 #warning "Extend equality exprs to work on more than arithmetic types"
7030         struct triple *def;
7031         int done;
7032         def = relational_expr(state);
7033         do {
7034                 struct triple *left, *right;
7035                 int tok, op;
7036                 done = 0;
7037                 switch((tok = peek(state))) {
7038                 case TOK_EQEQ:
7039                 case TOK_NOTEQ:
7040                         left = read_expr(state, def);
7041                         arithmetic(state, left);
7042                         eat(state, tok);
7043                         right = read_expr(state, relational_expr(state));
7044                         arithmetic(state, right);
7045                         op = (tok == TOK_EQEQ) ? OP_EQ: OP_NOTEQ;
7046                         def = triple(state, op, &int_type, left, right);
7047                         break;
7048                 default:
7049                         done = 1;
7050                         break;
7051                 }
7052         } while(!done);
7053         return def;
7054 }
7055
7056 static struct triple *and_expr(struct compile_state *state)
7057 {
7058         struct triple *def;
7059         def = equality_expr(state);
7060         while(peek(state) == TOK_AND) {
7061                 struct triple *left, *right;
7062                 struct type *result_type;
7063                 left = read_expr(state, def);
7064                 integral(state, left);
7065                 eat(state, TOK_AND);
7066                 right = read_expr(state, equality_expr(state));
7067                 integral(state, right);
7068                 result_type = arithmetic_result(state, left, right);
7069                 def = triple(state, OP_AND, result_type, left, right);
7070         }
7071         return def;
7072 }
7073
7074 static struct triple *xor_expr(struct compile_state *state)
7075 {
7076         struct triple *def;
7077         def = and_expr(state);
7078         while(peek(state) == TOK_XOR) {
7079                 struct triple *left, *right;
7080                 struct type *result_type;
7081                 left = read_expr(state, def);
7082                 integral(state, left);
7083                 eat(state, TOK_XOR);
7084                 right = read_expr(state, and_expr(state));
7085                 integral(state, right);
7086                 result_type = arithmetic_result(state, left, right);
7087                 def = triple(state, OP_XOR, result_type, left, right);
7088         }
7089         return def;
7090 }
7091
7092 static struct triple *or_expr(struct compile_state *state)
7093 {
7094         struct triple *def;
7095         def = xor_expr(state);
7096         while(peek(state) == TOK_OR) {
7097                 struct triple *left, *right;
7098                 struct type *result_type;
7099                 left = read_expr(state, def);
7100                 integral(state, left);
7101                 eat(state, TOK_OR);
7102                 right = read_expr(state, xor_expr(state));
7103                 integral(state, right);
7104                 result_type = arithmetic_result(state, left, right);
7105                 def = triple(state, OP_OR, result_type, left, right);
7106         }
7107         return def;
7108 }
7109
7110 static struct triple *land_expr(struct compile_state *state)
7111 {
7112         struct triple *def;
7113         def = or_expr(state);
7114         while(peek(state) == TOK_LOGAND) {
7115                 struct triple *left, *right;
7116                 left = read_expr(state, def);
7117                 bool(state, left);
7118                 eat(state, TOK_LOGAND);
7119                 right = read_expr(state, or_expr(state));
7120                 bool(state, right);
7121
7122                 def = triple(state, OP_LAND, &int_type,
7123                         ltrue_expr(state, left),
7124                         ltrue_expr(state, right));
7125         }
7126         return def;
7127 }
7128
7129 static struct triple *lor_expr(struct compile_state *state)
7130 {
7131         struct triple *def;
7132         def = land_expr(state);
7133         while(peek(state) == TOK_LOGOR) {
7134                 struct triple *left, *right;
7135                 left = read_expr(state, def);
7136                 bool(state, left);
7137                 eat(state, TOK_LOGOR);
7138                 right = read_expr(state, land_expr(state));
7139                 bool(state, right);
7140                 
7141                 def = triple(state, OP_LOR, &int_type,
7142                         ltrue_expr(state, left),
7143                         ltrue_expr(state, right));
7144         }
7145         return def;
7146 }
7147
7148 static struct triple *conditional_expr(struct compile_state *state)
7149 {
7150         struct triple *def;
7151         def = lor_expr(state);
7152         if (peek(state) == TOK_QUEST) {
7153                 struct triple *test, *left, *right;
7154                 bool(state, def);
7155                 test = ltrue_expr(state, read_expr(state, def));
7156                 eat(state, TOK_QUEST);
7157                 left = read_expr(state, expr(state));
7158                 eat(state, TOK_COLON);
7159                 right = read_expr(state, conditional_expr(state));
7160
7161                 def = cond_expr(state, test, left, right);
7162         }
7163         return def;
7164 }
7165
7166 static struct triple *eval_const_expr(
7167         struct compile_state *state, struct triple *expr)
7168 {
7169         struct triple *def;
7170         struct triple *head, *ptr;
7171         head = label(state); /* dummy initial triple */
7172         flatten(state, head, expr);
7173         for(ptr = head->next; ptr != head; ptr = ptr->next) {
7174                 simplify(state, ptr);
7175         }
7176         /* Remove the constant value the tail of the list */
7177         def = head->prev;
7178         def->prev->next = def->next;
7179         def->next->prev = def->prev;
7180         def->next = def->prev = def;
7181         if (!is_const(def)) {
7182                 internal_error(state, 0, "Not a constant expression");
7183         }
7184         /* Free the intermediate expressions */
7185         while(head->next != head) {
7186                 release_triple(state, head->next);
7187         }
7188         free_triple(state, head);
7189         return def;
7190 }
7191
7192 static struct triple *constant_expr(struct compile_state *state)
7193 {
7194         return eval_const_expr(state, conditional_expr(state));
7195 }
7196
7197 static struct triple *assignment_expr(struct compile_state *state)
7198 {
7199         struct triple *def, *left, *right;
7200         int tok, op, sign;
7201         /* The C grammer in K&R shows assignment expressions
7202          * only taking unary expressions as input on their
7203          * left hand side.  But specifies the precedence of
7204          * assignemnt as the lowest operator except for comma.
7205          *
7206          * Allowing conditional expressions on the left hand side
7207          * of an assignement results in a grammar that accepts
7208          * a larger set of statements than standard C.   As long
7209          * as the subset of the grammar that is standard C behaves
7210          * correctly this should cause no problems.
7211          * 
7212          * For the extra token strings accepted by the grammar
7213          * none of them should produce a valid lvalue, so they
7214          * should not produce functioning programs.
7215          *
7216          * GCC has this bug as well, so surprises should be minimal.
7217          */
7218         def = conditional_expr(state);
7219         left = def;
7220         switch((tok = peek(state))) {
7221         case TOK_EQ:
7222                 lvalue(state, left);
7223                 eat(state, TOK_EQ);
7224                 def = write_expr(state, left, 
7225                         read_expr(state, assignment_expr(state)));
7226                 break;
7227         case TOK_TIMESEQ:
7228         case TOK_DIVEQ:
7229         case TOK_MODEQ:
7230                 lvalue(state, left);
7231                 arithmetic(state, left);
7232                 eat(state, tok);
7233                 right = read_expr(state, assignment_expr(state));
7234                 arithmetic(state, right);
7235
7236                 sign = is_signed(left->type);
7237                 op = -1;
7238                 switch(tok) {
7239                 case TOK_TIMESEQ: op = sign? OP_SMUL : OP_UMUL; break;
7240                 case TOK_DIVEQ:   op = sign? OP_SDIV : OP_UDIV; break;
7241                 case TOK_MODEQ:   op = sign? OP_SMOD : OP_UMOD; break;
7242                 }
7243                 def = write_expr(state, left,
7244                         triple(state, op, left->type, 
7245                                 read_expr(state, left), right));
7246                 break;
7247         case TOK_PLUSEQ:
7248                 lvalue(state, left);
7249                 eat(state, TOK_PLUSEQ);
7250                 def = write_expr(state, left,
7251                         mk_add_expr(state, left, assignment_expr(state)));
7252                 break;
7253         case TOK_MINUSEQ:
7254                 lvalue(state, left);
7255                 eat(state, TOK_MINUSEQ);
7256                 def = write_expr(state, left,
7257                         mk_sub_expr(state, left, assignment_expr(state)));
7258                 break;
7259         case TOK_SLEQ:
7260         case TOK_SREQ:
7261         case TOK_ANDEQ:
7262         case TOK_XOREQ:
7263         case TOK_OREQ:
7264                 lvalue(state, left);
7265                 integral(state, left);
7266                 eat(state, tok);
7267                 right = read_expr(state, assignment_expr(state));
7268                 integral(state, right);
7269                 right = integral_promotion(state, right);
7270                 sign = is_signed(left->type);
7271                 op = -1;
7272                 switch(tok) {
7273                 case TOK_SLEQ:  op = OP_SL; break;
7274                 case TOK_SREQ:  op = sign? OP_SSR: OP_USR; break;
7275                 case TOK_ANDEQ: op = OP_AND; break;
7276                 case TOK_XOREQ: op = OP_XOR; break;
7277                 case TOK_OREQ:  op = OP_OR; break;
7278                 }
7279                 def = write_expr(state, left,
7280                         triple(state, op, left->type, 
7281                                 read_expr(state, left), right));
7282                 break;
7283         }
7284         return def;
7285 }
7286
7287 static struct triple *expr(struct compile_state *state)
7288 {
7289         struct triple *def;
7290         def = assignment_expr(state);
7291         while(peek(state) == TOK_COMMA) {
7292                 struct triple *left, *right;
7293                 left = def;
7294                 eat(state, TOK_COMMA);
7295                 right = assignment_expr(state);
7296                 def = triple(state, OP_COMMA, right->type, left, right);
7297         }
7298         return def;
7299 }
7300
7301 static void expr_statement(struct compile_state *state, struct triple *first)
7302 {
7303         if (peek(state) != TOK_SEMI) {
7304                 flatten(state, first, expr(state));
7305         }
7306         eat(state, TOK_SEMI);
7307 }
7308
7309 static void if_statement(struct compile_state *state, struct triple *first)
7310 {
7311         struct triple *test, *jmp1, *jmp2, *middle, *end;
7312
7313         jmp1 = jmp2 = middle = 0;
7314         eat(state, TOK_IF);
7315         eat(state, TOK_LPAREN);
7316         test = expr(state);
7317         bool(state, test);
7318         /* Cleanup and invert the test */
7319         test = lfalse_expr(state, read_expr(state, test));
7320         eat(state, TOK_RPAREN);
7321         /* Generate the needed pieces */
7322         middle = label(state);
7323         jmp1 = branch(state, middle, test);
7324         /* Thread the pieces together */
7325         flatten(state, first, test);
7326         flatten(state, first, jmp1);
7327         flatten(state, first, label(state));
7328         statement(state, first);
7329         if (peek(state) == TOK_ELSE) {
7330                 eat(state, TOK_ELSE);
7331                 /* Generate the rest of the pieces */
7332                 end = label(state);
7333                 jmp2 = branch(state, end, 0);
7334                 /* Thread them together */
7335                 flatten(state, first, jmp2);
7336                 flatten(state, first, middle);
7337                 statement(state, first);
7338                 flatten(state, first, end);
7339         }
7340         else {
7341                 flatten(state, first, middle);
7342         }
7343 }
7344
7345 static void for_statement(struct compile_state *state, struct triple *first)
7346 {
7347         struct triple *head, *test, *tail, *jmp1, *jmp2, *end;
7348         struct triple *label1, *label2, *label3;
7349         struct hash_entry *ident;
7350
7351         eat(state, TOK_FOR);
7352         eat(state, TOK_LPAREN);
7353         head = test = tail = jmp1 = jmp2 = 0;
7354         if (peek(state) != TOK_SEMI) {
7355                 head = expr(state);
7356         } 
7357         eat(state, TOK_SEMI);
7358         if (peek(state) != TOK_SEMI) {
7359                 test = expr(state);
7360                 bool(state, test);
7361                 test = ltrue_expr(state, read_expr(state, test));
7362         }
7363         eat(state, TOK_SEMI);
7364         if (peek(state) != TOK_RPAREN) {
7365                 tail = expr(state);
7366         }
7367         eat(state, TOK_RPAREN);
7368         /* Generate the needed pieces */
7369         label1 = label(state);
7370         label2 = label(state);
7371         label3 = label(state);
7372         if (test) {
7373                 jmp1 = branch(state, label3, 0);
7374                 jmp2 = branch(state, label1, test);
7375         }
7376         else {
7377                 jmp2 = branch(state, label1, 0);
7378         }
7379         end = label(state);
7380         /* Remember where break and continue go */
7381         start_scope(state);
7382         ident = state->i_break;
7383         symbol(state, ident, &ident->sym_ident, end, end->type);
7384         ident = state->i_continue;
7385         symbol(state, ident, &ident->sym_ident, label2, label2->type);
7386         /* Now include the body */
7387         flatten(state, first, head);
7388         flatten(state, first, jmp1);
7389         flatten(state, first, label1);
7390         statement(state, first);
7391         flatten(state, first, label2);
7392         flatten(state, first, tail);
7393         flatten(state, first, label3);
7394         flatten(state, first, test);
7395         flatten(state, first, jmp2);
7396         flatten(state, first, end);
7397         /* Cleanup the break/continue scope */
7398         end_scope(state);
7399 }
7400
7401 static void while_statement(struct compile_state *state, struct triple *first)
7402 {
7403         struct triple *label1, *test, *label2, *jmp1, *jmp2, *end;
7404         struct hash_entry *ident;
7405         eat(state, TOK_WHILE);
7406         eat(state, TOK_LPAREN);
7407         test = expr(state);
7408         bool(state, test);
7409         test = ltrue_expr(state, read_expr(state, test));
7410         eat(state, TOK_RPAREN);
7411         /* Generate the needed pieces */
7412         label1 = label(state);
7413         label2 = label(state);
7414         jmp1 = branch(state, label2, 0);
7415         jmp2 = branch(state, label1, test);
7416         end = label(state);
7417         /* Remember where break and continue go */
7418         start_scope(state);
7419         ident = state->i_break;
7420         symbol(state, ident, &ident->sym_ident, end, end->type);
7421         ident = state->i_continue;
7422         symbol(state, ident, &ident->sym_ident, label2, label2->type);
7423         /* Thread them together */
7424         flatten(state, first, jmp1);
7425         flatten(state, first, label1);
7426         statement(state, first);
7427         flatten(state, first, label2);
7428         flatten(state, first, test);
7429         flatten(state, first, jmp2);
7430         flatten(state, first, end);
7431         /* Cleanup the break/continue scope */
7432         end_scope(state);
7433 }
7434
7435 static void do_statement(struct compile_state *state, struct triple *first)
7436 {
7437         struct triple *label1, *label2, *test, *end;
7438         struct hash_entry *ident;
7439         eat(state, TOK_DO);
7440         /* Generate the needed pieces */
7441         label1 = label(state);
7442         label2 = label(state);
7443         end = label(state);
7444         /* Remember where break and continue go */
7445         start_scope(state);
7446         ident = state->i_break;
7447         symbol(state, ident, &ident->sym_ident, end, end->type);
7448         ident = state->i_continue;
7449         symbol(state, ident, &ident->sym_ident, label2, label2->type);
7450         /* Now include the body */
7451         flatten(state, first, label1);
7452         statement(state, first);
7453         /* Cleanup the break/continue scope */
7454         end_scope(state);
7455         /* Eat the rest of the loop */
7456         eat(state, TOK_WHILE);
7457         eat(state, TOK_LPAREN);
7458         test = read_expr(state, expr(state));
7459         bool(state, test);
7460         eat(state, TOK_RPAREN);
7461         eat(state, TOK_SEMI);
7462         /* Thread the pieces together */
7463         test = ltrue_expr(state, test);
7464         flatten(state, first, label2);
7465         flatten(state, first, test);
7466         flatten(state, first, branch(state, label1, test));
7467         flatten(state, first, end);
7468 }
7469
7470
7471 static void return_statement(struct compile_state *state, struct triple *first)
7472 {
7473         struct triple *jmp, *mv, *dest, *var, *val;
7474         int last;
7475         eat(state, TOK_RETURN);
7476
7477 #warning "FIXME implement a more general excess branch elimination"
7478         val = 0;
7479         /* If we have a return value do some more work */
7480         if (peek(state) != TOK_SEMI) {
7481                 val = read_expr(state, expr(state));
7482         }
7483         eat(state, TOK_SEMI);
7484
7485         /* See if this last statement in a function */
7486         last = ((peek(state) == TOK_RBRACE) && 
7487                 (state->scope_depth == GLOBAL_SCOPE_DEPTH +2));
7488
7489         /* Find the return variable */
7490         var = MISC(state->main_function, 0);
7491         /* Find the return destination */
7492         dest = RHS(state->main_function, 0)->prev;
7493         mv = jmp = 0;
7494         /* If needed generate a jump instruction */
7495         if (!last) {
7496                 jmp = branch(state, dest, 0);
7497         }
7498         /* If needed generate an assignment instruction */
7499         if (val) {
7500                 mv = write_expr(state, var, val);
7501         }
7502         /* Now put the code together */
7503         if (mv) {
7504                 flatten(state, first, mv);
7505                 flatten(state, first, jmp);
7506         }
7507         else if (jmp) {
7508                 flatten(state, first, jmp);
7509         }
7510 }
7511
7512 static void break_statement(struct compile_state *state, struct triple *first)
7513 {
7514         struct triple *dest;
7515         eat(state, TOK_BREAK);
7516         eat(state, TOK_SEMI);
7517         if (!state->i_break->sym_ident) {
7518                 error(state, 0, "break statement not within loop or switch");
7519         }
7520         dest = state->i_break->sym_ident->def;
7521         flatten(state, first, branch(state, dest, 0));
7522 }
7523
7524 static void continue_statement(struct compile_state *state, struct triple *first)
7525 {
7526         struct triple *dest;
7527         eat(state, TOK_CONTINUE);
7528         eat(state, TOK_SEMI);
7529         if (!state->i_continue->sym_ident) {
7530                 error(state, 0, "continue statement outside of a loop");
7531         }
7532         dest = state->i_continue->sym_ident->def;
7533         flatten(state, first, branch(state, dest, 0));
7534 }
7535
7536 static void goto_statement(struct compile_state *state, struct triple *first)
7537 {
7538         FINISHME();
7539         eat(state, TOK_GOTO);
7540         eat(state, TOK_IDENT);
7541         eat(state, TOK_SEMI);
7542         error(state, 0, "goto is not implemeted");
7543         FINISHME();
7544 }
7545
7546 static void labeled_statement(struct compile_state *state, struct triple *first)
7547 {
7548         FINISHME();
7549         eat(state, TOK_IDENT);
7550         eat(state, TOK_COLON);
7551         statement(state, first);
7552         error(state, 0, "labeled statements are not implemented");
7553         FINISHME();
7554 }
7555
7556 static void switch_statement(struct compile_state *state, struct triple *first)
7557 {
7558         FINISHME();
7559         eat(state, TOK_SWITCH);
7560         eat(state, TOK_LPAREN);
7561         expr(state);
7562         eat(state, TOK_RPAREN);
7563         statement(state, first);
7564         error(state, 0, "switch statements are not implemented");
7565         FINISHME();
7566 }
7567
7568 static void case_statement(struct compile_state *state, struct triple *first)
7569 {
7570         FINISHME();
7571         eat(state, TOK_CASE);
7572         constant_expr(state);
7573         eat(state, TOK_COLON);
7574         statement(state, first);
7575         error(state, 0, "case statements are not implemented");
7576         FINISHME();
7577 }
7578
7579 static void default_statement(struct compile_state *state, struct triple *first)
7580 {
7581         FINISHME();
7582         eat(state, TOK_DEFAULT);
7583         eat(state, TOK_COLON);
7584         statement(state, first);
7585         error(state, 0, "default statements are not implemented");
7586         FINISHME();
7587 }
7588
7589 static void asm_statement(struct compile_state *state, struct triple *first)
7590 {
7591         struct asm_info *info;
7592         struct {
7593                 struct triple *constraint;
7594                 struct triple *expr;
7595         } out_param[MAX_LHS], in_param[MAX_RHS], clob_param[MAX_LHS];
7596         struct triple *def, *asm_str;
7597         int out, in, clobbers, more, colons, i;
7598
7599         eat(state, TOK_ASM);
7600         /* For now ignore the qualifiers */
7601         switch(peek(state)) {
7602         case TOK_CONST:
7603                 eat(state, TOK_CONST);
7604                 break;
7605         case TOK_VOLATILE:
7606                 eat(state, TOK_VOLATILE);
7607                 break;
7608         }
7609         eat(state, TOK_LPAREN);
7610         asm_str = string_constant(state);
7611
7612         colons = 0;
7613         out = in = clobbers = 0;
7614         /* Outputs */
7615         if ((colons == 0) && (peek(state) == TOK_COLON)) {
7616                 eat(state, TOK_COLON);
7617                 colons++;
7618                 more = (peek(state) == TOK_LIT_STRING);
7619                 while(more) {
7620                         struct triple *var;
7621                         struct triple *constraint;
7622                         more = 0;
7623                         if (out > MAX_LHS) {
7624                                 error(state, 0, "Maximum output count exceeded.");
7625                         }
7626                         constraint = string_constant(state);
7627                         eat(state, TOK_LPAREN);
7628                         var = conditional_expr(state);
7629                         eat(state, TOK_RPAREN);
7630
7631                         lvalue(state, var);
7632                         out_param[out].constraint = constraint;
7633                         out_param[out].expr       = var;
7634                         if (peek(state) == TOK_COMMA) {
7635                                 eat(state, TOK_COMMA);
7636                                 more = 1;
7637                         }
7638                         out++;
7639                 }
7640         }
7641         /* Inputs */
7642         if ((colons == 1) && (peek(state) == TOK_COLON)) {
7643                 eat(state, TOK_COLON);
7644                 colons++;
7645                 more = (peek(state) == TOK_LIT_STRING);
7646                 while(more) {
7647                         struct triple *val;
7648                         struct triple *constraint;
7649                         more = 0;
7650                         if (in > MAX_RHS) {
7651                                 error(state, 0, "Maximum input count exceeded.");
7652                         }
7653                         constraint = string_constant(state);
7654                         eat(state, TOK_LPAREN);
7655                         val = conditional_expr(state);
7656                         eat(state, TOK_RPAREN);
7657
7658                         in_param[in].constraint = constraint;
7659                         in_param[in].expr       = val;
7660                         if (peek(state) == TOK_COMMA) {
7661                                 eat(state, TOK_COMMA);
7662                                 more = 1;
7663                         }
7664                         in++;
7665                 }
7666         }
7667
7668         /* Clobber */
7669         if ((colons == 2) && (peek(state) == TOK_COLON)) {
7670                 eat(state, TOK_COLON);
7671                 colons++;
7672                 more = (peek(state) == TOK_LIT_STRING);
7673                 while(more) {
7674                         struct triple *clobber;
7675                         more = 0;
7676                         if ((clobbers + out) > MAX_LHS) {
7677                                 error(state, 0, "Maximum clobber limit exceeded.");
7678                         }
7679                         clobber = string_constant(state);
7680                         eat(state, TOK_RPAREN);
7681
7682                         clob_param[clobbers].constraint = clobber;
7683                         if (peek(state) == TOK_COMMA) {
7684                                 eat(state, TOK_COMMA);
7685                                 more = 1;
7686                         }
7687                         clobbers++;
7688                 }
7689         }
7690         eat(state, TOK_RPAREN);
7691         eat(state, TOK_SEMI);
7692
7693
7694         info = xcmalloc(sizeof(*info), "asm_info");
7695         info->str = asm_str->u.blob;
7696         free_triple(state, asm_str);
7697
7698         def = new_triple(state, OP_ASM, &void_type, clobbers + out, in);
7699         def->u.ainfo = info;
7700         for(i = 0; i < in; i++) {
7701                 struct triple *constraint;
7702                 constraint = in_param[i].constraint;
7703                 info->tmpl.rhs[i] = arch_reg_constraint(state, 
7704                         in_param[i].expr->type, constraint->u.blob);
7705
7706                 RHS(def, i) = read_expr(state,in_param[i].expr);
7707                 free_triple(state, constraint);
7708         }
7709         flatten(state, first, def);
7710         for(i = 0; i < out; i++) {
7711                 struct triple *piece;
7712                 struct triple *constraint;
7713                 constraint = out_param[i].constraint;
7714                 info->tmpl.lhs[i] = arch_reg_constraint(state,
7715                         out_param[i].expr->type, constraint->u.blob);
7716
7717                 piece = triple(state, OP_PIECE, out_param[i].expr->type, def, 0);
7718                 piece->u.cval = i;
7719                 LHS(def, i) = piece;
7720                 flatten(state, first,
7721                         write_expr(state, out_param[i].expr, piece));
7722                 free_triple(state, constraint);
7723         }
7724         for(; i - out < clobbers; i++) {
7725                 struct triple *piece;
7726                 struct triple *constraint;
7727                 constraint = clob_param[i - out].constraint;
7728                 info->tmpl.lhs[i] = arch_reg_clobber(state, constraint->u.blob);
7729
7730                 piece = triple(state, OP_PIECE, &void_type, def, 0);
7731                 piece->u.cval = i;
7732                 LHS(def, i) = piece;
7733                 flatten(state, first, piece);
7734                 free_triple(state, constraint);
7735         }
7736 }
7737
7738
7739 static int isdecl(int tok)
7740 {
7741         switch(tok) {
7742         case TOK_AUTO:
7743         case TOK_REGISTER:
7744         case TOK_STATIC:
7745         case TOK_EXTERN:
7746         case TOK_TYPEDEF:
7747         case TOK_CONST:
7748         case TOK_RESTRICT:
7749         case TOK_VOLATILE:
7750         case TOK_VOID:
7751         case TOK_CHAR:
7752         case TOK_SHORT:
7753         case TOK_INT:
7754         case TOK_LONG:
7755         case TOK_FLOAT:
7756         case TOK_DOUBLE:
7757         case TOK_SIGNED:
7758         case TOK_UNSIGNED:
7759         case TOK_STRUCT:
7760         case TOK_UNION:
7761         case TOK_ENUM:
7762         case TOK_TYPE_NAME: /* typedef name */
7763                 return 1;
7764         default:
7765                 return 0;
7766         }
7767 }
7768
7769 static void compound_statement(struct compile_state *state, struct triple *first)
7770 {
7771         eat(state, TOK_LBRACE);
7772         start_scope(state);
7773
7774         /* statement-list opt */
7775         while (peek(state) != TOK_RBRACE) {
7776                 statement(state, first);
7777         }
7778         end_scope(state);
7779         eat(state, TOK_RBRACE);
7780 }
7781
7782 static void statement(struct compile_state *state, struct triple *first)
7783 {
7784         int tok;
7785         tok = peek(state);
7786         if (tok == TOK_LBRACE) {
7787                 compound_statement(state, first);
7788         }
7789         else if (tok == TOK_IF) {
7790                 if_statement(state, first); 
7791         }
7792         else if (tok == TOK_FOR) {
7793                 for_statement(state, first);
7794         }
7795         else if (tok == TOK_WHILE) {
7796                 while_statement(state, first);
7797         }
7798         else if (tok == TOK_DO) {
7799                 do_statement(state, first);
7800         }
7801         else if (tok == TOK_RETURN) {
7802                 return_statement(state, first);
7803         }
7804         else if (tok == TOK_BREAK) {
7805                 break_statement(state, first);
7806         }
7807         else if (tok == TOK_CONTINUE) {
7808                 continue_statement(state, first);
7809         }
7810         else if (tok == TOK_GOTO) {
7811                 goto_statement(state, first);
7812         }
7813         else if (tok == TOK_SWITCH) {
7814                 switch_statement(state, first);
7815         }
7816         else if (tok == TOK_ASM) {
7817                 asm_statement(state, first);
7818         }
7819         else if ((tok == TOK_IDENT) && (peek2(state) == TOK_COLON)) {
7820                 labeled_statement(state, first); 
7821         }
7822         else if (tok == TOK_CASE) {
7823                 case_statement(state, first);
7824         }
7825         else if (tok == TOK_DEFAULT) {
7826                 default_statement(state, first);
7827         }
7828         else if (isdecl(tok)) {
7829                 /* This handles C99 intermixing of statements and decls */
7830                 decl(state, first);
7831         }
7832         else {
7833                 expr_statement(state, first);
7834         }
7835 }
7836
7837 static struct type *param_decl(struct compile_state *state)
7838 {
7839         struct type *type;
7840         struct hash_entry *ident;
7841         /* Cheat so the declarator will know we are not global */
7842         start_scope(state); 
7843         ident = 0;
7844         type = decl_specifiers(state);
7845         type = declarator(state, type, &ident, 0);
7846         type->field_ident = ident;
7847         end_scope(state);
7848         return type;
7849 }
7850
7851 static struct type *param_type_list(struct compile_state *state, struct type *type)
7852 {
7853         struct type *ftype, **next;
7854         ftype = new_type(TYPE_FUNCTION, type, param_decl(state));
7855         next = &ftype->right;
7856         while(peek(state) == TOK_COMMA) {
7857                 eat(state, TOK_COMMA);
7858                 if (peek(state) == TOK_DOTS) {
7859                         eat(state, TOK_DOTS);
7860                         error(state, 0, "variadic functions not supported");
7861                 }
7862                 else {
7863                         *next = new_type(TYPE_PRODUCT, *next, param_decl(state));
7864                         next = &((*next)->right);
7865                 }
7866         }
7867         return ftype;
7868 }
7869
7870
7871 static struct type *type_name(struct compile_state *state)
7872 {
7873         struct type *type;
7874         type = specifier_qualifier_list(state);
7875         /* abstract-declarator (may consume no tokens) */
7876         type = declarator(state, type, 0, 0);
7877         return type;
7878 }
7879
7880 static struct type *direct_declarator(
7881         struct compile_state *state, struct type *type, 
7882         struct hash_entry **ident, int need_ident)
7883 {
7884         struct type *outer;
7885         int op;
7886         outer = 0;
7887         arrays_complete(state, type);
7888         switch(peek(state)) {
7889         case TOK_IDENT:
7890                 eat(state, TOK_IDENT);
7891                 if (!ident) {
7892                         error(state, 0, "Unexpected identifier found");
7893                 }
7894                 /* The name of what we are declaring */
7895                 *ident = state->token[0].ident;
7896                 break;
7897         case TOK_LPAREN:
7898                 eat(state, TOK_LPAREN);
7899                 outer = declarator(state, type, ident, need_ident);
7900                 eat(state, TOK_RPAREN);
7901                 break;
7902         default:
7903                 if (need_ident) {
7904                         error(state, 0, "Identifier expected");
7905                 }
7906                 break;
7907         }
7908         do {
7909                 op = 1;
7910                 arrays_complete(state, type);
7911                 switch(peek(state)) {
7912                 case TOK_LPAREN:
7913                         eat(state, TOK_LPAREN);
7914                         type = param_type_list(state, type);
7915                         eat(state, TOK_RPAREN);
7916                         break;
7917                 case TOK_LBRACKET:
7918                 {
7919                         unsigned int qualifiers;
7920                         struct triple *value;
7921                         value = 0;
7922                         eat(state, TOK_LBRACKET);
7923                         if (peek(state) != TOK_RBRACKET) {
7924                                 value = constant_expr(state);
7925                                 integral(state, value);
7926                         }
7927                         eat(state, TOK_RBRACKET);
7928
7929                         qualifiers = type->type & (QUAL_MASK | STOR_MASK);
7930                         type = new_type(TYPE_ARRAY | qualifiers, type, 0);
7931                         if (value) {
7932                                 type->elements = value->u.cval;
7933                                 free_triple(state, value);
7934                         } else {
7935                                 type->elements = ELEMENT_COUNT_UNSPECIFIED;
7936                                 op = 0;
7937                         }
7938                 }
7939                         break;
7940                 default:
7941                         op = 0;
7942                         break;
7943                 }
7944         } while(op);
7945         if (outer) {
7946                 struct type *inner;
7947                 arrays_complete(state, type);
7948                 FINISHME();
7949                 for(inner = outer; inner->left; inner = inner->left)
7950                         ;
7951                 inner->left = type;
7952                 type = outer;
7953         }
7954         return type;
7955 }
7956
7957 static struct type *declarator(
7958         struct compile_state *state, struct type *type, 
7959         struct hash_entry **ident, int need_ident)
7960 {
7961         while(peek(state) == TOK_STAR) {
7962                 eat(state, TOK_STAR);
7963                 type = new_type(TYPE_POINTER | (type->type & STOR_MASK), type, 0);
7964         }
7965         type = direct_declarator(state, type, ident, need_ident);
7966         return type;
7967 }
7968
7969
7970 static struct type *typedef_name(
7971         struct compile_state *state, unsigned int specifiers)
7972 {
7973         struct hash_entry *ident;
7974         struct type *type;
7975         eat(state, TOK_TYPE_NAME);
7976         ident = state->token[0].ident;
7977         type = ident->sym_ident->type;
7978         specifiers |= type->type & QUAL_MASK;
7979         if ((specifiers & (STOR_MASK | QUAL_MASK)) != 
7980                 (type->type & (STOR_MASK | QUAL_MASK))) {
7981                 type = clone_type(specifiers, type);
7982         }
7983         return type;
7984 }
7985
7986 static struct type *enum_specifier(
7987         struct compile_state *state, unsigned int specifiers)
7988 {
7989         int tok;
7990         struct type *type;
7991         type = 0;
7992         FINISHME();
7993         eat(state, TOK_ENUM);
7994         tok = peek(state);
7995         if (tok == TOK_IDENT) {
7996                 eat(state, TOK_IDENT);
7997         }
7998         if ((tok != TOK_IDENT) || (peek(state) == TOK_LBRACE)) {
7999                 eat(state, TOK_LBRACE);
8000                 do {
8001                         eat(state, TOK_IDENT);
8002                         if (peek(state) == TOK_EQ) {
8003                                 eat(state, TOK_EQ);
8004                                 constant_expr(state);
8005                         }
8006                         if (peek(state) == TOK_COMMA) {
8007                                 eat(state, TOK_COMMA);
8008                         }
8009                 } while(peek(state) != TOK_RBRACE);
8010                 eat(state, TOK_RBRACE);
8011         }
8012         FINISHME();
8013         return type;
8014 }
8015
8016 #if 0
8017 static struct type *struct_declarator(
8018         struct compile_state *state, struct type *type, struct hash_entry **ident)
8019 {
8020         int tok;
8021 #warning "struct_declarator is complicated because of bitfields, kill them?"
8022         tok = peek(state);
8023         if (tok != TOK_COLON) {
8024                 type = declarator(state, type, ident, 1);
8025         }
8026         if ((tok == TOK_COLON) || (peek(state) == TOK_COLON)) {
8027                 eat(state, TOK_COLON);
8028                 constant_expr(state);
8029         }
8030         FINISHME();
8031         return type;
8032 }
8033 #endif
8034
8035 static struct type *struct_or_union_specifier(
8036         struct compile_state *state, unsigned int specifiers)
8037 {
8038         struct type *struct_type;
8039         struct hash_entry *ident;
8040         unsigned int type_join;
8041         int tok;
8042         struct_type = 0;
8043         ident = 0;
8044         switch(peek(state)) {
8045         case TOK_STRUCT:
8046                 eat(state, TOK_STRUCT);
8047                 type_join = TYPE_PRODUCT;
8048                 break;
8049         case TOK_UNION:
8050                 eat(state, TOK_UNION);
8051                 type_join = TYPE_OVERLAP;
8052                 error(state, 0, "unions not yet supported\n");
8053                 break;
8054         default:
8055                 eat(state, TOK_STRUCT);
8056                 type_join = TYPE_PRODUCT;
8057                 break;
8058         }
8059         tok = peek(state);
8060         if ((tok == TOK_IDENT) || (tok == TOK_TYPE_NAME)) {
8061                 eat(state, tok);
8062                 ident = state->token[0].ident;
8063         }
8064         if (!ident || (peek(state) == TOK_LBRACE)) {
8065                 ulong_t elements;
8066                 elements = 0;
8067                 eat(state, TOK_LBRACE);
8068                 do {
8069                         struct type *base_type;
8070                         struct type **next;
8071                         int done;
8072                         base_type = specifier_qualifier_list(state);
8073                         next = &struct_type;
8074                         do {
8075                                 struct type *type;
8076                                 struct hash_entry *fident;
8077                                 done = 1;
8078                                 type = declarator(state, base_type, &fident, 1);
8079                                 elements++;
8080                                 if (peek(state) == TOK_COMMA) {
8081                                         done = 0;
8082                                         eat(state, TOK_COMMA);
8083                                 }
8084                                 type = clone_type(0, type);
8085                                 type->field_ident = fident;
8086                                 if (*next) {
8087                                         *next = new_type(type_join, *next, type);
8088                                         next = &((*next)->right);
8089                                 } else {
8090                                         *next = type;
8091                                 }
8092                         } while(!done);
8093                         eat(state, TOK_SEMI);
8094                 } while(peek(state) != TOK_RBRACE);
8095                 eat(state, TOK_RBRACE);
8096                 struct_type = new_type(TYPE_STRUCT, struct_type, 0);
8097                 struct_type->type_ident = ident;
8098                 struct_type->elements = elements;
8099                 symbol(state, ident, &ident->sym_struct, 0, struct_type);
8100         }
8101         if (ident && ident->sym_struct) {
8102                 struct_type = ident->sym_struct->type;
8103         }
8104         else if (ident && !ident->sym_struct) {
8105                 error(state, 0, "struct %s undeclared", ident->name);
8106         }
8107         return struct_type;
8108 }
8109
8110 static unsigned int storage_class_specifier_opt(struct compile_state *state)
8111 {
8112         unsigned int specifiers;
8113         switch(peek(state)) {
8114         case TOK_AUTO:
8115                 eat(state, TOK_AUTO);
8116                 specifiers = STOR_AUTO;
8117                 break;
8118         case TOK_REGISTER:
8119                 eat(state, TOK_REGISTER);
8120                 specifiers = STOR_REGISTER;
8121                 break;
8122         case TOK_STATIC:
8123                 eat(state, TOK_STATIC);
8124                 specifiers = STOR_STATIC;
8125                 break;
8126         case TOK_EXTERN:
8127                 eat(state, TOK_EXTERN);
8128                 specifiers = STOR_EXTERN;
8129                 break;
8130         case TOK_TYPEDEF:
8131                 eat(state, TOK_TYPEDEF);
8132                 specifiers = STOR_TYPEDEF;
8133                 break;
8134         default:
8135                 if (state->scope_depth <= GLOBAL_SCOPE_DEPTH) {
8136                         specifiers = STOR_STATIC;
8137                 }
8138                 else {
8139                         specifiers = STOR_AUTO;
8140                 }
8141         }
8142         return specifiers;
8143 }
8144
8145 static unsigned int function_specifier_opt(struct compile_state *state)
8146 {
8147         /* Ignore the inline keyword */
8148         unsigned int specifiers;
8149         specifiers = 0;
8150         switch(peek(state)) {
8151         case TOK_INLINE:
8152                 eat(state, TOK_INLINE);
8153                 specifiers = STOR_INLINE;
8154         }
8155         return specifiers;
8156 }
8157
8158 static unsigned int type_qualifiers(struct compile_state *state)
8159 {
8160         unsigned int specifiers;
8161         int done;
8162         done = 0;
8163         specifiers = QUAL_NONE;
8164         do {
8165                 switch(peek(state)) {
8166                 case TOK_CONST:
8167                         eat(state, TOK_CONST);
8168                         specifiers = QUAL_CONST;
8169                         break;
8170                 case TOK_VOLATILE:
8171                         eat(state, TOK_VOLATILE);
8172                         specifiers = QUAL_VOLATILE;
8173                         break;
8174                 case TOK_RESTRICT:
8175                         eat(state, TOK_RESTRICT);
8176                         specifiers = QUAL_RESTRICT;
8177                         break;
8178                 default:
8179                         done = 1;
8180                         break;
8181                 }
8182         } while(!done);
8183         return specifiers;
8184 }
8185
8186 static struct type *type_specifier(
8187         struct compile_state *state, unsigned int spec)
8188 {
8189         struct type *type;
8190         type = 0;
8191         switch(peek(state)) {
8192         case TOK_VOID:
8193                 eat(state, TOK_VOID);
8194                 type = new_type(TYPE_VOID | spec, 0, 0);
8195                 break;
8196         case TOK_CHAR:
8197                 eat(state, TOK_CHAR);
8198                 type = new_type(TYPE_CHAR | spec, 0, 0);
8199                 break;
8200         case TOK_SHORT:
8201                 eat(state, TOK_SHORT);
8202                 if (peek(state) == TOK_INT) {
8203                         eat(state, TOK_INT);
8204                 }
8205                 type = new_type(TYPE_SHORT | spec, 0, 0);
8206                 break;
8207         case TOK_INT:
8208                 eat(state, TOK_INT);
8209                 type = new_type(TYPE_INT | spec, 0, 0);
8210                 break;
8211         case TOK_LONG:
8212                 eat(state, TOK_LONG);
8213                 switch(peek(state)) {
8214                 case TOK_LONG:
8215                         eat(state, TOK_LONG);
8216                         error(state, 0, "long long not supported");
8217                         break;
8218                 case TOK_DOUBLE:
8219                         eat(state, TOK_DOUBLE);
8220                         error(state, 0, "long double not supported");
8221                         break;
8222                 case TOK_INT:
8223                         eat(state, TOK_INT);
8224                         type = new_type(TYPE_LONG | spec, 0, 0);
8225                         break;
8226                 default:
8227                         type = new_type(TYPE_LONG | spec, 0, 0);
8228                         break;
8229                 }
8230                 break;
8231         case TOK_FLOAT:
8232                 eat(state, TOK_FLOAT);
8233                 error(state, 0, "type float not supported");
8234                 break;
8235         case TOK_DOUBLE:
8236                 eat(state, TOK_DOUBLE);
8237                 error(state, 0, "type double not supported");
8238                 break;
8239         case TOK_SIGNED:
8240                 eat(state, TOK_SIGNED);
8241                 switch(peek(state)) {
8242                 case TOK_LONG:
8243                         eat(state, TOK_LONG);
8244                         switch(peek(state)) {
8245                         case TOK_LONG:
8246                                 eat(state, TOK_LONG);
8247                                 error(state, 0, "type long long not supported");
8248                                 break;
8249                         case TOK_INT:
8250                                 eat(state, TOK_INT);
8251                                 type = new_type(TYPE_LONG | spec, 0, 0);
8252                                 break;
8253                         default:
8254                                 type = new_type(TYPE_LONG | spec, 0, 0);
8255                                 break;
8256                         }
8257                         break;
8258                 case TOK_INT:
8259                         eat(state, TOK_INT);
8260                         type = new_type(TYPE_INT | spec, 0, 0);
8261                         break;
8262                 case TOK_SHORT:
8263                         eat(state, TOK_SHORT);
8264                         type = new_type(TYPE_SHORT | spec, 0, 0);
8265                         break;
8266                 case TOK_CHAR:
8267                         eat(state, TOK_CHAR);
8268                         type = new_type(TYPE_CHAR | spec, 0, 0);
8269                         break;
8270                 default:
8271                         type = new_type(TYPE_INT | spec, 0, 0);
8272                         break;
8273                 }
8274                 break;
8275         case TOK_UNSIGNED:
8276                 eat(state, TOK_UNSIGNED);
8277                 switch(peek(state)) {
8278                 case TOK_LONG:
8279                         eat(state, TOK_LONG);
8280                         switch(peek(state)) {
8281                         case TOK_LONG:
8282                                 eat(state, TOK_LONG);
8283                                 error(state, 0, "unsigned long long not supported");
8284                                 break;
8285                         case TOK_INT:
8286                                 eat(state, TOK_INT);
8287                                 type = new_type(TYPE_ULONG | spec, 0, 0);
8288                                 break;
8289                         default:
8290                                 type = new_type(TYPE_ULONG | spec, 0, 0);
8291                                 break;
8292                         }
8293                         break;
8294                 case TOK_INT:
8295                         eat(state, TOK_INT);
8296                         type = new_type(TYPE_UINT | spec, 0, 0);
8297                         break;
8298                 case TOK_SHORT:
8299                         eat(state, TOK_SHORT);
8300                         type = new_type(TYPE_USHORT | spec, 0, 0);
8301                         break;
8302                 case TOK_CHAR:
8303                         eat(state, TOK_CHAR);
8304                         type = new_type(TYPE_UCHAR | spec, 0, 0);
8305                         break;
8306                 default:
8307                         type = new_type(TYPE_UINT | spec, 0, 0);
8308                         break;
8309                 }
8310                 break;
8311                 /* struct or union specifier */
8312         case TOK_STRUCT:
8313         case TOK_UNION:
8314                 type = struct_or_union_specifier(state, spec);
8315                 break;
8316                 /* enum-spefifier */
8317         case TOK_ENUM:
8318                 type = enum_specifier(state, spec);
8319                 break;
8320                 /* typedef name */
8321         case TOK_TYPE_NAME:
8322                 type = typedef_name(state, spec);
8323                 break;
8324         default:
8325                 error(state, 0, "bad type specifier %s", 
8326                         tokens[peek(state)]);
8327                 break;
8328         }
8329         return type;
8330 }
8331
8332 static int istype(int tok)
8333 {
8334         switch(tok) {
8335         case TOK_CONST:
8336         case TOK_RESTRICT:
8337         case TOK_VOLATILE:
8338         case TOK_VOID:
8339         case TOK_CHAR:
8340         case TOK_SHORT:
8341         case TOK_INT:
8342         case TOK_LONG:
8343         case TOK_FLOAT:
8344         case TOK_DOUBLE:
8345         case TOK_SIGNED:
8346         case TOK_UNSIGNED:
8347         case TOK_STRUCT:
8348         case TOK_UNION:
8349         case TOK_ENUM:
8350         case TOK_TYPE_NAME:
8351                 return 1;
8352         default:
8353                 return 0;
8354         }
8355 }
8356
8357
8358 static struct type *specifier_qualifier_list(struct compile_state *state)
8359 {
8360         struct type *type;
8361         unsigned int specifiers = 0;
8362
8363         /* type qualifiers */
8364         specifiers |= type_qualifiers(state);
8365
8366         /* type specifier */
8367         type = type_specifier(state, specifiers);
8368
8369         return type;
8370 }
8371
8372 static int isdecl_specifier(int tok)
8373 {
8374         switch(tok) {
8375                 /* storage class specifier */
8376         case TOK_AUTO:
8377         case TOK_REGISTER:
8378         case TOK_STATIC:
8379         case TOK_EXTERN:
8380         case TOK_TYPEDEF:
8381                 /* type qualifier */
8382         case TOK_CONST:
8383         case TOK_RESTRICT:
8384         case TOK_VOLATILE:
8385                 /* type specifiers */
8386         case TOK_VOID:
8387         case TOK_CHAR:
8388         case TOK_SHORT:
8389         case TOK_INT:
8390         case TOK_LONG:
8391         case TOK_FLOAT:
8392         case TOK_DOUBLE:
8393         case TOK_SIGNED:
8394         case TOK_UNSIGNED:
8395                 /* struct or union specifier */
8396         case TOK_STRUCT:
8397         case TOK_UNION:
8398                 /* enum-spefifier */
8399         case TOK_ENUM:
8400                 /* typedef name */
8401         case TOK_TYPE_NAME:
8402                 /* function specifiers */
8403         case TOK_INLINE:
8404                 return 1;
8405         default:
8406                 return 0;
8407         }
8408 }
8409
8410 static struct type *decl_specifiers(struct compile_state *state)
8411 {
8412         struct type *type;
8413         unsigned int specifiers;
8414         /* I am overly restrictive in the arragement of specifiers supported.
8415          * C is overly flexible in this department it makes interpreting
8416          * the parse tree difficult.
8417          */
8418         specifiers = 0;
8419
8420         /* storage class specifier */
8421         specifiers |= storage_class_specifier_opt(state);
8422
8423         /* function-specifier */
8424         specifiers |= function_specifier_opt(state);
8425
8426         /* type qualifier */
8427         specifiers |= type_qualifiers(state);
8428
8429         /* type specifier */
8430         type = type_specifier(state, specifiers);
8431         return type;
8432 }
8433
8434 static unsigned designator(struct compile_state *state)
8435 {
8436         int tok;
8437         unsigned index;
8438         index = -1U;
8439         do {
8440                 switch(peek(state)) {
8441                 case TOK_LBRACKET:
8442                 {
8443                         struct triple *value;
8444                         eat(state, TOK_LBRACKET);
8445                         value = constant_expr(state);
8446                         eat(state, TOK_RBRACKET);
8447                         index = value->u.cval;
8448                         break;
8449                 }
8450                 case TOK_DOT:
8451                         eat(state, TOK_DOT);
8452                         eat(state, TOK_IDENT);
8453                         error(state, 0, "Struct Designators not currently supported");
8454                         break;
8455                 default:
8456                         error(state, 0, "Invalid designator");
8457                 }
8458                 tok = peek(state);
8459         } while((tok == TOK_LBRACKET) || (tok == TOK_DOT));
8460         eat(state, TOK_EQ);
8461         return index;
8462 }
8463
8464 static struct triple *initializer(
8465         struct compile_state *state, struct type *type)
8466 {
8467         struct triple *result;
8468         if (peek(state) != TOK_LBRACE) {
8469                 result = assignment_expr(state);
8470         }
8471         else {
8472                 int comma;
8473                 unsigned index, max_index;
8474                 void *buf;
8475                 max_index = index = 0;
8476                 if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
8477                         max_index = type->elements;
8478                         if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
8479                                 type->elements = 0;
8480                         }
8481                 } else {
8482                         error(state, 0, "Struct initializers not currently supported");
8483                 }
8484                 buf = xcmalloc(size_of(state, type), "initializer");
8485                 eat(state, TOK_LBRACE);
8486                 do {
8487                         struct triple *value;
8488                         struct type *value_type;
8489                         size_t value_size;
8490                         int tok;
8491                         comma = 0;
8492                         tok = peek(state);
8493                         if ((tok == TOK_LBRACKET) || (tok == TOK_DOT)) {
8494                                 index = designator(state);
8495                         }
8496                         if ((max_index != ELEMENT_COUNT_UNSPECIFIED) &&
8497                                 (index > max_index)) {
8498                                 error(state, 0, "element beyond bounds");
8499                         }
8500                         value_type = 0;
8501                         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
8502                                 value_type = type->left;
8503                         }
8504                         value = eval_const_expr(state, initializer(state, value_type));
8505                         value_size = size_of(state, value_type);
8506                         if (((type->type & TYPE_MASK) == TYPE_ARRAY) &&
8507                                 (max_index == ELEMENT_COUNT_UNSPECIFIED) &&
8508                                 (type->elements <= index)) {
8509                                 void *old_buf;
8510                                 size_t old_size;
8511                                 old_buf = buf;
8512                                 old_size = size_of(state, type);
8513                                 type->elements = index + 1;
8514                                 buf = xmalloc(size_of(state, type), "initializer");
8515                                 memcpy(buf, old_buf, old_size);
8516                                 xfree(old_buf);
8517                         }
8518                         if (value->op == OP_BLOBCONST) {
8519                                 memcpy((char *)buf + index * value_size, value->u.blob, value_size);
8520                         }
8521                         else if ((value->op == OP_INTCONST) && (value_size == 1)) {
8522                                 *(((uint8_t *)buf) + index) = value->u.cval & 0xff;
8523                         }
8524                         else if ((value->op == OP_INTCONST) && (value_size == 2)) {
8525                                 *(((uint16_t *)buf) + index) = value->u.cval & 0xffff;
8526                         }
8527                         else if ((value->op == OP_INTCONST) && (value_size == 4)) {
8528                                 *(((uint32_t *)buf) + index) = value->u.cval & 0xffffffff;
8529                         }
8530                         else {
8531                                 fprintf(stderr, "%d %d\n",
8532                                         value->op, value_size);
8533                                 internal_error(state, 0, "unhandled constant initializer");
8534                         }
8535                         if (peek(state) == TOK_COMMA) {
8536                                 eat(state, TOK_COMMA);
8537                                 comma = 1;
8538                         }
8539                         index += 1;
8540                 } while(comma && (peek(state) != TOK_RBRACE));
8541                 eat(state, TOK_RBRACE);
8542                 result = triple(state, OP_BLOBCONST, type, 0, 0);
8543                 result->u.blob = buf;
8544         }
8545         return result;
8546 }
8547
8548 static struct triple *function_definition(
8549         struct compile_state *state, struct type *type)
8550 {
8551         struct triple *def, *tmp, *first, *end;
8552         struct hash_entry *ident;
8553         struct type *param;
8554         int i;
8555         if ((type->type &TYPE_MASK) != TYPE_FUNCTION) {
8556                 error(state, 0, "Invalid function header");
8557         }
8558
8559         /* Verify the function type */
8560         if (((type->right->type & TYPE_MASK) != TYPE_VOID)  &&
8561                 ((type->right->type & TYPE_MASK) != TYPE_PRODUCT) &&
8562                 (type->right->field_ident == 0)) {
8563                 error(state, 0, "Invalid function parameters");
8564         }
8565         param = type->right;
8566         i = 0;
8567         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
8568                 i++;
8569                 if (!param->left->field_ident) {
8570                         error(state, 0, "No identifier for parameter %d\n", i);
8571                 }
8572                 param = param->right;
8573         }
8574         i++;
8575         if (((param->type & TYPE_MASK) != TYPE_VOID) && !param->field_ident) {
8576                 error(state, 0, "No identifier for paramter %d\n", i);
8577         }
8578         
8579         /* Get a list of statements for this function. */
8580         def = triple(state, OP_LIST, type, 0, 0);
8581
8582         /* Start a new scope for the passed parameters */
8583         start_scope(state);
8584
8585         /* Put a label at the very start of a function */
8586         first = label(state);
8587         RHS(def, 0) = first;
8588
8589         /* Put a label at the very end of a function */
8590         end = label(state);
8591         flatten(state, first, end);
8592
8593         /* Walk through the parameters and create symbol table entries
8594          * for them.
8595          */
8596         param = type->right;
8597         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
8598                 ident = param->left->field_ident;
8599                 tmp = variable(state, param->left);
8600                 symbol(state, ident, &ident->sym_ident, tmp, tmp->type);
8601                 flatten(state, end, tmp);
8602                 param = param->right;
8603         }
8604         if ((param->type & TYPE_MASK) != TYPE_VOID) {
8605                 /* And don't forget the last parameter */
8606                 ident = param->field_ident;
8607                 tmp = variable(state, param);
8608                 symbol(state, ident, &ident->sym_ident, tmp, tmp->type);
8609                 flatten(state, end, tmp);
8610         }
8611         /* Add a variable for the return value */
8612         MISC(def, 0) = 0;
8613         if ((type->left->type & TYPE_MASK) != TYPE_VOID) {
8614                 /* Remove all type qualifiers from the return type */
8615                 tmp = variable(state, clone_type(0, type->left));
8616                 flatten(state, end, tmp);
8617                 /* Remember where the return value is */
8618                 MISC(def, 0) = tmp;
8619         }
8620
8621         /* Remember which function I am compiling.
8622          * Also assume the last defined function is the main function.
8623          */
8624         state->main_function = def;
8625
8626         /* Now get the actual function definition */
8627         compound_statement(state, end);
8628
8629         /* Remove the parameter scope */
8630         end_scope(state);
8631 #if 0
8632         fprintf(stdout, "\n");
8633         loc(stdout, state, 0);
8634         fprintf(stdout, "\n__________ function_definition _________\n");
8635         print_triple(state, def);
8636         fprintf(stdout, "__________ function_definition _________ done\n\n");
8637 #endif
8638
8639         return def;
8640 }
8641
8642 static struct triple *do_decl(struct compile_state *state, 
8643         struct type *type, struct hash_entry *ident)
8644 {
8645         struct triple *def;
8646         def = 0;
8647         /* Clean up the storage types used */
8648         switch (type->type & STOR_MASK) {
8649         case STOR_AUTO:
8650         case STOR_STATIC:
8651                 /* These are the good types I am aiming for */
8652                 break;
8653         case STOR_REGISTER:
8654                 type->type &= ~STOR_MASK;
8655                 type->type |= STOR_AUTO;
8656                 break;
8657         case STOR_EXTERN:
8658                 type->type &= ~STOR_MASK;
8659                 type->type |= STOR_STATIC;
8660                 break;
8661         case STOR_TYPEDEF:
8662                 if (!ident) {
8663                         error(state, 0, "typedef without name");
8664                 }
8665                 symbol(state, ident, &ident->sym_ident, 0, type);
8666                 ident->tok = TOK_TYPE_NAME;
8667                 return 0;
8668                 break;
8669         default:
8670                 internal_error(state, 0, "Undefined storage class");
8671         }
8672         if (((type->type & STOR_MASK) == STOR_STATIC) &&
8673                 ((type->type & QUAL_CONST) == 0)) {
8674                 error(state, 0, "non const static variables not supported");
8675         }
8676         if (ident) {
8677                 def = variable(state, type);
8678                 symbol(state, ident, &ident->sym_ident, def, type);
8679         }
8680         return def;
8681 }
8682
8683 static void decl(struct compile_state *state, struct triple *first)
8684 {
8685         struct type *base_type, *type;
8686         struct hash_entry *ident;
8687         struct triple *def;
8688         int global;
8689         global = (state->scope_depth <= GLOBAL_SCOPE_DEPTH);
8690         base_type = decl_specifiers(state);
8691         ident = 0;
8692         type = declarator(state, base_type, &ident, 0);
8693         if (global && ident && (peek(state) == TOK_LBRACE)) {
8694                 /* function */
8695                 def = function_definition(state, type);
8696                 symbol(state, ident, &ident->sym_ident, def, type);
8697         }
8698         else {
8699                 int done;
8700                 flatten(state, first, do_decl(state, type, ident));
8701                 /* type or variable definition */
8702                 do {
8703                         done = 1;
8704                         if (peek(state) == TOK_EQ) {
8705                                 if (!ident) {
8706                                         error(state, 0, "cannot assign to a type");
8707                                 }
8708                                 eat(state, TOK_EQ);
8709                                 flatten(state, first,
8710                                         init_expr(state, 
8711                                                 ident->sym_ident->def, 
8712                                                 initializer(state, type)));
8713                         }
8714                         arrays_complete(state, type);
8715                         if (peek(state) == TOK_COMMA) {
8716                                 eat(state, TOK_COMMA);
8717                                 ident = 0;
8718                                 type = declarator(state, base_type, &ident, 0);
8719                                 flatten(state, first, do_decl(state, type, ident));
8720                                 done = 0;
8721                         }
8722                 } while(!done);
8723                 eat(state, TOK_SEMI);
8724         }
8725 }
8726
8727 static void decls(struct compile_state *state)
8728 {
8729         struct triple *list;
8730         int tok;
8731         list = label(state);
8732         while(1) {
8733                 tok = peek(state);
8734                 if (tok == TOK_EOF) {
8735                         return;
8736                 }
8737                 if (tok == TOK_SPACE) {
8738                         eat(state, TOK_SPACE);
8739                 }
8740                 decl(state, list);
8741                 if (list->next != list) {
8742                         error(state, 0, "global variables not supported");
8743                 }
8744         }
8745 }
8746
8747 /*
8748  * Data structurs for optimation.
8749  */
8750
8751 static void do_use_block(
8752         struct block *used, struct block_set **head, struct block *user, 
8753         int front)
8754 {
8755         struct block_set **ptr, *new;
8756         if (!used)
8757                 return;
8758         if (!user)
8759                 return;
8760         ptr = head;
8761         while(*ptr) {
8762                 if ((*ptr)->member == user) {
8763                         return;
8764                 }
8765                 ptr = &(*ptr)->next;
8766         }
8767         new = xcmalloc(sizeof(*new), "block_set");
8768         new->member = user;
8769         if (front) {
8770                 new->next = *head;
8771                 *head = new;
8772         }
8773         else {
8774                 new->next = 0;
8775                 *ptr = new;
8776         }
8777 }
8778 static void do_unuse_block(
8779         struct block *used, struct block_set **head, struct block *unuser)
8780 {
8781         struct block_set *use, **ptr;
8782         ptr = head;
8783         while(*ptr) {
8784                 use = *ptr;
8785                 if (use->member == unuser) {
8786                         *ptr = use->next;
8787                         memset(use, -1, sizeof(*use));
8788                         xfree(use);
8789                 }
8790                 else {
8791                         ptr = &use->next;
8792                 }
8793         }
8794 }
8795
8796 static void use_block(struct block *used, struct block *user)
8797 {
8798         /* Append new to the head of the list, print_block
8799          * depends on this.
8800          */
8801         do_use_block(used, &used->use, user, 1); 
8802         used->users++;
8803 }
8804 static void unuse_block(struct block *used, struct block *unuser)
8805 {
8806         do_unuse_block(used, &used->use, unuser); 
8807         used->users--;
8808 }
8809
8810 static void idom_block(struct block *idom, struct block *user)
8811 {
8812         do_use_block(idom, &idom->idominates, user, 0);
8813 }
8814
8815 static void unidom_block(struct block *idom, struct block *unuser)
8816 {
8817         do_unuse_block(idom, &idom->idominates, unuser);
8818 }
8819
8820 static void domf_block(struct block *block, struct block *domf)
8821 {
8822         do_use_block(block, &block->domfrontier, domf, 0);
8823 }
8824
8825 static void undomf_block(struct block *block, struct block *undomf)
8826 {
8827         do_unuse_block(block, &block->domfrontier, undomf);
8828 }
8829
8830 static void ipdom_block(struct block *ipdom, struct block *user)
8831 {
8832         do_use_block(ipdom, &ipdom->ipdominates, user, 0);
8833 }
8834
8835 static void unipdom_block(struct block *ipdom, struct block *unuser)
8836 {
8837         do_unuse_block(ipdom, &ipdom->ipdominates, unuser);
8838 }
8839
8840 static void ipdomf_block(struct block *block, struct block *ipdomf)
8841 {
8842         do_use_block(block, &block->ipdomfrontier, ipdomf, 0);
8843 }
8844
8845 static void unipdomf_block(struct block *block, struct block *unipdomf)
8846 {
8847         do_unuse_block(block, &block->ipdomfrontier, unipdomf);
8848 }
8849
8850
8851
8852 static int do_walk_triple(struct compile_state *state,
8853         struct triple *ptr, int depth,
8854         int (*cb)(struct compile_state *state, struct triple *ptr, int depth)) 
8855 {
8856         int result;
8857         result = cb(state, ptr, depth);
8858         if ((result == 0) && (ptr->op == OP_LIST)) {
8859                 struct triple *list;
8860                 list = ptr;
8861                 ptr = RHS(list, 0);
8862                 do {
8863                         result = do_walk_triple(state, ptr, depth + 1, cb);
8864                         if (ptr->next->prev != ptr) {
8865                                 internal_error(state, ptr->next, "bad prev");
8866                         }
8867                         ptr = ptr->next;
8868                         
8869                 } while((result == 0) && (ptr != RHS(list, 0)));
8870         }
8871         return result;
8872 }
8873
8874 static int walk_triple(
8875         struct compile_state *state, 
8876         struct triple *ptr, 
8877         int (*cb)(struct compile_state *state, struct triple *ptr, int depth))
8878 {
8879         return do_walk_triple(state, ptr, 0, cb);
8880 }
8881
8882 static void do_print_prefix(int depth)
8883 {
8884         int i;
8885         for(i = 0; i < depth; i++) {
8886                 printf("  ");
8887         }
8888 }
8889
8890 #define PRINT_LIST 1
8891 static int do_print_triple(struct compile_state *state, struct triple *ins, int depth)
8892 {
8893         int op;
8894         op = ins->op;
8895         if (op == OP_LIST) {
8896 #if !PRINT_LIST
8897                 return 0;
8898 #endif
8899         }
8900         if ((op == OP_LABEL) && (ins->use)) {
8901                 printf("\n%p:\n", ins);
8902         }
8903         do_print_prefix(depth);
8904         display_triple(stdout, ins);
8905
8906         if ((ins->op == OP_BRANCH) && ins->use) {
8907                 internal_error(state, ins, "branch used?");
8908         }
8909 #if 0
8910         {
8911                 struct triple_set *user;
8912                 for(user = ins->use; user; user = user->next) {
8913                         printf("use: %p\n", user->member);
8914                 }
8915         }
8916 #endif
8917         if (triple_is_branch(state, ins)) {
8918                 printf("\n");
8919         }
8920         return 0;
8921 }
8922
8923 static void print_triple(struct compile_state *state, struct triple *ins)
8924 {
8925         walk_triple(state, ins, do_print_triple);
8926 }
8927
8928 static void print_triples(struct compile_state *state)
8929 {
8930         print_triple(state, state->main_function);
8931 }
8932
8933 struct cf_block {
8934         struct block *block;
8935 };
8936 static void find_cf_blocks(struct cf_block *cf, struct block *block)
8937 {
8938         if (!block || (cf[block->vertex].block == block)) {
8939                 return;
8940         }
8941         cf[block->vertex].block = block;
8942         find_cf_blocks(cf, block->left);
8943         find_cf_blocks(cf, block->right);
8944 }
8945
8946 static void print_control_flow(struct compile_state *state)
8947 {
8948         struct cf_block *cf;
8949         int i;
8950         printf("\ncontrol flow\n");
8951         cf = xcmalloc(sizeof(*cf) * (state->last_vertex + 1), "cf_block");
8952         find_cf_blocks(cf, state->first_block);
8953
8954         for(i = 1; i <= state->last_vertex; i++) {
8955                 struct block *block;
8956                 block = cf[i].block;
8957                 if (!block)
8958                         continue;
8959                 printf("(%p) %d:", block, block->vertex);
8960                 if (block->left) {
8961                         printf(" %d", block->left->vertex);
8962                 }
8963                 if (block->right && (block->right != block->left)) {
8964                         printf(" %d", block->right->vertex);
8965                 }
8966                 printf("\n");
8967         }
8968
8969         xfree(cf);
8970 }
8971
8972
8973 static struct block *basic_block(struct compile_state *state,
8974         struct triple *first)
8975 {
8976         struct block *block;
8977         struct triple *ptr;
8978         int op;
8979         if (first->op != OP_LABEL) {
8980                 internal_error(state, 0, "block does not start with a label");
8981         }
8982         /* See if this basic block has already been setup */
8983         if (first->u.block != 0) {
8984                 return first->u.block;
8985         }
8986         /* Allocate another basic block structure */
8987         state->last_vertex += 1;
8988         block = xcmalloc(sizeof(*block), "block");
8989         block->first = block->last = first;
8990         block->vertex = state->last_vertex;
8991         ptr = first;
8992         do {
8993                 if ((ptr != first) && (ptr->op == OP_LABEL) && ptr->use) {
8994                         break;
8995                 }
8996                 block->last = ptr;
8997                 /* If ptr->u is not used remember where the baic block is */
8998                 if (triple_stores_block(state, ptr)) {
8999                         ptr->u.block = block;
9000                 }
9001                 if (ptr->op == OP_BRANCH) {
9002                         break;
9003                 }
9004                 ptr = ptr->next;
9005         } while (ptr != RHS(state->main_function, 0));
9006         if (ptr == RHS(state->main_function, 0))
9007                 return block;
9008         op = ptr->op;
9009         if (op == OP_LABEL) {
9010                 block->left = basic_block(state, ptr);
9011                 block->right = 0;
9012                 use_block(block->left, block);
9013         }
9014         else if (op == OP_BRANCH) {
9015                 block->left = 0;
9016                 /* Trace the branch target */
9017                 block->right = basic_block(state, TARG(ptr, 0));
9018                 use_block(block->right, block);
9019                 /* If there is a test trace the branch as well */
9020                 if (TRIPLE_RHS(ptr->sizes)) {
9021                         block->left = basic_block(state, ptr->next);
9022                         use_block(block->left, block);
9023                 }
9024         }
9025         else {
9026                 internal_error(state, 0, "Bad basic block split");
9027         }
9028         return block;
9029 }
9030
9031
9032 static void walk_blocks(struct compile_state *state,
9033         void (*cb)(struct compile_state *state, struct block *block, void *arg),
9034         void *arg)
9035 {
9036         struct triple *ptr, *first;
9037         struct block *last_block;
9038         last_block = 0;
9039         first = RHS(state->main_function, 0);
9040         ptr = first;
9041         do {
9042                 struct block *block;
9043                 if (ptr->op == OP_LABEL) {
9044                         block = ptr->u.block;
9045                         if (block && (block != last_block)) {
9046                                 cb(state, block, arg);
9047                         }
9048                         last_block = block;
9049                 }
9050                 ptr = ptr->next;
9051         } while(ptr != first);
9052 }
9053
9054 static void print_block(
9055         struct compile_state *state, struct block *block, void *arg)
9056 {
9057         struct triple *ptr;
9058         FILE *fp = arg;
9059
9060         fprintf(fp, "\nblock: %p (%d), %p<-%p %p<-%p\n", 
9061                 block, 
9062                 block->vertex,
9063                 block->left, 
9064                 block->left && block->left->use?block->left->use->member : 0,
9065                 block->right, 
9066                 block->right && block->right->use?block->right->use->member : 0);
9067         if (block->first->op == OP_LABEL) {
9068                 fprintf(fp, "%p:\n", block->first);
9069         }
9070         for(ptr = block->first; ; ptr = ptr->next) {
9071                 struct triple_set *user;
9072                 int op = ptr->op;
9073                 
9074                 if (triple_stores_block(state, ptr)) {
9075                         if (ptr->u.block != block) {
9076                                 internal_error(state, ptr, 
9077                                         "Wrong block pointer: %p\n",
9078                                         ptr->u.block);
9079                         }
9080                 }
9081                 if (op == OP_ADECL) {
9082                         for(user = ptr->use; user; user = user->next) {
9083                                 if (!user->member->u.block) {
9084                                         internal_error(state, user->member, 
9085                                                 "Use %p not in a block?\n",
9086                                                 user->member);
9087                                 }
9088                         }
9089                 }
9090                 display_triple(fp, ptr);
9091
9092 #if 0
9093                 for(user = ptr->use; user; user = user->next) {
9094                         fprintf(fp, "use: %p\n", user->member);
9095                 }
9096 #endif
9097
9098                 /* Sanity checks... */
9099                 valid_ins(state, ptr);
9100                 for(user = ptr->use; user; user = user->next) {
9101                         struct triple *use;
9102                         use = user->member;
9103                         valid_ins(state, use);
9104                         if (triple_stores_block(state, user->member) &&
9105                                 !user->member->u.block) {
9106                                 internal_error(state, user->member,
9107                                         "Use %p not in a block?",
9108                                         user->member);
9109                         }
9110                 }
9111
9112                 if (ptr == block->last)
9113                         break;
9114         }
9115         fprintf(fp,"\n");
9116 }
9117
9118
9119 static void print_blocks(struct compile_state *state, FILE *fp)
9120 {
9121         fprintf(fp, "--------------- blocks ---------------\n");
9122         walk_blocks(state, print_block, fp);
9123 }
9124
9125 static void prune_nonblock_triples(struct compile_state *state)
9126 {
9127         struct block *block;
9128         struct triple *first, *ins, *next;
9129         /* Delete the triples not in a basic block */
9130         first = RHS(state->main_function, 0);
9131         block = 0;
9132         ins = first;
9133         do {
9134                 next = ins->next;
9135                 if (ins->op == OP_LABEL) {
9136                         block = ins->u.block;
9137                 }
9138                 if (!block) {
9139                         release_triple(state, ins);
9140                 }
9141                 ins = next;
9142         } while(ins != first);
9143 }
9144
9145 static void setup_basic_blocks(struct compile_state *state)
9146 {
9147         if (!triple_stores_block(state, RHS(state->main_function, 0)) ||
9148                 !triple_stores_block(state, RHS(state->main_function,0)->prev)) {
9149                 internal_error(state, 0, "ins will not store block?");
9150         }
9151         /* Find the basic blocks */
9152         state->last_vertex = 0;
9153         state->first_block = basic_block(state, RHS(state->main_function,0));
9154         /* Delete the triples not in a basic block */
9155         prune_nonblock_triples(state);
9156         /* Find the last basic block */
9157         state->last_block = RHS(state->main_function, 0)->prev->u.block;
9158         if (!state->last_block) {
9159                 internal_error(state, 0, "end not used?");
9160         }
9161         /* Insert an extra unused edge from start to the end 
9162          * This helps with reverse control flow calculations.
9163          */
9164         use_block(state->first_block, state->last_block);
9165         /* If we are debugging print what I have just done */
9166         if (state->debug & DEBUG_BASIC_BLOCKS) {
9167                 print_blocks(state, stdout);
9168                 print_control_flow(state);
9169         }
9170 }
9171
9172 static void free_basic_block(struct compile_state *state, struct block *block)
9173 {
9174         struct block_set *entry, *next;
9175         struct block *child;
9176         if (!block) {
9177                 return;
9178         }
9179         if (block->vertex == -1) {
9180                 return;
9181         }
9182         block->vertex = -1;
9183         if (block->left) {
9184                 unuse_block(block->left, block);
9185         }
9186         if (block->right) {
9187                 unuse_block(block->right, block);
9188         }
9189         if (block->idom) {
9190                 unidom_block(block->idom, block);
9191         }
9192         block->idom = 0;
9193         if (block->ipdom) {
9194                 unipdom_block(block->ipdom, block);
9195         }
9196         block->ipdom = 0;
9197         for(entry = block->use; entry; entry = next) {
9198                 next = entry->next;
9199                 child = entry->member;
9200                 unuse_block(block, child);
9201                 if (child->left == block) {
9202                         child->left = 0;
9203                 }
9204                 if (child->right == block) {
9205                         child->right = 0;
9206                 }
9207         }
9208         for(entry = block->idominates; entry; entry = next) {
9209                 next = entry->next;
9210                 child = entry->member;
9211                 unidom_block(block, child);
9212                 child->idom = 0;
9213         }
9214         for(entry = block->domfrontier; entry; entry = next) {
9215                 next = entry->next;
9216                 child = entry->member;
9217                 undomf_block(block, child);
9218         }
9219         for(entry = block->ipdominates; entry; entry = next) {
9220                 next = entry->next;
9221                 child = entry->member;
9222                 unipdom_block(block, child);
9223                 child->ipdom = 0;
9224         }
9225         for(entry = block->ipdomfrontier; entry; entry = next) {
9226                 next = entry->next;
9227                 child = entry->member;
9228                 unipdomf_block(block, child);
9229         }
9230         if (block->users != 0) {
9231                 internal_error(state, 0, "block still has users");
9232         }
9233         free_basic_block(state, block->left);
9234         block->left = 0;
9235         free_basic_block(state, block->right);
9236         block->right = 0;
9237         memset(block, -1, sizeof(*block));
9238         xfree(block);
9239 }
9240
9241 static void free_basic_blocks(struct compile_state *state)
9242 {
9243         struct triple *first, *ins;
9244         free_basic_block(state, state->first_block);
9245         state->last_vertex = 0;
9246         state->first_block = state->last_block = 0;
9247         first = RHS(state->main_function, 0);
9248         ins = first;
9249         do {
9250                 if (triple_stores_block(state, ins)) {
9251                         ins->u.block = 0;
9252                 }
9253                 ins = ins->next;
9254         } while(ins != first);
9255         
9256 }
9257
9258 struct sdom_block {
9259         struct block *block;
9260         struct sdom_block *sdominates;
9261         struct sdom_block *sdom_next;
9262         struct sdom_block *sdom;
9263         struct sdom_block *label;
9264         struct sdom_block *parent;
9265         struct sdom_block *ancestor;
9266         int vertex;
9267 };
9268
9269
9270 static void unsdom_block(struct sdom_block *block)
9271 {
9272         struct sdom_block **ptr;
9273         if (!block->sdom_next) {
9274                 return;
9275         }
9276         ptr = &block->sdom->sdominates;
9277         while(*ptr) {
9278                 if ((*ptr) == block) {
9279                         *ptr = block->sdom_next;
9280                         return;
9281                 }
9282                 ptr = &(*ptr)->sdom_next;
9283         }
9284 }
9285
9286 static void sdom_block(struct sdom_block *sdom, struct sdom_block *block)
9287 {
9288         unsdom_block(block);
9289         block->sdom = sdom;
9290         block->sdom_next = sdom->sdominates;
9291         sdom->sdominates = block;
9292 }
9293
9294
9295
9296 static int initialize_sdblock(struct sdom_block *sd,
9297         struct block *parent, struct block *block, int vertex)
9298 {
9299         if (!block || (sd[block->vertex].block == block)) {
9300                 return vertex;
9301         }
9302         vertex += 1;
9303         /* Renumber the blocks in a convinient fashion */
9304         block->vertex = vertex;
9305         sd[vertex].block    = block;
9306         sd[vertex].sdom     = &sd[vertex];
9307         sd[vertex].label    = &sd[vertex];
9308         sd[vertex].parent   = parent? &sd[parent->vertex] : 0;
9309         sd[vertex].ancestor = 0;
9310         sd[vertex].vertex   = vertex;
9311         vertex = initialize_sdblock(sd, block, block->left, vertex);
9312         vertex = initialize_sdblock(sd, block, block->right, vertex);
9313         return vertex;
9314 }
9315
9316 static int initialize_sdpblock(struct sdom_block *sd,
9317         struct block *parent, struct block *block, int vertex)
9318 {
9319         struct block_set *user;
9320         if (!block || (sd[block->vertex].block == block)) {
9321                 return vertex;
9322         }
9323         vertex += 1;
9324         /* Renumber the blocks in a convinient fashion */
9325         block->vertex = vertex;
9326         sd[vertex].block    = block;
9327         sd[vertex].sdom     = &sd[vertex];
9328         sd[vertex].label    = &sd[vertex];
9329         sd[vertex].parent   = parent? &sd[parent->vertex] : 0;
9330         sd[vertex].ancestor = 0;
9331         sd[vertex].vertex   = vertex;
9332         for(user = block->use; user; user = user->next) {
9333                 vertex = initialize_sdpblock(sd, block, user->member, vertex);
9334         }
9335         return vertex;
9336 }
9337
9338 static void compress_ancestors(struct sdom_block *v)
9339 {
9340         /* This procedure assumes ancestor(v) != 0 */
9341         /* if (ancestor(ancestor(v)) != 0) {
9342          *      compress(ancestor(ancestor(v)));
9343          *      if (semi(label(ancestor(v))) < semi(label(v))) {
9344          *              label(v) = label(ancestor(v));
9345          *      }
9346          *      ancestor(v) = ancestor(ancestor(v));
9347          * }
9348          */
9349         if (!v->ancestor) {
9350                 return;
9351         }
9352         if (v->ancestor->ancestor) {
9353                 compress_ancestors(v->ancestor->ancestor);
9354                 if (v->ancestor->label->sdom->vertex < v->label->sdom->vertex) {
9355                         v->label = v->ancestor->label;
9356                 }
9357                 v->ancestor = v->ancestor->ancestor;
9358         }
9359 }
9360
9361 static void compute_sdom(struct compile_state *state, struct sdom_block *sd)
9362 {
9363         int i;
9364         /* // step 2 
9365          *  for each v <= pred(w) {
9366          *      u = EVAL(v);
9367          *      if (semi[u] < semi[w] { 
9368          *              semi[w] = semi[u]; 
9369          *      } 
9370          * }
9371          * add w to bucket(vertex(semi[w]));
9372          * LINK(parent(w), w);
9373          *
9374          * // step 3
9375          * for each v <= bucket(parent(w)) {
9376          *      delete v from bucket(parent(w));
9377          *      u = EVAL(v);
9378          *      dom(v) = (semi[u] < semi[v]) ? u : parent(w);
9379          * }
9380          */
9381         for(i = state->last_vertex; i >= 2; i--) {
9382                 struct sdom_block *v, *parent, *next;
9383                 struct block_set *user;
9384                 struct block *block;
9385                 block = sd[i].block;
9386                 parent = sd[i].parent;
9387                 /* Step 2 */
9388                 for(user = block->use; user; user = user->next) {
9389                         struct sdom_block *v, *u;
9390                         v = &sd[user->member->vertex];
9391                         u = !(v->ancestor)? v : (compress_ancestors(v), v->label);
9392                         if (u->sdom->vertex < sd[i].sdom->vertex) {
9393                                 sd[i].sdom = u->sdom;
9394                         }
9395                 }
9396                 sdom_block(sd[i].sdom, &sd[i]);
9397                 sd[i].ancestor = parent;
9398                 /* Step 3 */
9399                 for(v = parent->sdominates; v; v = next) {
9400                         struct sdom_block *u;
9401                         next = v->sdom_next;
9402                         unsdom_block(v);
9403                         u = (!v->ancestor) ? v : (compress_ancestors(v), v->label);
9404                         v->block->idom = (u->sdom->vertex < v->sdom->vertex)? 
9405                                 u->block : parent->block;
9406                 }
9407         }
9408 }
9409
9410 static void compute_spdom(struct compile_state *state, struct sdom_block *sd)
9411 {
9412         int i;
9413         /* // step 2 
9414          *  for each v <= pred(w) {
9415          *      u = EVAL(v);
9416          *      if (semi[u] < semi[w] { 
9417          *              semi[w] = semi[u]; 
9418          *      } 
9419          * }
9420          * add w to bucket(vertex(semi[w]));
9421          * LINK(parent(w), w);
9422          *
9423          * // step 3
9424          * for each v <= bucket(parent(w)) {
9425          *      delete v from bucket(parent(w));
9426          *      u = EVAL(v);
9427          *      dom(v) = (semi[u] < semi[v]) ? u : parent(w);
9428          * }
9429          */
9430         for(i = state->last_vertex; i >= 2; i--) {
9431                 struct sdom_block *u, *v, *parent, *next;
9432                 struct block *block;
9433                 block = sd[i].block;
9434                 parent = sd[i].parent;
9435                 /* Step 2 */
9436                 if (block->left) {
9437                         v = &sd[block->left->vertex];
9438                         u = !(v->ancestor)? v : (compress_ancestors(v), v->label);
9439                         if (u->sdom->vertex < sd[i].sdom->vertex) {
9440                                 sd[i].sdom = u->sdom;
9441                         }
9442                 }
9443                 if (block->right && (block->right != block->left)) {
9444                         v = &sd[block->right->vertex];
9445                         u = !(v->ancestor)? v : (compress_ancestors(v), v->label);
9446                         if (u->sdom->vertex < sd[i].sdom->vertex) {
9447                                 sd[i].sdom = u->sdom;
9448                         }
9449                 }
9450                 sdom_block(sd[i].sdom, &sd[i]);
9451                 sd[i].ancestor = parent;
9452                 /* Step 3 */
9453                 for(v = parent->sdominates; v; v = next) {
9454                         struct sdom_block *u;
9455                         next = v->sdom_next;
9456                         unsdom_block(v);
9457                         u = (!v->ancestor) ? v : (compress_ancestors(v), v->label);
9458                         v->block->ipdom = (u->sdom->vertex < v->sdom->vertex)? 
9459                                 u->block : parent->block;
9460                 }
9461         }
9462 }
9463
9464 static void compute_idom(struct compile_state *state, struct sdom_block *sd)
9465 {
9466         int i;
9467         for(i = 2; i <= state->last_vertex; i++) {
9468                 struct block *block;
9469                 block = sd[i].block;
9470                 if (block->idom->vertex != sd[i].sdom->vertex) {
9471                         block->idom = block->idom->idom;
9472                 }
9473                 idom_block(block->idom, block);
9474         }
9475         sd[1].block->idom = 0;
9476 }
9477
9478 static void compute_ipdom(struct compile_state *state, struct sdom_block *sd)
9479 {
9480         int i;
9481         for(i = 2; i <= state->last_vertex; i++) {
9482                 struct block *block;
9483                 block = sd[i].block;
9484                 if (block->ipdom->vertex != sd[i].sdom->vertex) {
9485                         block->ipdom = block->ipdom->ipdom;
9486                 }
9487                 ipdom_block(block->ipdom, block);
9488         }
9489         sd[1].block->ipdom = 0;
9490 }
9491
9492         /* Theorem 1:
9493          *   Every vertex of a flowgraph G = (V, E, r) except r has
9494          *   a unique immediate dominator.  
9495          *   The edges {(idom(w), w) |w <= V - {r}} form a directed tree
9496          *   rooted at r, called the dominator tree of G, such that 
9497          *   v dominates w if and only if v is a proper ancestor of w in
9498          *   the dominator tree.
9499          */
9500         /* Lemma 1:  
9501          *   If v and w are vertices of G such that v <= w,
9502          *   than any path from v to w must contain a common ancestor
9503          *   of v and w in T.
9504          */
9505         /* Lemma 2:  For any vertex w != r, idom(w) -> w */
9506         /* Lemma 3:  For any vertex w != r, sdom(w) -> w */
9507         /* Lemma 4:  For any vertex w != r, idom(w) -> sdom(w) */
9508         /* Theorem 2:
9509          *   Let w != r.  Suppose every u for which sdom(w) -> u -> w satisfies
9510          *   sdom(u) >= sdom(w).  Then idom(w) = sdom(w).
9511          */
9512         /* Theorem 3:
9513          *   Let w != r and let u be a vertex for which sdom(u) is 
9514          *   minimum amoung vertices u satisfying sdom(w) -> u -> w.
9515          *   Then sdom(u) <= sdom(w) and idom(u) = idom(w).
9516          */
9517         /* Lemma 5:  Let vertices v,w satisfy v -> w.
9518          *           Then v -> idom(w) or idom(w) -> idom(v)
9519          */
9520
9521 static void find_immediate_dominators(struct compile_state *state)
9522 {
9523         struct sdom_block *sd;
9524         /* w->sdom = min{v| there is a path v = v0,v1,...,vk = w such that:
9525          *           vi > w for (1 <= i <= k - 1}
9526          */
9527         /* Theorem 4:
9528          *   For any vertex w != r.
9529          *   sdom(w) = min(
9530          *                 {v|(v,w) <= E  and v < w } U 
9531          *                 {sdom(u) | u > w and there is an edge (v, w) such that u -> v})
9532          */
9533         /* Corollary 1:
9534          *   Let w != r and let u be a vertex for which sdom(u) is 
9535          *   minimum amoung vertices u satisfying sdom(w) -> u -> w.
9536          *   Then:
9537          *                   { sdom(w) if sdom(w) = sdom(u),
9538          *        idom(w) = {
9539          *                   { idom(u) otherwise
9540          */
9541         /* The algorithm consists of the following 4 steps.
9542          * Step 1.  Carry out a depth-first search of the problem graph.  
9543          *    Number the vertices from 1 to N as they are reached during
9544          *    the search.  Initialize the variables used in succeeding steps.
9545          * Step 2.  Compute the semidominators of all vertices by applying
9546          *    theorem 4.   Carry out the computation vertex by vertex in
9547          *    decreasing order by number.
9548          * Step 3.  Implicitly define the immediate dominator of each vertex
9549          *    by applying Corollary 1.
9550          * Step 4.  Explicitly define the immediate dominator of each vertex,
9551          *    carrying out the computation vertex by vertex in increasing order
9552          *    by number.
9553          */
9554         /* Step 1 initialize the basic block information */
9555         sd = xcmalloc(sizeof(*sd) * (state->last_vertex + 1), "sdom_state");
9556         initialize_sdblock(sd, 0, state->first_block, 0);
9557 #if 0
9558         sd[1].size  = 0;
9559         sd[1].label = 0;
9560         sd[1].sdom  = 0;
9561 #endif
9562         /* Step 2 compute the semidominators */
9563         /* Step 3 implicitly define the immediate dominator of each vertex */
9564         compute_sdom(state, sd);
9565         /* Step 4 explicitly define the immediate dominator of each vertex */
9566         compute_idom(state, sd);
9567         xfree(sd);
9568 }
9569
9570 static void find_post_dominators(struct compile_state *state)
9571 {
9572         struct sdom_block *sd;
9573         /* Step 1 initialize the basic block information */
9574         sd = xcmalloc(sizeof(*sd) * (state->last_vertex + 1), "sdom_state");
9575
9576         initialize_sdpblock(sd, 0, state->last_block, 0);
9577
9578         /* Step 2 compute the semidominators */
9579         /* Step 3 implicitly define the immediate dominator of each vertex */
9580         compute_spdom(state, sd);
9581         /* Step 4 explicitly define the immediate dominator of each vertex */
9582         compute_ipdom(state, sd);
9583         xfree(sd);
9584 }
9585
9586
9587
9588 static void find_block_domf(struct compile_state *state, struct block *block)
9589 {
9590         struct block *child;
9591         struct block_set *user;
9592         if (block->domfrontier != 0) {
9593                 internal_error(state, block->first, "domfrontier present?");
9594         }
9595         for(user = block->idominates; user; user = user->next) {
9596                 child = user->member;
9597                 if (child->idom != block) {
9598                         internal_error(state, block->first, "bad idom");
9599                 }
9600                 find_block_domf(state, child);
9601         }
9602         if (block->left && block->left->idom != block) {
9603                 domf_block(block, block->left);
9604         }
9605         if (block->right && block->right->idom != block) {
9606                 domf_block(block, block->right);
9607         }
9608         for(user = block->idominates; user; user = user->next) {
9609                 struct block_set *frontier;
9610                 child = user->member;
9611                 for(frontier = child->domfrontier; frontier; frontier = frontier->next) {
9612                         if (frontier->member->idom != block) {
9613                                 domf_block(block, frontier->member);
9614                         }
9615                 }
9616         }
9617 }
9618
9619 static void find_block_ipdomf(struct compile_state *state, struct block *block)
9620 {
9621         struct block *child;
9622         struct block_set *user;
9623         if (block->ipdomfrontier != 0) {
9624                 internal_error(state, block->first, "ipdomfrontier present?");
9625         }
9626         for(user = block->ipdominates; user; user = user->next) {
9627                 child = user->member;
9628                 if (child->ipdom != block) {
9629                         internal_error(state, block->first, "bad ipdom");
9630                 }
9631                 find_block_ipdomf(state, child);
9632         }
9633         if (block->left && block->left->ipdom != block) {
9634                 ipdomf_block(block, block->left);
9635         }
9636         if (block->right && block->right->ipdom != block) {
9637                 ipdomf_block(block, block->right);
9638         }
9639         for(user = block->idominates; user; user = user->next) {
9640                 struct block_set *frontier;
9641                 child = user->member;
9642                 for(frontier = child->ipdomfrontier; frontier; frontier = frontier->next) {
9643                         if (frontier->member->ipdom != block) {
9644                                 ipdomf_block(block, frontier->member);
9645                         }
9646                 }
9647         }
9648 }
9649
9650 static void print_dominated(
9651         struct compile_state *state, struct block *block, void *arg)
9652 {
9653         struct block_set *user;
9654         FILE *fp = arg;
9655
9656         fprintf(fp, "%d:", block->vertex);
9657         for(user = block->idominates; user; user = user->next) {
9658                 fprintf(fp, " %d", user->member->vertex);
9659                 if (user->member->idom != block) {
9660                         internal_error(state, user->member->first, "bad idom");
9661                 }
9662         }
9663         fprintf(fp,"\n");
9664 }
9665
9666 static void print_dominators(struct compile_state *state, FILE *fp)
9667 {
9668         fprintf(fp, "\ndominates\n");
9669         walk_blocks(state, print_dominated, fp);
9670 }
9671
9672
9673 static int print_frontiers(
9674         struct compile_state *state, struct block *block, int vertex)
9675 {
9676         struct block_set *user;
9677
9678         if (!block || (block->vertex != vertex + 1)) {
9679                 return vertex;
9680         }
9681         vertex += 1;
9682
9683         printf("%d:", block->vertex);
9684         for(user = block->domfrontier; user; user = user->next) {
9685                 printf(" %d", user->member->vertex);
9686         }
9687         printf("\n");
9688
9689         vertex = print_frontiers(state, block->left, vertex);
9690         vertex = print_frontiers(state, block->right, vertex);
9691         return vertex;
9692 }
9693 static void print_dominance_frontiers(struct compile_state *state)
9694 {
9695         printf("\ndominance frontiers\n");
9696         print_frontiers(state, state->first_block, 0);
9697         
9698 }
9699
9700 static void analyze_idominators(struct compile_state *state)
9701 {
9702         /* Find the immediate dominators */
9703         find_immediate_dominators(state);
9704         /* Find the dominance frontiers */
9705         find_block_domf(state, state->first_block);
9706         /* If debuging print the print what I have just found */
9707         if (state->debug & DEBUG_FDOMINATORS) {
9708                 print_dominators(state, stdout);
9709                 print_dominance_frontiers(state);
9710                 print_control_flow(state);
9711         }
9712 }
9713
9714
9715
9716 static void print_ipdominated(
9717         struct compile_state *state, struct block *block, void *arg)
9718 {
9719         struct block_set *user;
9720         FILE *fp = arg;
9721
9722         fprintf(fp, "%d:", block->vertex);
9723         for(user = block->ipdominates; user; user = user->next) {
9724                 fprintf(fp, " %d", user->member->vertex);
9725                 if (user->member->ipdom != block) {
9726                         internal_error(state, user->member->first, "bad ipdom");
9727                 }
9728         }
9729         fprintf(fp, "\n");
9730 }
9731
9732 static void print_ipdominators(struct compile_state *state, FILE *fp)
9733 {
9734         fprintf(fp, "\nipdominates\n");
9735         walk_blocks(state, print_ipdominated, fp);
9736 }
9737
9738 static int print_pfrontiers(
9739         struct compile_state *state, struct block *block, int vertex)
9740 {
9741         struct block_set *user;
9742
9743         if (!block || (block->vertex != vertex + 1)) {
9744                 return vertex;
9745         }
9746         vertex += 1;
9747
9748         printf("%d:", block->vertex);
9749         for(user = block->ipdomfrontier; user; user = user->next) {
9750                 printf(" %d", user->member->vertex);
9751         }
9752         printf("\n");
9753         for(user = block->use; user; user = user->next) {
9754                 vertex = print_pfrontiers(state, user->member, vertex);
9755         }
9756         return vertex;
9757 }
9758 static void print_ipdominance_frontiers(struct compile_state *state)
9759 {
9760         printf("\nipdominance frontiers\n");
9761         print_pfrontiers(state, state->last_block, 0);
9762         
9763 }
9764
9765 static void analyze_ipdominators(struct compile_state *state)
9766 {
9767         /* Find the post dominators */
9768         find_post_dominators(state);
9769         /* Find the control dependencies (post dominance frontiers) */
9770         find_block_ipdomf(state, state->last_block);
9771         /* If debuging print the print what I have just found */
9772         if (state->debug & DEBUG_RDOMINATORS) {
9773                 print_ipdominators(state, stdout);
9774                 print_ipdominance_frontiers(state);
9775                 print_control_flow(state);
9776         }
9777 }
9778
9779 static int bdominates(struct compile_state *state,
9780         struct block *dom, struct block *sub)
9781 {
9782         while(sub && (sub != dom)) {
9783                 sub = sub->idom;
9784         }
9785         return sub == dom;
9786 }
9787
9788 static int tdominates(struct compile_state *state,
9789         struct triple *dom, struct triple *sub)
9790 {
9791         struct block *bdom, *bsub;
9792         int result;
9793         bdom = block_of_triple(state, dom);
9794         bsub = block_of_triple(state, sub);
9795         if (bdom != bsub) {
9796                 result = bdominates(state, bdom, bsub);
9797         } 
9798         else {
9799                 struct triple *ins;
9800                 ins = sub;
9801                 while((ins != bsub->first) && (ins != dom)) {
9802                         ins = ins->prev;
9803                 }
9804                 result = (ins == dom);
9805         }
9806         return result;
9807 }
9808
9809 static int tdistance(struct compile_state *state,
9810         struct triple *dom, struct triple *sub)
9811 {
9812         int count;
9813         struct block *bdom, *bsub;
9814         if (!tdominates(state, dom, sub)) {
9815                 internal_error(state, 0, "dom does not dom sub");
9816         }
9817         bdom = block_of_triple(state, dom);
9818         bsub = block_of_triple(state, sub);
9819         count = 0;
9820         for(; bsub != bdom; (bsub = bsub->idom), sub = bsub->last) {
9821                 for(; sub != bsub->first; sub = sub->prev) {
9822                         count++;
9823                 }
9824         }
9825         for(; sub != dom; sub = sub->prev) {
9826                 count++;
9827         }
9828         return count;
9829 }
9830
9831 static void insert_phi_operations(struct compile_state *state)
9832 {
9833         size_t size;
9834         struct triple *first;
9835         int *has_already, *work;
9836         struct block *work_list, **work_list_tail;
9837         int iter;
9838         struct triple *var;
9839
9840         size = sizeof(int) * (state->last_vertex + 1);
9841         has_already = xcmalloc(size, "has_already");
9842         work =        xcmalloc(size, "work");
9843         iter = 0;
9844
9845         first = RHS(state->main_function, 0);
9846         for(var = first->next; var != first ; var = var->next) {
9847                 struct block *block;
9848                 struct triple_set *user;
9849                 if ((var->op != OP_ADECL) || !var->use) {
9850                         continue;
9851                 }
9852                 iter += 1;
9853                 work_list = 0;
9854                 work_list_tail = &work_list;
9855                 for(user = var->use; user; user = user->next) {
9856                         if (user->member->op == OP_READ) {
9857                                 continue;
9858                         }
9859                         if (user->member->op != OP_WRITE) {
9860                                 internal_error(state, user->member, 
9861                                         "bad variable access");
9862                         }
9863                         block = user->member->u.block;
9864                         if (!block) {
9865                                 warning(state, user->member, "dead code");
9866                         }
9867                         work[block->vertex] = iter;
9868                         *work_list_tail = block;
9869                         block->work_next = 0;
9870                         work_list_tail = &block->work_next;
9871                 }
9872                 for(block = work_list; block; block = block->work_next) {
9873                         struct block_set *df;
9874                         for(df = block->domfrontier; df; df = df->next) {
9875                                 struct triple *phi;
9876                                 struct block *front;
9877                                 int in_edges;
9878                                 front = df->member;
9879
9880                                 if (has_already[front->vertex] >= iter) {
9881                                         continue;
9882                                 }
9883                                 /* Count how many edges flow into this block */
9884                                 in_edges = front->users;
9885                                 /* Insert a phi function for this variable */
9886                                 phi = alloc_triple(
9887                                         state, OP_PHI, var->type, -1, in_edges, 
9888                                         front->first->filename, 
9889                                         front->first->line,
9890                                         front->first->col);
9891                                 phi->u.block = front;
9892                                 MISC(phi, 0) = var;
9893                                 use_triple(var, phi);
9894                                 /* Insert the phi functions immediately after the label */
9895                                 insert_triple(state, front->first->next, phi);
9896                                 if (front->first == front->last) {
9897                                         front->last = front->first->next;
9898                                 }
9899                                 has_already[front->vertex] = iter;
9900                                 
9901                                 /* If necessary plan to visit the basic block */
9902                                 if (work[front->vertex] >= iter) {
9903                                         continue;
9904                                 }
9905                                 work[front->vertex] = iter;
9906                                 *work_list_tail = front;
9907                                 front->work_next = 0;
9908                                 work_list_tail = &front->work_next;
9909                         }
9910                 }
9911         }
9912         xfree(has_already);
9913         xfree(work);
9914 }
9915
9916 /*
9917  * C(V)
9918  * S(V)
9919  */
9920 static void fixup_block_phi_variables(
9921         struct compile_state *state, struct block *parent, struct block *block)
9922 {
9923         struct block_set *set;
9924         struct triple *ptr;
9925         int edge;
9926         if (!parent || !block)
9927                 return;
9928         /* Find the edge I am coming in on */
9929         edge = 0;
9930         for(set = block->use; set; set = set->next, edge++) {
9931                 if (set->member == parent) {
9932                         break;
9933                 }
9934         }
9935         if (!set) {
9936                 internal_error(state, 0, "phi input is not on a control predecessor");
9937         }
9938         for(ptr = block->first; ; ptr = ptr->next) {
9939                 if (ptr->op == OP_PHI) {
9940                         struct triple *var, *val, **slot;
9941                         var = MISC(ptr, 0);
9942                         if (!var) {
9943                                 internal_error(state, ptr, "no var???");
9944                         }
9945                         /* Find the current value of the variable */
9946                         val = var->use->member;
9947                         if ((val->op == OP_WRITE) || (val->op == OP_READ)) {
9948                                 internal_error(state, val, "bad value in phi");
9949                         }
9950                         if (edge >= TRIPLE_RHS(ptr->sizes)) {
9951                                 internal_error(state, ptr, "edges > phi rhs");
9952                         }
9953                         slot = &RHS(ptr, edge);
9954                         if ((*slot != 0) && (*slot != val)) {
9955                                 internal_error(state, ptr, "phi already bound on this edge");
9956                         }
9957                         *slot = val;
9958                         use_triple(val, ptr);
9959                 }
9960                 if (ptr == block->last) {
9961                         break;
9962                 }
9963         }
9964 }
9965
9966
9967 static void rename_block_variables(
9968         struct compile_state *state, struct block *block)
9969 {
9970         struct block_set *user;
9971         struct triple *ptr, *next, *last;
9972         int done;
9973         if (!block)
9974                 return;
9975         last = block->first;
9976         done = 0;
9977         for(ptr = block->first; !done; ptr = next) {
9978                 next = ptr->next;
9979                 if (ptr == block->last) {
9980                         done = 1;
9981                 }
9982                 /* RHS(A) */
9983                 if (ptr->op == OP_READ) {
9984                         struct triple *var, *val;
9985                         var = RHS(ptr, 0);
9986                         unuse_triple(var, ptr);
9987                         if (!var->use) {
9988                                 error(state, ptr, "variable used without being set");
9989                         }
9990                         /* Find the current value of the variable */
9991                         val = var->use->member;
9992                         if ((val->op == OP_WRITE) || (val->op == OP_READ)) {
9993                                 internal_error(state, val, "bad value in read");
9994                         }
9995                         propogate_use(state, ptr, val);
9996                         release_triple(state, ptr);
9997                         continue;
9998                 }
9999                 /* LHS(A) */
10000                 if (ptr->op == OP_WRITE) {
10001                         struct triple *var, *val;
10002                         var = LHS(ptr, 0);
10003                         val = RHS(ptr, 0);
10004                         if ((val->op == OP_WRITE) || (val->op == OP_READ)) {
10005                                 internal_error(state, val, "bad value in write");
10006                         }
10007                         propogate_use(state, ptr, val);
10008                         unuse_triple(var, ptr);
10009                         /* Push OP_WRITE ptr->right onto a stack of variable uses */
10010                         push_triple(var, val);
10011                 }
10012                 if (ptr->op == OP_PHI) {
10013                         struct triple *var;
10014                         var = MISC(ptr, 0);
10015                         /* Push OP_PHI onto a stack of variable uses */
10016                         push_triple(var, ptr);
10017                 }
10018                 last = ptr;
10019         }
10020         block->last = last;
10021
10022         /* Fixup PHI functions in the cf successors */
10023         fixup_block_phi_variables(state, block, block->left);
10024         fixup_block_phi_variables(state, block, block->right);
10025         /* rename variables in the dominated nodes */
10026         for(user = block->idominates; user; user = user->next) {
10027                 rename_block_variables(state, user->member);
10028         }
10029         /* pop the renamed variable stack */
10030         last = block->first;
10031         done = 0;
10032         for(ptr = block->first; !done ; ptr = next) {
10033                 next = ptr->next;
10034                 if (ptr == block->last) {
10035                         done = 1;
10036                 }
10037                 if (ptr->op == OP_WRITE) {
10038                         struct triple *var;
10039                         var = LHS(ptr, 0);
10040                         /* Pop OP_WRITE ptr->right from the stack of variable uses */
10041                         pop_triple(var, RHS(ptr, 0));
10042                         release_triple(state, ptr);
10043                         continue;
10044                 }
10045                 if (ptr->op == OP_PHI) {
10046                         struct triple *var;
10047                         var = MISC(ptr, 0);
10048                         /* Pop OP_WRITE ptr->right from the stack of variable uses */
10049                         pop_triple(var, ptr);
10050                 }
10051                 last = ptr;
10052         }
10053         block->last = last;
10054 }
10055
10056 static void prune_block_variables(struct compile_state *state,
10057         struct block *block)
10058 {
10059         struct block_set *user;
10060         struct triple *next, *last, *ptr;
10061         int done;
10062         last = block->first;
10063         done = 0;
10064         for(ptr = block->first; !done; ptr = next) {
10065                 next = ptr->next;
10066                 if (ptr == block->last) {
10067                         done = 1;
10068                 }
10069                 if (ptr->op == OP_ADECL) {
10070                         struct triple_set *user, *next;
10071                         for(user = ptr->use; user; user = next) {
10072                                 struct triple *use;
10073                                 next = user->next;
10074                                 use = user->member;
10075                                 if (use->op != OP_PHI) {
10076                                         internal_error(state, use, "decl still used");
10077                                 }
10078                                 if (MISC(use, 0) != ptr) {
10079                                         internal_error(state, use, "bad phi use of decl");
10080                                 }
10081                                 unuse_triple(ptr, use);
10082                                 MISC(use, 0) = 0;
10083                         }
10084                         release_triple(state, ptr);
10085                         continue;
10086                 }
10087                 last = ptr;
10088         }
10089         block->last = last;
10090         for(user = block->idominates; user; user = user->next) {
10091                 prune_block_variables(state, user->member);
10092         }
10093 }
10094
10095 static void transform_to_ssa_form(struct compile_state *state)
10096 {
10097         insert_phi_operations(state);
10098 #if 0
10099         printf("@%s:%d\n", __FILE__, __LINE__);
10100         print_blocks(state, stdout);
10101 #endif
10102         rename_block_variables(state, state->first_block);
10103         prune_block_variables(state, state->first_block);
10104 }
10105
10106
10107 static void clear_vertex(
10108         struct compile_state *state, struct block *block, void *arg)
10109 {
10110         block->vertex = 0;
10111 }
10112
10113 static void mark_live_block(
10114         struct compile_state *state, struct block *block, int *next_vertex)
10115 {
10116         /* See if this is a block that has not been marked */
10117         if (block->vertex != 0) {
10118                 return;
10119         }
10120         block->vertex = *next_vertex;
10121         *next_vertex += 1;
10122         if (triple_is_branch(state, block->last)) {
10123                 struct triple **targ;
10124                 targ = triple_targ(state, block->last, 0);
10125                 for(; targ; targ = triple_targ(state, block->last, targ)) {
10126                         if (!*targ) {
10127                                 continue;
10128                         }
10129                         if (!triple_stores_block(state, *targ)) {
10130                                 internal_error(state, 0, "bad targ");
10131                         }
10132                         mark_live_block(state, (*targ)->u.block, next_vertex);
10133                 }
10134         }
10135         else if (block->last->next != RHS(state->main_function, 0)) {
10136                 struct triple *ins;
10137                 ins = block->last->next;
10138                 if (!triple_stores_block(state, ins)) {
10139                         internal_error(state, 0, "bad block start");
10140                 }
10141                 mark_live_block(state, ins->u.block, next_vertex);
10142         }
10143 }
10144
10145 static void transform_from_ssa_form(struct compile_state *state)
10146 {
10147         /* To get out of ssa form we insert moves on the incoming
10148          * edges to blocks containting phi functions.
10149          */
10150         struct triple *first;
10151         struct triple *phi, *next;
10152         int next_vertex;
10153
10154         /* Walk the control flow to see which blocks remain alive */
10155         walk_blocks(state, clear_vertex, 0);
10156         next_vertex = 1;
10157         mark_live_block(state, state->first_block, &next_vertex);
10158
10159         /* Walk all of the operations to find the phi functions */
10160         first = RHS(state->main_function, 0);
10161         for(phi = first->next; phi != first ; phi = next) {
10162                 struct block_set *set;
10163                 struct block *block;
10164                 struct triple **slot;
10165                 struct triple *var, *read;
10166                 struct triple_set *use, *use_next;
10167                 int edge, used;
10168                 next = phi->next;
10169                 if (phi->op != OP_PHI) {
10170                         continue;
10171                 }
10172                 block = phi->u.block;
10173                 slot  = &RHS(phi, 0);
10174
10175                 /* Forget uses from code in dead blocks */
10176                 for(use = phi->use; use; use = use_next) {
10177                         struct block *ublock;
10178                         struct triple **expr;
10179                         use_next = use->next;
10180                         ublock = block_of_triple(state, use->member);
10181                         if ((use->member == phi) || (ublock->vertex != 0)) {
10182                                 continue;
10183                         }
10184                         expr = triple_rhs(state, use->member, 0);
10185                         for(; expr; expr = triple_rhs(state, use->member, expr)) {
10186                                 if (*expr == phi) {
10187                                         *expr = 0;
10188                                 }
10189                         }
10190                         unuse_triple(phi, use->member);
10191                 }
10192
10193                 /* A variable to replace the phi function */
10194                 var = post_triple(state, phi, OP_ADECL, phi->type, 0,0);
10195                 /* A read of the single value that is set into the variable */
10196                 read = post_triple(state, var, OP_READ, phi->type, var, 0);
10197                 use_triple(var, read);
10198
10199                 /* Replaces uses of the phi with variable reads */
10200                 propogate_use(state, phi, read);
10201
10202                 /* Walk all of the incoming edges/blocks and insert moves.
10203                  */
10204                 for(edge = 0, set = block->use; set; set = set->next, edge++) {
10205                         struct block *eblock;
10206                         struct triple *move;
10207                         struct triple *val;
10208                         eblock = set->member;
10209                         val = slot[edge];
10210                         slot[edge] = 0;
10211                         unuse_triple(val, phi);
10212
10213                         if (!val || (val == &zero_triple) ||
10214                                 (block->vertex == 0) || (eblock->vertex == 0) ||
10215                                 (val == phi) || (val == read)) {
10216                                 continue;
10217                         }
10218                         
10219                         move = post_triple(state, 
10220                                 val, OP_WRITE, phi->type, var, val);
10221                         use_triple(val, move);
10222                         use_triple(var, move);
10223                 }               
10224                 /* See if there are any writers of var */
10225                 used = 0;
10226                 for(use = var->use; use; use = use->next) {
10227                         struct triple **expr;
10228                         expr = triple_lhs(state, use->member, 0);
10229                         for(; expr; expr = triple_lhs(state, use->member, expr)) {
10230                                 if (*expr == var) {
10231                                         used = 1;
10232                                 }
10233                         }
10234                 }
10235                 /* If var is not used free it */
10236                 if (!used) {
10237                         unuse_triple(var, read);
10238                         free_triple(state, read);
10239                         free_triple(state, var);
10240                 }
10241
10242                 /* Release the phi function */
10243                 release_triple(state, phi);
10244         }
10245         
10246 }
10247
10248
10249 /* 
10250  * Register conflict resolution
10251  * =========================================================
10252  */
10253
10254 static struct reg_info find_def_color(
10255         struct compile_state *state, struct triple *def)
10256 {
10257         struct triple_set *set;
10258         struct reg_info info;
10259         info.reg = REG_UNSET;
10260         info.regcm = 0;
10261         if (!triple_is_def(state, def)) {
10262                 return info;
10263         }
10264         info = arch_reg_lhs(state, def, 0);
10265         if (info.reg >= MAX_REGISTERS) {
10266                 info.reg = REG_UNSET;
10267         }
10268         for(set = def->use; set; set = set->next) {
10269                 struct reg_info tinfo;
10270                 int i;
10271                 i = find_rhs_use(state, set->member, def);
10272                 if (i < 0) {
10273                         continue;
10274                 }
10275                 tinfo = arch_reg_rhs(state, set->member, i);
10276                 if (tinfo.reg >= MAX_REGISTERS) {
10277                         tinfo.reg = REG_UNSET;
10278                 }
10279                 if ((tinfo.reg != REG_UNSET) && 
10280                         (info.reg != REG_UNSET) &&
10281                         (tinfo.reg != info.reg)) {
10282                         internal_error(state, def, "register conflict");
10283                 }
10284                 if ((info.regcm & tinfo.regcm) == 0) {
10285                         internal_error(state, def, "regcm conflict %x & %x == 0",
10286                                 info.regcm, tinfo.regcm);
10287                 }
10288                 if (info.reg == REG_UNSET) {
10289                         info.reg = tinfo.reg;
10290                 }
10291                 info.regcm &= tinfo.regcm;
10292         }
10293         if (info.reg >= MAX_REGISTERS) {
10294                 internal_error(state, def, "register out of range");
10295         }
10296         return info;
10297 }
10298
10299 static struct reg_info find_lhs_pre_color(
10300         struct compile_state *state, struct triple *ins, int index)
10301 {
10302         struct reg_info info;
10303         int zlhs, zrhs, i;
10304         zrhs = TRIPLE_RHS(ins->sizes);
10305         zlhs = TRIPLE_LHS(ins->sizes);
10306         if (!zlhs && triple_is_def(state, ins)) {
10307                 zlhs = 1;
10308         }
10309         if (index >= zlhs) {
10310                 internal_error(state, ins, "Bad lhs %d", index);
10311         }
10312         info = arch_reg_lhs(state, ins, index);
10313         for(i = 0; i < zrhs; i++) {
10314                 struct reg_info rinfo;
10315                 rinfo = arch_reg_rhs(state, ins, i);
10316                 if ((info.reg == rinfo.reg) &&
10317                         (rinfo.reg >= MAX_REGISTERS)) {
10318                         struct reg_info tinfo;
10319                         tinfo = find_lhs_pre_color(state, RHS(ins, index), 0);
10320                         info.reg = tinfo.reg;
10321                         info.regcm &= tinfo.regcm;
10322                         break;
10323                 }
10324         }
10325         if (info.reg >= MAX_REGISTERS) {
10326                 info.reg = REG_UNSET;
10327         }
10328         return info;
10329 }
10330
10331 static struct reg_info find_rhs_post_color(
10332         struct compile_state *state, struct triple *ins, int index);
10333
10334 static struct reg_info find_lhs_post_color(
10335         struct compile_state *state, struct triple *ins, int index)
10336 {
10337         struct triple_set *set;
10338         struct reg_info info;
10339         struct triple *lhs;
10340 #if 0
10341         fprintf(stderr, "find_lhs_post_color(%p, %d)\n",
10342                 ins, index);
10343 #endif
10344         if ((index == 0) && triple_is_def(state, ins)) {
10345                 lhs = ins;
10346         }
10347         else if (index < TRIPLE_LHS(ins->sizes)) {
10348                 lhs = LHS(ins, index);
10349         }
10350         else {
10351                 internal_error(state, ins, "Bad lhs %d", index);
10352                 lhs = 0;
10353         }
10354         info = arch_reg_lhs(state, ins, index);
10355         if (info.reg >= MAX_REGISTERS) {
10356                 info.reg = REG_UNSET;
10357         }
10358         for(set = lhs->use; set; set = set->next) {
10359                 struct reg_info rinfo;
10360                 struct triple *user;
10361                 int zrhs, i;
10362                 user = set->member;
10363                 zrhs = TRIPLE_RHS(user->sizes);
10364                 for(i = 0; i < zrhs; i++) {
10365                         if (RHS(user, i) != lhs) {
10366                                 continue;
10367                         }
10368                         rinfo = find_rhs_post_color(state, user, i);
10369                         if ((info.reg != REG_UNSET) &&
10370                                 (rinfo.reg != REG_UNSET) &&
10371                                 (info.reg != rinfo.reg)) {
10372                                 internal_error(state, ins, "register conflict");
10373                         }
10374                         if ((info.regcm & rinfo.regcm) == 0) {
10375                                 internal_error(state, ins, "regcm conflict %x & %x == 0",
10376                                         info.regcm, rinfo.regcm);
10377                         }
10378                         if (info.reg == REG_UNSET) {
10379                                 info.reg = rinfo.reg;
10380                         }
10381                         info.regcm &= rinfo.regcm;
10382                 }
10383         }
10384 #if 0
10385         fprintf(stderr, "find_lhs_post_color(%p, %d) -> ( %d, %x)\n",
10386                 ins, index, info.reg, info.regcm);
10387 #endif
10388         return info;
10389 }
10390
10391 static struct reg_info find_rhs_post_color(
10392         struct compile_state *state, struct triple *ins, int index)
10393 {
10394         struct reg_info info, rinfo;
10395         int zlhs, i;
10396 #if 0
10397         fprintf(stderr, "find_rhs_post_color(%p, %d)\n",
10398                 ins, index);
10399 #endif
10400         rinfo = arch_reg_rhs(state, ins, index);
10401         zlhs = TRIPLE_LHS(ins->sizes);
10402         if (!zlhs && triple_is_def(state, ins)) {
10403                 zlhs = 1;
10404         }
10405         info = rinfo;
10406         if (info.reg >= MAX_REGISTERS) {
10407                 info.reg = REG_UNSET;
10408         }
10409         for(i = 0; i < zlhs; i++) {
10410                 struct reg_info linfo;
10411                 linfo = arch_reg_lhs(state, ins, i);
10412                 if ((linfo.reg == rinfo.reg) &&
10413                         (linfo.reg >= MAX_REGISTERS)) {
10414                         struct reg_info tinfo;
10415                         tinfo = find_lhs_post_color(state, ins, i);
10416                         if (tinfo.reg >= MAX_REGISTERS) {
10417                                 tinfo.reg = REG_UNSET;
10418                         }
10419                         info.regcm &= linfo.reg;
10420                         info.regcm &= tinfo.regcm;
10421                         if (info.reg != REG_UNSET) {
10422                                 internal_error(state, ins, "register conflict");
10423                         }
10424                         if (info.regcm == 0) {
10425                                 internal_error(state, ins, "regcm conflict");
10426                         }
10427                         info.reg = tinfo.reg;
10428                 }
10429         }
10430 #if 0
10431         fprintf(stderr, "find_rhs_post_color(%p, %d) -> ( %d, %x)\n",
10432                 ins, index, info.reg, info.regcm);
10433 #endif
10434         return info;
10435 }
10436
10437 static struct reg_info find_lhs_color(
10438         struct compile_state *state, struct triple *ins, int index)
10439 {
10440         struct reg_info pre, post, info;
10441 #if 0
10442         fprintf(stderr, "find_lhs_color(%p, %d)\n",
10443                 ins, index);
10444 #endif
10445         pre = find_lhs_pre_color(state, ins, index);
10446         post = find_lhs_post_color(state, ins, index);
10447         if ((pre.reg != post.reg) &&
10448                 (pre.reg != REG_UNSET) &&
10449                 (post.reg != REG_UNSET)) {
10450                 internal_error(state, ins, "register conflict");
10451         }
10452         info.regcm = pre.regcm & post.regcm;
10453         info.reg = pre.reg;
10454         if (info.reg == REG_UNSET) {
10455                 info.reg = post.reg;
10456         }
10457 #if 0
10458         fprintf(stderr, "find_lhs_color(%p, %d) -> ( %d, %x)\n",
10459                 ins, index, info.reg, info.regcm);
10460 #endif
10461         return info;
10462 }
10463
10464 static struct triple *post_copy(struct compile_state *state, struct triple *ins)
10465 {
10466         struct triple_set *entry, *next;
10467         struct triple *out;
10468         struct reg_info info, rinfo;
10469
10470         info = arch_reg_lhs(state, ins, 0);
10471         out = post_triple(state, ins, OP_COPY, ins->type, ins, 0);
10472         use_triple(RHS(out, 0), out);
10473         /* Get the users of ins to use out instead */
10474         for(entry = ins->use; entry; entry = next) {
10475                 int i;
10476                 next = entry->next;
10477                 if (entry->member == out) {
10478                         continue;
10479                 }
10480                 i = find_rhs_use(state, entry->member, ins);
10481                 if (i < 0) {
10482                         continue;
10483                 }
10484                 rinfo = arch_reg_rhs(state, entry->member, i);
10485                 if ((info.reg == REG_UNNEEDED) && (rinfo.reg == REG_UNNEEDED)) {
10486                         continue;
10487                 }
10488                 replace_rhs_use(state, ins, out, entry->member);
10489         }
10490         transform_to_arch_instruction(state, out);
10491         return out;
10492 }
10493
10494 static struct triple *pre_copy(
10495         struct compile_state *state, struct triple *ins, int index)
10496 {
10497         /* Carefully insert enough operations so that I can
10498          * enter any operation with a GPR32.
10499          */
10500         struct triple *in;
10501         struct triple **expr;
10502         expr = &RHS(ins, index);
10503         in = pre_triple(state, ins, OP_COPY, (*expr)->type, *expr, 0);
10504         unuse_triple(*expr, ins);
10505         *expr = in;
10506         use_triple(RHS(in, 0), in);
10507         use_triple(in, ins);
10508         transform_to_arch_instruction(state, in);
10509         return in;
10510 }
10511
10512
10513 static void insert_copies_to_phi(struct compile_state *state)
10514 {
10515         /* To get out of ssa form we insert moves on the incoming
10516          * edges to blocks containting phi functions.
10517          */
10518         struct triple *first;
10519         struct triple *phi;
10520
10521         /* Walk all of the operations to find the phi functions */
10522         first = RHS(state->main_function, 0);
10523         for(phi = first->next; phi != first ; phi = phi->next) {
10524                 struct block_set *set;
10525                 struct block *block;
10526                 struct triple **slot;
10527                 int edge;
10528                 if (phi->op != OP_PHI) {
10529                         continue;
10530                 }
10531                 phi->id |= TRIPLE_FLAG_POST_SPLIT;
10532                 block = phi->u.block;
10533                 slot  = &RHS(phi, 0);
10534                 /* Walk all of the incoming edges/blocks and insert moves.
10535                  */
10536                 for(edge = 0, set = block->use; set; set = set->next, edge++) {
10537                         struct block *eblock;
10538                         struct triple *move;
10539                         struct triple *val;
10540                         struct triple *ptr;
10541                         eblock = set->member;
10542                         val = slot[edge];
10543
10544                         if (val == phi) {
10545                                 continue;
10546                         }
10547
10548                         move = build_triple(state, OP_COPY, phi->type, val, 0,
10549                                 val->filename, val->line, val->col);
10550                         move->u.block = eblock;
10551                         move->id |= TRIPLE_FLAG_PRE_SPLIT;
10552                         use_triple(val, move);
10553                         
10554                         slot[edge] = move;
10555                         unuse_triple(val, phi);
10556                         use_triple(move, phi);
10557
10558                         /* Walk through the block backwards to find
10559                          * an appropriate location for the OP_COPY.
10560                          */
10561                         for(ptr = eblock->last; ptr != eblock->first; ptr = ptr->prev) {
10562                                 struct triple **expr;
10563                                 if ((ptr == phi) || (ptr == val)) {
10564                                         goto out;
10565                                 }
10566                                 expr = triple_rhs(state, ptr, 0);
10567                                 for(;expr; expr = triple_rhs(state, ptr, expr)) {
10568                                         if ((*expr) == phi) {
10569                                                 goto out;
10570                                         }
10571                                 }
10572                         }
10573                 out:
10574                         if (triple_is_branch(state, ptr)) {
10575                                 internal_error(state, ptr,
10576                                         "Could not insert write to phi");
10577                         }
10578                         insert_triple(state, ptr->next, move);
10579                         if (eblock->last == ptr) {
10580                                 eblock->last = move;
10581                         }
10582                         transform_to_arch_instruction(state, move);
10583                 }
10584         }
10585 }
10586
10587 struct triple_reg_set {
10588         struct triple_reg_set *next;
10589         struct triple *member;
10590         struct triple *new;
10591 };
10592
10593 struct reg_block {
10594         struct block *block;
10595         struct triple_reg_set *in;
10596         struct triple_reg_set *out;
10597         int vertex;
10598 };
10599
10600 static int do_triple_set(struct triple_reg_set **head, 
10601         struct triple *member, struct triple *new_member)
10602 {
10603         struct triple_reg_set **ptr, *new;
10604         if (!member)
10605                 return 0;
10606         ptr = head;
10607         while(*ptr) {
10608                 if ((*ptr)->member == member) {
10609                         return 0;
10610                 }
10611                 ptr = &(*ptr)->next;
10612         }
10613         new = xcmalloc(sizeof(*new), "triple_set");
10614         new->member = member;
10615         new->new    = new_member;
10616         new->next   = *head;
10617         *head       = new;
10618         return 1;
10619 }
10620
10621 static void do_triple_unset(struct triple_reg_set **head, struct triple *member)
10622 {
10623         struct triple_reg_set *entry, **ptr;
10624         ptr = head;
10625         while(*ptr) {
10626                 entry = *ptr;
10627                 if (entry->member == member) {
10628                         *ptr = entry->next;
10629                         xfree(entry);
10630                         return;
10631                 }
10632                 else {
10633                         ptr = &entry->next;
10634                 }
10635         }
10636 }
10637
10638 static int in_triple(struct reg_block *rb, struct triple *in)
10639 {
10640         return do_triple_set(&rb->in, in, 0);
10641 }
10642 static void unin_triple(struct reg_block *rb, struct triple *unin)
10643 {
10644         do_triple_unset(&rb->in, unin);
10645 }
10646
10647 static int out_triple(struct reg_block *rb, struct triple *out)
10648 {
10649         return do_triple_set(&rb->out, out, 0);
10650 }
10651 static void unout_triple(struct reg_block *rb, struct triple *unout)
10652 {
10653         do_triple_unset(&rb->out, unout);
10654 }
10655
10656 static int initialize_regblock(struct reg_block *blocks,
10657         struct block *block, int vertex)
10658 {
10659         struct block_set *user;
10660         if (!block || (blocks[block->vertex].block == block)) {
10661                 return vertex;
10662         }
10663         vertex += 1;
10664         /* Renumber the blocks in a convinient fashion */
10665         block->vertex = vertex;
10666         blocks[vertex].block    = block;
10667         blocks[vertex].vertex   = vertex;
10668         for(user = block->use; user; user = user->next) {
10669                 vertex = initialize_regblock(blocks, user->member, vertex);
10670         }
10671         return vertex;
10672 }
10673
10674 static int phi_in(struct compile_state *state, struct reg_block *blocks,
10675         struct reg_block *rb, struct block *suc)
10676 {
10677         /* Read the conditional input set of a successor block
10678          * (i.e. the input to the phi nodes) and place it in the
10679          * current blocks output set.
10680          */
10681         struct block_set *set;
10682         struct triple *ptr;
10683         int edge;
10684         int done, change;
10685         change = 0;
10686         /* Find the edge I am coming in on */
10687         for(edge = 0, set = suc->use; set; set = set->next, edge++) {
10688                 if (set->member == rb->block) {
10689                         break;
10690                 }
10691         }
10692         if (!set) {
10693                 internal_error(state, 0, "Not coming on a control edge?");
10694         }
10695         for(done = 0, ptr = suc->first; !done; ptr = ptr->next) {
10696                 struct triple **slot, *expr, *ptr2;
10697                 int out_change, done2;
10698                 done = (ptr == suc->last);
10699                 if (ptr->op != OP_PHI) {
10700                         continue;
10701                 }
10702                 slot = &RHS(ptr, 0);
10703                 expr = slot[edge];
10704                 out_change = out_triple(rb, expr);
10705                 if (!out_change) {
10706                         continue;
10707                 }
10708                 /* If we don't define the variable also plast it
10709                  * in the current blocks input set.
10710                  */
10711                 ptr2 = rb->block->first;
10712                 for(done2 = 0; !done2; ptr2 = ptr2->next) {
10713                         if (ptr2 == expr) {
10714                                 break;
10715                         }
10716                         done2 = (ptr2 == rb->block->last);
10717                 }
10718                 if (!done2) {
10719                         continue;
10720                 }
10721                 change |= in_triple(rb, expr);
10722         }
10723         return change;
10724 }
10725
10726 static int reg_in(struct compile_state *state, struct reg_block *blocks,
10727         struct reg_block *rb, struct block *suc)
10728 {
10729         struct triple_reg_set *in_set;
10730         int change;
10731         change = 0;
10732         /* Read the input set of a successor block
10733          * and place it in the current blocks output set.
10734          */
10735         in_set = blocks[suc->vertex].in;
10736         for(; in_set; in_set = in_set->next) {
10737                 int out_change, done;
10738                 struct triple *first, *last, *ptr;
10739                 out_change = out_triple(rb, in_set->member);
10740                 if (!out_change) {
10741                         continue;
10742                 }
10743                 /* If we don't define the variable also place it
10744                  * in the current blocks input set.
10745                  */
10746                 first = rb->block->first;
10747                 last = rb->block->last;
10748                 done = 0;
10749                 for(ptr = first; !done; ptr = ptr->next) {
10750                         if (ptr == in_set->member) {
10751                                 break;
10752                         }
10753                         done = (ptr == last);
10754                 }
10755                 if (!done) {
10756                         continue;
10757                 }
10758                 change |= in_triple(rb, in_set->member);
10759         }
10760         change |= phi_in(state, blocks, rb, suc);
10761         return change;
10762 }
10763
10764
10765 static int use_in(struct compile_state *state, struct reg_block *rb)
10766 {
10767         /* Find the variables we use but don't define and add
10768          * it to the current blocks input set.
10769          */
10770 #warning "FIXME is this O(N^2) algorithm bad?"
10771         struct block *block;
10772         struct triple *ptr;
10773         int done;
10774         int change;
10775         block = rb->block;
10776         change = 0;
10777         for(done = 0, ptr = block->last; !done; ptr = ptr->prev) {
10778                 struct triple **expr;
10779                 done = (ptr == block->first);
10780                 /* The variable a phi function uses depends on the
10781                  * control flow, and is handled in phi_in, not
10782                  * here.
10783                  */
10784                 if (ptr->op == OP_PHI) {
10785                         continue;
10786                 }
10787                 expr = triple_rhs(state, ptr, 0);
10788                 for(;expr; expr = triple_rhs(state, ptr, expr)) {
10789                         struct triple *rhs, *test;
10790                         int tdone;
10791                         rhs = *expr;
10792                         if (!rhs) {
10793                                 continue;
10794                         }
10795                         /* See if rhs is defined in this block */
10796                         for(tdone = 0, test = ptr; !tdone; test = test->prev) {
10797                                 tdone = (test == block->first);
10798                                 if (test == rhs) {
10799                                         rhs = 0;
10800                                         break;
10801                                 }
10802                         }
10803                         /* If I still have a valid rhs add it to in */
10804                         change |= in_triple(rb, rhs);
10805                 }
10806         }
10807         return change;
10808 }
10809
10810 static struct reg_block *compute_variable_lifetimes(
10811         struct compile_state *state)
10812 {
10813         struct reg_block *blocks;
10814         int change;
10815         blocks = xcmalloc(
10816                 sizeof(*blocks)*(state->last_vertex + 1), "reg_block");
10817         initialize_regblock(blocks, state->last_block, 0);
10818         do {
10819                 int i;
10820                 change = 0;
10821                 for(i = 1; i <= state->last_vertex; i++) {
10822                         struct reg_block *rb;
10823                         rb = &blocks[i];
10824                         /* Add the left successor's input set to in */
10825                         if (rb->block->left) {
10826                                 change |= reg_in(state, blocks, rb, rb->block->left);
10827                         }
10828                         /* Add the right successor's input set to in */
10829                         if ((rb->block->right) && 
10830                                 (rb->block->right != rb->block->left)) {
10831                                 change |= reg_in(state, blocks, rb, rb->block->right);
10832                         }
10833                         /* Add use to in... */
10834                         change |= use_in(state, rb);
10835                 }
10836         } while(change);
10837         return blocks;
10838 }
10839
10840 static void free_variable_lifetimes(
10841         struct compile_state *state, struct reg_block *blocks)
10842 {
10843         int i;
10844         /* free in_set && out_set on each block */
10845         for(i = 1; i <= state->last_vertex; i++) {
10846                 struct triple_reg_set *entry, *next;
10847                 struct reg_block *rb;
10848                 rb = &blocks[i];
10849                 for(entry = rb->in; entry ; entry = next) {
10850                         next = entry->next;
10851                         do_triple_unset(&rb->in, entry->member);
10852                 }
10853                 for(entry = rb->out; entry; entry = next) {
10854                         next = entry->next;
10855                         do_triple_unset(&rb->out, entry->member);
10856                 }
10857         }
10858         xfree(blocks);
10859
10860 }
10861
10862 typedef struct triple *(*wvl_cb_t)(
10863         struct compile_state *state, 
10864         struct reg_block *blocks, struct triple_reg_set *live, 
10865         struct reg_block *rb, struct triple *ins, void *arg);
10866
10867 static void walk_variable_lifetimes(struct compile_state *state,
10868         struct reg_block *blocks, wvl_cb_t cb, void *arg)
10869 {
10870         int i;
10871         
10872         for(i = 1; i <= state->last_vertex; i++) {
10873                 struct triple_reg_set *live;
10874                 struct triple_reg_set *entry, *next;
10875                 struct triple *ptr, *prev;
10876                 struct reg_block *rb;
10877                 struct block *block;
10878                 int done;
10879
10880                 /* Get the blocks */
10881                 rb = &blocks[i];
10882                 block = rb->block;
10883
10884                 /* Copy out into live */
10885                 live = 0;
10886                 for(entry = rb->out; entry; entry = next) {
10887                         next = entry->next;
10888                         do_triple_set(&live, entry->member, entry->new);
10889                 }
10890                 /* Walk through the basic block calculating live */
10891                 for(done = 0, ptr = block->last; !done; ptr = prev) {
10892                         struct triple **expr, *result;
10893
10894                         prev = ptr->prev;
10895                         done = (ptr == block->first);
10896
10897                         /* Ensure the current definition is in live */
10898                         if (triple_is_def(state, ptr)) {
10899                                 do_triple_set(&live, ptr, 0);
10900                         }
10901
10902                         /* Inform the callback function of what is
10903                          * going on.
10904                          */
10905                         result = cb(state, blocks, live, rb, ptr, arg);
10906                         
10907                         /* Remove the current definition from live */
10908                         do_triple_unset(&live, ptr);
10909
10910                         /* If the current instruction was deleted continue */
10911                         if (!result) {
10912                                 if (block->last == ptr) {
10913                                         block->last = prev;
10914                                 }
10915                                 continue;
10916                         }
10917                         
10918
10919                         /* Add the current uses to live.
10920                          *
10921                          * It is safe to skip phi functions because they do
10922                          * not have any block local uses, and the block
10923                          * output sets already properly account for what
10924                          * control flow depedent uses phi functions do have.
10925                          */
10926                         if (ptr->op == OP_PHI) {
10927                                 continue;
10928                         }
10929                         expr = triple_rhs(state, ptr, 0);
10930                         for(;expr; expr = triple_rhs(state, ptr, expr)) {
10931                                 /* If the triple is not a definition skip it. */
10932                                 if (!*expr || !triple_is_def(state, *expr)) {
10933                                         continue;
10934                                 }
10935                                 do_triple_set(&live, *expr, 0);
10936                         }
10937                 }
10938                 /* Free live */
10939                 for(entry = live; entry; entry = next) {
10940                         next = entry->next;
10941                         do_triple_unset(&live, entry->member);
10942                 }
10943         }
10944 }
10945
10946 static int count_triples(struct compile_state *state)
10947 {
10948         struct triple *first, *ins;
10949         int triples = 0;
10950         first = RHS(state->main_function, 0);
10951         ins = first;
10952         do {
10953                 triples++;
10954                 ins = ins->next;
10955         } while (ins != first);
10956         return triples;
10957 }
10958 struct dead_triple {
10959         struct triple *triple;
10960         struct dead_triple *work_next;
10961         struct block *block;
10962         int color;
10963         int flags;
10964 #define TRIPLE_FLAG_ALIVE 1
10965 };
10966
10967
10968 static void awaken(
10969         struct compile_state *state,
10970         struct dead_triple *dtriple, struct triple **expr,
10971         struct dead_triple ***work_list_tail)
10972 {
10973         struct triple *triple;
10974         struct dead_triple *dt;
10975         if (!expr) {
10976                 return;
10977         }
10978         triple = *expr;
10979         if (!triple) {
10980                 return;
10981         }
10982         if (triple->id <= 0)  {
10983                 internal_error(state, triple, "bad triple id: %d",
10984                         triple->id);
10985         }
10986         if (triple->op == OP_NOOP) {
10987                 internal_warning(state, triple, "awakening noop?");
10988                 return;
10989         }
10990         dt = &dtriple[triple->id];
10991         if (!(dt->flags & TRIPLE_FLAG_ALIVE)) {
10992                 dt->flags |= TRIPLE_FLAG_ALIVE;
10993                 if (!dt->work_next) {
10994                         **work_list_tail = dt;
10995                         *work_list_tail = &dt->work_next;
10996                 }
10997         }
10998 }
10999
11000 static void eliminate_inefectual_code(struct compile_state *state)
11001 {
11002         struct block *block;
11003         struct dead_triple *dtriple, *work_list, **work_list_tail, *dt;
11004         int triples, i;
11005         struct triple *first, *ins;
11006
11007         /* Setup the work list */
11008         work_list = 0;
11009         work_list_tail = &work_list;
11010
11011         first = RHS(state->main_function, 0);
11012
11013         /* Count how many triples I have */
11014         triples = count_triples(state);
11015
11016         /* Now put then in an array and mark all of the triples dead */
11017         dtriple = xcmalloc(sizeof(*dtriple) * (triples + 1), "dtriples");
11018         
11019         ins = first;
11020         i = 1;
11021         block = 0;
11022         do {
11023                 if (ins->op == OP_LABEL) {
11024                         block = ins->u.block;
11025                 }
11026                 dtriple[i].triple = ins;
11027                 dtriple[i].block  = block;
11028                 dtriple[i].flags  = 0;
11029                 dtriple[i].color  = ins->id;
11030                 ins->id = i;
11031                 /* See if it is an operation we always keep */
11032 #warning "FIXME handle the case of killing a branch instruction"
11033                 if (!triple_is_pure(state, ins) || triple_is_branch(state, ins)) {
11034                         awaken(state, dtriple, &ins, &work_list_tail);
11035                 }
11036                 i++;
11037                 ins = ins->next;
11038         } while(ins != first);
11039         while(work_list) {
11040                 struct dead_triple *dt;
11041                 struct block_set *user;
11042                 struct triple **expr;
11043                 dt = work_list;
11044                 work_list = dt->work_next;
11045                 if (!work_list) {
11046                         work_list_tail = &work_list;
11047                 }
11048                 /* Wake up the data depencencies of this triple */
11049                 expr = 0;
11050                 do {
11051                         expr = triple_rhs(state, dt->triple, expr);
11052                         awaken(state, dtriple, expr, &work_list_tail);
11053                 } while(expr);
11054                 do {
11055                         expr = triple_lhs(state, dt->triple, expr);
11056                         awaken(state, dtriple, expr, &work_list_tail);
11057                 } while(expr);
11058                 do {
11059                         expr = triple_misc(state, dt->triple, expr);
11060                         awaken(state, dtriple, expr, &work_list_tail);
11061                 } while(expr);
11062                 /* Wake up the forward control dependencies */
11063                 do {
11064                         expr = triple_targ(state, dt->triple, expr);
11065                         awaken(state, dtriple, expr, &work_list_tail);
11066                 } while(expr);
11067                 /* Wake up the reverse control dependencies of this triple */
11068                 for(user = dt->block->ipdomfrontier; user; user = user->next) {
11069                         awaken(state, dtriple, &user->member->last, &work_list_tail);
11070                 }
11071         }
11072         for(dt = &dtriple[1]; dt <= &dtriple[triples]; dt++) {
11073                 if ((dt->triple->op == OP_NOOP) && 
11074                         (dt->flags & TRIPLE_FLAG_ALIVE)) {
11075                         internal_error(state, dt->triple, "noop effective?");
11076                 }
11077                 dt->triple->id = dt->color;     /* Restore the color */
11078                 if (!(dt->flags & TRIPLE_FLAG_ALIVE)) {
11079 #warning "FIXME handle the case of killing a basic block"
11080                         if (dt->block->first == dt->triple) {
11081                                 continue;
11082                         }
11083                         if (dt->block->last == dt->triple) {
11084                                 dt->block->last = dt->triple->prev;
11085                         }
11086                         release_triple(state, dt->triple);
11087                 }
11088         }
11089         xfree(dtriple);
11090 }
11091
11092
11093 static void insert_mandatory_copies(struct compile_state *state)
11094 {
11095         struct triple *ins, *first;
11096
11097         /* The object is with a minimum of inserted copies,
11098          * to resolve in fundamental register conflicts between
11099          * register value producers and consumers.
11100          * Theoretically we may be greater than minimal when we
11101          * are inserting copies before instructions but that
11102          * case should be rare.
11103          */
11104         first = RHS(state->main_function, 0);
11105         ins = first;
11106         do {
11107                 struct triple_set *entry, *next;
11108                 struct triple *tmp;
11109                 struct reg_info info;
11110                 unsigned reg, regcm;
11111                 int do_post_copy, do_pre_copy;
11112                 tmp = 0;
11113                 if (!triple_is_def(state, ins)) {
11114                         goto next;
11115                 }
11116                 /* Find the architecture specific color information */
11117                 info = arch_reg_lhs(state, ins, 0);
11118                 if (info.reg >= MAX_REGISTERS) {
11119                         info.reg = REG_UNSET;
11120                 }
11121                 
11122                 reg = REG_UNSET;
11123                 regcm = arch_type_to_regcm(state, ins->type);
11124                 do_post_copy = do_pre_copy = 0;
11125
11126                 /* Walk through the uses of ins and check for conflicts */
11127                 for(entry = ins->use; entry; entry = next) {
11128                         struct reg_info rinfo;
11129                         int i;
11130                         next = entry->next;
11131                         i = find_rhs_use(state, entry->member, ins);
11132                         if (i < 0) {
11133                                 continue;
11134                         }
11135                         
11136                         /* Find the users color requirements */
11137                         rinfo = arch_reg_rhs(state, entry->member, i);
11138                         if (rinfo.reg >= MAX_REGISTERS) {
11139                                 rinfo.reg = REG_UNSET;
11140                         }
11141                         
11142                         /* See if I need a pre_copy */
11143                         if (rinfo.reg != REG_UNSET) {
11144                                 if ((reg != REG_UNSET) && (reg != rinfo.reg)) {
11145                                         do_pre_copy = 1;
11146                                 }
11147                                 reg = rinfo.reg;
11148                         }
11149                         regcm &= rinfo.regcm;
11150                         regcm = arch_regcm_normalize(state, regcm);
11151                         if (regcm == 0) {
11152                                 do_pre_copy = 1;
11153                         }
11154                 }
11155                 do_post_copy =
11156                         !do_pre_copy &&
11157                         (((info.reg != REG_UNSET) && 
11158                                 (reg != REG_UNSET) &&
11159                                 (info.reg != reg)) ||
11160                         ((info.regcm & regcm) == 0));
11161
11162                 reg = info.reg;
11163                 regcm = info.regcm;
11164                 /* Walk through the uses of insert and do a pre_copy or see if a post_copy is warranted */
11165                 for(entry = ins->use; entry; entry = next) {
11166                         struct reg_info rinfo;
11167                         int i;
11168                         next = entry->next;
11169                         i = find_rhs_use(state, entry->member, ins);
11170                         if (i < 0) {
11171                                 continue;
11172                         }
11173                         
11174                         /* Find the users color requirements */
11175                         rinfo = arch_reg_rhs(state, entry->member, i);
11176                         if (rinfo.reg >= MAX_REGISTERS) {
11177                                 rinfo.reg = REG_UNSET;
11178                         }
11179
11180                         /* Now see if it is time to do the pre_copy */
11181                         if (rinfo.reg != REG_UNSET) {
11182                                 if (((reg != REG_UNSET) && (reg != rinfo.reg)) ||
11183                                         ((regcm & rinfo.regcm) == 0) ||
11184                                         /* Don't let a mandatory coalesce sneak
11185                                          * into a operation that is marked to prevent
11186                                          * coalescing.
11187                                          */
11188                                         ((reg != REG_UNNEEDED) &&
11189                                         ((ins->id & TRIPLE_FLAG_POST_SPLIT) ||
11190                                         (entry->member->id & TRIPLE_FLAG_PRE_SPLIT)))
11191                                         ) {
11192                                         if (do_pre_copy) {
11193                                                 struct triple *user;
11194                                                 user = entry->member;
11195                                                 if (RHS(user, i) != ins) {
11196                                                         internal_error(state, user, "bad rhs");
11197                                                 }
11198                                                 tmp = pre_copy(state, user, i);
11199                                                 continue;
11200                                         } else {
11201                                                 do_post_copy = 1;
11202                                         }
11203                                 }
11204                                 reg = rinfo.reg;
11205                         }
11206                         if ((regcm & rinfo.regcm) == 0) {
11207                                 if (do_pre_copy) {
11208                                         struct triple *user;
11209                                         user = entry->member;
11210                                         if (RHS(user, i) != ins) {
11211                                                 internal_error(state, user, "bad rhs");
11212                                         }
11213                                         tmp = pre_copy(state, user, i);
11214                                         continue;
11215                                 } else {
11216                                         do_post_copy = 1;
11217                                 }
11218                         }
11219                         regcm &= rinfo.regcm;
11220                         
11221                 }
11222                 if (do_post_copy) {
11223                         struct reg_info pre, post;
11224                         tmp = post_copy(state, ins);
11225                         pre = arch_reg_lhs(state, ins, 0);
11226                         post = arch_reg_lhs(state, tmp, 0);
11227                         if ((pre.reg == post.reg) && (pre.regcm == post.regcm)) {
11228                                 internal_error(state, tmp, "useless copy");
11229                         }
11230                 }
11231         next:
11232                 ins = ins->next;
11233         } while(ins != first);
11234 }
11235
11236
11237 struct live_range_edge;
11238 struct live_range_def;
11239 struct live_range {
11240         struct live_range_edge *edges;
11241         struct live_range_def *defs;
11242 /* Note. The list pointed to by defs is kept in order.
11243  * That is baring splits in the flow control
11244  * defs dominates defs->next wich dominates defs->next->next
11245  * etc.
11246  */
11247         unsigned color;
11248         unsigned classes;
11249         unsigned degree;
11250         unsigned length;
11251         struct live_range *group_next, **group_prev;
11252 };
11253
11254 struct live_range_edge {
11255         struct live_range_edge *next;
11256         struct live_range *node;
11257 };
11258
11259 struct live_range_def {
11260         struct live_range_def *next;
11261         struct live_range_def *prev;
11262         struct live_range *lr;
11263         struct triple *def;
11264         unsigned orig_id;
11265 };
11266
11267 #define LRE_HASH_SIZE 2048
11268 struct lre_hash {
11269         struct lre_hash *next;
11270         struct live_range *left;
11271         struct live_range *right;
11272 };
11273
11274
11275 struct reg_state {
11276         struct lre_hash *hash[LRE_HASH_SIZE];
11277         struct reg_block *blocks;
11278         struct live_range_def *lrd;
11279         struct live_range *lr;
11280         struct live_range *low, **low_tail;
11281         struct live_range *high, **high_tail;
11282         unsigned defs;
11283         unsigned ranges;
11284         int passes, max_passes;
11285 #define MAX_ALLOCATION_PASSES 100
11286 };
11287
11288
11289 static unsigned regc_max_size(struct compile_state *state, int classes)
11290 {
11291         unsigned max_size;
11292         int i;
11293         max_size = 0;
11294         for(i = 0; i < MAX_REGC; i++) {
11295                 if (classes & (1 << i)) {
11296                         unsigned size;
11297                         size = arch_regc_size(state, i);
11298                         if (size > max_size) {
11299                                 max_size = size;
11300                         }
11301                 }
11302         }
11303         return max_size;
11304 }
11305
11306 static int reg_is_reg(struct compile_state *state, int reg1, int reg2)
11307 {
11308         unsigned equivs[MAX_REG_EQUIVS];
11309         int i;
11310         if ((reg1 < 0) || (reg1 >= MAX_REGISTERS)) {
11311                 internal_error(state, 0, "invalid register");
11312         }
11313         if ((reg2 < 0) || (reg2 >= MAX_REGISTERS)) {
11314                 internal_error(state, 0, "invalid register");
11315         }
11316         arch_reg_equivs(state, equivs, reg1);
11317         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
11318                 if (equivs[i] == reg2) {
11319                         return 1;
11320                 }
11321         }
11322         return 0;
11323 }
11324
11325 static void reg_fill_used(struct compile_state *state, char *used, int reg)
11326 {
11327         unsigned equivs[MAX_REG_EQUIVS];
11328         int i;
11329         if (reg == REG_UNNEEDED) {
11330                 return;
11331         }
11332         arch_reg_equivs(state, equivs, reg);
11333         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
11334                 used[equivs[i]] = 1;
11335         }
11336         return;
11337 }
11338
11339 static void reg_inc_used(struct compile_state *state, char *used, int reg)
11340 {
11341         unsigned equivs[MAX_REG_EQUIVS];
11342         int i;
11343         if (reg == REG_UNNEEDED) {
11344                 return;
11345         }
11346         arch_reg_equivs(state, equivs, reg);
11347         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
11348                 used[equivs[i]] += 1;
11349         }
11350         return;
11351 }
11352
11353 static unsigned int hash_live_edge(
11354         struct live_range *left, struct live_range *right)
11355 {
11356         unsigned int hash, val;
11357         unsigned long lval, rval;
11358         lval = ((unsigned long)left)/sizeof(struct live_range);
11359         rval = ((unsigned long)right)/sizeof(struct live_range);
11360         hash = 0;
11361         while(lval) {
11362                 val = lval & 0xff;
11363                 lval >>= 8;
11364                 hash = (hash *263) + val;
11365         }
11366         while(rval) {
11367                 val = rval & 0xff;
11368                 rval >>= 8;
11369                 hash = (hash *263) + val;
11370         }
11371         hash = hash & (LRE_HASH_SIZE - 1);
11372         return hash;
11373 }
11374
11375 static struct lre_hash **lre_probe(struct reg_state *rstate,
11376         struct live_range *left, struct live_range *right)
11377 {
11378         struct lre_hash **ptr;
11379         unsigned int index;
11380         /* Ensure left <= right */
11381         if (left > right) {
11382                 struct live_range *tmp;
11383                 tmp = left;
11384                 left = right;
11385                 right = tmp;
11386         }
11387         index = hash_live_edge(left, right);
11388         
11389         ptr = &rstate->hash[index];
11390         while((*ptr) && ((*ptr)->left != left) && ((*ptr)->right != right)) {
11391                 ptr = &(*ptr)->next;
11392         }
11393         return ptr;
11394 }
11395
11396 static int interfere(struct reg_state *rstate,
11397         struct live_range *left, struct live_range *right)
11398 {
11399         struct lre_hash **ptr;
11400         ptr = lre_probe(rstate, left, right);
11401         return ptr && *ptr;
11402 }
11403
11404 static void add_live_edge(struct reg_state *rstate, 
11405         struct live_range *left, struct live_range *right)
11406 {
11407         /* FIXME the memory allocation overhead is noticeable here... */
11408         struct lre_hash **ptr, *new_hash;
11409         struct live_range_edge *edge;
11410
11411         if (left == right) {
11412                 return;
11413         }
11414         if ((left == &rstate->lr[0]) || (right == &rstate->lr[0])) {
11415                 return;
11416         }
11417         /* Ensure left <= right */
11418         if (left > right) {
11419                 struct live_range *tmp;
11420                 tmp = left;
11421                 left = right;
11422                 right = tmp;
11423         }
11424         ptr = lre_probe(rstate, left, right);
11425         if (*ptr) {
11426                 return;
11427         }
11428         new_hash = xmalloc(sizeof(*new_hash), "lre_hash");
11429         new_hash->next  = *ptr;
11430         new_hash->left  = left;
11431         new_hash->right = right;
11432         *ptr = new_hash;
11433
11434         edge = xmalloc(sizeof(*edge), "live_range_edge");
11435         edge->next   = left->edges;
11436         edge->node   = right;
11437         left->edges  = edge;
11438         left->degree += 1;
11439         
11440         edge = xmalloc(sizeof(*edge), "live_range_edge");
11441         edge->next    = right->edges;
11442         edge->node    = left;
11443         right->edges  = edge;
11444         right->degree += 1;
11445 }
11446
11447 static void remove_live_edge(struct reg_state *rstate,
11448         struct live_range *left, struct live_range *right)
11449 {
11450         struct live_range_edge *edge, **ptr;
11451         struct lre_hash **hptr, *entry;
11452         hptr = lre_probe(rstate, left, right);
11453         if (!hptr || !*hptr) {
11454                 return;
11455         }
11456         entry = *hptr;
11457         *hptr = entry->next;
11458         xfree(entry);
11459
11460         for(ptr = &left->edges; *ptr; ptr = &(*ptr)->next) {
11461                 edge = *ptr;
11462                 if (edge->node == right) {
11463                         *ptr = edge->next;
11464                         memset(edge, 0, sizeof(*edge));
11465                         xfree(edge);
11466                         break;
11467                 }
11468         }
11469         for(ptr = &right->edges; *ptr; ptr = &(*ptr)->next) {
11470                 edge = *ptr;
11471                 if (edge->node == left) {
11472                         *ptr = edge->next;
11473                         memset(edge, 0, sizeof(*edge));
11474                         xfree(edge);
11475                         break;
11476                 }
11477         }
11478 }
11479
11480 static void remove_live_edges(struct reg_state *rstate, struct live_range *range)
11481 {
11482         struct live_range_edge *edge, *next;
11483         for(edge = range->edges; edge; edge = next) {
11484                 next = edge->next;
11485                 remove_live_edge(rstate, range, edge->node);
11486         }
11487 }
11488
11489
11490 /* Interference graph...
11491  * 
11492  * new(n) --- Return a graph with n nodes but no edges.
11493  * add(g,x,y) --- Return a graph including g with an between x and y
11494  * interfere(g, x, y) --- Return true if there exists an edge between the nodes
11495  *                x and y in the graph g
11496  * degree(g, x) --- Return the degree of the node x in the graph g
11497  * neighbors(g, x, f) --- Apply function f to each neighbor of node x in the graph g
11498  *
11499  * Implement with a hash table && a set of adjcency vectors.
11500  * The hash table supports constant time implementations of add and interfere.
11501  * The adjacency vectors support an efficient implementation of neighbors.
11502  */
11503
11504 /* 
11505  *     +---------------------------------------------------+
11506  *     |         +--------------+                          |
11507  *     v         v              |                          |
11508  * renumber -> build graph -> colalesce -> spill_costs -> simplify -> select 
11509  *
11510  * -- In simplify implment optimistic coloring... (No backtracking)
11511  * -- Implement Rematerialization it is the only form of spilling we can perform
11512  *    Essentially this means dropping a constant from a register because
11513  *    we can regenerate it later.
11514  *
11515  * --- Very conservative colalescing (don't colalesce just mark the opportunities)
11516  *     coalesce at phi points...
11517  * --- Bias coloring if at all possible do the coalesing a compile time.
11518  *
11519  *
11520  */
11521
11522 static void different_colored(
11523         struct compile_state *state, struct reg_state *rstate, 
11524         struct triple *parent, struct triple *ins)
11525 {
11526         struct live_range *lr;
11527         struct triple **expr;
11528         lr = rstate->lrd[ins->id].lr;
11529         expr = triple_rhs(state, ins, 0);
11530         for(;expr; expr = triple_rhs(state, ins, expr)) {
11531                 struct live_range *lr2;
11532                 if (!*expr || (*expr == parent) || (*expr == ins)) {
11533                         continue;
11534                 }
11535                 lr2 = rstate->lrd[(*expr)->id].lr;
11536                 if (lr->color == lr2->color) {
11537                         internal_error(state, ins, "live range too big");
11538                 }
11539         }
11540 }
11541
11542
11543 static struct live_range *coalesce_ranges(
11544         struct compile_state *state, struct reg_state *rstate,
11545         struct live_range *lr1, struct live_range *lr2)
11546 {
11547         struct live_range_def *head, *mid1, *mid2, *end, *lrd;
11548         unsigned color;
11549         unsigned classes;
11550         if (lr1 == lr2) {
11551                 return lr1;
11552         }
11553         if (!lr1->defs || !lr2->defs) {
11554                 internal_error(state, 0,
11555                         "cannot coalese dead live ranges");
11556         }
11557         if ((lr1->color == REG_UNNEEDED) ||
11558                 (lr2->color == REG_UNNEEDED)) {
11559                 internal_error(state, 0, 
11560                         "cannot coalesce live ranges without a possible color");
11561         }
11562         if ((lr1->color != lr2->color) &&
11563                 (lr1->color != REG_UNSET) &&
11564                 (lr2->color != REG_UNSET)) {
11565                 internal_error(state, lr1->defs->def, 
11566                         "cannot coalesce live ranges of different colors");
11567         }
11568         color = lr1->color;
11569         if (color == REG_UNSET) {
11570                 color = lr2->color;
11571         }
11572         classes = lr1->classes & lr2->classes;
11573         if (!classes) {
11574                 internal_error(state, lr1->defs->def,
11575                         "cannot coalesce live ranges with dissimilar register classes");
11576         }
11577         /* If there is a clear dominate live range put it in lr1,
11578          * For purposes of this test phi functions are
11579          * considered dominated by the definitions that feed into
11580          * them. 
11581          */
11582         if ((lr1->defs->prev->def->op == OP_PHI) ||
11583                 ((lr2->defs->prev->def->op != OP_PHI) &&
11584                 tdominates(state, lr2->defs->def, lr1->defs->def))) {
11585                 struct live_range *tmp;
11586                 tmp = lr1;
11587                 lr1 = lr2;
11588                 lr2 = tmp;
11589         }
11590 #if 0
11591         if (lr1->defs->orig_id  & TRIPLE_FLAG_POST_SPLIT) {
11592                 fprintf(stderr, "lr1 post\n");
11593         }
11594         if (lr1->defs->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
11595                 fprintf(stderr, "lr1 pre\n");
11596         }
11597         if (lr2->defs->orig_id  & TRIPLE_FLAG_POST_SPLIT) {
11598                 fprintf(stderr, "lr2 post\n");
11599         }
11600         if (lr2->defs->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
11601                 fprintf(stderr, "lr2 pre\n");
11602         }
11603 #endif
11604 #if 0
11605         fprintf(stderr, "coalesce color1(%p): %3d color2(%p) %3d\n",
11606                 lr1->defs->def,
11607                 lr1->color,
11608                 lr2->defs->def,
11609                 lr2->color);
11610 #endif
11611         
11612         lr1->classes = classes;
11613         /* Append lr2 onto lr1 */
11614 #warning "FIXME should this be a merge instead of a splice?"
11615         head = lr1->defs;
11616         mid1 = lr1->defs->prev;
11617         mid2 = lr2->defs;
11618         end  = lr2->defs->prev;
11619         
11620         head->prev = end;
11621         end->next  = head;
11622
11623         mid1->next = mid2;
11624         mid2->prev = mid1;
11625
11626         /* Fixup the live range in the added live range defs */
11627         lrd = head;
11628         do {
11629                 lrd->lr = lr1;
11630                 lrd = lrd->next;
11631         } while(lrd != head);
11632
11633         /* Mark lr2 as free. */
11634         lr2->defs = 0;
11635         lr2->color = REG_UNNEEDED;
11636         lr2->classes = 0;
11637
11638         if (!lr1->defs) {
11639                 internal_error(state, 0, "lr1->defs == 0 ?");
11640         }
11641
11642         lr1->color   = color;
11643         lr1->classes = classes;
11644
11645         return lr1;
11646 }
11647
11648 static struct live_range_def *live_range_head(
11649         struct compile_state *state, struct live_range *lr,
11650         struct live_range_def *last)
11651 {
11652         struct live_range_def *result;
11653         result = 0;
11654         if (last == 0) {
11655                 result = lr->defs;
11656         }
11657         else if (!tdominates(state, lr->defs->def, last->next->def)) {
11658                 result = last->next;
11659         }
11660         return result;
11661 }
11662
11663 static struct live_range_def *live_range_end(
11664         struct compile_state *state, struct live_range *lr,
11665         struct live_range_def *last)
11666 {
11667         struct live_range_def *result;
11668         result = 0;
11669         if (last == 0) {
11670                 result = lr->defs->prev;
11671         }
11672         else if (!tdominates(state, last->prev->def, lr->defs->prev->def)) {
11673                 result = last->prev;
11674         }
11675         return result;
11676 }
11677
11678
11679 static void initialize_live_ranges(
11680         struct compile_state *state, struct reg_state *rstate)
11681 {
11682         struct triple *ins, *first;
11683         size_t count, size;
11684         int i, j;
11685
11686         first = RHS(state->main_function, 0);
11687         /* First count how many instructions I have.
11688          */
11689         count = count_triples(state);
11690         /* Potentially I need one live range definitions for each
11691          * instruction, plus an extra for the split routines.
11692          */
11693         rstate->defs = count + 1;
11694         /* Potentially I need one live range for each instruction
11695          * plus an extra for the dummy live range.
11696          */
11697         rstate->ranges = count + 1;
11698         size = sizeof(rstate->lrd[0]) * rstate->defs;
11699         rstate->lrd = xcmalloc(size, "live_range_def");
11700         size = sizeof(rstate->lr[0]) * rstate->ranges;
11701         rstate->lr  = xcmalloc(size, "live_range");
11702
11703         /* Setup the dummy live range */
11704         rstate->lr[0].classes = 0;
11705         rstate->lr[0].color = REG_UNSET;
11706         rstate->lr[0].defs = 0;
11707         i = j = 0;
11708         ins = first;
11709         do {
11710                 /* If the triple is a variable give it a live range */
11711                 if (triple_is_def(state, ins)) {
11712                         struct reg_info info;
11713                         /* Find the architecture specific color information */
11714                         info = find_def_color(state, ins);
11715
11716                         i++;
11717                         rstate->lr[i].defs    = &rstate->lrd[j];
11718                         rstate->lr[i].color   = info.reg;
11719                         rstate->lr[i].classes = info.regcm;
11720                         rstate->lr[i].degree  = 0;
11721                         rstate->lrd[j].lr = &rstate->lr[i];
11722                 } 
11723                 /* Otherwise give the triple the dummy live range. */
11724                 else {
11725                         rstate->lrd[j].lr = &rstate->lr[0];
11726                 }
11727
11728                 /* Initalize the live_range_def */
11729                 rstate->lrd[j].next    = &rstate->lrd[j];
11730                 rstate->lrd[j].prev    = &rstate->lrd[j];
11731                 rstate->lrd[j].def     = ins;
11732                 rstate->lrd[j].orig_id = ins->id;
11733                 ins->id = j;
11734
11735                 j++;
11736                 ins = ins->next;
11737         } while(ins != first);
11738         rstate->ranges = i;
11739         rstate->defs -= 1;
11740
11741         /* Make a second pass to handle achitecture specific register
11742          * constraints.
11743          */
11744         ins = first;
11745         do {
11746                 int zlhs, zrhs, i, j;
11747                 if (ins->id > rstate->defs) {
11748                         internal_error(state, ins, "bad id");
11749                 }
11750                 
11751                 /* Walk through the template of ins and coalesce live ranges */
11752                 zlhs = TRIPLE_LHS(ins->sizes);
11753                 if ((zlhs == 0) && triple_is_def(state, ins)) {
11754                         zlhs = 1;
11755                 }
11756                 zrhs = TRIPLE_RHS(ins->sizes);
11757                 
11758                 for(i = 0; i < zlhs; i++) {
11759                         struct reg_info linfo;
11760                         struct live_range_def *lhs;
11761                         linfo = arch_reg_lhs(state, ins, i);
11762                         if (linfo.reg < MAX_REGISTERS) {
11763                                 continue;
11764                         }
11765                         if (triple_is_def(state, ins)) {
11766                                 lhs = &rstate->lrd[ins->id];
11767                         } else {
11768                                 lhs = &rstate->lrd[LHS(ins, i)->id];
11769                         }
11770                         for(j = 0; j < zrhs; j++) {
11771                                 struct reg_info rinfo;
11772                                 struct live_range_def *rhs;
11773                                 rinfo = arch_reg_rhs(state, ins, j);
11774                                 if (rinfo.reg < MAX_REGISTERS) {
11775                                         continue;
11776                                 }
11777                                 rhs = &rstate->lrd[RHS(ins, i)->id];
11778                                 if (rinfo.reg == linfo.reg) {
11779                                         coalesce_ranges(state, rstate, 
11780                                                 lhs->lr, rhs->lr);
11781                                 }
11782                         }
11783                 }
11784                 ins = ins->next;
11785         } while(ins != first);
11786 }
11787
11788 static struct triple *graph_ins(
11789         struct compile_state *state, 
11790         struct reg_block *blocks, struct triple_reg_set *live, 
11791         struct reg_block *rb, struct triple *ins, void *arg)
11792 {
11793         struct reg_state *rstate = arg;
11794         struct live_range *def;
11795         struct triple_reg_set *entry;
11796
11797         /* If the triple is not a definition
11798          * we do not have a definition to add to
11799          * the interference graph.
11800          */
11801         if (!triple_is_def(state, ins)) {
11802                 return ins;
11803         }
11804         def = rstate->lrd[ins->id].lr;
11805         
11806         /* Create an edge between ins and everything that is
11807          * alive, unless the live_range cannot share
11808          * a physical register with ins.
11809          */
11810         for(entry = live; entry; entry = entry->next) {
11811                 struct live_range *lr;
11812                 if ((entry->member->id < 0) || (entry->member->id > rstate->defs)) {
11813                         internal_error(state, 0, "bad entry?");
11814                 }
11815                 lr = rstate->lrd[entry->member->id].lr;
11816                 if (def == lr) {
11817                         continue;
11818                 }
11819                 if (!arch_regcm_intersect(def->classes, lr->classes)) {
11820                         continue;
11821                 }
11822                 add_live_edge(rstate, def, lr);
11823         }
11824         return ins;
11825 }
11826
11827
11828 static struct triple *print_interference_ins(
11829         struct compile_state *state, 
11830         struct reg_block *blocks, struct triple_reg_set *live, 
11831         struct reg_block *rb, struct triple *ins, void *arg)
11832 {
11833         struct reg_state *rstate = arg;
11834         struct live_range *lr;
11835
11836         lr = rstate->lrd[ins->id].lr;
11837         display_triple(stdout, ins);
11838
11839         if (lr->defs) {
11840                 struct live_range_def *lrd;
11841                 printf("       range:");
11842                 lrd = lr->defs;
11843                 do {
11844                         printf(" %-10p", lrd->def);
11845                         lrd = lrd->next;
11846                 } while(lrd != lr->defs);
11847                 printf("\n");
11848         }
11849         if (live) {
11850                 struct triple_reg_set *entry;
11851                 printf("        live:");
11852                 for(entry = live; entry; entry = entry->next) {
11853                         printf(" %-10p", entry->member);
11854                 }
11855                 printf("\n");
11856         }
11857         if (lr->edges) {
11858                 struct live_range_edge *entry;
11859                 printf("       edges:");
11860                 for(entry = lr->edges; entry; entry = entry->next) {
11861                         struct live_range_def *lrd;
11862                         lrd = entry->node->defs;
11863                         do {
11864                                 printf(" %-10p", lrd->def);
11865                                 lrd = lrd->next;
11866                         } while(lrd != entry->node->defs);
11867                         printf("|");
11868                 }
11869                 printf("\n");
11870         }
11871         if (triple_is_branch(state, ins)) {
11872                 printf("\n");
11873         }
11874         return ins;
11875 }
11876
11877 static int coalesce_live_ranges(
11878         struct compile_state *state, struct reg_state *rstate)
11879 {
11880         /* At the point where a value is moved from one
11881          * register to another that value requires two
11882          * registers, thus increasing register pressure.
11883          * Live range coaleescing reduces the register
11884          * pressure by keeping a value in one register
11885          * longer.
11886          *
11887          * In the case of a phi function all paths leading
11888          * into it must be allocated to the same register
11889          * otherwise the phi function may not be removed.
11890          *
11891          * Forcing a value to stay in a single register
11892          * for an extended period of time does have
11893          * limitations when applied to non homogenous
11894          * register pool.  
11895          *
11896          * The two cases I have identified are:
11897          * 1) Two forced register assignments may
11898          *    collide.
11899          * 2) Registers may go unused because they
11900          *    are only good for storing the value
11901          *    and not manipulating it.
11902          *
11903          * Because of this I need to split live ranges,
11904          * even outside of the context of coalesced live
11905          * ranges.  The need to split live ranges does
11906          * impose some constraints on live range coalescing.
11907          *
11908          * - Live ranges may not be coalesced across phi
11909          *   functions.  This creates a 2 headed live
11910          *   range that cannot be sanely split.
11911          *
11912          * - phi functions (coalesced in initialize_live_ranges) 
11913          *   are handled as pre split live ranges so we will
11914          *   never attempt to split them.
11915          */
11916         int coalesced;
11917         int i;
11918
11919         coalesced = 0;
11920         for(i = 0; i <= rstate->ranges; i++) {
11921                 struct live_range *lr1;
11922                 struct live_range_def *lrd1;
11923                 lr1 = &rstate->lr[i];
11924                 if (!lr1->defs) {
11925                         continue;
11926                 }
11927                 lrd1 = live_range_end(state, lr1, 0);
11928                 for(; lrd1; lrd1 = live_range_end(state, lr1, lrd1)) {
11929                         struct triple_set *set;
11930                         if (lrd1->def->op != OP_COPY) {
11931                                 continue;
11932                         }
11933                         /* Skip copies that are the result of a live range split. */
11934                         if (lrd1->orig_id & TRIPLE_FLAG_POST_SPLIT) {
11935                                 continue;
11936                         }
11937                         for(set = lrd1->def->use; set; set = set->next) {
11938                                 struct live_range_def *lrd2;
11939                                 struct live_range *lr2, *res;
11940
11941                                 lrd2 = &rstate->lrd[set->member->id];
11942
11943                                 /* Don't coalesce with instructions
11944                                  * that are the result of a live range
11945                                  * split.
11946                                  */
11947                                 if (lrd2->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
11948                                         continue;
11949                                 }
11950                                 lr2 = rstate->lrd[set->member->id].lr;
11951                                 if (lr1 == lr2) {
11952                                         continue;
11953                                 }
11954                                 if ((lr1->color != lr2->color) &&
11955                                         (lr1->color != REG_UNSET) &&
11956                                         (lr2->color != REG_UNSET)) {
11957                                         continue;
11958                                 }
11959                                 if ((lr1->classes & lr2->classes) == 0) {
11960                                         continue;
11961                                 }
11962                                 
11963                                 if (interfere(rstate, lr1, lr2)) {
11964                                         continue;
11965                                 }
11966                                 
11967                                 res = coalesce_ranges(state, rstate, lr1, lr2);
11968                                 coalesced += 1;
11969                                 if (res != lr1) {
11970                                         goto next;
11971                                 }
11972                         }
11973                 }
11974         next:
11975         }
11976         return coalesced;
11977 }
11978
11979
11980 struct coalesce_conflict {
11981         struct triple *ins;
11982         int index;
11983 };
11984 static struct triple *spot_coalesce_conflict(struct compile_state *state,
11985         struct reg_block *blocks, struct triple_reg_set *live,
11986         struct reg_block *rb, struct triple *ins, void *arg)
11987 {
11988         struct coalesce_conflict *conflict = arg;
11989         int zlhs, zrhs, i, j;
11990         int found;
11991
11992         /* See if we have a mandatory coalesce operation between
11993          * a lhs and a rhs value.  If so and the rhs value is also
11994          * alive then this triple needs to be pre copied.  Otherwise
11995          * we would have two definitions in the same live range simultaneously
11996          * alive.
11997          */
11998         found = -1;
11999         zlhs = TRIPLE_LHS(ins->sizes);
12000         if ((zlhs == 0) && triple_is_def(state, ins)) {
12001                 zlhs = 1;
12002         }
12003         zrhs = TRIPLE_RHS(ins->sizes);
12004         for(i = 0; (i < zlhs) && (found == -1); i++) {
12005                 struct reg_info linfo;
12006                 linfo = arch_reg_lhs(state, ins, i);
12007                 if (linfo.reg < MAX_REGISTERS) {
12008                         continue;
12009                 }
12010                 for(j = 0; (j < zrhs) && (found == -1); j++) {
12011                         struct reg_info rinfo;
12012                         struct triple *rhs;
12013                         struct triple_reg_set *set;
12014                         rinfo = arch_reg_rhs(state, ins, j);
12015                         if (rinfo.reg != linfo.reg) {
12016                                 continue;
12017                         }
12018                         rhs = RHS(ins, j);
12019                         for(set = live; set && (found == -1); set = set->next) {
12020                                 if (set->member == rhs) {
12021                                         found = j;
12022                                 }
12023                         }
12024                 }
12025         }
12026         /* Only update conflict if we are the least dominated conflict */
12027         if ((found != -1) &&
12028                 (!conflict->ins || tdominates(state, ins, conflict->ins))) {
12029                 conflict->ins = ins;
12030                 conflict->index = found;
12031         }
12032         return ins;
12033 }
12034
12035 static void resolve_coalesce_conflict(
12036         struct compile_state *state, struct coalesce_conflict *conflict)
12037 {
12038         struct triple *copy;
12039         copy = pre_copy(state, conflict->ins, conflict->index);
12040         copy->id |= TRIPLE_FLAG_PRE_SPLIT;
12041 }
12042         
12043
12044 static struct triple *spot_tangle(struct compile_state *state,
12045         struct reg_block *blocks, struct triple_reg_set *live,
12046         struct reg_block *rb, struct triple *ins, void *arg)
12047 {
12048         struct triple **tangle = arg;
12049         char used[MAX_REGISTERS];
12050         struct triple_reg_set *set;
12051
12052         /* Find out which registers have multiple uses at this point */
12053         memset(used, 0, sizeof(used));
12054         for(set = live; set; set = set->next) {
12055                 struct reg_info info;
12056                 info = find_lhs_color(state, set->member, 0);
12057                 if (info.reg == REG_UNSET) {
12058                         continue;
12059                 }
12060                 reg_inc_used(state, used, info.reg);
12061         }
12062
12063         /* Now find the least dominated definition of a register in
12064          * conflict I have seen so far.
12065          */
12066         for(set = live; set; set = set->next) {
12067                 struct reg_info info;
12068                 info = find_lhs_color(state, set->member, 0);
12069                 if (used[info.reg] < 2) {
12070                         continue;
12071                 }
12072                 if (!*tangle || tdominates(state, set->member, *tangle)) {
12073                         *tangle = set->member;
12074                 }
12075         }
12076         return ins;
12077 }
12078
12079 static void resolve_tangle(struct compile_state *state, struct triple *tangle)
12080 {
12081         struct reg_info info, uinfo;
12082         struct triple_set *set, *next;
12083         struct triple *copy;
12084
12085 #if 0
12086         fprintf(stderr, "Resolving tangle: %p\n", tangle);
12087         print_blocks(state, stderr);
12088 #endif
12089         info = find_lhs_color(state, tangle, 0);
12090 #if 0
12091         fprintf(stderr, "color: %d\n", info.reg);
12092 #endif
12093         for(set = tangle->use; set; set = next) {
12094                 struct triple *user;
12095                 int i, zrhs;
12096                 next = set->next;
12097                 user = set->member;
12098                 zrhs = TRIPLE_RHS(user->sizes);
12099                 for(i = 0; i < zrhs; i++) {
12100                         if (RHS(user, i) != tangle) {
12101                                 continue;
12102                         }
12103                         uinfo = find_rhs_post_color(state, user, i);
12104 #if 0
12105                         fprintf(stderr, "%p rhs %d color: %d\n", 
12106                                 user, i, uinfo.reg);
12107 #endif
12108                         if (uinfo.reg == info.reg) {
12109                                 copy = pre_copy(state, user, i);
12110                                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
12111                         }
12112                 }
12113         }
12114         uinfo = find_lhs_pre_color(state, tangle, 0);
12115 #if 0
12116         fprintf(stderr, "pre color: %d\n", uinfo.reg);
12117 #endif
12118         if (uinfo.reg == info.reg) {
12119                 copy = post_copy(state, tangle);
12120                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
12121         }
12122 }
12123
12124
12125 struct least_conflict {
12126         struct reg_state *rstate;
12127         struct live_range *ref_range;
12128         struct triple *ins;
12129         struct triple_reg_set *live;
12130         size_t count;
12131 };
12132 static struct triple *least_conflict(struct compile_state *state,
12133         struct reg_block *blocks, struct triple_reg_set *live,
12134         struct reg_block *rb, struct triple *ins, void *arg)
12135 {
12136         struct least_conflict *conflict = arg;
12137         struct live_range_edge *edge;
12138         struct triple_reg_set *set;
12139         size_t count;
12140
12141 #warning "FIXME handle instructions with left hand sides..."
12142         /* Only instructions that introduce a new definition
12143          * can be the conflict instruction.
12144          */
12145         if (!triple_is_def(state, ins)) {
12146                 return ins;
12147         }
12148
12149         /* See if live ranges at this instruction are a
12150          * strict subset of the live ranges that are in conflict.
12151          */
12152         count = 0;
12153         for(set = live; set; set = set->next) {
12154                 struct live_range *lr;
12155                 lr = conflict->rstate->lrd[set->member->id].lr;
12156                 for(edge = conflict->ref_range->edges; edge; edge = edge->next) {
12157                         if (edge->node == lr) {
12158                                 break;
12159                         }
12160                 }
12161                 if (!edge && (lr != conflict->ref_range)) {
12162                         return ins;
12163                 }
12164                 count++;
12165         }
12166         if (count <= 1) {
12167                 return ins;
12168         }
12169
12170         /* See if there is an uncolored member in this subset. 
12171          */
12172          for(set = live; set; set = set->next) {
12173                 struct live_range *lr;
12174                 lr = conflict->rstate->lrd[set->member->id].lr;
12175                 if (lr->color == REG_UNSET) {
12176                         break;
12177                 }
12178         }
12179         if (!set && (conflict->ref_range != REG_UNSET)) {
12180                 return ins;
12181         }
12182
12183
12184         /* Find the instruction with the largest possible subset of
12185          * conflict ranges and that dominates any other instruction
12186          * with an equal sized set of conflicting ranges.
12187          */
12188         if ((count > conflict->count) ||
12189                 ((count == conflict->count) &&
12190                         tdominates(state, ins, conflict->ins))) {
12191                 struct triple_reg_set *next;
12192                 /* Remember the canidate instruction */
12193                 conflict->ins = ins;
12194                 conflict->count = count;
12195                 /* Free the old collection of live registers */
12196                 for(set = conflict->live; set; set = next) {
12197                         next = set->next;
12198                         do_triple_unset(&conflict->live, set->member);
12199                 }
12200                 conflict->live = 0;
12201                 /* Rember the registers that are alive but do not feed
12202                  * into or out of conflict->ins.
12203                  */
12204                 for(set = live; set; set = set->next) {
12205                         struct triple **expr;
12206                         if (set->member == ins) {
12207                                 goto next;
12208                         }
12209                         expr = triple_rhs(state, ins, 0);
12210                         for(;expr; expr = triple_rhs(state, ins, expr)) {
12211                                 if (*expr == set->member) {
12212                                         goto next;
12213                                 }
12214                         }
12215                         expr = triple_lhs(state, ins, 0);
12216                         for(; expr; expr = triple_lhs(state, ins, expr)) {
12217                                 if (*expr == set->member) {
12218                                         goto next;
12219                                 }
12220                         }
12221                         do_triple_set(&conflict->live, set->member, set->new);
12222                 next:
12223                 }
12224         }
12225         return ins;
12226 }
12227
12228 static void find_range_conflict(struct compile_state *state,
12229         struct reg_state *rstate, char *used, struct live_range *ref_range,
12230         struct least_conflict *conflict)
12231 {
12232         /* there are 3 kinds ways conflicts can occure.
12233          * 1) the life time of 2 values simply overlap.
12234          * 2) the 2 values feed into the same instruction.
12235          * 3) the 2 values feed into a phi function.
12236          */
12237
12238         /* find the instruction where the problematic conflict comes
12239          * into existance.  that the instruction where all of
12240          * the values are alive, and among such instructions it is
12241          * the least dominated one.
12242          *
12243          * a value is alive an an instruction if either;
12244          * 1) the value defintion dominates the instruction and there
12245          *    is a use at or after that instrction
12246          * 2) the value definition feeds into a phi function in the
12247          *    same block as the instruction.  and the phi function
12248          *    is at or after the instruction.
12249          */
12250         memset(conflict, 0, sizeof(*conflict));
12251         conflict->rstate    = rstate;
12252         conflict->ref_range = ref_range;
12253         conflict->ins       = 0;
12254         conflict->count     = 0;
12255         conflict->live      = 0;
12256         walk_variable_lifetimes(state, rstate->blocks, least_conflict, conflict);
12257
12258         if (!conflict->ins) {
12259                 internal_error(state, 0, "No conflict ins?");
12260         }
12261         if (!conflict->live) {
12262                 internal_error(state, 0, "No conflict live?");
12263         }
12264         return;
12265 }
12266
12267 static struct triple *split_constrained_range(struct compile_state *state, 
12268         struct reg_state *rstate, char *used, struct least_conflict *conflict)
12269 {
12270         unsigned constrained_size;
12271         struct triple *new, *constrained;
12272         struct triple_reg_set *cset;
12273         /* Find a range that is having problems because it is
12274          * artificially constrained.
12275          */
12276         constrained_size = ~0;
12277         constrained = 0;
12278         new = 0;
12279         for(cset = conflict->live; cset; cset = cset->next) {
12280                 struct triple_set *set;
12281                 struct reg_info info;
12282                 unsigned classes;
12283                 unsigned cur_size, size;
12284                 /* Skip the live range that starts with conflict->ins */
12285                 if (cset->member == conflict->ins) {
12286                         continue;
12287                 }
12288                 /* Find how many registers this value can potentially
12289                  * be assigned to.
12290                  */
12291                 classes = arch_type_to_regcm(state, cset->member->type);
12292                 size = regc_max_size(state, classes);
12293
12294                 /* Find how many registers we allow this value to
12295                  * be assigned to.
12296                  */
12297                 info = arch_reg_lhs(state, cset->member, 0);
12298 #warning "FIXME do I need a call to arch_reg_rhs around here somewhere?"
12299                 if ((info.reg == REG_UNSET) || (info.reg >= MAX_REGISTERS)) {
12300                         cur_size = regc_max_size(state, info.regcm);
12301                 } else {
12302                         cur_size = 1;
12303                 }
12304                 /* If this live_range feeds into conflict->ins
12305                  * splitting it is unlikely to help.
12306                  */
12307                 for(set = cset->member->use; set; set = set->next) {
12308                         if (set->member == conflict->ins) {
12309                                 goto next;
12310                         }
12311                 }
12312
12313                 /* If there is no difference between potential and
12314                  * actual register count there is nothing to do.
12315                  */
12316                 if (cur_size >= size) {
12317                         continue;
12318                 }
12319                 /* Of the constrained registers deal with the
12320                  * most constrained one first.
12321                  */
12322                 if (!constrained ||
12323                         (size < constrained_size)) {
12324                         constrained = cset->member;
12325                         constrained_size = size;
12326                 }
12327         next:
12328         }
12329         if (constrained) {
12330                 new = post_copy(state, constrained);
12331                 new->id |= TRIPLE_FLAG_POST_SPLIT;
12332         }
12333         return new;
12334 }
12335
12336 static int split_ranges(
12337         struct compile_state *state, struct reg_state *rstate, 
12338         char *used, struct live_range *range)
12339 {
12340         struct triple *new;
12341
12342         if ((range->color == REG_UNNEEDED) ||
12343                 (rstate->passes >= rstate->max_passes)) {
12344                 return 0;
12345         }
12346         new = 0;
12347         /* If I can't allocate a register something needs to be split */
12348         if (arch_select_free_register(state, used, range->classes) == REG_UNSET) {
12349                 struct least_conflict conflict;
12350
12351                 /* Find where in the set of registers the conflict
12352                  * actually occurs.
12353                  */
12354                 find_range_conflict(state, rstate, used, range, &conflict);
12355
12356                 /* If a range has been artifically constrained split it */
12357                 new = split_constrained_range(state, rstate, used, &conflict);
12358                 
12359                 if (!new) {
12360                 /* Ideally I would split the live range that will not be used
12361                  * for the longest period of time in hopes that this will 
12362                  * (a) allow me to spill a register or
12363                  * (b) allow me to place a value in another register.
12364                  *
12365                  * So far I don't have a test case for this, the resolving
12366                  * of mandatory constraints has solved all of my
12367                  * know issues.  So I have choosen not to write any
12368                  * code until I cat get a better feel for cases where
12369                  * it would be useful to have.
12370                  *
12371                  */
12372 #warning "WISHLIST implement live range splitting..."
12373                         return 0;
12374                 }
12375         }
12376         if (new) {
12377                 rstate->lrd[rstate->defs].orig_id = new->id;
12378                 new->id = rstate->defs;
12379                 rstate->defs++;
12380 #if 0
12381                 fprintf(stderr, "new: %p\n", new);
12382 #endif
12383                 return 1;
12384         }
12385         return 0;
12386 }
12387
12388 #if DEBUG_COLOR_GRAPH > 1
12389 #define cgdebug_printf(...) fprintf(stdout, __VA_ARGS__)
12390 #define cgdebug_flush() fflush(stdout)
12391 #elif DEBUG_COLOR_GRAPH == 1
12392 #define cgdebug_printf(...) fprintf(stderr, __VA_ARGS__)
12393 #define cgdebug_flush() fflush(stderr)
12394 #else
12395 #define cgdebug_printf(...)
12396 #define cgdebug_flush()
12397 #endif
12398
12399         
12400 static int select_free_color(struct compile_state *state, 
12401         struct reg_state *rstate, struct live_range *range)
12402 {
12403         struct triple_set *entry;
12404         struct live_range_def *lrd;
12405         struct live_range_def *phi;
12406         struct live_range_edge *edge;
12407         char used[MAX_REGISTERS];
12408         struct triple **expr;
12409
12410         /* Instead of doing just the trivial color select here I try
12411          * a few extra things because a good color selection will help reduce
12412          * copies.
12413          */
12414
12415         /* Find the registers currently in use */
12416         memset(used, 0, sizeof(used));
12417         for(edge = range->edges; edge; edge = edge->next) {
12418                 if (edge->node->color == REG_UNSET) {
12419                         continue;
12420                 }
12421                 reg_fill_used(state, used, edge->node->color);
12422         }
12423 #if DEBUG_COLOR_GRAPH > 1
12424         {
12425                 int i;
12426                 i = 0;
12427                 for(edge = range->edges; edge; edge = edge->next) {
12428                         i++;
12429                 }
12430                 cgdebug_printf("\n%s edges: %d @%s:%d.%d\n", 
12431                         tops(range->def->op), i, 
12432                         range->def->filename, range->def->line, range->def->col);
12433                 for(i = 0; i < MAX_REGISTERS; i++) {
12434                         if (used[i]) {
12435                                 cgdebug_printf("used: %s\n",
12436                                         arch_reg_str(i));
12437                         }
12438                 }
12439         }       
12440 #endif
12441
12442 #warning "FIXME detect conflicts caused by the source and destination being the same register"
12443
12444         /* If a color is already assigned see if it will work */
12445         if (range->color != REG_UNSET) {
12446                 struct live_range_def *lrd;
12447                 if (!used[range->color]) {
12448                         return 1;
12449                 }
12450                 for(edge = range->edges; edge; edge = edge->next) {
12451                         if (edge->node->color != range->color) {
12452                                 continue;
12453                         }
12454                         warning(state, edge->node->defs->def, "edge: ");
12455                         lrd = edge->node->defs;
12456                         do {
12457                                 warning(state, lrd->def, " %p %s",
12458                                         lrd->def, tops(lrd->def->op));
12459                                 lrd = lrd->next;
12460                         } while(lrd != edge->node->defs);
12461                 }
12462                 lrd = range->defs;
12463                 warning(state, range->defs->def, "def: ");
12464                 do {
12465                         warning(state, lrd->def, " %p %s",
12466                                 lrd->def, tops(lrd->def->op));
12467                         lrd = lrd->next;
12468                 } while(lrd != range->defs);
12469                 internal_error(state, range->defs->def,
12470                         "live range with already used color %s",
12471                         arch_reg_str(range->color));
12472         }
12473
12474         /* If I feed into an expression reuse it's color.
12475          * This should help remove copies in the case of 2 register instructions
12476          * and phi functions.
12477          */
12478         phi = 0;
12479         lrd = live_range_end(state, range, 0);
12480         for(; (range->color == REG_UNSET) && lrd ; lrd = live_range_end(state, range, lrd)) {
12481                 entry = lrd->def->use;
12482                 for(;(range->color == REG_UNSET) && entry; entry = entry->next) {
12483                         struct live_range_def *insd;
12484                         insd = &rstate->lrd[entry->member->id];
12485                         if (insd->lr->defs == 0) {
12486                                 continue;
12487                         }
12488                         if (!phi && (insd->def->op == OP_PHI) &&
12489                                 !interfere(rstate, range, insd->lr)) {
12490                                 phi = insd;
12491                         }
12492                         if ((insd->lr->color == REG_UNSET) ||
12493                                 ((insd->lr->classes & range->classes) == 0) ||
12494                                 (used[insd->lr->color])) {
12495                                 continue;
12496                         }
12497                         if (interfere(rstate, range, insd->lr)) {
12498                                 continue;
12499                         }
12500                         range->color = insd->lr->color;
12501                 }
12502         }
12503         /* If I feed into a phi function reuse it's color or the color
12504          * of something else that feeds into the phi function.
12505          */
12506         if (phi) {
12507                 if (phi->lr->color != REG_UNSET) {
12508                         if (used[phi->lr->color]) {
12509                                 range->color = phi->lr->color;
12510                         }
12511                 }
12512                 else {
12513                         expr = triple_rhs(state, phi->def, 0);
12514                         for(; expr; expr = triple_rhs(state, phi->def, expr)) {
12515                                 struct live_range *lr;
12516                                 if (!*expr) {
12517                                         continue;
12518                                 }
12519                                 lr = rstate->lrd[(*expr)->id].lr;
12520                                 if ((lr->color == REG_UNSET) || 
12521                                         ((lr->classes & range->classes) == 0) ||
12522                                         (used[lr->color])) {
12523                                         continue;
12524                                 }
12525                                 if (interfere(rstate, range, lr)) {
12526                                         continue;
12527                                 }
12528                                 range->color = lr->color;
12529                         }
12530                 }
12531         }
12532         /* If I don't interfere with a rhs node reuse it's color */
12533         lrd = live_range_head(state, range, 0);
12534         for(; (range->color == REG_UNSET) && lrd ; lrd = live_range_head(state, range, lrd)) {
12535                 expr = triple_rhs(state, lrd->def, 0);
12536                 for(; expr; expr = triple_rhs(state, lrd->def, expr)) {
12537                         struct live_range *lr;
12538                         if (!*expr) {
12539                                 continue;
12540                         }
12541                         lr = rstate->lrd[(*expr)->id].lr;
12542                         if ((lr->color == -1) || 
12543                                 ((lr->classes & range->classes) == 0) ||
12544                                 (used[lr->color])) {
12545                                 continue;
12546                         }
12547                         if (interfere(rstate, range, lr)) {
12548                                 continue;
12549                         }
12550                         range->color = lr->color;
12551                         break;
12552                 }
12553         }
12554         /* If I have not opportunitically picked a useful color
12555          * pick the first color that is free.
12556          */
12557         if (range->color == REG_UNSET) {
12558                 range->color = 
12559                         arch_select_free_register(state, used, range->classes);
12560         }
12561         if (range->color == REG_UNSET) {
12562                 int i;
12563                 if (split_ranges(state, rstate, used, range)) {
12564                         return 0;
12565                 }
12566                 for(edge = range->edges; edge; edge = edge->next) {
12567                         if (edge->node->color == REG_UNSET) {
12568                                 continue;
12569                         }
12570                         warning(state, edge->node->defs->def, "reg %s", 
12571                                 arch_reg_str(edge->node->color));
12572                 }
12573                 warning(state, range->defs->def, "classes: %x",
12574                         range->classes);
12575                 for(i = 0; i < MAX_REGISTERS; i++) {
12576                         if (used[i]) {
12577                                 warning(state, range->defs->def, "used: %s",
12578                                         arch_reg_str(i));
12579                         }
12580                 }
12581 #if DEBUG_COLOR_GRAPH < 2
12582                 error(state, range->defs->def, "too few registers");
12583 #else
12584                 internal_error(state, range->defs->def, "too few registers");
12585 #endif
12586         }
12587         range->classes = arch_reg_regcm(state, range->color);
12588         if (range->color == -1) {
12589                 internal_error(state, range->defs->def, "select_free_color did not?");
12590         }
12591         return 1;
12592 }
12593
12594 static int color_graph(struct compile_state *state, struct reg_state *rstate)
12595 {
12596         int colored;
12597         struct live_range_edge *edge;
12598         struct live_range *range;
12599         if (rstate->low) {
12600                 cgdebug_printf("Lo: ");
12601                 range = rstate->low;
12602                 if (*range->group_prev != range) {
12603                         internal_error(state, 0, "lo: *prev != range?");
12604                 }
12605                 *range->group_prev = range->group_next;
12606                 if (range->group_next) {
12607                         range->group_next->group_prev = range->group_prev;
12608                 }
12609                 if (&range->group_next == rstate->low_tail) {
12610                         rstate->low_tail = range->group_prev;
12611                 }
12612                 if (rstate->low == range) {
12613                         internal_error(state, 0, "low: next != prev?");
12614                 }
12615         }
12616         else if (rstate->high) {
12617                 cgdebug_printf("Hi: ");
12618                 range = rstate->high;
12619                 if (*range->group_prev != range) {
12620                         internal_error(state, 0, "hi: *prev != range?");
12621                 }
12622                 *range->group_prev = range->group_next;
12623                 if (range->group_next) {
12624                         range->group_next->group_prev = range->group_prev;
12625                 }
12626                 if (&range->group_next == rstate->high_tail) {
12627                         rstate->high_tail = range->group_prev;
12628                 }
12629                 if (rstate->high == range) {
12630                         internal_error(state, 0, "high: next != prev?");
12631                 }
12632         }
12633         else {
12634                 return 1;
12635         }
12636         cgdebug_printf(" %d\n", range - rstate->lr);
12637         range->group_prev = 0;
12638         for(edge = range->edges; edge; edge = edge->next) {
12639                 struct live_range *node;
12640                 node = edge->node;
12641                 /* Move nodes from the high to the low list */
12642                 if (node->group_prev && (node->color == REG_UNSET) &&
12643                         (node->degree == regc_max_size(state, node->classes))) {
12644                         if (*node->group_prev != node) {
12645                                 internal_error(state, 0, "move: *prev != node?");
12646                         }
12647                         *node->group_prev = node->group_next;
12648                         if (node->group_next) {
12649                                 node->group_next->group_prev = node->group_prev;
12650                         }
12651                         if (&node->group_next == rstate->high_tail) {
12652                                 rstate->high_tail = node->group_prev;
12653                         }
12654                         cgdebug_printf("Moving...%d to low\n", node - rstate->lr);
12655                         node->group_prev  = rstate->low_tail;
12656                         node->group_next  = 0;
12657                         *rstate->low_tail = node;
12658                         rstate->low_tail  = &node->group_next;
12659                         if (*node->group_prev != node) {
12660                                 internal_error(state, 0, "move2: *prev != node?");
12661                         }
12662                 }
12663                 node->degree -= 1;
12664         }
12665         colored = color_graph(state, rstate);
12666         if (colored) {
12667                 cgdebug_printf("Coloring %d @%s:%d.%d:", 
12668                         range - rstate->lr,
12669                         range->def->filename, range->def->line, range->def->col);
12670                 cgdebug_flush();
12671                 colored = select_free_color(state, rstate, range);
12672                 cgdebug_printf(" %s\n", arch_reg_str(range->color));
12673         }
12674         return colored;
12675 }
12676
12677 static void verify_colors(struct compile_state *state, struct reg_state *rstate)
12678 {
12679         struct live_range *lr;
12680         struct live_range_edge *edge;
12681         struct triple *ins, *first;
12682         char used[MAX_REGISTERS];
12683         first = RHS(state->main_function, 0);
12684         ins = first;
12685         do {
12686                 if (triple_is_def(state, ins)) {
12687                         if ((ins->id < 0) || (ins->id > rstate->defs)) {
12688                                 internal_error(state, ins, 
12689                                         "triple without a live range def");
12690                         }
12691                         lr = rstate->lrd[ins->id].lr;
12692                         if (lr->color == REG_UNSET) {
12693                                 internal_error(state, ins,
12694                                         "triple without a color");
12695                         }
12696                         /* Find the registers used by the edges */
12697                         memset(used, 0, sizeof(used));
12698                         for(edge = lr->edges; edge; edge = edge->next) {
12699                                 if (edge->node->color == REG_UNSET) {
12700                                         internal_error(state, 0,
12701                                                 "live range without a color");
12702                         }
12703                                 reg_fill_used(state, used, edge->node->color);
12704                         }
12705                         if (used[lr->color]) {
12706                                 internal_error(state, ins,
12707                                         "triple with already used color");
12708                         }
12709                 }
12710                 ins = ins->next;
12711         } while(ins != first);
12712 }
12713
12714 static void color_triples(struct compile_state *state, struct reg_state *rstate)
12715 {
12716         struct live_range *lr;
12717         struct triple *first, *ins;
12718         first = RHS(state->main_function, 0);
12719         ins = first;
12720         do {
12721                 if ((ins->id < 0) || (ins->id > rstate->defs)) {
12722                         internal_error(state, ins, 
12723                                 "triple without a live range");
12724                 }
12725                 lr = rstate->lrd[ins->id].lr;
12726                 SET_REG(ins->id, lr->color);
12727                 ins = ins->next;
12728         } while (ins != first);
12729 }
12730
12731 static void print_interference_block(
12732         struct compile_state *state, struct block *block, void *arg)
12733
12734 {
12735         struct reg_state *rstate = arg;
12736         struct reg_block *rb;
12737         struct triple *ptr;
12738         int phi_present;
12739         int done;
12740         rb = &rstate->blocks[block->vertex];
12741
12742         printf("\nblock: %p (%d), %p<-%p %p<-%p\n", 
12743                 block, 
12744                 block->vertex,
12745                 block->left, 
12746                 block->left && block->left->use?block->left->use->member : 0,
12747                 block->right, 
12748                 block->right && block->right->use?block->right->use->member : 0);
12749         if (rb->in) {
12750                 struct triple_reg_set *in_set;
12751                 printf("        in:");
12752                 for(in_set = rb->in; in_set; in_set = in_set->next) {
12753                         printf(" %-10p", in_set->member);
12754                 }
12755                 printf("\n");
12756         }
12757         phi_present = 0;
12758         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
12759                 done = (ptr == block->last);
12760                 if (ptr->op == OP_PHI) {
12761                         phi_present = 1;
12762                         break;
12763                 }
12764         }
12765         if (phi_present) {
12766                 int edge;
12767                 for(edge = 0; edge < block->users; edge++) {
12768                         printf("     in(%d):", edge);
12769                         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
12770                                 struct triple **slot;
12771                                 done = (ptr == block->last);
12772                                 if (ptr->op != OP_PHI) {
12773                                         continue;
12774                                 }
12775                                 slot = &RHS(ptr, 0);
12776                                 printf(" %-10p", slot[edge]);
12777                         }
12778                         printf("\n");
12779                 }
12780         }
12781         if (block->first->op == OP_LABEL) {
12782                 printf("%p:\n", block->first);
12783         }
12784         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
12785                 struct triple_set *user;
12786                 struct live_range *lr;
12787                 unsigned id;
12788                 int op;
12789                 op = ptr->op;
12790                 done = (ptr == block->last);
12791                 lr = rstate->lrd[ptr->id].lr;
12792                 
12793                 if (triple_stores_block(state, ptr)) {
12794                         if (ptr->u.block != block) {
12795                                 internal_error(state, ptr, 
12796                                         "Wrong block pointer: %p",
12797                                         ptr->u.block);
12798                         }
12799                 }
12800                 if (op == OP_ADECL) {
12801                         for(user = ptr->use; user; user = user->next) {
12802                                 if (!user->member->u.block) {
12803                                         internal_error(state, user->member, 
12804                                                 "Use %p not in a block?",
12805                                                 user->member);
12806                                 }
12807                                 
12808                         }
12809                 }
12810                 id = ptr->id;
12811                 SET_REG(ptr->id, lr->color);
12812                 display_triple(stdout, ptr);
12813                 ptr->id = id;
12814
12815                 if (triple_is_def(state, ptr) && (lr->defs == 0)) {
12816                         internal_error(state, ptr, "lr has no defs!");
12817                 }
12818
12819                 if (lr->defs) {
12820                         struct live_range_def *lrd;
12821                         printf("       range:");
12822                         lrd = lr->defs;
12823                         do {
12824                                 printf(" %-10p", lrd->def);
12825                                 lrd = lrd->next;
12826                         } while(lrd != lr->defs);
12827                         printf("\n");
12828                 }
12829                 if (lr->edges > 0) {
12830                         struct live_range_edge *edge;
12831                         printf("       edges:");
12832                         for(edge = lr->edges; edge; edge = edge->next) {
12833                                 struct live_range_def *lrd;
12834                                 lrd = edge->node->defs;
12835                                 do {
12836                                         printf(" %-10p", lrd->def);
12837                                         lrd = lrd->next;
12838                                 } while(lrd != edge->node->defs);
12839                                 printf("|");
12840                         }
12841                         printf("\n");
12842                 }
12843                 /* Do a bunch of sanity checks */
12844                 valid_ins(state, ptr);
12845                 if ((ptr->id < 0) || (ptr->id > rstate->defs)) {
12846                         internal_error(state, ptr, "Invalid triple id: %d",
12847                                 ptr->id);
12848                 }
12849                 for(user = ptr->use; user; user = user->next) {
12850                         struct triple *use;
12851                         struct live_range *ulr;
12852                         use = user->member;
12853                         valid_ins(state, use);
12854                         if ((use->id < 0) || (use->id > rstate->defs)) {
12855                                 internal_error(state, use, "Invalid triple id: %d",
12856                                         use->id);
12857                         }
12858                         ulr = rstate->lrd[user->member->id].lr;
12859                         if (triple_stores_block(state, user->member) &&
12860                                 !user->member->u.block) {
12861                                 internal_error(state, user->member,
12862                                         "Use %p not in a block?",
12863                                         user->member);
12864                         }
12865                 }
12866         }
12867         if (rb->out) {
12868                 struct triple_reg_set *out_set;
12869                 printf("       out:");
12870                 for(out_set = rb->out; out_set; out_set = out_set->next) {
12871                         printf(" %-10p", out_set->member);
12872                 }
12873                 printf("\n");
12874         }
12875         printf("\n");
12876 }
12877
12878 static struct live_range *merge_sort_lr(
12879         struct live_range *first, struct live_range *last)
12880 {
12881         struct live_range *mid, *join, **join_tail, *pick;
12882         size_t size;
12883         size = (last - first) + 1;
12884         if (size >= 2) {
12885                 mid = first + size/2;
12886                 first = merge_sort_lr(first, mid -1);
12887                 mid   = merge_sort_lr(mid, last);
12888                 
12889                 join = 0;
12890                 join_tail = &join;
12891                 /* merge the two lists */
12892                 while(first && mid) {
12893                         if ((first->degree < mid->degree) ||
12894                                 ((first->degree == mid->degree) &&
12895                                         (first->length < mid->length))) {
12896                                 pick = first;
12897                                 first = first->group_next;
12898                                 if (first) {
12899                                         first->group_prev = 0;
12900                                 }
12901                         }
12902                         else {
12903                                 pick = mid;
12904                                 mid = mid->group_next;
12905                                 if (mid) {
12906                                         mid->group_prev = 0;
12907                                 }
12908                         }
12909                         pick->group_next = 0;
12910                         pick->group_prev = join_tail;
12911                         *join_tail = pick;
12912                         join_tail = &pick->group_next;
12913                 }
12914                 /* Splice the remaining list */
12915                 pick = (first)? first : mid;
12916                 *join_tail = pick;
12917                 if (pick) { 
12918                         pick->group_prev = join_tail;
12919                 }
12920         }
12921         else {
12922                 if (!first->defs) {
12923                         first = 0;
12924                 }
12925                 join = first;
12926         }
12927         return join;
12928 }
12929
12930 static void ids_from_rstate(struct compile_state *state, 
12931         struct reg_state *rstate)
12932 {
12933         struct triple *ins, *first;
12934         if (!rstate->defs) {
12935                 return;
12936         }
12937         /* Display the graph if desired */
12938         if (state->debug & DEBUG_INTERFERENCE) {
12939                 print_blocks(state, stdout);
12940                 print_control_flow(state);
12941         }
12942         first = RHS(state->main_function, 0);
12943         ins = first;
12944         do {
12945                 if (ins->id) {
12946                         struct live_range_def *lrd;
12947                         lrd = &rstate->lrd[ins->id];
12948                         ins->id = lrd->orig_id;
12949                 }
12950                 ins = ins->next;
12951         } while(ins != first);
12952 }
12953
12954 static void cleanup_live_edges(struct reg_state *rstate)
12955 {
12956         int i;
12957         /* Free the edges on each node */
12958         for(i = 1; i <= rstate->ranges; i++) {
12959                 remove_live_edges(rstate, &rstate->lr[i]);
12960         }
12961 }
12962
12963 static void cleanup_rstate(struct compile_state *state, struct reg_state *rstate)
12964 {
12965         cleanup_live_edges(rstate);
12966         xfree(rstate->lrd);
12967         xfree(rstate->lr);
12968
12969         /* Free the variable lifetime information */
12970         if (rstate->blocks) {
12971                 free_variable_lifetimes(state, rstate->blocks);
12972         }
12973         rstate->defs = 0;
12974         rstate->ranges = 0;
12975         rstate->lrd = 0;
12976         rstate->lr = 0;
12977         rstate->blocks = 0;
12978 }
12979
12980 static void allocate_registers(struct compile_state *state)
12981 {
12982         struct reg_state rstate;
12983         int colored;
12984
12985         /* Clear out the reg_state */
12986         memset(&rstate, 0, sizeof(rstate));
12987         rstate.max_passes = MAX_ALLOCATION_PASSES;
12988
12989         do {
12990                 struct live_range **point, **next;
12991                 struct triple *tangle;
12992                 struct coalesce_conflict conflict;
12993                 int coalesced;
12994
12995                 /* Restore ids */
12996                 ids_from_rstate(state, &rstate);
12997
12998                 do {
12999                         /* Cleanup the temporary data structures */
13000                         cleanup_rstate(state, &rstate);
13001
13002                         /* Compute the variable lifetimes */
13003                         rstate.blocks = compute_variable_lifetimes(state);
13004
13005                         /* Find an invalid mandatory live range coalesce */
13006                         conflict.ins = 0;
13007                         conflict.index = -1;
13008                         walk_variable_lifetimes(
13009                                 state, rstate.blocks, spot_coalesce_conflict, &conflict);
13010                         
13011                         /* If a tangle was found resolve it */
13012                         if (conflict.ins) {
13013                                 resolve_coalesce_conflict(state, &conflict);
13014                         }
13015                 } while(conflict.ins);
13016
13017                 do {
13018                         /* Cleanup the temporary data structures */
13019                         cleanup_rstate(state, &rstate);
13020
13021                         /* Compute the variable lifetimes */
13022                         rstate.blocks = compute_variable_lifetimes(state);
13023
13024                         /* Find two simultaneous uses of the same register */
13025                         tangle = 0;
13026                         walk_variable_lifetimes(
13027                                 state, rstate.blocks, spot_tangle, &tangle);
13028                         
13029                         /* If a tangle was found resolve it */
13030                         if (tangle) {
13031                                 resolve_tangle(state, tangle);
13032                         }
13033                 } while(tangle);
13034
13035                 if (state->debug & DEBUG_INSERTED_COPIES) {
13036                         printf("After resolve_tangles\n");
13037                         print_blocks(state, stdout);
13038                         print_control_flow(state);
13039                 }
13040
13041                 
13042                 /* Allocate and initialize the live ranges */
13043                 initialize_live_ranges(state, &rstate);
13044                 
13045                 do {
13046                         /* Forget previous live range edge calculations */
13047                         cleanup_live_edges(&rstate);
13048
13049                         /* Compute the interference graph */
13050                         walk_variable_lifetimes(
13051                                 state, rstate.blocks, graph_ins, &rstate);
13052                 
13053                         /* Display the interference graph if desired */
13054                         if (state->debug & DEBUG_INTERFERENCE) {
13055                                 printf("\nlive variables by block\n");
13056                                 walk_blocks(state, print_interference_block, &rstate);
13057                                 printf("\nlive variables by instruction\n");
13058                                 walk_variable_lifetimes(
13059                                         state, rstate.blocks, 
13060                                         print_interference_ins, &rstate);
13061                         }
13062                         
13063                         coalesced = coalesce_live_ranges(state, &rstate);
13064                 } while(coalesced);
13065                         
13066                 /* Build the groups low and high.  But with the nodes
13067                  * first sorted by degree order.
13068                  */
13069                 rstate.low_tail  = &rstate.low;
13070                 rstate.high_tail = &rstate.high;
13071                 rstate.high = merge_sort_lr(&rstate.lr[1], &rstate.lr[rstate.ranges]);
13072                 if (rstate.high) {
13073                         rstate.high->group_prev = &rstate.high;
13074                 }
13075                 for(point = &rstate.high; *point; point = &(*point)->group_next)
13076                         ;
13077                 rstate.high_tail = point;
13078                 /* Walk through the high list and move everything that needs
13079                  * to be onto low.
13080                  */
13081                 for(point = &rstate.high; *point; point = next) {
13082                         struct live_range *range;
13083                         next = &(*point)->group_next;
13084                         range = *point;
13085                         
13086                         /* If it has a low degree or it already has a color
13087                          * place the node in low.
13088                          */
13089                         if ((range->degree < regc_max_size(state, range->classes)) ||
13090                                 (range->color != REG_UNSET)) {
13091                                 cgdebug_printf("Lo: %5d degree %5d%s\n", 
13092                                         range - rstate.lr, range->degree,
13093                                         (range->color != REG_UNSET) ? " (colored)": "");
13094                                 *range->group_prev = range->group_next;
13095                                 if (range->group_next) {
13096                                         range->group_next->group_prev = range->group_prev;
13097                                 }
13098                                 if (&range->group_next == rstate.high_tail) {
13099                                         rstate.high_tail = range->group_prev;
13100                                 }
13101                                 range->group_prev  = rstate.low_tail;
13102                                 range->group_next  = 0;
13103                                 *rstate.low_tail   = range;
13104                                 rstate.low_tail    = &range->group_next;
13105                                 next = point;
13106                         }
13107                         else {
13108                                 cgdebug_printf("hi: %5d degree %5d%s\n", 
13109                                         range - rstate.lr, range->degree,
13110                                         (range->color != REG_UNSET) ? " (colored)": "");
13111                         }
13112                 }
13113                 /* Color the live_ranges */
13114                 colored = color_graph(state, &rstate);
13115                 rstate.passes++;
13116         } while (!colored);
13117
13118         /* Verify the graph was properly colored */
13119         verify_colors(state, &rstate);
13120
13121         /* Move the colors from the graph to the triples */
13122         color_triples(state, &rstate);
13123
13124         /* Cleanup the temporary data structures */
13125         cleanup_rstate(state, &rstate);
13126 }
13127
13128 /* Sparce Conditional Constant Propogation
13129  * =========================================
13130  */
13131 struct ssa_edge;
13132 struct flow_block;
13133 struct lattice_node {
13134         unsigned old_id;
13135         struct triple *def;
13136         struct ssa_edge *out;
13137         struct flow_block *fblock;
13138         struct triple *val;
13139         /* lattice high   val && !is_const(val) 
13140          * lattice const  is_const(val)
13141          * lattice low    val == 0
13142          */
13143 };
13144 struct ssa_edge {
13145         struct lattice_node *src;
13146         struct lattice_node *dst;
13147         struct ssa_edge *work_next;
13148         struct ssa_edge *work_prev;
13149         struct ssa_edge *out_next;
13150 };
13151 struct flow_edge {
13152         struct flow_block *src;
13153         struct flow_block *dst;
13154         struct flow_edge *work_next;
13155         struct flow_edge *work_prev;
13156         struct flow_edge *in_next;
13157         struct flow_edge *out_next;
13158         int executable;
13159 };
13160 struct flow_block {
13161         struct block *block;
13162         struct flow_edge *in;
13163         struct flow_edge *out;
13164         struct flow_edge left, right;
13165 };
13166
13167 struct scc_state {
13168         int ins_count;
13169         struct lattice_node *lattice;
13170         struct ssa_edge     *ssa_edges;
13171         struct flow_block   *flow_blocks;
13172         struct flow_edge    *flow_work_list;
13173         struct ssa_edge     *ssa_work_list;
13174 };
13175
13176
13177 static void scc_add_fedge(struct compile_state *state, struct scc_state *scc, 
13178         struct flow_edge *fedge)
13179 {
13180         if (!scc->flow_work_list) {
13181                 scc->flow_work_list = fedge;
13182                 fedge->work_next = fedge->work_prev = fedge;
13183         }
13184         else {
13185                 struct flow_edge *ftail;
13186                 ftail = scc->flow_work_list->work_prev;
13187                 fedge->work_next = ftail->work_next;
13188                 fedge->work_prev = ftail;
13189                 fedge->work_next->work_prev = fedge;
13190                 fedge->work_prev->work_next = fedge;
13191         }
13192 }
13193
13194 static struct flow_edge *scc_next_fedge(
13195         struct compile_state *state, struct scc_state *scc)
13196 {
13197         struct flow_edge *fedge;
13198         fedge = scc->flow_work_list;
13199         if (fedge) {
13200                 fedge->work_next->work_prev = fedge->work_prev;
13201                 fedge->work_prev->work_next = fedge->work_next;
13202                 if (fedge->work_next != fedge) {
13203                         scc->flow_work_list = fedge->work_next;
13204                 } else {
13205                         scc->flow_work_list = 0;
13206                 }
13207         }
13208         return fedge;
13209 }
13210
13211 static void scc_add_sedge(struct compile_state *state, struct scc_state *scc,
13212         struct ssa_edge *sedge)
13213 {
13214         if (!scc->ssa_work_list) {
13215                 scc->ssa_work_list = sedge;
13216                 sedge->work_next = sedge->work_prev = sedge;
13217         }
13218         else {
13219                 struct ssa_edge *stail;
13220                 stail = scc->ssa_work_list->work_prev;
13221                 sedge->work_next = stail->work_next;
13222                 sedge->work_prev = stail;
13223                 sedge->work_next->work_prev = sedge;
13224                 sedge->work_prev->work_next = sedge;
13225         }
13226 }
13227
13228 static struct ssa_edge *scc_next_sedge(
13229         struct compile_state *state, struct scc_state *scc)
13230 {
13231         struct ssa_edge *sedge;
13232         sedge = scc->ssa_work_list;
13233         if (sedge) {
13234                 sedge->work_next->work_prev = sedge->work_prev;
13235                 sedge->work_prev->work_next = sedge->work_next;
13236                 if (sedge->work_next != sedge) {
13237                         scc->ssa_work_list = sedge->work_next;
13238                 } else {
13239                         scc->ssa_work_list = 0;
13240                 }
13241         }
13242         return sedge;
13243 }
13244
13245 static void initialize_scc_state(
13246         struct compile_state *state, struct scc_state *scc)
13247 {
13248         int ins_count, ssa_edge_count;
13249         int ins_index, ssa_edge_index, fblock_index;
13250         struct triple *first, *ins;
13251         struct block *block;
13252         struct flow_block *fblock;
13253
13254         memset(scc, 0, sizeof(*scc));
13255
13256         /* Inialize pass zero find out how much memory we need */
13257         first = RHS(state->main_function, 0);
13258         ins = first;
13259         ins_count = ssa_edge_count = 0;
13260         do {
13261                 struct triple_set *edge;
13262                 ins_count += 1;
13263                 for(edge = ins->use; edge; edge = edge->next) {
13264                         ssa_edge_count++;
13265                 }
13266                 ins = ins->next;
13267         } while(ins != first);
13268 #if DEBUG_SCC
13269         fprintf(stderr, "ins_count: %d ssa_edge_count: %d vertex_count: %d\n",
13270                 ins_count, ssa_edge_count, state->last_vertex);
13271 #endif
13272         scc->ins_count   = ins_count;
13273         scc->lattice     = 
13274                 xcmalloc(sizeof(*scc->lattice)*(ins_count + 1), "lattice");
13275         scc->ssa_edges   = 
13276                 xcmalloc(sizeof(*scc->ssa_edges)*(ssa_edge_count + 1), "ssa_edges");
13277         scc->flow_blocks = 
13278                 xcmalloc(sizeof(*scc->flow_blocks)*(state->last_vertex + 1), 
13279                         "flow_blocks");
13280
13281         /* Initialize pass one collect up the nodes */
13282         fblock = 0;
13283         block = 0;
13284         ins_index = ssa_edge_index = fblock_index = 0;
13285         ins = first;
13286         do {
13287                 if ((ins->op == OP_LABEL) && (block != ins->u.block)) {
13288                         block = ins->u.block;
13289                         if (!block) {
13290                                 internal_error(state, ins, "label without block");
13291                         }
13292                         fblock_index += 1;
13293                         block->vertex = fblock_index;
13294                         fblock = &scc->flow_blocks[fblock_index];
13295                         fblock->block = block;
13296                 }
13297                 {
13298                         struct lattice_node *lnode;
13299                         ins_index += 1;
13300                         lnode = &scc->lattice[ins_index];
13301                         lnode->def = ins;
13302                         lnode->out = 0;
13303                         lnode->fblock = fblock;
13304                         lnode->val = ins; /* LATTICE HIGH */
13305                         lnode->old_id = ins->id;
13306                         ins->id = ins_index;
13307                 }
13308                 ins = ins->next;
13309         } while(ins != first);
13310         /* Initialize pass two collect up the edges */
13311         block = 0;
13312         fblock = 0;
13313         ins = first;
13314         do {
13315                 if ((ins->op == OP_LABEL) && (block != ins->u.block)) {
13316                         struct flow_edge *fedge, **ftail;
13317                         struct block_set *bedge;
13318                         block = ins->u.block;
13319                         fblock = &scc->flow_blocks[block->vertex];
13320                         fblock->in = 0;
13321                         fblock->out = 0;
13322                         ftail = &fblock->out;
13323                         if (block->left) {
13324                                 fblock->left.dst = &scc->flow_blocks[block->left->vertex];
13325                                 if (fblock->left.dst->block != block->left) {
13326                                         internal_error(state, 0, "block mismatch");
13327                                 }
13328                                 fblock->left.out_next = 0;
13329                                 *ftail = &fblock->left;
13330                                 ftail = &fblock->left.out_next;
13331                         }
13332                         if (block->right) {
13333                                 fblock->right.dst = &scc->flow_blocks[block->right->vertex];
13334                                 if (fblock->right.dst->block != block->right) {
13335                                         internal_error(state, 0, "block mismatch");
13336                                 }
13337                                 fblock->right.out_next = 0;
13338                                 *ftail = &fblock->right;
13339                                 ftail = &fblock->right.out_next;
13340                         }
13341                         for(fedge = fblock->out; fedge; fedge = fedge->out_next) {
13342                                 fedge->src = fblock;
13343                                 fedge->work_next = fedge->work_prev = fedge;
13344                                 fedge->executable = 0;
13345                         }
13346                         ftail = &fblock->in;
13347                         for(bedge = block->use; bedge; bedge = bedge->next) {
13348                                 struct block *src_block;
13349                                 struct flow_block *sfblock;
13350                                 struct flow_edge *sfedge;
13351                                 src_block = bedge->member;
13352                                 sfblock = &scc->flow_blocks[src_block->vertex];
13353                                 sfedge = 0;
13354                                 if (src_block->left == block) {
13355                                         sfedge = &sfblock->left;
13356                                 } else {
13357                                         sfedge = &sfblock->right;
13358                                 }
13359                                 *ftail = sfedge;
13360                                 ftail = &sfedge->in_next;
13361                                 sfedge->in_next = 0;
13362                         }
13363                 }
13364                 {
13365                         struct triple_set *edge;
13366                         struct ssa_edge **stail;
13367                         struct lattice_node *lnode;
13368                         lnode = &scc->lattice[ins->id];
13369                         lnode->out = 0;
13370                         stail = &lnode->out;
13371                         for(edge = ins->use; edge; edge = edge->next) {
13372                                 struct ssa_edge *sedge;
13373                                 ssa_edge_index += 1;
13374                                 sedge = &scc->ssa_edges[ssa_edge_index];
13375                                 *stail = sedge;
13376                                 stail = &sedge->out_next;
13377                                 sedge->src = lnode;
13378                                 sedge->dst = &scc->lattice[edge->member->id];
13379                                 sedge->work_next = sedge->work_prev = sedge;
13380                                 sedge->out_next = 0;
13381                         }
13382                 }
13383                 ins = ins->next;
13384         } while(ins != first);
13385         /* Setup a dummy block 0 as a node above the start node */
13386         {
13387                 struct flow_block *fblock, *dst;
13388                 struct flow_edge *fedge;
13389                 fblock = &scc->flow_blocks[0];
13390                 fblock->block = 0;
13391                 fblock->in = 0;
13392                 fblock->out = &fblock->left;
13393                 dst = &scc->flow_blocks[state->first_block->vertex];
13394                 fedge = &fblock->left;
13395                 fedge->src        = fblock;
13396                 fedge->dst        = dst;
13397                 fedge->work_next  = fedge;
13398                 fedge->work_prev  = fedge;
13399                 fedge->in_next    = fedge->dst->in;
13400                 fedge->out_next   = 0;
13401                 fedge->executable = 0;
13402                 fedge->dst->in = fedge;
13403                 
13404                 /* Initialize the work lists */
13405                 scc->flow_work_list = 0;
13406                 scc->ssa_work_list  = 0;
13407                 scc_add_fedge(state, scc, fedge);
13408         }
13409 #if DEBUG_SCC
13410         fprintf(stderr, "ins_index: %d ssa_edge_index: %d fblock_index: %d\n",
13411                 ins_index, ssa_edge_index, fblock_index);
13412 #endif
13413 }
13414
13415         
13416 static void free_scc_state(
13417         struct compile_state *state, struct scc_state *scc)
13418 {
13419         xfree(scc->flow_blocks);
13420         xfree(scc->ssa_edges);
13421         xfree(scc->lattice);
13422         
13423 }
13424
13425 static struct lattice_node *triple_to_lattice(
13426         struct compile_state *state, struct scc_state *scc, struct triple *ins)
13427 {
13428         if (ins->id <= 0) {
13429                 internal_error(state, ins, "bad id");
13430         }
13431         return &scc->lattice[ins->id];
13432 }
13433
13434 static struct triple *preserve_lval(
13435         struct compile_state *state, struct lattice_node *lnode)
13436 {
13437         struct triple *old;
13438         /* Preserve the original value */
13439         if (lnode->val) {
13440                 old = dup_triple(state, lnode->val);
13441                 if (lnode->val != lnode->def) {
13442                         xfree(lnode->val);
13443                 }
13444                 lnode->val = 0;
13445         } else {
13446                 old = 0;
13447         }
13448         return old;
13449 }
13450
13451 static int lval_changed(struct compile_state *state, 
13452         struct triple *old, struct lattice_node *lnode)
13453 {
13454         int changed;
13455         /* See if the lattice value has changed */
13456         changed = 1;
13457         if (!old && !lnode->val) {
13458                 changed = 0;
13459         }
13460         if (changed && lnode->val && !is_const(lnode->val)) {
13461                 changed = 0;
13462         }
13463         if (changed &&
13464                 lnode->val && old &&
13465                 (memcmp(lnode->val->param, old->param,
13466                         TRIPLE_SIZE(lnode->val->sizes) * sizeof(lnode->val->param[0])) == 0) &&
13467                 (memcmp(&lnode->val->u, &old->u, sizeof(old->u)) == 0)) {
13468                 changed = 0;
13469         }
13470         if (old) {
13471                 xfree(old);
13472         }
13473         return changed;
13474
13475 }
13476
13477 static void scc_visit_phi(struct compile_state *state, struct scc_state *scc, 
13478         struct lattice_node *lnode)
13479 {
13480         struct lattice_node *tmp;
13481         struct triple **slot, *old;
13482         struct flow_edge *fedge;
13483         int index;
13484         if (lnode->def->op != OP_PHI) {
13485                 internal_error(state, lnode->def, "not phi");
13486         }
13487         /* Store the original value */
13488         old = preserve_lval(state, lnode);
13489
13490         /* default to lattice high */
13491         lnode->val = lnode->def;
13492         slot = &RHS(lnode->def, 0);
13493         index = 0;
13494         for(fedge = lnode->fblock->in; fedge; index++, fedge = fedge->in_next) {
13495                 if (!fedge->executable) {
13496                         continue;
13497                 }
13498                 if (!slot[index]) {
13499                         internal_error(state, lnode->def, "no phi value");
13500                 }
13501                 tmp = triple_to_lattice(state, scc, slot[index]);
13502                 /* meet(X, lattice low) = lattice low */
13503                 if (!tmp->val) {
13504                         lnode->val = 0;
13505                 }
13506                 /* meet(X, lattice high) = X */
13507                 else if (!tmp->val) {
13508                         lnode->val = lnode->val;
13509                 }
13510                 /* meet(lattice high, X) = X */
13511                 else if (!is_const(lnode->val)) {
13512                         lnode->val = dup_triple(state, tmp->val);
13513                         lnode->val->type = lnode->def->type;
13514                 }
13515                 /* meet(const, const) = const or lattice low */
13516                 else if (!constants_equal(state, lnode->val, tmp->val)) {
13517                         lnode->val = 0;
13518                 }
13519                 if (!lnode->val) {
13520                         break;
13521                 }
13522         }
13523 #if DEBUG_SCC
13524         fprintf(stderr, "phi: %d -> %s\n",
13525                 lnode->def->id,
13526                 (!lnode->val)? "lo": is_const(lnode->val)? "const": "hi");
13527 #endif
13528         /* If the lattice value has changed update the work lists. */
13529         if (lval_changed(state, old, lnode)) {
13530                 struct ssa_edge *sedge;
13531                 for(sedge = lnode->out; sedge; sedge = sedge->out_next) {
13532                         scc_add_sedge(state, scc, sedge);
13533                 }
13534         }
13535 }
13536
13537 static int compute_lnode_val(struct compile_state *state, struct scc_state *scc,
13538         struct lattice_node *lnode)
13539 {
13540         int changed;
13541         struct triple *old, *scratch;
13542         struct triple **dexpr, **vexpr;
13543         int count, i;
13544         
13545         /* Store the original value */
13546         old = preserve_lval(state, lnode);
13547
13548         /* Reinitialize the value */
13549         lnode->val = scratch = dup_triple(state, lnode->def);
13550         scratch->id = lnode->old_id;
13551         scratch->next     = scratch;
13552         scratch->prev     = scratch;
13553         scratch->use      = 0;
13554
13555         count = TRIPLE_SIZE(scratch->sizes);
13556         for(i = 0; i < count; i++) {
13557                 dexpr = &lnode->def->param[i];
13558                 vexpr = &scratch->param[i];
13559                 *vexpr = *dexpr;
13560                 if (((i < TRIPLE_MISC_OFF(scratch->sizes)) ||
13561                         (i >= TRIPLE_TARG_OFF(scratch->sizes))) &&
13562                         *dexpr) {
13563                         struct lattice_node *tmp;
13564                         tmp = triple_to_lattice(state, scc, *dexpr);
13565                         *vexpr = (tmp->val)? tmp->val : tmp->def;
13566                 }
13567         }
13568         if (scratch->op == OP_BRANCH) {
13569                 scratch->next = lnode->def->next;
13570         }
13571         /* Recompute the value */
13572 #warning "FIXME see if simplify does anything bad"
13573         /* So far it looks like only the strength reduction
13574          * optimization are things I need to worry about.
13575          */
13576         simplify(state, scratch);
13577         /* Cleanup my value */
13578         if (scratch->use) {
13579                 internal_error(state, lnode->def, "scratch used?");
13580         }
13581         if ((scratch->prev != scratch) ||
13582                 ((scratch->next != scratch) &&
13583                         ((lnode->def->op != OP_BRANCH) ||
13584                                 (scratch->next != lnode->def->next)))) {
13585                 internal_error(state, lnode->def, "scratch in list?");
13586         }
13587         /* undo any uses... */
13588         count = TRIPLE_SIZE(scratch->sizes);
13589         for(i = 0; i < count; i++) {
13590                 vexpr = &scratch->param[i];
13591                 if (*vexpr) {
13592                         unuse_triple(*vexpr, scratch);
13593                 }
13594         }
13595         if (!is_const(scratch)) {
13596                 for(i = 0; i < count; i++) {
13597                         dexpr = &lnode->def->param[i];
13598                         if (((i < TRIPLE_MISC_OFF(scratch->sizes)) ||
13599                                 (i >= TRIPLE_TARG_OFF(scratch->sizes))) &&
13600                                 *dexpr) {
13601                                 struct lattice_node *tmp;
13602                                 tmp = triple_to_lattice(state, scc, *dexpr);
13603                                 if (!tmp->val) {
13604                                         lnode->val = 0;
13605                                 }
13606                         }
13607                 }
13608         }
13609         if (lnode->val && 
13610                 (lnode->val->op == lnode->def->op) &&
13611                 (memcmp(lnode->val->param, lnode->def->param, 
13612                         count * sizeof(lnode->val->param[0])) == 0) &&
13613                 (memcmp(&lnode->val->u, &lnode->def->u, sizeof(lnode->def->u)) == 0)) {
13614                 lnode->val = lnode->def;
13615         }
13616         /* Find the cases that are always lattice lo */
13617         if (lnode->val && 
13618                 triple_is_def(state, lnode->val) &&
13619                 !triple_is_pure(state, lnode->val)) {
13620                 lnode->val = 0;
13621         }
13622         if (lnode->val && 
13623                 (lnode->val->op == OP_SDECL) && 
13624                 (lnode->val != lnode->def)) {
13625                 internal_error(state, lnode->def, "bad sdecl");
13626         }
13627         /* See if the lattice value has changed */
13628         changed = lval_changed(state, old, lnode);
13629         if (lnode->val != scratch) {
13630                 xfree(scratch);
13631         }
13632         return changed;
13633 }
13634
13635 static void scc_visit_branch(struct compile_state *state, struct scc_state *scc,
13636         struct lattice_node *lnode)
13637 {
13638         struct lattice_node *cond;
13639 #if DEBUG_SCC
13640         {
13641                 struct flow_edge *fedge;
13642                 fprintf(stderr, "branch: %d (",
13643                         lnode->def->id);
13644                 
13645                 for(fedge = lnode->fblock->out; fedge; fedge = fedge->out_next) {
13646                         fprintf(stderr, " %d", fedge->dst->block->vertex);
13647                 }
13648                 fprintf(stderr, " )");
13649                 if (TRIPLE_RHS(lnode->def->sizes) > 0) {
13650                         fprintf(stderr, " <- %d",
13651                                 RHS(lnode->def, 0)->id);
13652                 }
13653                 fprintf(stderr, "\n");
13654         }
13655 #endif
13656         if (lnode->def->op != OP_BRANCH) {
13657                 internal_error(state, lnode->def, "not branch");
13658         }
13659         /* This only applies to conditional branches */
13660         if (TRIPLE_RHS(lnode->def->sizes) == 0) {
13661                 return;
13662         }
13663         cond = triple_to_lattice(state, scc, RHS(lnode->def,0));
13664         if (cond->val && !is_const(cond->val)) {
13665 #warning "FIXME do I need to do something here?"
13666                 warning(state, cond->def, "condition not constant?");
13667                 return;
13668         }
13669         if (cond->val == 0) {
13670                 scc_add_fedge(state, scc, cond->fblock->out);
13671                 scc_add_fedge(state, scc, cond->fblock->out->out_next);
13672         }
13673         else if (cond->val->u.cval) {
13674                 scc_add_fedge(state, scc, cond->fblock->out->out_next);
13675                 
13676         } else {
13677                 scc_add_fedge(state, scc, cond->fblock->out);
13678         }
13679
13680 }
13681
13682 static void scc_visit_expr(struct compile_state *state, struct scc_state *scc,
13683         struct lattice_node *lnode)
13684 {
13685         int changed;
13686
13687         changed = compute_lnode_val(state, scc, lnode);
13688 #if DEBUG_SCC
13689         {
13690                 struct triple **expr;
13691                 fprintf(stderr, "expr: %3d %10s (",
13692                         lnode->def->id, tops(lnode->def->op));
13693                 expr = triple_rhs(state, lnode->def, 0);
13694                 for(;expr;expr = triple_rhs(state, lnode->def, expr)) {
13695                         if (*expr) {
13696                                 fprintf(stderr, " %d", (*expr)->id);
13697                         }
13698                 }
13699                 fprintf(stderr, " ) -> %s\n",
13700                         (!lnode->val)? "lo": is_const(lnode->val)? "const": "hi");
13701         }
13702 #endif
13703         if (lnode->def->op == OP_BRANCH) {
13704                 scc_visit_branch(state, scc, lnode);
13705
13706         }
13707         else if (changed) {
13708                 struct ssa_edge *sedge;
13709                 for(sedge = lnode->out; sedge; sedge = sedge->out_next) {
13710                         scc_add_sedge(state, scc, sedge);
13711                 }
13712         }
13713 }
13714
13715 static void scc_writeback_values(
13716         struct compile_state *state, struct scc_state *scc)
13717 {
13718         struct triple *first, *ins;
13719         first = RHS(state->main_function, 0);
13720         ins = first;
13721         do {
13722                 struct lattice_node *lnode;
13723                 lnode = triple_to_lattice(state, scc, ins);
13724                 /* Restore id */
13725                 ins->id = lnode->old_id;
13726 #if DEBUG_SCC
13727                 if (lnode->val && !is_const(lnode->val)) {
13728                         warning(state, lnode->def, 
13729                                 "lattice node still high?");
13730                 }
13731 #endif
13732                 if (lnode->val && (lnode->val != ins)) {
13733                         /* See if it something I know how to write back */
13734                         switch(lnode->val->op) {
13735                         case OP_INTCONST:
13736                                 mkconst(state, ins, lnode->val->u.cval);
13737                                 break;
13738                         case OP_ADDRCONST:
13739                                 mkaddr_const(state, ins, 
13740                                         MISC(lnode->val, 0), lnode->val->u.cval);
13741                                 break;
13742                         default:
13743                                 /* By default don't copy the changes,
13744                                  * recompute them in place instead.
13745                                  */
13746                                 simplify(state, ins);
13747                                 break;
13748                         }
13749                         if (is_const(lnode->val) &&
13750                                 !constants_equal(state, lnode->val, ins)) {
13751                                 internal_error(state, 0, "constants not equal");
13752                         }
13753                         /* Free the lattice nodes */
13754                         xfree(lnode->val);
13755                         lnode->val = 0;
13756                 }
13757                 ins = ins->next;
13758         } while(ins != first);
13759 }
13760
13761 static void scc_transform(struct compile_state *state)
13762 {
13763         struct scc_state scc;
13764
13765         initialize_scc_state(state, &scc);
13766
13767         while(scc.flow_work_list || scc.ssa_work_list) {
13768                 struct flow_edge *fedge;
13769                 struct ssa_edge *sedge;
13770                 struct flow_edge *fptr;
13771                 while((fedge = scc_next_fedge(state, &scc))) {
13772                         struct block *block;
13773                         struct triple *ptr;
13774                         struct flow_block *fblock;
13775                         int time;
13776                         int done;
13777                         if (fedge->executable) {
13778                                 continue;
13779                         }
13780                         if (!fedge->dst) {
13781                                 internal_error(state, 0, "fedge without dst");
13782                         }
13783                         if (!fedge->src) {
13784                                 internal_error(state, 0, "fedge without src");
13785                         }
13786                         fedge->executable = 1;
13787                         fblock = fedge->dst;
13788                         block = fblock->block;
13789                         time = 0;
13790                         for(fptr = fblock->in; fptr; fptr = fptr->in_next) {
13791                                 if (fptr->executable) {
13792                                         time++;
13793                                 }
13794                         }
13795 #if DEBUG_SCC
13796                         fprintf(stderr, "vertex: %d time: %d\n", 
13797                                 block->vertex, time);
13798                         
13799 #endif
13800                         done = 0;
13801                         for(ptr = block->first; !done; ptr = ptr->next) {
13802                                 struct lattice_node *lnode;
13803                                 done = (ptr == block->last);
13804                                 lnode = &scc.lattice[ptr->id];
13805                                 if (ptr->op == OP_PHI) {
13806                                         scc_visit_phi(state, &scc, lnode);
13807                                 }
13808                                 else if (time == 1) {
13809                                         scc_visit_expr(state, &scc, lnode);
13810                                 }
13811                         }
13812                         if (fblock->out && !fblock->out->out_next) {
13813                                 scc_add_fedge(state, &scc, fblock->out);
13814                         }
13815                 }
13816                 while((sedge = scc_next_sedge(state, &scc))) {
13817                         struct lattice_node *lnode;
13818                         struct flow_block *fblock;
13819                         lnode = sedge->dst;
13820                         fblock = lnode->fblock;
13821 #if DEBUG_SCC
13822                         fprintf(stderr, "sedge: %5d (%5d -> %5d)\n",
13823                                 sedge - scc.ssa_edges,
13824                                 sedge->src->def->id,
13825                                 sedge->dst->def->id);
13826 #endif
13827                         if (lnode->def->op == OP_PHI) {
13828                                 scc_visit_phi(state, &scc, lnode);
13829                         }
13830                         else {
13831                                 for(fptr = fblock->in; fptr; fptr = fptr->in_next) {
13832                                         if (fptr->executable) {
13833                                                 break;
13834                                         }
13835                                 }
13836                                 if (fptr) {
13837                                         scc_visit_expr(state, &scc, lnode);
13838                                 }
13839                         }
13840                 }
13841         }
13842         
13843         scc_writeback_values(state, &scc);
13844         free_scc_state(state, &scc);
13845 }
13846
13847
13848 static void transform_to_arch_instructions(struct compile_state *state)
13849 {
13850         struct triple *ins, *first;
13851         first = RHS(state->main_function, 0);
13852         ins = first;
13853         do {
13854                 ins = transform_to_arch_instruction(state, ins);
13855         } while(ins != first);
13856 }
13857
13858 #if DEBUG_CONSISTENCY
13859 static void verify_uses(struct compile_state *state)
13860 {
13861         struct triple *first, *ins;
13862         struct triple_set *set;
13863         first = RHS(state->main_function, 0);
13864         ins = first;
13865         do {
13866                 struct triple **expr;
13867                 expr = triple_rhs(state, ins, 0);
13868                 for(; expr; expr = triple_rhs(state, ins, expr)) {
13869                         for(set = *expr?(*expr)->use:0; set; set = set->next) {
13870                                 if (set->member == ins) {
13871                                         break;
13872                                 }
13873                         }
13874                         if (!set) {
13875                                 internal_error(state, ins, "rhs not used");
13876                         }
13877                 }
13878                 expr = triple_lhs(state, ins, 0);
13879                 for(; expr; expr = triple_lhs(state, ins, expr)) {
13880                         for(set =  *expr?(*expr)->use:0; set; set = set->next) {
13881                                 if (set->member == ins) {
13882                                         break;
13883                                 }
13884                         }
13885                         if (!set) {
13886                                 internal_error(state, ins, "lhs not used");
13887                         }
13888                 }
13889                 ins = ins->next;
13890         } while(ins != first);
13891         
13892 }
13893 static void verify_blocks(struct compile_state *state)
13894 {
13895         struct triple *ins;
13896         struct block *block;
13897         block = state->first_block;
13898         if (!block) {
13899                 return;
13900         }
13901         do {
13902                 for(ins = block->first; ins != block->last->next; ins = ins->next) {
13903                         if (!triple_stores_block(state, ins)) {
13904                                 continue;
13905                         }
13906                         if (ins->u.block != block) {
13907                                 internal_error(state, ins, "inconsitent block specified");
13908                         }
13909                 }
13910                 if (!triple_stores_block(state, block->last->next)) {
13911                         internal_error(state, block->last->next, 
13912                                 "cannot find next block");
13913                 }
13914                 block = block->last->next->u.block;
13915                 if (!block) {
13916                         internal_error(state, block->last->next,
13917                                 "bad next block");
13918                 }
13919         } while(block != state->first_block);
13920 }
13921
13922 static void verify_domination(struct compile_state *state)
13923 {
13924         struct triple *first, *ins;
13925         struct triple_set *set;
13926         if (!state->first_block) {
13927                 return;
13928         }
13929         
13930         first = RHS(state->main_function, 0);
13931         ins = first;
13932         do {
13933                 for(set = ins->use; set; set = set->next) {
13934                         struct triple **expr;
13935                         if (set->member->op == OP_PHI) {
13936                                 continue;
13937                         }
13938                         /* See if the use is on the righ hand side */
13939                         expr = triple_rhs(state, set->member, 0);
13940                         for(; expr ; expr = triple_rhs(state, set->member, expr)) {
13941                                 if (*expr == ins) {
13942                                         break;
13943                                 }
13944                         }
13945                         if (expr &&
13946                                 !tdominates(state, ins, set->member)) {
13947                                 internal_error(state, set->member, 
13948                                         "non dominated rhs use?");
13949                         }
13950                 }
13951                 ins = ins->next;
13952         } while(ins != first);
13953 }
13954
13955 static void verify_piece(struct compile_state *state)
13956 {
13957         struct triple *first, *ins;
13958         first = RHS(state->main_function, 0);
13959         ins = first;
13960         do {
13961                 struct triple *ptr;
13962                 int lhs, i;
13963                 lhs = TRIPLE_LHS(ins->sizes);
13964                 if ((ins->op == OP_WRITE) || (ins->op == OP_STORE)) {
13965                         lhs = 0;
13966                 }
13967                 for(ptr = ins->next, i = 0; i < lhs; i++, ptr = ptr->next) {
13968                         if (ptr != LHS(ins, i)) {
13969                                 internal_error(state, ins, "malformed lhs on %s",
13970                                         tops(ins->op));
13971                         }
13972                         if (ptr->op != OP_PIECE) {
13973                                 internal_error(state, ins, "bad lhs op %s at %d on %s",
13974                                         tops(ptr->op), i, tops(ins->op));
13975                         }
13976                         if (ptr->u.cval != i) {
13977                                 internal_error(state, ins, "bad u.cval of %d %d expected",
13978                                         ptr->u.cval, i);
13979                         }
13980                 }
13981                 ins = ins->next;
13982         } while(ins != first);
13983 }
13984 static void verify_ins_colors(struct compile_state *state)
13985 {
13986         struct triple *first, *ins;
13987         
13988         first = RHS(state->main_function, 0);
13989         ins = first;
13990         do {
13991                 ins = ins->next;
13992         } while(ins != first);
13993 }
13994 static void verify_consistency(struct compile_state *state)
13995 {
13996         verify_uses(state);
13997         verify_blocks(state);
13998         verify_domination(state);
13999         verify_piece(state);
14000         verify_ins_colors(state);
14001 }
14002 #else 
14003 #define verify_consistency(state) do {} while(0)
14004 #endif /* DEBUG_USES */
14005
14006 static void optimize(struct compile_state *state)
14007 {
14008         if (state->debug & DEBUG_TRIPLES) {
14009                 print_triples(state);
14010         }
14011         /* Replace structures with simpler data types */
14012         flatten_structures(state);
14013         if (state->debug & DEBUG_TRIPLES) {
14014                 print_triples(state);
14015         }
14016         verify_consistency(state);
14017         /* Analize the intermediate code */
14018         setup_basic_blocks(state);
14019         analyze_idominators(state);
14020         analyze_ipdominators(state);
14021         /* Transform the code to ssa form */
14022         transform_to_ssa_form(state);
14023         verify_consistency(state);
14024         /* Do strength reduction and simple constant optimizations */
14025         if (state->optimize >= 1) {
14026                 simplify_all(state);
14027         }
14028         verify_consistency(state);
14029         /* Propogate constants throughout the code */
14030         if (state->optimize >= 2) {
14031 #warning "FIXME fix scc_transform"
14032                 scc_transform(state);
14033                 transform_from_ssa_form(state);
14034                 free_basic_blocks(state);
14035                 setup_basic_blocks(state);
14036                 analyze_idominators(state);
14037                 analyze_ipdominators(state);
14038                 transform_to_ssa_form(state);
14039         }
14040         verify_consistency(state);
14041 #warning "WISHLIST implement single use constants (least possible register pressure)"
14042 #warning "WISHLIST implement induction variable elimination"
14043         /* Select architecture instructions and an initial partial
14044          * coloring based on architecture constraints.
14045          */
14046         transform_to_arch_instructions(state);
14047         verify_consistency(state);
14048         if (state->debug & DEBUG_ARCH_CODE) {
14049                 printf("After transform_to_arch_instructions\n");
14050                 print_blocks(state, stdout);
14051                 print_control_flow(state);
14052         }
14053         eliminate_inefectual_code(state);
14054         verify_consistency(state);
14055         if (state->debug & DEBUG_CODE_ELIMINATION) {
14056                 printf("After eliminate_inefectual_code\n");
14057                 print_blocks(state, stdout);
14058                 print_control_flow(state);
14059         }
14060         verify_consistency(state);
14061         /* Color all of the variables to see if they will fit in registers */
14062         insert_copies_to_phi(state);
14063         if (state->debug & DEBUG_INSERTED_COPIES) {
14064                 printf("After insert_copies_to_phi\n");
14065                 print_blocks(state, stdout);
14066                 print_control_flow(state);
14067         }
14068         verify_consistency(state);
14069         insert_mandatory_copies(state);
14070         if (state->debug & DEBUG_INSERTED_COPIES) {
14071                 printf("After insert_mandatory_copies\n");
14072                 print_blocks(state, stdout);
14073                 print_control_flow(state);
14074         }
14075         verify_consistency(state);
14076         allocate_registers(state);
14077         verify_consistency(state);
14078         if (state->debug & DEBUG_INTERMEDIATE_CODE) {
14079                 print_blocks(state, stdout);
14080         }
14081         if (state->debug & DEBUG_CONTROL_FLOW) {
14082                 print_control_flow(state);
14083         }
14084         /* Remove the optimization information.
14085          * This is more to check for memory consistency than to free memory.
14086          */
14087         free_basic_blocks(state);
14088 }
14089
14090 static void print_op_asm(struct compile_state *state,
14091         struct triple *ins, FILE *fp)
14092 {
14093         struct asm_info *info;
14094         const char *ptr;
14095         unsigned lhs, rhs, i;
14096         info = ins->u.ainfo;
14097         lhs = TRIPLE_LHS(ins->sizes);
14098         rhs = TRIPLE_RHS(ins->sizes);
14099         /* Don't count the clobbers in lhs */
14100         for(i = 0; i < lhs; i++) {
14101                 if (LHS(ins, i)->type == &void_type) {
14102                         break;
14103                 }
14104         }
14105         lhs = i;
14106         fputc('\t', fp);
14107         for(ptr = info->str; *ptr; ptr++) {
14108                 char *next;
14109                 unsigned long param;
14110                 struct triple *piece;
14111                 if (*ptr != '%') {
14112                         fputc(*ptr, fp);
14113                         continue;
14114                 }
14115                 ptr++;
14116                 if (*ptr == '%') {
14117                         fputc('%', fp);
14118                         continue;
14119                 }
14120                 param = strtoul(ptr, &next, 10);
14121                 if (ptr == next) {
14122                         error(state, ins, "Invalid asm template");
14123                 }
14124                 if (param >= (lhs + rhs)) {
14125                         error(state, ins, "Invalid param %%%u in asm template",
14126                                 param);
14127                 }
14128                 piece = (param < lhs)? LHS(ins, param) : RHS(ins, param - lhs);
14129                 fprintf(fp, "%s", 
14130                         arch_reg_str(ID_REG(piece->id)));
14131                 ptr = next;
14132         }
14133         fputc('\n', fp);
14134 }
14135
14136
14137 /* Only use the low x86 byte registers.  This allows me
14138  * allocate the entire register when a byte register is used.
14139  */
14140 #define X86_4_8BIT_GPRS 1
14141
14142 /* Recognized x86 cpu variants */
14143 #define BAD_CPU      0
14144 #define CPU_I386     1
14145 #define CPU_P3       2
14146 #define CPU_P4       3
14147 #define CPU_K7       4
14148 #define CPU_K8       5
14149
14150 #define CPU_DEFAULT  CPU_I386
14151
14152 /* The x86 register classes */
14153 #define REGC_FLAGS    0
14154 #define REGC_GPR8     1
14155 #define REGC_GPR16    2
14156 #define REGC_GPR32    3
14157 #define REGC_GPR64    4
14158 #define REGC_MMX      5
14159 #define REGC_XMM      6
14160 #define REGC_GPR32_8  7
14161 #define REGC_GPR16_8  8
14162 #define REGC_IMM32    9
14163 #define REGC_IMM16   10
14164 #define REGC_IMM8    11
14165 #define LAST_REGC  REGC_IMM8
14166 #if LAST_REGC >= MAX_REGC
14167 #error "MAX_REGC is to low"
14168 #endif
14169
14170 /* Register class masks */
14171 #define REGCM_FLAGS   (1 << REGC_FLAGS)
14172 #define REGCM_GPR8    (1 << REGC_GPR8)
14173 #define REGCM_GPR16   (1 << REGC_GPR16)
14174 #define REGCM_GPR32   (1 << REGC_GPR32)
14175 #define REGCM_GPR64   (1 << REGC_GPR64)
14176 #define REGCM_MMX     (1 << REGC_MMX)
14177 #define REGCM_XMM     (1 << REGC_XMM)
14178 #define REGCM_GPR32_8 (1 << REGC_GPR32_8)
14179 #define REGCM_GPR16_8 (1 << REGC_GPR16_8)
14180 #define REGCM_IMM32   (1 << REGC_IMM32)
14181 #define REGCM_IMM16   (1 << REGC_IMM16)
14182 #define REGCM_IMM8    (1 << REGC_IMM8)
14183 #define REGCM_ALL     ((1 << (LAST_REGC + 1)) - 1)
14184
14185 /* The x86 registers */
14186 #define REG_EFLAGS  2
14187 #define REGC_FLAGS_FIRST REG_EFLAGS
14188 #define REGC_FLAGS_LAST  REG_EFLAGS
14189 #define REG_AL      3
14190 #define REG_BL      4
14191 #define REG_CL      5
14192 #define REG_DL      6
14193 #define REG_AH      7
14194 #define REG_BH      8
14195 #define REG_CH      9
14196 #define REG_DH      10
14197 #define REGC_GPR8_FIRST  REG_AL
14198 #if X86_4_8BIT_GPRS
14199 #define REGC_GPR8_LAST   REG_DL
14200 #else 
14201 #define REGC_GPR8_LAST   REG_DH
14202 #endif
14203 #define REG_AX     11
14204 #define REG_BX     12
14205 #define REG_CX     13
14206 #define REG_DX     14
14207 #define REG_SI     15
14208 #define REG_DI     16
14209 #define REG_BP     17
14210 #define REG_SP     18
14211 #define REGC_GPR16_FIRST REG_AX
14212 #define REGC_GPR16_LAST  REG_SP
14213 #define REG_EAX    19
14214 #define REG_EBX    20
14215 #define REG_ECX    21
14216 #define REG_EDX    22
14217 #define REG_ESI    23
14218 #define REG_EDI    24
14219 #define REG_EBP    25
14220 #define REG_ESP    26
14221 #define REGC_GPR32_FIRST REG_EAX
14222 #define REGC_GPR32_LAST  REG_ESP
14223 #define REG_EDXEAX 27
14224 #define REGC_GPR64_FIRST REG_EDXEAX
14225 #define REGC_GPR64_LAST  REG_EDXEAX
14226 #define REG_MMX0   28
14227 #define REG_MMX1   29
14228 #define REG_MMX2   30
14229 #define REG_MMX3   31
14230 #define REG_MMX4   32
14231 #define REG_MMX5   33
14232 #define REG_MMX6   34
14233 #define REG_MMX7   35
14234 #define REGC_MMX_FIRST REG_MMX0
14235 #define REGC_MMX_LAST  REG_MMX7
14236 #define REG_XMM0   36
14237 #define REG_XMM1   37
14238 #define REG_XMM2   38
14239 #define REG_XMM3   39
14240 #define REG_XMM4   40
14241 #define REG_XMM5   41
14242 #define REG_XMM6   42
14243 #define REG_XMM7   43
14244 #define REGC_XMM_FIRST REG_XMM0
14245 #define REGC_XMM_LAST  REG_XMM7
14246 #warning "WISHLIST figure out how to use pinsrw and pextrw to better use extended regs"
14247 #define LAST_REG   REG_XMM7
14248
14249 #define REGC_GPR32_8_FIRST REG_EAX
14250 #define REGC_GPR32_8_LAST  REG_EDX
14251 #define REGC_GPR16_8_FIRST REG_AX
14252 #define REGC_GPR16_8_LAST  REG_DX
14253
14254 #define REGC_IMM8_FIRST    -1
14255 #define REGC_IMM8_LAST     -1
14256 #define REGC_IMM16_FIRST   -2
14257 #define REGC_IMM16_LAST    -1
14258 #define REGC_IMM32_FIRST   -4
14259 #define REGC_IMM32_LAST    -1
14260
14261 #if LAST_REG >= MAX_REGISTERS
14262 #error "MAX_REGISTERS to low"
14263 #endif
14264
14265
14266 static unsigned regc_size[LAST_REGC +1] = {
14267         [REGC_FLAGS]   = REGC_FLAGS_LAST   - REGC_FLAGS_FIRST + 1,
14268         [REGC_GPR8]    = REGC_GPR8_LAST    - REGC_GPR8_FIRST + 1,
14269         [REGC_GPR16]   = REGC_GPR16_LAST   - REGC_GPR16_FIRST + 1,
14270         [REGC_GPR32]   = REGC_GPR32_LAST   - REGC_GPR32_FIRST + 1,
14271         [REGC_GPR64]   = REGC_GPR64_LAST   - REGC_GPR64_FIRST + 1,
14272         [REGC_MMX]     = REGC_MMX_LAST     - REGC_MMX_FIRST + 1,
14273         [REGC_XMM]     = REGC_XMM_LAST     - REGC_XMM_FIRST + 1,
14274         [REGC_GPR32_8] = REGC_GPR32_8_LAST - REGC_GPR32_8_FIRST + 1,
14275         [REGC_GPR16_8] = REGC_GPR16_8_LAST - REGC_GPR16_8_FIRST + 1,
14276         [REGC_IMM32]   = 0,
14277         [REGC_IMM16]   = 0,
14278         [REGC_IMM8]    = 0,
14279 };
14280
14281 static const struct {
14282         int first, last;
14283 } regcm_bound[LAST_REGC + 1] = {
14284         [REGC_FLAGS]   = { REGC_FLAGS_FIRST,   REGC_FLAGS_LAST },
14285         [REGC_GPR8]    = { REGC_GPR8_FIRST,    REGC_GPR8_LAST },
14286         [REGC_GPR16]   = { REGC_GPR16_FIRST,   REGC_GPR16_LAST },
14287         [REGC_GPR32]   = { REGC_GPR32_FIRST,   REGC_GPR32_LAST },
14288         [REGC_GPR64]   = { REGC_GPR64_FIRST,   REGC_GPR64_LAST },
14289         [REGC_MMX]     = { REGC_MMX_FIRST,     REGC_MMX_LAST },
14290         [REGC_XMM]     = { REGC_XMM_FIRST,     REGC_XMM_LAST },
14291         [REGC_GPR32_8] = { REGC_GPR32_8_FIRST, REGC_GPR32_8_LAST },
14292         [REGC_GPR16_8] = { REGC_GPR16_8_FIRST, REGC_GPR16_8_LAST },
14293         [REGC_IMM32]   = { REGC_IMM32_FIRST,   REGC_IMM32_LAST },
14294         [REGC_IMM16]   = { REGC_IMM16_FIRST,   REGC_IMM16_LAST },
14295         [REGC_IMM8]    = { REGC_IMM8_FIRST,    REGC_IMM8_LAST },
14296 };
14297
14298 static int arch_encode_cpu(const char *cpu)
14299 {
14300         struct cpu {
14301                 const char *name;
14302                 int cpu;
14303         } cpus[] = {
14304                 { "i386", CPU_I386 },
14305                 { "p3",   CPU_P3 },
14306                 { "p4",   CPU_P4 },
14307                 { "k7",   CPU_K7 },
14308                 { "k8",   CPU_K8 },
14309                 {  0,     BAD_CPU }
14310         };
14311         struct cpu *ptr;
14312         for(ptr = cpus; ptr->name; ptr++) {
14313                 if (strcmp(ptr->name, cpu) == 0) {
14314                         break;
14315                 }
14316         }
14317         return ptr->cpu;
14318 }
14319
14320 static unsigned arch_regc_size(struct compile_state *state, int class)
14321 {
14322         if ((class < 0) || (class > LAST_REGC)) {
14323                 return 0;
14324         }
14325         return regc_size[class];
14326 }
14327 static int arch_regcm_intersect(unsigned regcm1, unsigned regcm2)
14328 {
14329         /* See if two register classes may have overlapping registers */
14330         unsigned gpr_mask = REGCM_GPR8 | REGCM_GPR16_8 | REGCM_GPR16 |
14331                 REGCM_GPR32_8 | REGCM_GPR32 | REGCM_GPR64;
14332
14333         /* Special case for the immediates */
14334         if ((regcm1 & (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) &&
14335                 ((regcm1 & ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) == 0) &&
14336                 (regcm2 & (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) &&
14337                 ((regcm2 & ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) == 0)) { 
14338                 return 0;
14339         }
14340         return (regcm1 & regcm2) ||
14341                 ((regcm1 & gpr_mask) && (regcm2 & gpr_mask));
14342 }
14343
14344 static void arch_reg_equivs(
14345         struct compile_state *state, unsigned *equiv, int reg)
14346 {
14347         if ((reg < 0) || (reg > LAST_REG)) {
14348                 internal_error(state, 0, "invalid register");
14349         }
14350         *equiv++ = reg;
14351         switch(reg) {
14352         case REG_AL:
14353 #if X86_4_8BIT_GPRS
14354                 *equiv++ = REG_AH;
14355 #endif
14356                 *equiv++ = REG_AX;
14357                 *equiv++ = REG_EAX;
14358                 *equiv++ = REG_EDXEAX;
14359                 break;
14360         case REG_AH:
14361 #if X86_4_8BIT_GPRS
14362                 *equiv++ = REG_AL;
14363 #endif
14364                 *equiv++ = REG_AX;
14365                 *equiv++ = REG_EAX;
14366                 *equiv++ = REG_EDXEAX;
14367                 break;
14368         case REG_BL:  
14369 #if X86_4_8BIT_GPRS
14370                 *equiv++ = REG_BH;
14371 #endif
14372                 *equiv++ = REG_BX;
14373                 *equiv++ = REG_EBX;
14374                 break;
14375
14376         case REG_BH:
14377 #if X86_4_8BIT_GPRS
14378                 *equiv++ = REG_BL;
14379 #endif
14380                 *equiv++ = REG_BX;
14381                 *equiv++ = REG_EBX;
14382                 break;
14383         case REG_CL:
14384 #if X86_4_8BIT_GPRS
14385                 *equiv++ = REG_CH;
14386 #endif
14387                 *equiv++ = REG_CX;
14388                 *equiv++ = REG_ECX;
14389                 break;
14390
14391         case REG_CH:
14392 #if X86_4_8BIT_GPRS
14393                 *equiv++ = REG_CL;
14394 #endif
14395                 *equiv++ = REG_CX;
14396                 *equiv++ = REG_ECX;
14397                 break;
14398         case REG_DL:
14399 #if X86_4_8BIT_GPRS
14400                 *equiv++ = REG_DH;
14401 #endif
14402                 *equiv++ = REG_DX;
14403                 *equiv++ = REG_EDX;
14404                 *equiv++ = REG_EDXEAX;
14405                 break;
14406         case REG_DH:
14407 #if X86_4_8BIT_GPRS
14408                 *equiv++ = REG_DL;
14409 #endif
14410                 *equiv++ = REG_DX;
14411                 *equiv++ = REG_EDX;
14412                 *equiv++ = REG_EDXEAX;
14413                 break;
14414         case REG_AX:
14415                 *equiv++ = REG_AL;
14416                 *equiv++ = REG_AH;
14417                 *equiv++ = REG_EAX;
14418                 *equiv++ = REG_EDXEAX;
14419                 break;
14420         case REG_BX:
14421                 *equiv++ = REG_BL;
14422                 *equiv++ = REG_BH;
14423                 *equiv++ = REG_EBX;
14424                 break;
14425         case REG_CX:  
14426                 *equiv++ = REG_CL;
14427                 *equiv++ = REG_CH;
14428                 *equiv++ = REG_ECX;
14429                 break;
14430         case REG_DX:  
14431                 *equiv++ = REG_DL;
14432                 *equiv++ = REG_DH;
14433                 *equiv++ = REG_EDX;
14434                 *equiv++ = REG_EDXEAX;
14435                 break;
14436         case REG_SI:  
14437                 *equiv++ = REG_ESI;
14438                 break;
14439         case REG_DI:
14440                 *equiv++ = REG_EDI;
14441                 break;
14442         case REG_BP:
14443                 *equiv++ = REG_EBP;
14444                 break;
14445         case REG_SP:
14446                 *equiv++ = REG_ESP;
14447                 break;
14448         case REG_EAX:
14449                 *equiv++ = REG_AL;
14450                 *equiv++ = REG_AH;
14451                 *equiv++ = REG_AX;
14452                 *equiv++ = REG_EDXEAX;
14453                 break;
14454         case REG_EBX:
14455                 *equiv++ = REG_BL;
14456                 *equiv++ = REG_BH;
14457                 *equiv++ = REG_BX;
14458                 break;
14459         case REG_ECX:
14460                 *equiv++ = REG_CL;
14461                 *equiv++ = REG_CH;
14462                 *equiv++ = REG_CX;
14463                 break;
14464         case REG_EDX:
14465                 *equiv++ = REG_DL;
14466                 *equiv++ = REG_DH;
14467                 *equiv++ = REG_DX;
14468                 *equiv++ = REG_EDXEAX;
14469                 break;
14470         case REG_ESI: 
14471                 *equiv++ = REG_SI;
14472                 break;
14473         case REG_EDI: 
14474                 *equiv++ = REG_DI;
14475                 break;
14476         case REG_EBP: 
14477                 *equiv++ = REG_BP;
14478                 break;
14479         case REG_ESP: 
14480                 *equiv++ = REG_SP;
14481                 break;
14482         case REG_EDXEAX: 
14483                 *equiv++ = REG_AL;
14484                 *equiv++ = REG_AH;
14485                 *equiv++ = REG_DL;
14486                 *equiv++ = REG_DH;
14487                 *equiv++ = REG_AX;
14488                 *equiv++ = REG_DX;
14489                 *equiv++ = REG_EAX;
14490                 *equiv++ = REG_EDX;
14491                 break;
14492         }
14493         *equiv++ = REG_UNSET; 
14494 }
14495
14496 static unsigned arch_avail_mask(struct compile_state *state)
14497 {
14498         unsigned avail_mask;
14499         avail_mask = REGCM_GPR8 | REGCM_GPR16_8 | REGCM_GPR16 | 
14500                 REGCM_GPR32 | REGCM_GPR32_8 | REGCM_GPR64 |
14501                 REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8 | REGCM_FLAGS;
14502         switch(state->cpu) {
14503         case CPU_P3:
14504         case CPU_K7:
14505                 avail_mask |= REGCM_MMX;
14506                 break;
14507         case CPU_P4:
14508         case CPU_K8:
14509                 avail_mask |= REGCM_MMX | REGCM_XMM;
14510                 break;
14511         }
14512 #if 0
14513         /* Don't enable 8 bit values until I can force both operands
14514          * to be 8bits simultaneously.
14515          */
14516         avail_mask &= ~(REGCM_GPR8 | REGCM_GPR16_8 | REGCM_GPR16);
14517 #endif
14518         return avail_mask;
14519 }
14520
14521 static unsigned arch_regcm_normalize(struct compile_state *state, unsigned regcm)
14522 {
14523         unsigned mask, result;
14524         int class, class2;
14525         result = regcm;
14526         result &= arch_avail_mask(state);
14527
14528         for(class = 0, mask = 1; mask; mask <<= 1, class++) {
14529                 if ((result & mask) == 0) {
14530                         continue;
14531                 }
14532                 if (class > LAST_REGC) {
14533                         result &= ~mask;
14534                 }
14535                 for(class2 = 0; class2 <= LAST_REGC; class2++) {
14536                         if ((regcm_bound[class2].first >= regcm_bound[class].first) &&
14537                                 (regcm_bound[class2].last <= regcm_bound[class].last)) {
14538                                 result |= (1 << class2);
14539                         }
14540                 }
14541         }
14542         return result;
14543 }
14544
14545 static unsigned arch_reg_regcm(struct compile_state *state, int reg)
14546 {
14547         unsigned mask;
14548         int class;
14549         mask = 0;
14550         for(class = 0; class <= LAST_REGC; class++) {
14551                 if ((reg >= regcm_bound[class].first) &&
14552                         (reg <= regcm_bound[class].last)) {
14553                         mask |= (1 << class);
14554                 }
14555         }
14556         if (!mask) {
14557                 internal_error(state, 0, "reg %d not in any class", reg);
14558         }
14559         return mask;
14560 }
14561
14562 static struct reg_info arch_reg_constraint(
14563         struct compile_state *state, struct type *type, const char *constraint)
14564 {
14565         static const struct {
14566                 char class;
14567                 unsigned int mask;
14568                 unsigned int reg;
14569         } constraints[] = {
14570                 { 'r', REGCM_GPR32, REG_UNSET },
14571                 { 'g', REGCM_GPR32, REG_UNSET },
14572                 { 'p', REGCM_GPR32, REG_UNSET },
14573                 { 'q', REGCM_GPR8,  REG_UNSET },
14574                 { 'Q', REGCM_GPR32_8, REG_UNSET },
14575                 { 'x', REGCM_XMM,   REG_UNSET },
14576                 { 'y', REGCM_MMX,   REG_UNSET },
14577                 { 'a', REGCM_GPR32, REG_EAX },
14578                 { 'b', REGCM_GPR32, REG_EBX },
14579                 { 'c', REGCM_GPR32, REG_ECX },
14580                 { 'd', REGCM_GPR32, REG_EDX },
14581                 { 'D', REGCM_GPR32, REG_EDI },
14582                 { 'S', REGCM_GPR32, REG_ESI },
14583                 { '\0', 0, REG_UNSET },
14584         };
14585         unsigned int regcm;
14586         unsigned int mask, reg;
14587         struct reg_info result;
14588         const char *ptr;
14589         regcm = arch_type_to_regcm(state, type);
14590         reg = REG_UNSET;
14591         mask = 0;
14592         for(ptr = constraint; *ptr; ptr++) {
14593                 int i;
14594                 if (*ptr ==  ' ') {
14595                         continue;
14596                 }
14597                 for(i = 0; constraints[i].class != '\0'; i++) {
14598                         if (constraints[i].class == *ptr) {
14599                                 break;
14600                         }
14601                 }
14602                 if (constraints[i].class == '\0') {
14603                         error(state, 0, "invalid register constraint ``%c''", *ptr);
14604                         break;
14605                 }
14606                 if ((constraints[i].mask & regcm) == 0) {
14607                         error(state, 0, "invalid register class %c specified",
14608                                 *ptr);
14609                 }
14610                 mask |= constraints[i].mask;
14611                 if (constraints[i].reg != REG_UNSET) {
14612                         if ((reg != REG_UNSET) && (reg != constraints[i].reg)) {
14613                                 error(state, 0, "Only one register may be specified");
14614                         }
14615                         reg = constraints[i].reg;
14616                 }
14617         }
14618         result.reg = reg;
14619         result.regcm = mask;
14620         return result;
14621 }
14622
14623 static struct reg_info arch_reg_clobber(
14624         struct compile_state *state, const char *clobber)
14625 {
14626         struct reg_info result;
14627         if (strcmp(clobber, "memory") == 0) {
14628                 result.reg = REG_UNSET;
14629                 result.regcm = 0;
14630         }
14631         else if (strcmp(clobber, "%eax") == 0) {
14632                 result.reg = REG_EAX;
14633                 result.regcm = REGCM_GPR32;
14634         }
14635         else if (strcmp(clobber, "%ebx") == 0) {
14636                 result.reg = REG_EBX;
14637                 result.regcm = REGCM_GPR32;
14638         }
14639         else if (strcmp(clobber, "%ecx") == 0) {
14640                 result.reg = REG_ECX;
14641                 result.regcm = REGCM_GPR32;
14642         }
14643         else if (strcmp(clobber, "%edx") == 0) {
14644                 result.reg = REG_EDX;
14645                 result.regcm = REGCM_GPR32;
14646         }
14647         else if (strcmp(clobber, "%esi") == 0) {
14648                 result.reg = REG_ESI;
14649                 result.regcm = REGCM_GPR32;
14650         }
14651         else if (strcmp(clobber, "%edi") == 0) {
14652                 result.reg = REG_EDI;
14653                 result.regcm = REGCM_GPR32;
14654         }
14655         else if (strcmp(clobber, "%ebp") == 0) {
14656                 result.reg = REG_EBP;
14657                 result.regcm = REGCM_GPR32;
14658         }
14659         else if (strcmp(clobber, "%esp") == 0) {
14660                 result.reg = REG_ESP;
14661                 result.regcm = REGCM_GPR32;
14662         }
14663         else if (strcmp(clobber, "cc") == 0) {
14664                 result.reg = REG_EFLAGS;
14665                 result.regcm = REGCM_FLAGS;
14666         }
14667         else if ((strncmp(clobber, "xmm", 3) == 0)  &&
14668                 octdigitp(clobber[3]) && (clobber[4] == '\0')) {
14669                 result.reg = REG_XMM0 + octdigval(clobber[3]);
14670                 result.regcm = REGCM_XMM;
14671         }
14672         else if ((strncmp(clobber, "mmx", 3) == 0) &&
14673                 octdigitp(clobber[3]) && (clobber[4] == '\0')) {
14674                 result.reg = REG_MMX0 + octdigval(clobber[3]);
14675                 result.regcm = REGCM_MMX;
14676         }
14677         else {
14678                 error(state, 0, "Invalid register clobber");
14679                 result.reg = REG_UNSET;
14680                 result.regcm = 0;
14681         }
14682         return result;
14683 }
14684
14685 static int do_select_reg(struct compile_state *state, 
14686         char *used, int reg, unsigned classes)
14687 {
14688         unsigned mask;
14689         if (used[reg]) {
14690                 return REG_UNSET;
14691         }
14692         mask = arch_reg_regcm(state, reg);
14693         return (classes & mask) ? reg : REG_UNSET;
14694 }
14695
14696 static int arch_select_free_register(
14697         struct compile_state *state, char *used, int classes)
14698 {
14699         /* Preference: flags, 8bit gprs, 32bit gprs, other 32bit reg
14700          * other types of registers.
14701          */
14702         int i, reg;
14703         reg = REG_UNSET;
14704         for(i = REGC_FLAGS_FIRST; (reg == REG_UNSET) && (i <= REGC_FLAGS_LAST); i++) {
14705                 reg = do_select_reg(state, used, i, classes);
14706         }
14707         for(i = REGC_GPR32_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR32_LAST); i++) {
14708                 reg = do_select_reg(state, used, i, classes);
14709         }
14710         for(i = REGC_MMX_FIRST; (reg == REG_UNSET) && (i <= REGC_MMX_LAST); i++) {
14711                 reg = do_select_reg(state, used, i, classes);
14712         }
14713         for(i = REGC_XMM_FIRST; (reg == REG_UNSET) && (i <= REGC_XMM_LAST); i++) {
14714                 reg = do_select_reg(state, used, i, classes);
14715         }
14716         for(i = REGC_GPR16_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR16_LAST); i++) {
14717                 reg = do_select_reg(state, used, i, classes);
14718         }
14719         for(i = REGC_GPR8_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR8_LAST); i++) {
14720                 reg = do_select_reg(state, used, i, classes);
14721         }
14722         for(i = REGC_GPR64_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR64_LAST); i++) {
14723                 reg = do_select_reg(state, used, i, classes);
14724         }
14725         return reg;
14726 }
14727
14728
14729 static unsigned arch_type_to_regcm(struct compile_state *state, struct type *type) 
14730 {
14731 #warning "FIXME force types smaller (if legal) before I get here"
14732         unsigned avail_mask;
14733         unsigned mask;
14734         mask = 0;
14735         avail_mask = arch_avail_mask(state);
14736         switch(type->type & TYPE_MASK) {
14737         case TYPE_ARRAY:
14738         case TYPE_VOID: 
14739                 mask = 0; 
14740                 break;
14741         case TYPE_CHAR:
14742         case TYPE_UCHAR:
14743                 mask = REGCM_GPR8 | 
14744                         REGCM_GPR16 | REGCM_GPR16_8 | 
14745                         REGCM_GPR32 | REGCM_GPR32_8 |
14746                         REGCM_GPR64 |
14747                         REGCM_MMX | REGCM_XMM |
14748                         REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8;
14749                 break;
14750         case TYPE_SHORT:
14751         case TYPE_USHORT:
14752                 mask =  REGCM_GPR16 | REGCM_GPR16_8 |
14753                         REGCM_GPR32 | REGCM_GPR32_8 |
14754                         REGCM_GPR64 |
14755                         REGCM_MMX | REGCM_XMM |
14756                         REGCM_IMM32 | REGCM_IMM16;
14757                 break;
14758         case TYPE_INT:
14759         case TYPE_UINT:
14760         case TYPE_LONG:
14761         case TYPE_ULONG:
14762         case TYPE_POINTER:
14763                 mask =  REGCM_GPR32 | REGCM_GPR32_8 |
14764                         REGCM_GPR64 | REGCM_MMX | REGCM_XMM |
14765                         REGCM_IMM32;
14766                 break;
14767         default:
14768                 internal_error(state, 0, "no register class for type");
14769                 break;
14770         }
14771         mask &= avail_mask;
14772         return mask;
14773 }
14774
14775 static int is_imm32(struct triple *imm)
14776 {
14777         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xffffffffUL)) ||
14778                 (imm->op == OP_ADDRCONST);
14779         
14780 }
14781 static int is_imm16(struct triple *imm)
14782 {
14783         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xffff));
14784 }
14785 static int is_imm8(struct triple *imm)
14786 {
14787         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xff));
14788 }
14789
14790 static int get_imm32(struct triple *ins, struct triple **expr)
14791 {
14792         struct triple *imm;
14793         imm = *expr;
14794         while(imm->op == OP_COPY) {
14795                 imm = RHS(imm, 0);
14796         }
14797         if (!is_imm32(imm)) {
14798                 return 0;
14799         }
14800         unuse_triple(*expr, ins);
14801         use_triple(imm, ins);
14802         *expr = imm;
14803         return 1;
14804 }
14805
14806 static int get_imm8(struct triple *ins, struct triple **expr)
14807 {
14808         struct triple *imm;
14809         imm = *expr;
14810         while(imm->op == OP_COPY) {
14811                 imm = RHS(imm, 0);
14812         }
14813         if (!is_imm8(imm)) {
14814                 return 0;
14815         }
14816         unuse_triple(*expr, ins);
14817         use_triple(imm, ins);
14818         *expr = imm;
14819         return 1;
14820 }
14821
14822 #define TEMPLATE_NOP         0
14823 #define TEMPLATE_INTCONST8   1
14824 #define TEMPLATE_INTCONST32  2
14825 #define TEMPLATE_COPY_REG    3
14826 #define TEMPLATE_COPY_IMM32  4
14827 #define TEMPLATE_COPY_IMM16  5
14828 #define TEMPLATE_COPY_IMM8   6
14829 #define TEMPLATE_PHI         7
14830 #define TEMPLATE_STORE8      8
14831 #define TEMPLATE_STORE16     9
14832 #define TEMPLATE_STORE32    10
14833 #define TEMPLATE_LOAD8      11
14834 #define TEMPLATE_LOAD16     12
14835 #define TEMPLATE_LOAD32     13
14836 #define TEMPLATE_BINARY_REG 14
14837 #define TEMPLATE_BINARY_IMM 15
14838 #define TEMPLATE_SL_CL      16
14839 #define TEMPLATE_SL_IMM     17
14840 #define TEMPLATE_UNARY      18
14841 #define TEMPLATE_CMP_REG    19
14842 #define TEMPLATE_CMP_IMM    20
14843 #define TEMPLATE_TEST       21
14844 #define TEMPLATE_SET        22
14845 #define TEMPLATE_JMP        23
14846 #define TEMPLATE_INB_DX     24
14847 #define TEMPLATE_INB_IMM    25
14848 #define TEMPLATE_INW_DX     26
14849 #define TEMPLATE_INW_IMM    27
14850 #define TEMPLATE_INL_DX     28
14851 #define TEMPLATE_INL_IMM    29
14852 #define TEMPLATE_OUTB_DX    30
14853 #define TEMPLATE_OUTB_IMM   31
14854 #define TEMPLATE_OUTW_DX    32
14855 #define TEMPLATE_OUTW_IMM   33
14856 #define TEMPLATE_OUTL_DX    34
14857 #define TEMPLATE_OUTL_IMM   35
14858 #define TEMPLATE_BSF        36
14859 #define TEMPLATE_RDMSR      37
14860 #define TEMPLATE_WRMSR      38
14861 #define LAST_TEMPLATE       TEMPLATE_WRMSR
14862 #if LAST_TEMPLATE >= MAX_TEMPLATES
14863 #error "MAX_TEMPLATES to low"
14864 #endif
14865
14866 #define COPY_REGCM (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8 | REGCM_MMX | REGCM_XMM)
14867 #define COPY32_REGCM (REGCM_GPR32 | REGCM_MMX | REGCM_XMM)
14868
14869 static struct ins_template templates[] = {
14870         [TEMPLATE_NOP]      = {},
14871         [TEMPLATE_INTCONST8] = { 
14872                 .lhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
14873         },
14874         [TEMPLATE_INTCONST32] = { 
14875                 .lhs = { [0] = { REG_UNNEEDED, REGCM_IMM32 } },
14876         },
14877         [TEMPLATE_COPY_REG] = {
14878                 .lhs = { [0] = { REG_UNSET, COPY_REGCM } },
14879                 .rhs = { [0] = { REG_UNSET, COPY_REGCM }  },
14880         },
14881         [TEMPLATE_COPY_IMM32] = {
14882                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM } },
14883                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM32 } },
14884         },
14885         [TEMPLATE_COPY_IMM16] = {
14886                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM | REGCM_GPR16 } },
14887                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM16 } },
14888         },
14889         [TEMPLATE_COPY_IMM8] = {
14890                 .lhs = { [0] = { REG_UNSET, COPY_REGCM } },
14891                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
14892         },
14893         [TEMPLATE_PHI] = { 
14894                 .lhs = { [0] = { REG_VIRT0, COPY_REGCM } },
14895                 .rhs = { 
14896                         [ 0] = { REG_VIRT0, COPY_REGCM },
14897                         [ 1] = { REG_VIRT0, COPY_REGCM },
14898                         [ 2] = { REG_VIRT0, COPY_REGCM },
14899                         [ 3] = { REG_VIRT0, COPY_REGCM },
14900                         [ 4] = { REG_VIRT0, COPY_REGCM },
14901                         [ 5] = { REG_VIRT0, COPY_REGCM },
14902                         [ 6] = { REG_VIRT0, COPY_REGCM },
14903                         [ 7] = { REG_VIRT0, COPY_REGCM },
14904                         [ 8] = { REG_VIRT0, COPY_REGCM },
14905                         [ 9] = { REG_VIRT0, COPY_REGCM },
14906                         [10] = { REG_VIRT0, COPY_REGCM },
14907                         [11] = { REG_VIRT0, COPY_REGCM },
14908                         [12] = { REG_VIRT0, COPY_REGCM },
14909                         [13] = { REG_VIRT0, COPY_REGCM },
14910                         [14] = { REG_VIRT0, COPY_REGCM },
14911                         [15] = { REG_VIRT0, COPY_REGCM },
14912                 }, },
14913         [TEMPLATE_STORE8] = {
14914                 .lhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
14915                 .rhs = { [0] = { REG_UNSET, REGCM_GPR8 } },
14916         },
14917         [TEMPLATE_STORE16] = {
14918                 .lhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
14919                 .rhs = { [0] = { REG_UNSET, REGCM_GPR16 } },
14920         },
14921         [TEMPLATE_STORE32] = {
14922                 .lhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
14923                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
14924         },
14925         [TEMPLATE_LOAD8] = {
14926                 .lhs = { [0] = { REG_UNSET, REGCM_GPR8 } },
14927                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
14928         },
14929         [TEMPLATE_LOAD16] = {
14930                 .lhs = { [0] = { REG_UNSET, REGCM_GPR16 } },
14931                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
14932         },
14933         [TEMPLATE_LOAD32] = {
14934                 .lhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
14935                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
14936         },
14937         [TEMPLATE_BINARY_REG] = {
14938                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
14939                 .rhs = { 
14940                         [0] = { REG_VIRT0, REGCM_GPR32 },
14941                         [1] = { REG_UNSET, REGCM_GPR32 },
14942                 },
14943         },
14944         [TEMPLATE_BINARY_IMM] = {
14945                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
14946                 .rhs = { 
14947                         [0] = { REG_VIRT0,    REGCM_GPR32 },
14948                         [1] = { REG_UNNEEDED, REGCM_IMM32 },
14949                 },
14950         },
14951         [TEMPLATE_SL_CL] = {
14952                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
14953                 .rhs = { 
14954                         [0] = { REG_VIRT0, REGCM_GPR32 },
14955                         [1] = { REG_CL, REGCM_GPR8 },
14956                 },
14957         },
14958         [TEMPLATE_SL_IMM] = {
14959                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
14960                 .rhs = { 
14961                         [0] = { REG_VIRT0,    REGCM_GPR32 },
14962                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
14963                 },
14964         },
14965         [TEMPLATE_UNARY] = {
14966                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
14967                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
14968         },
14969         [TEMPLATE_CMP_REG] = {
14970                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
14971                 .rhs = {
14972                         [0] = { REG_UNSET, REGCM_GPR32 },
14973                         [1] = { REG_UNSET, REGCM_GPR32 },
14974                 },
14975         },
14976         [TEMPLATE_CMP_IMM] = {
14977                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
14978                 .rhs = {
14979                         [0] = { REG_UNSET, REGCM_GPR32 },
14980                         [1] = { REG_UNNEEDED, REGCM_IMM32 },
14981                 },
14982         },
14983         [TEMPLATE_TEST] = {
14984                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
14985                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
14986         },
14987         [TEMPLATE_SET] = {
14988                 .lhs = { [0] = { REG_UNSET, REGCM_GPR8 } },
14989                 .rhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
14990         },
14991         [TEMPLATE_JMP] = {
14992                 .rhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
14993         },
14994         [TEMPLATE_INB_DX] = {
14995                 .lhs = { [0] = { REG_AL,  REGCM_GPR8 } },  
14996                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
14997         },
14998         [TEMPLATE_INB_IMM] = {
14999                 .lhs = { [0] = { REG_AL,  REGCM_GPR8 } },  
15000                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
15001         },
15002         [TEMPLATE_INW_DX]  = { 
15003                 .lhs = { [0] = { REG_AX,  REGCM_GPR16 } }, 
15004                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
15005         },
15006         [TEMPLATE_INW_IMM] = { 
15007                 .lhs = { [0] = { REG_AX,  REGCM_GPR16 } }, 
15008                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
15009         },
15010         [TEMPLATE_INL_DX]  = {
15011                 .lhs = { [0] = { REG_EAX, REGCM_GPR32 } },
15012                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
15013         },
15014         [TEMPLATE_INL_IMM] = {
15015                 .lhs = { [0] = { REG_EAX, REGCM_GPR32 } },
15016                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
15017         },
15018         [TEMPLATE_OUTB_DX] = { 
15019                 .rhs = {
15020                         [0] = { REG_AL,  REGCM_GPR8 },
15021                         [1] = { REG_DX, REGCM_GPR16 },
15022                 },
15023         },
15024         [TEMPLATE_OUTB_IMM] = { 
15025                 .rhs = {
15026                         [0] = { REG_AL,  REGCM_GPR8 },  
15027                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
15028                 },
15029         },
15030         [TEMPLATE_OUTW_DX] = { 
15031                 .rhs = {
15032                         [0] = { REG_AX,  REGCM_GPR16 },
15033                         [1] = { REG_DX, REGCM_GPR16 },
15034                 },
15035         },
15036         [TEMPLATE_OUTW_IMM] = {
15037                 .rhs = {
15038                         [0] = { REG_AX,  REGCM_GPR16 }, 
15039                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
15040                 },
15041         },
15042         [TEMPLATE_OUTL_DX] = { 
15043                 .rhs = {
15044                         [0] = { REG_EAX, REGCM_GPR32 },
15045                         [1] = { REG_DX, REGCM_GPR16 },
15046                 },
15047         },
15048         [TEMPLATE_OUTL_IMM] = { 
15049                 .rhs = {
15050                         [0] = { REG_EAX, REGCM_GPR32 }, 
15051                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
15052                 },
15053         },
15054         [TEMPLATE_BSF] = {
15055                 .lhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
15056                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
15057         },
15058         [TEMPLATE_RDMSR] = {
15059                 .lhs = { 
15060                         [0] = { REG_EAX, REGCM_GPR32 },
15061                         [1] = { REG_EDX, REGCM_GPR32 },
15062                 },
15063                 .rhs = { [0] = { REG_ECX, REGCM_GPR32 } },
15064         },
15065         [TEMPLATE_WRMSR] = {
15066                 .rhs = {
15067                         [0] = { REG_ECX, REGCM_GPR32 },
15068                         [1] = { REG_EAX, REGCM_GPR32 },
15069                         [2] = { REG_EDX, REGCM_GPR32 },
15070                 },
15071         },
15072 };
15073
15074 static void fixup_branches(struct compile_state *state,
15075         struct triple *cmp, struct triple *use, int jmp_op)
15076 {
15077         struct triple_set *entry, *next;
15078         for(entry = use->use; entry; entry = next) {
15079                 next = entry->next;
15080                 if (entry->member->op == OP_COPY) {
15081                         fixup_branches(state, cmp, entry->member, jmp_op);
15082                 }
15083                 else if (entry->member->op == OP_BRANCH) {
15084                         struct triple *branch, *test;
15085                         struct triple *left, *right;
15086                         left = right = 0;
15087                         left = RHS(cmp, 0);
15088                         if (TRIPLE_RHS(cmp->sizes) > 1) {
15089                                 right = RHS(cmp, 1);
15090                         }
15091                         branch = entry->member;
15092                         test = pre_triple(state, branch,
15093                                 cmp->op, cmp->type, left, right);
15094                         test->template_id = TEMPLATE_TEST; 
15095                         if (cmp->op == OP_CMP) {
15096                                 test->template_id = TEMPLATE_CMP_REG;
15097                                 if (get_imm32(test, &RHS(test, 1))) {
15098                                         test->template_id = TEMPLATE_CMP_IMM;
15099                                 }
15100                         }
15101                         use_triple(RHS(test, 0), test);
15102                         use_triple(RHS(test, 1), test);
15103                         unuse_triple(RHS(branch, 0), branch);
15104                         RHS(branch, 0) = test;
15105                         branch->op = jmp_op;
15106                         branch->template_id = TEMPLATE_JMP;
15107                         use_triple(RHS(branch, 0), branch);
15108                 }
15109         }
15110 }
15111
15112 static void bool_cmp(struct compile_state *state, 
15113         struct triple *ins, int cmp_op, int jmp_op, int set_op)
15114 {
15115         struct triple_set *entry, *next;
15116         struct triple *set;
15117
15118         /* Put a barrier up before the cmp which preceeds the
15119          * copy instruction.  If a set actually occurs this gives
15120          * us a chance to move variables in registers out of the way.
15121          */
15122
15123         /* Modify the comparison operator */
15124         ins->op = cmp_op;
15125         ins->template_id = TEMPLATE_TEST;
15126         if (cmp_op == OP_CMP) {
15127                 ins->template_id = TEMPLATE_CMP_REG;
15128                 if (get_imm32(ins, &RHS(ins, 1))) {
15129                         ins->template_id =  TEMPLATE_CMP_IMM;
15130                 }
15131         }
15132         /* Generate the instruction sequence that will transform the
15133          * result of the comparison into a logical value.
15134          */
15135         set = post_triple(state, ins, set_op, ins->type, ins, 0);
15136         use_triple(ins, set);
15137         set->template_id = TEMPLATE_SET;
15138
15139         for(entry = ins->use; entry; entry = next) {
15140                 next = entry->next;
15141                 if (entry->member == set) {
15142                         continue;
15143                 }
15144                 replace_rhs_use(state, ins, set, entry->member);
15145         }
15146         fixup_branches(state, ins, set, jmp_op);
15147 }
15148
15149 static struct triple *after_lhs(struct compile_state *state, struct triple *ins)
15150 {
15151         struct triple *next;
15152         int lhs, i;
15153         lhs = TRIPLE_LHS(ins->sizes);
15154         for(next = ins->next, i = 0; i < lhs; i++, next = next->next) {
15155                 if (next != LHS(ins, i)) {
15156                         internal_error(state, ins, "malformed lhs on %s",
15157                                 tops(ins->op));
15158                 }
15159                 if (next->op != OP_PIECE) {
15160                         internal_error(state, ins, "bad lhs op %s at %d on %s",
15161                                 tops(next->op), i, tops(ins->op));
15162                 }
15163                 if (next->u.cval != i) {
15164                         internal_error(state, ins, "bad u.cval of %d %d expected",
15165                                 next->u.cval, i);
15166                 }
15167         }
15168         return next;
15169 }
15170
15171 struct reg_info arch_reg_lhs(struct compile_state *state, struct triple *ins, int index)
15172 {
15173         struct ins_template *template;
15174         struct reg_info result;
15175         int zlhs;
15176         if (ins->op == OP_PIECE) {
15177                 index = ins->u.cval;
15178                 ins = MISC(ins, 0);
15179         }
15180         zlhs = TRIPLE_LHS(ins->sizes);
15181         if (triple_is_def(state, ins)) {
15182                 zlhs = 1;
15183         }
15184         if (index >= zlhs) {
15185                 internal_error(state, ins, "index %d out of range for %s\n",
15186                         index, tops(ins->op));
15187         }
15188         switch(ins->op) {
15189         case OP_ASM:
15190                 template = &ins->u.ainfo->tmpl;
15191                 break;
15192         default:
15193                 if (ins->template_id > LAST_TEMPLATE) {
15194                         internal_error(state, ins, "bad template number %d", 
15195                                 ins->template_id);
15196                 }
15197                 template = &templates[ins->template_id];
15198                 break;
15199         }
15200         result = template->lhs[index];
15201         result.regcm = arch_regcm_normalize(state, result.regcm);
15202         if (result.reg != REG_UNNEEDED) {
15203                 result.regcm &= ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8);
15204         }
15205         if (result.regcm == 0) {
15206                 internal_error(state, ins, "lhs %d regcm == 0", index);
15207         }
15208         return result;
15209 }
15210
15211 struct reg_info arch_reg_rhs(struct compile_state *state, struct triple *ins, int index)
15212 {
15213         struct reg_info result;
15214         struct ins_template *template;
15215         if ((index > TRIPLE_RHS(ins->sizes)) ||
15216                 (ins->op == OP_PIECE)) {
15217                 internal_error(state, ins, "index %d out of range for %s\n",
15218                         index, tops(ins->op));
15219         }
15220         switch(ins->op) {
15221         case OP_ASM:
15222                 template = &ins->u.ainfo->tmpl;
15223                 break;
15224         default:
15225                 if (ins->template_id > LAST_TEMPLATE) {
15226                         internal_error(state, ins, "bad template number %d", 
15227                                 ins->template_id);
15228                 }
15229                 template = &templates[ins->template_id];
15230                 break;
15231         }
15232         result = template->rhs[index];
15233         result.regcm = arch_regcm_normalize(state, result.regcm);
15234         if (result.regcm == 0) {
15235                 internal_error(state, ins, "rhs %d regcm == 0", index);
15236         }
15237         return result;
15238 }
15239
15240 static struct triple *transform_to_arch_instruction(
15241         struct compile_state *state, struct triple *ins)
15242 {
15243         /* Transform from generic 3 address instructions
15244          * to archtecture specific instructions.
15245          * And apply architecture specific constrains to instructions.
15246          * Copies are inserted to preserve the register flexibility
15247          * of 3 address instructions.
15248          */
15249         struct triple *next;
15250         next = ins->next;
15251         switch(ins->op) {
15252         case OP_INTCONST:
15253                 ins->template_id = TEMPLATE_INTCONST32;
15254                 if (ins->u.cval < 256) {
15255                         ins->template_id = TEMPLATE_INTCONST8;
15256                 }
15257                 break;
15258         case OP_ADDRCONST:
15259                 ins->template_id = TEMPLATE_INTCONST32;
15260                 break;
15261         case OP_NOOP:
15262         case OP_SDECL:
15263         case OP_BLOBCONST:
15264         case OP_LABEL:
15265                 ins->template_id = TEMPLATE_NOP;
15266                 break;
15267         case OP_COPY:
15268                 ins->template_id = TEMPLATE_COPY_REG;
15269                 if (is_imm8(RHS(ins, 0))) {
15270                         ins->template_id = TEMPLATE_COPY_IMM8;
15271                 }
15272                 else if (is_imm16(RHS(ins, 0))) {
15273                         ins->template_id = TEMPLATE_COPY_IMM16;
15274                 }
15275                 else if (is_imm32(RHS(ins, 0))) {
15276                         ins->template_id = TEMPLATE_COPY_IMM32;
15277                 }
15278                 else if (is_const(RHS(ins, 0))) {
15279                         internal_error(state, ins, "bad constant passed to copy");
15280                 }
15281                 break;
15282         case OP_PHI:
15283                 ins->template_id = TEMPLATE_PHI;
15284                 break;
15285         case OP_STORE:
15286                 switch(ins->type->type & TYPE_MASK) {
15287                 case TYPE_CHAR:    case TYPE_UCHAR:
15288                         ins->template_id = TEMPLATE_STORE8;
15289                         break;
15290                 case TYPE_SHORT:   case TYPE_USHORT:
15291                         ins->template_id = TEMPLATE_STORE16;
15292                         break;
15293                 case TYPE_INT:     case TYPE_UINT:
15294                 case TYPE_LONG:    case TYPE_ULONG:
15295                 case TYPE_POINTER:
15296                         ins->template_id = TEMPLATE_STORE32;
15297                         break;
15298                 default:
15299                         internal_error(state, ins, "unknown type in store");
15300                         break;
15301                 }
15302                 break;
15303         case OP_LOAD:
15304                 switch(ins->type->type & TYPE_MASK) {
15305                 case TYPE_CHAR:   case TYPE_UCHAR:
15306                         ins->template_id = TEMPLATE_LOAD8;
15307                         break;
15308                 case TYPE_SHORT:
15309                 case TYPE_USHORT:
15310                         ins->template_id = TEMPLATE_LOAD16;
15311                         break;
15312                 case TYPE_INT:
15313                 case TYPE_UINT:
15314                 case TYPE_LONG:
15315                 case TYPE_ULONG:
15316                 case TYPE_POINTER:
15317                         ins->template_id = TEMPLATE_LOAD32;
15318                         break;
15319                 default:
15320                         internal_error(state, ins, "unknown type in load");
15321                         break;
15322                 }
15323                 break;
15324         case OP_ADD:
15325         case OP_SUB:
15326         case OP_AND:
15327         case OP_XOR:
15328         case OP_OR:
15329         case OP_SMUL:
15330                 ins->template_id = TEMPLATE_BINARY_REG;
15331                 if (get_imm32(ins, &RHS(ins, 1))) {
15332                         ins->template_id = TEMPLATE_BINARY_IMM;
15333                 }
15334                 break;
15335         case OP_SL:
15336         case OP_SSR:
15337         case OP_USR:
15338                 ins->template_id = TEMPLATE_SL_CL;
15339                 if (get_imm8(ins, &RHS(ins, 1))) {
15340                         ins->template_id = TEMPLATE_SL_IMM;
15341                 }
15342                 break;
15343         case OP_INVERT:
15344         case OP_NEG:
15345                 ins->template_id = TEMPLATE_UNARY;
15346                 break;
15347         case OP_EQ: 
15348                 bool_cmp(state, ins, OP_CMP, OP_JMP_EQ, OP_SET_EQ); 
15349                 break;
15350         case OP_NOTEQ:
15351                 bool_cmp(state, ins, OP_CMP, OP_JMP_NOTEQ, OP_SET_NOTEQ);
15352                 break;
15353         case OP_SLESS:
15354                 bool_cmp(state, ins, OP_CMP, OP_JMP_SLESS, OP_SET_SLESS);
15355                 break;
15356         case OP_ULESS:
15357                 bool_cmp(state, ins, OP_CMP, OP_JMP_ULESS, OP_SET_ULESS);
15358                 break;
15359         case OP_SMORE:
15360                 bool_cmp(state, ins, OP_CMP, OP_JMP_SMORE, OP_SET_SMORE);
15361                 break;
15362         case OP_UMORE:
15363                 bool_cmp(state, ins, OP_CMP, OP_JMP_UMORE, OP_SET_UMORE);
15364                 break;
15365         case OP_SLESSEQ:
15366                 bool_cmp(state, ins, OP_CMP, OP_JMP_SLESSEQ, OP_SET_SLESSEQ);
15367                 break;
15368         case OP_ULESSEQ:
15369                 bool_cmp(state, ins, OP_CMP, OP_JMP_ULESSEQ, OP_SET_ULESSEQ);
15370                 break;
15371         case OP_SMOREEQ:
15372                 bool_cmp(state, ins, OP_CMP, OP_JMP_SMOREEQ, OP_SET_SMOREEQ);
15373                 break;
15374         case OP_UMOREEQ:
15375                 bool_cmp(state, ins, OP_CMP, OP_JMP_UMOREEQ, OP_SET_UMOREEQ);
15376                 break;
15377         case OP_LTRUE:
15378                 bool_cmp(state, ins, OP_TEST, OP_JMP_NOTEQ, OP_SET_NOTEQ);
15379                 break;
15380         case OP_LFALSE:
15381                 bool_cmp(state, ins, OP_TEST, OP_JMP_EQ, OP_SET_EQ);
15382                 break;
15383         case OP_BRANCH:
15384                 if (TRIPLE_RHS(ins->sizes) > 0) {
15385                         internal_error(state, ins, "bad branch test");
15386                 }
15387                 ins->op = OP_JMP;
15388                 ins->template_id = TEMPLATE_NOP;
15389                 break;
15390         case OP_INB:
15391         case OP_INW:
15392         case OP_INL:
15393                 switch(ins->op) {
15394                 case OP_INB: ins->template_id = TEMPLATE_INB_DX; break;
15395                 case OP_INW: ins->template_id = TEMPLATE_INW_DX; break;
15396                 case OP_INL: ins->template_id = TEMPLATE_INL_DX; break;
15397                 }
15398                 if (get_imm8(ins, &RHS(ins, 0))) {
15399                         ins->template_id += 1;
15400                 }
15401                 break;
15402         case OP_OUTB:
15403         case OP_OUTW:
15404         case OP_OUTL:
15405                 switch(ins->op) {
15406                 case OP_OUTB: ins->template_id = TEMPLATE_OUTB_DX; break;
15407                 case OP_OUTW: ins->template_id = TEMPLATE_OUTW_DX; break;
15408                 case OP_OUTL: ins->template_id = TEMPLATE_OUTL_DX; break;
15409                 }
15410                 if (get_imm8(ins, &RHS(ins, 1))) {
15411                         ins->template_id += 1;
15412                 }
15413                 break;
15414         case OP_BSF:
15415         case OP_BSR:
15416                 ins->template_id = TEMPLATE_BSF;
15417                 break;
15418         case OP_RDMSR:
15419                 ins->template_id = TEMPLATE_RDMSR;
15420                 next = after_lhs(state, ins);
15421                 break;
15422         case OP_WRMSR:
15423                 ins->template_id = TEMPLATE_WRMSR;
15424                 break;
15425         case OP_HLT:
15426                 ins->template_id = TEMPLATE_NOP;
15427                 break;
15428         case OP_ASM:
15429                 ins->template_id = TEMPLATE_NOP;
15430                 next = after_lhs(state, ins);
15431                 break;
15432                 /* Already transformed instructions */
15433         case OP_TEST:
15434                 ins->template_id = TEMPLATE_TEST;
15435                 break;
15436         case OP_CMP:
15437                 ins->template_id = TEMPLATE_CMP_REG;
15438                 if (get_imm32(ins, &RHS(ins, 1))) {
15439                         ins->template_id = TEMPLATE_CMP_IMM;
15440                 }
15441                 break;
15442         case OP_JMP_EQ:      case OP_JMP_NOTEQ:
15443         case OP_JMP_SLESS:   case OP_JMP_ULESS:
15444         case OP_JMP_SMORE:   case OP_JMP_UMORE:
15445         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
15446         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
15447                 ins->template_id = TEMPLATE_JMP;
15448                 break;
15449         case OP_SET_EQ:      case OP_SET_NOTEQ:
15450         case OP_SET_SLESS:   case OP_SET_ULESS:
15451         case OP_SET_SMORE:   case OP_SET_UMORE:
15452         case OP_SET_SLESSEQ: case OP_SET_ULESSEQ:
15453         case OP_SET_SMOREEQ: case OP_SET_UMOREEQ:
15454                 ins->template_id = TEMPLATE_SET;
15455                 break;
15456                 /* Unhandled instructions */
15457         case OP_PIECE:
15458         default:
15459                 internal_error(state, ins, "unhandled ins: %d %s\n",
15460                         ins->op, tops(ins->op));
15461                 break;
15462         }
15463         return next;
15464 }
15465
15466 static void generate_local_labels(struct compile_state *state)
15467 {
15468         struct triple *first, *label;
15469         int label_counter;
15470         label_counter = 0;
15471         first = RHS(state->main_function, 0);
15472         label = first;
15473         do {
15474                 if ((label->op == OP_LABEL) || 
15475                         (label->op == OP_SDECL)) {
15476                         if (label->use) {
15477                                 label->u.cval = ++label_counter;
15478                         } else {
15479                                 label->u.cval = 0;
15480                         }
15481                         
15482                 }
15483                 label = label->next;
15484         } while(label != first);
15485 }
15486
15487 static int check_reg(struct compile_state *state, 
15488         struct triple *triple, int classes)
15489 {
15490         unsigned mask;
15491         int reg;
15492         reg = ID_REG(triple->id);
15493         if (reg == REG_UNSET) {
15494                 internal_error(state, triple, "register not set");
15495         }
15496         mask = arch_reg_regcm(state, reg);
15497         if (!(classes & mask)) {
15498                 internal_error(state, triple, "reg %d in wrong class",
15499                         reg);
15500         }
15501         return reg;
15502 }
15503
15504 static const char *arch_reg_str(int reg)
15505 {
15506         static const char *regs[] = {
15507                 "%bad_register",
15508                 "%bad_register2",
15509                 "%eflags",
15510                 "%al", "%bl", "%cl", "%dl", "%ah", "%bh", "%ch", "%dh",
15511                 "%ax", "%bx", "%cx", "%dx", "%si", "%di", "%bp", "%sp",
15512                 "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp",
15513                 "%edx:%eax",
15514                 "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7",
15515                 "%xmm0", "%xmm1", "%xmm2", "%xmm3", 
15516                 "%xmm4", "%xmm5", "%xmm6", "%xmm7",
15517         };
15518         if (!((reg >= REG_EFLAGS) && (reg <= REG_XMM7))) {
15519                 reg = 0;
15520         }
15521         return regs[reg];
15522 }
15523
15524
15525 static const char *reg(struct compile_state *state, struct triple *triple,
15526         int classes)
15527 {
15528         int reg;
15529         reg = check_reg(state, triple, classes);
15530         return arch_reg_str(reg);
15531 }
15532
15533 const char *type_suffix(struct compile_state *state, struct type *type)
15534 {
15535         const char *suffix;
15536         switch(size_of(state, type)) {
15537         case 1: suffix = "b"; break;
15538         case 2: suffix = "w"; break;
15539         case 4: suffix = "l"; break;
15540         default:
15541                 internal_error(state, 0, "unknown suffix");
15542                 suffix = 0;
15543                 break;
15544         }
15545         return suffix;
15546 }
15547
15548 static void print_const_val(
15549         struct compile_state *state, struct triple *ins, FILE *fp)
15550 {
15551         switch(ins->op) {
15552         case OP_INTCONST:
15553                 fprintf(fp, " $%ld ", 
15554                         (long_t)(ins->u.cval));
15555                 break;
15556         case OP_ADDRCONST:
15557                 fprintf(fp, " $L%lu+%lu ",
15558                         MISC(ins, 0)->u.cval,
15559                         ins->u.cval);
15560                 break;
15561         default:
15562                 internal_error(state, ins, "unknown constant type");
15563                 break;
15564         }
15565 }
15566
15567 static void print_binary_op(struct compile_state *state,
15568         const char *op, struct triple *ins, FILE *fp) 
15569 {
15570         unsigned mask;
15571         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8;
15572         if (RHS(ins, 0)->id != ins->id) {
15573                 internal_error(state, ins, "invalid register assignment");
15574         }
15575         if (is_const(RHS(ins, 1))) {
15576                 fprintf(fp, "\t%s ", op);
15577                 print_const_val(state, RHS(ins, 1), fp);
15578                 fprintf(fp, ", %s\n",
15579                         reg(state, RHS(ins, 0), mask));
15580         }
15581         else {
15582                 unsigned lmask, rmask;
15583                 int lreg, rreg;
15584                 lreg = check_reg(state, RHS(ins, 0), mask);
15585                 rreg = check_reg(state, RHS(ins, 1), mask);
15586                 lmask = arch_reg_regcm(state, lreg);
15587                 rmask = arch_reg_regcm(state, rreg);
15588                 mask = lmask & rmask;
15589                 fprintf(fp, "\t%s %s, %s\n",
15590                         op,
15591                         reg(state, RHS(ins, 1), mask),
15592                         reg(state, RHS(ins, 0), mask));
15593         }
15594 }
15595 static void print_unary_op(struct compile_state *state, 
15596         const char *op, struct triple *ins, FILE *fp)
15597 {
15598         unsigned mask;
15599         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8;
15600         fprintf(fp, "\t%s %s\n",
15601                 op,
15602                 reg(state, RHS(ins, 0), mask));
15603 }
15604
15605 static void print_op_shift(struct compile_state *state,
15606         const char *op, struct triple *ins, FILE *fp)
15607 {
15608         unsigned mask;
15609         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8;
15610         if (RHS(ins, 0)->id != ins->id) {
15611                 internal_error(state, ins, "invalid register assignment");
15612         }
15613         if (is_const(RHS(ins, 1))) {
15614                 fprintf(fp, "\t%s ", op);
15615                 print_const_val(state, RHS(ins, 1), fp);
15616                 fprintf(fp, ", %s\n",
15617                         reg(state, RHS(ins, 0), mask));
15618         }
15619         else {
15620                 fprintf(fp, "\t%s %s, %s\n",
15621                         op,
15622                         reg(state, RHS(ins, 1), REGCM_GPR8),
15623                         reg(state, RHS(ins, 0), mask));
15624         }
15625 }
15626
15627 static void print_op_in(struct compile_state *state, struct triple *ins, FILE *fp)
15628 {
15629         const char *op;
15630         int mask;
15631         int dreg;
15632         mask = 0;
15633         switch(ins->op) {
15634         case OP_INB: op = "inb", mask = REGCM_GPR8; break;
15635         case OP_INW: op = "inw", mask = REGCM_GPR16; break;
15636         case OP_INL: op = "inl", mask = REGCM_GPR32; break;
15637         default:
15638                 internal_error(state, ins, "not an in operation");
15639                 op = 0;
15640                 break;
15641         }
15642         dreg = check_reg(state, ins, mask);
15643         if (!reg_is_reg(state, dreg, REG_EAX)) {
15644                 internal_error(state, ins, "dst != %%eax");
15645         }
15646         if (is_const(RHS(ins, 0))) {
15647                 fprintf(fp, "\t%s ", op);
15648                 print_const_val(state, RHS(ins, 0), fp);
15649                 fprintf(fp, ", %s\n",
15650                         reg(state, ins, mask));
15651         }
15652         else {
15653                 int addr_reg;
15654                 addr_reg = check_reg(state, RHS(ins, 0), REGCM_GPR16);
15655                 if (!reg_is_reg(state, addr_reg, REG_DX)) {
15656                         internal_error(state, ins, "src != %%dx");
15657                 }
15658                 fprintf(fp, "\t%s %s, %s\n",
15659                         op, 
15660                         reg(state, RHS(ins, 0), REGCM_GPR16),
15661                         reg(state, ins, mask));
15662         }
15663 }
15664
15665 static void print_op_out(struct compile_state *state, struct triple *ins, FILE *fp)
15666 {
15667         const char *op;
15668         int mask;
15669         int lreg;
15670         mask = 0;
15671         switch(ins->op) {
15672         case OP_OUTB: op = "outb", mask = REGCM_GPR8; break;
15673         case OP_OUTW: op = "outw", mask = REGCM_GPR16; break;
15674         case OP_OUTL: op = "outl", mask = REGCM_GPR32; break;
15675         default:
15676                 internal_error(state, ins, "not an out operation");
15677                 op = 0;
15678                 break;
15679         }
15680         lreg = check_reg(state, RHS(ins, 0), mask);
15681         if (!reg_is_reg(state, lreg, REG_EAX)) {
15682                 internal_error(state, ins, "src != %%eax");
15683         }
15684         if (is_const(RHS(ins, 1))) {
15685                 fprintf(fp, "\t%s %s,", 
15686                         op, reg(state, RHS(ins, 0), mask));
15687                 print_const_val(state, RHS(ins, 1), fp);
15688                 fprintf(fp, "\n");
15689         }
15690         else {
15691                 int addr_reg;
15692                 addr_reg = check_reg(state, RHS(ins, 1), REGCM_GPR16);
15693                 if (!reg_is_reg(state, addr_reg, REG_DX)) {
15694                         internal_error(state, ins, "dst != %%dx");
15695                 }
15696                 fprintf(fp, "\t%s %s, %s\n",
15697                         op, 
15698                         reg(state, RHS(ins, 0), mask),
15699                         reg(state, RHS(ins, 1), REGCM_GPR16));
15700         }
15701 }
15702
15703 static void print_op_move(struct compile_state *state,
15704         struct triple *ins, FILE *fp)
15705 {
15706         /* op_move is complex because there are many types
15707          * of registers we can move between.
15708          * Because OP_COPY will be introduced in arbitrary locations
15709          * OP_COPY must not affect flags.
15710          */
15711         int omit_copy = 1; /* Is it o.k. to omit a noop copy? */
15712         struct triple *dst, *src;
15713         if (ins->op == OP_COPY) {
15714                 src = RHS(ins, 0);
15715                 dst = ins;
15716         }
15717         else if (ins->op == OP_WRITE) {
15718                 dst = LHS(ins, 0);
15719                 src = RHS(ins, 0);
15720         }
15721         else {
15722                 internal_error(state, ins, "unknown move operation");
15723                 src = dst = 0;
15724         }
15725         if (!is_const(src)) {
15726                 int src_reg, dst_reg;
15727                 int src_regcm, dst_regcm;
15728                 src_reg = ID_REG(src->id);
15729                 dst_reg   = ID_REG(dst->id);
15730                 src_regcm = arch_reg_regcm(state, src_reg);
15731                 dst_regcm   = arch_reg_regcm(state, dst_reg);
15732                 /* If the class is the same just move the register */
15733                 if (src_regcm & dst_regcm & 
15734                         (REGCM_GPR8 | REGCM_GPR16 | REGCM_GPR32)) {
15735                         if ((src_reg != dst_reg) || !omit_copy) {
15736                                 fprintf(fp, "\tmov %s, %s\n",
15737                                         reg(state, src, src_regcm),
15738                                         reg(state, dst, dst_regcm));
15739                         }
15740                 }
15741                 /* Move 32bit to 16bit */
15742                 else if ((src_regcm & REGCM_GPR32) &&
15743                         (dst_regcm & REGCM_GPR16)) {
15744                         src_reg = (src_reg - REGC_GPR32_FIRST) + REGC_GPR16_FIRST;
15745                         if ((src_reg != dst_reg) || !omit_copy) {
15746                                 fprintf(fp, "\tmovw %s, %s\n",
15747                                         arch_reg_str(src_reg), 
15748                                         arch_reg_str(dst_reg));
15749                         }
15750                 }
15751                 /* Move 32bit to 8bit */
15752                 else if ((src_regcm & REGCM_GPR32_8) &&
15753                         (dst_regcm & REGCM_GPR8))
15754                 {
15755                         src_reg = (src_reg - REGC_GPR32_8_FIRST) + REGC_GPR8_FIRST;
15756                         if ((src_reg != dst_reg) || !omit_copy) {
15757                                 fprintf(fp, "\tmovb %s, %s\n",
15758                                         arch_reg_str(src_reg),
15759                                         arch_reg_str(dst_reg));
15760                         }
15761                 }
15762                 /* Move 16bit to 8bit */
15763                 else if ((src_regcm & REGCM_GPR16_8) &&
15764                         (dst_regcm & REGCM_GPR8))
15765                 {
15766                         src_reg = (src_reg - REGC_GPR16_8_FIRST) + REGC_GPR8_FIRST;
15767                         if ((src_reg != dst_reg) || !omit_copy) {
15768                                 fprintf(fp, "\tmovb %s, %s\n",
15769                                         arch_reg_str(src_reg),
15770                                         arch_reg_str(dst_reg));
15771                         }
15772                 }
15773                 /* Move 8/16bit to 16/32bit */
15774                 else if ((src_regcm & (REGCM_GPR8 | REGCM_GPR16)) && 
15775                         (dst_regcm & (REGCM_GPR16 | REGCM_GPR32))) {
15776                         const char *op;
15777                         op = is_signed(src->type)? "movsx": "movzx";
15778                         fprintf(fp, "\t%s %s, %s\n",
15779                                 op,
15780                                 reg(state, src, src_regcm),
15781                                 reg(state, dst, dst_regcm));
15782                 }
15783                 /* Move between sse registers */
15784                 else if ((src_regcm & dst_regcm & REGCM_XMM)) {
15785                         if ((src_reg != dst_reg) || !omit_copy) {
15786                                 fprintf(fp, "\tmovdqa %s, %s\n",
15787                                         reg(state, src, src_regcm),
15788                                         reg(state, dst, dst_regcm));
15789                         }
15790                 }
15791                 /* Move between mmx registers or mmx & sse  registers */
15792                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
15793                         (dst_regcm & (REGCM_MMX | REGCM_XMM))) {
15794                         if ((src_reg != dst_reg) || !omit_copy) {
15795                                 fprintf(fp, "\tmovq %s, %s\n",
15796                                         reg(state, src, src_regcm),
15797                                         reg(state, dst, dst_regcm));
15798                         }
15799                 }
15800                 /* Move between 32bit gprs & mmx/sse registers */
15801                 else if ((src_regcm & (REGCM_GPR32 | REGCM_MMX | REGCM_XMM)) &&
15802                         (dst_regcm & (REGCM_GPR32 | REGCM_MMX | REGCM_XMM))) {
15803                         fprintf(fp, "\tmovd %s, %s\n",
15804                                 reg(state, src, src_regcm),
15805                                 reg(state, dst, dst_regcm));
15806                 }
15807 #if X86_4_8BIT_GPRS
15808                 /* Move from 8bit gprs to  mmx/sse registers */
15809                 else if ((src_regcm & REGCM_GPR8) && (src_reg <= REG_DL) &&
15810                         (dst_regcm & (REGCM_MMX | REGCM_XMM))) {
15811                         const char *op;
15812                         int mid_reg;
15813                         op = is_signed(src->type)? "movsx":"movzx";
15814                         mid_reg = (src_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
15815                         fprintf(fp, "\t%s %s, %s\n\tmovd %s, %s\n",
15816                                 op,
15817                                 reg(state, src, src_regcm),
15818                                 arch_reg_str(mid_reg),
15819                                 arch_reg_str(mid_reg),
15820                                 reg(state, dst, dst_regcm));
15821                 }
15822                 /* Move from mmx/sse registers and 8bit gprs */
15823                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
15824                         (dst_regcm & REGCM_GPR8) && (dst_reg <= REG_DL)) {
15825                         int mid_reg;
15826                         mid_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
15827                         fprintf(fp, "\tmovd %s, %s\n",
15828                                 reg(state, src, src_regcm),
15829                                 arch_reg_str(mid_reg));
15830                 }
15831                 /* Move from 32bit gprs to 16bit gprs */
15832                 else if ((src_regcm & REGCM_GPR32) &&
15833                         (dst_regcm & REGCM_GPR16)) {
15834                         dst_reg = (dst_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
15835                         if ((src_reg != dst_reg) || !omit_copy) {
15836                                 fprintf(fp, "\tmov %s, %s\n",
15837                                         arch_reg_str(src_reg),
15838                                         arch_reg_str(dst_reg));
15839                         }
15840                 }
15841                 /* Move from 32bit gprs to 8bit gprs */
15842                 else if ((src_regcm & REGCM_GPR32) &&
15843                         (dst_regcm & REGCM_GPR8)) {
15844                         dst_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
15845                         if ((src_reg != dst_reg) || !omit_copy) {
15846                                 fprintf(fp, "\tmov %s, %s\n",
15847                                         arch_reg_str(src_reg),
15848                                         arch_reg_str(dst_reg));
15849                         }
15850                 }
15851                 /* Move from 16bit gprs to 8bit gprs */
15852                 else if ((src_regcm & REGCM_GPR16) &&
15853                         (dst_regcm & REGCM_GPR8)) {
15854                         dst_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR16_FIRST;
15855                         if ((src_reg != dst_reg) || !omit_copy) {
15856                                 fprintf(fp, "\tmov %s, %s\n",
15857                                         arch_reg_str(src_reg),
15858                                         arch_reg_str(dst_reg));
15859                         }
15860                 }
15861 #endif /* X86_4_8BIT_GPRS */
15862                 else {
15863                         internal_error(state, ins, "unknown copy type");
15864                 }
15865         }
15866         else {
15867                 fprintf(fp, "\tmov ");
15868                 print_const_val(state, src, fp);
15869                 fprintf(fp, ", %s\n",
15870                         reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8));
15871         }
15872 }
15873
15874 static void print_op_load(struct compile_state *state,
15875         struct triple *ins, FILE *fp)
15876 {
15877         struct triple *dst, *src;
15878         dst = ins;
15879         src = RHS(ins, 0);
15880         if (is_const(src) || is_const(dst)) {
15881                 internal_error(state, ins, "unknown load operation");
15882         }
15883         fprintf(fp, "\tmov (%s), %s\n",
15884                 reg(state, src, REGCM_GPR32),
15885                 reg(state, dst, REGCM_GPR8 | REGCM_GPR16 | REGCM_GPR32));
15886 }
15887
15888
15889 static void print_op_store(struct compile_state *state,
15890         struct triple *ins, FILE *fp)
15891 {
15892         struct triple *dst, *src;
15893         dst = LHS(ins, 0);
15894         src = RHS(ins, 0);
15895         if (is_const(src) && (src->op == OP_INTCONST)) {
15896                 long_t value;
15897                 value = (long_t)(src->u.cval);
15898                 fprintf(fp, "\tmov%s $%ld, (%s)\n",
15899                         type_suffix(state, src->type),
15900                         value,
15901                         reg(state, dst, REGCM_GPR32));
15902         }
15903         else if (is_const(dst) && (dst->op == OP_INTCONST)) {
15904                 fprintf(fp, "\tmov%s %s, 0x%08lx\n",
15905                         type_suffix(state, src->type),
15906                         reg(state, src, REGCM_GPR8 | REGCM_GPR16 | REGCM_GPR32),
15907                         dst->u.cval);
15908         }
15909         else {
15910                 if (is_const(src) || is_const(dst)) {
15911                         internal_error(state, ins, "unknown store operation");
15912                 }
15913                 fprintf(fp, "\tmov%s %s, (%s)\n",
15914                         type_suffix(state, src->type),
15915                         reg(state, src, REGCM_GPR8 | REGCM_GPR16 | REGCM_GPR32),
15916                         reg(state, dst, REGCM_GPR32));
15917         }
15918         
15919         
15920 }
15921
15922 static void print_op_smul(struct compile_state *state,
15923         struct triple *ins, FILE *fp)
15924 {
15925         if (!is_const(RHS(ins, 1))) {
15926                 fprintf(fp, "\timul %s, %s\n",
15927                         reg(state, RHS(ins, 1), REGCM_GPR32),
15928                         reg(state, RHS(ins, 0), REGCM_GPR32));
15929         }
15930         else {
15931                 fprintf(fp, "\timul ");
15932                 print_const_val(state, RHS(ins, 1), fp);
15933                 fprintf(fp, ", %s\n", reg(state, RHS(ins, 0), REGCM_GPR32));
15934         }
15935 }
15936
15937 static void print_op_cmp(struct compile_state *state,
15938         struct triple *ins, FILE *fp)
15939 {
15940         unsigned mask;
15941         int dreg;
15942         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8;
15943         dreg = check_reg(state, ins, REGCM_FLAGS);
15944         if (!reg_is_reg(state, dreg, REG_EFLAGS)) {
15945                 internal_error(state, ins, "bad dest register for cmp");
15946         }
15947         if (is_const(RHS(ins, 1))) {
15948                 fprintf(fp, "\tcmp ");
15949                 print_const_val(state, RHS(ins, 1), fp);
15950                 fprintf(fp, ", %s\n", reg(state, RHS(ins, 0), mask));
15951         }
15952         else {
15953                 unsigned lmask, rmask;
15954                 int lreg, rreg;
15955                 lreg = check_reg(state, RHS(ins, 0), mask);
15956                 rreg = check_reg(state, RHS(ins, 1), mask);
15957                 lmask = arch_reg_regcm(state, lreg);
15958                 rmask = arch_reg_regcm(state, rreg);
15959                 mask = lmask & rmask;
15960                 fprintf(fp, "\tcmp %s, %s\n",
15961                         reg(state, RHS(ins, 1), mask),
15962                         reg(state, RHS(ins, 0), mask));
15963         }
15964 }
15965
15966 static void print_op_test(struct compile_state *state,
15967         struct triple *ins, FILE *fp)
15968 {
15969         unsigned mask;
15970         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8;
15971         fprintf(fp, "\ttest %s, %s\n",
15972                 reg(state, RHS(ins, 0), mask),
15973                 reg(state, RHS(ins, 0), mask));
15974 }
15975
15976 static void print_op_branch(struct compile_state *state,
15977         struct triple *branch, FILE *fp)
15978 {
15979         const char *bop = "j";
15980         if (branch->op == OP_JMP) {
15981                 if (TRIPLE_RHS(branch->sizes) != 0) {
15982                         internal_error(state, branch, "jmp with condition?");
15983                 }
15984                 bop = "jmp";
15985         }
15986         else {
15987                 struct triple *ptr;
15988                 if (TRIPLE_RHS(branch->sizes) != 1) {
15989                         internal_error(state, branch, "jmpcc without condition?");
15990                 }
15991                 check_reg(state, RHS(branch, 0), REGCM_FLAGS);
15992                 if ((RHS(branch, 0)->op != OP_CMP) &&
15993                         (RHS(branch, 0)->op != OP_TEST)) {
15994                         internal_error(state, branch, "bad branch test");
15995                 }
15996 #warning "FIXME I have observed instructions between the test and branch instructions"
15997                 ptr = RHS(branch, 0);
15998                 for(ptr = RHS(branch, 0)->next; ptr != branch; ptr = ptr->next) {
15999                         if (ptr->op != OP_COPY) {
16000                                 internal_error(state, branch, "branch does not follow test");
16001                         }
16002                 }
16003                 switch(branch->op) {
16004                 case OP_JMP_EQ:       bop = "jz";  break;
16005                 case OP_JMP_NOTEQ:    bop = "jnz"; break;
16006                 case OP_JMP_SLESS:    bop = "jl";  break;
16007                 case OP_JMP_ULESS:    bop = "jb";  break;
16008                 case OP_JMP_SMORE:    bop = "jg";  break;
16009                 case OP_JMP_UMORE:    bop = "ja";  break;
16010                 case OP_JMP_SLESSEQ:  bop = "jle"; break;
16011                 case OP_JMP_ULESSEQ:  bop = "jbe"; break;
16012                 case OP_JMP_SMOREEQ:  bop = "jge"; break;
16013                 case OP_JMP_UMOREEQ:  bop = "jae"; break;
16014                 default:
16015                         internal_error(state, branch, "Invalid branch op");
16016                         break;
16017                 }
16018                 
16019         }
16020         fprintf(fp, "\t%s L%lu\n",
16021                 bop, TARG(branch, 0)->u.cval);
16022 }
16023
16024 static void print_op_set(struct compile_state *state,
16025         struct triple *set, FILE *fp)
16026 {
16027         const char *sop = "set";
16028         if (TRIPLE_RHS(set->sizes) != 1) {
16029                 internal_error(state, set, "setcc without condition?");
16030         }
16031         check_reg(state, RHS(set, 0), REGCM_FLAGS);
16032         if ((RHS(set, 0)->op != OP_CMP) &&
16033                 (RHS(set, 0)->op != OP_TEST)) {
16034                 internal_error(state, set, "bad set test");
16035         }
16036         if (RHS(set, 0)->next != set) {
16037                 internal_error(state, set, "set does not follow test");
16038         }
16039         switch(set->op) {
16040         case OP_SET_EQ:       sop = "setz";  break;
16041         case OP_SET_NOTEQ:    sop = "setnz"; break;
16042         case OP_SET_SLESS:    sop = "setl";  break;
16043         case OP_SET_ULESS:    sop = "setb";  break;
16044         case OP_SET_SMORE:    sop = "setg";  break;
16045         case OP_SET_UMORE:    sop = "seta";  break;
16046         case OP_SET_SLESSEQ:  sop = "setle"; break;
16047         case OP_SET_ULESSEQ:  sop = "setbe"; break;
16048         case OP_SET_SMOREEQ:  sop = "setge"; break;
16049         case OP_SET_UMOREEQ:  sop = "setae"; break;
16050         default:
16051                 internal_error(state, set, "Invalid set op");
16052                 break;
16053         }
16054         fprintf(fp, "\t%s %s\n",
16055                 sop, reg(state, set, REGCM_GPR8));
16056 }
16057
16058 static void print_op_bit_scan(struct compile_state *state, 
16059         struct triple *ins, FILE *fp) 
16060 {
16061         const char *op;
16062         switch(ins->op) {
16063         case OP_BSF: op = "bsf"; break;
16064         case OP_BSR: op = "bsr"; break;
16065         default: 
16066                 internal_error(state, ins, "unknown bit scan");
16067                 op = 0;
16068                 break;
16069         }
16070         fprintf(fp, 
16071                 "\t%s %s, %s\n"
16072                 "\tjnz 1f\n"
16073                 "\tmovl $-1, %s\n"
16074                 "1:\n",
16075                 op,
16076                 reg(state, RHS(ins, 0), REGCM_GPR32),
16077                 reg(state, ins, REGCM_GPR32),
16078                 reg(state, ins, REGCM_GPR32));
16079 }
16080
16081 static void print_const(struct compile_state *state,
16082         struct triple *ins, FILE *fp)
16083 {
16084         switch(ins->op) {
16085         case OP_INTCONST:
16086                 switch(ins->type->type & TYPE_MASK) {
16087                 case TYPE_CHAR:
16088                 case TYPE_UCHAR:
16089                         fprintf(fp, ".byte 0x%02lx\n", ins->u.cval);
16090                         break;
16091                 case TYPE_SHORT:
16092                 case TYPE_USHORT:
16093                         fprintf(fp, ".short 0x%04lx\n", ins->u.cval);
16094                         break;
16095                 case TYPE_INT:
16096                 case TYPE_UINT:
16097                 case TYPE_LONG:
16098                 case TYPE_ULONG:
16099                         fprintf(fp, ".int %lu\n", ins->u.cval);
16100                         break;
16101                 default:
16102                         internal_error(state, ins, "Unknown constant type");
16103                 }
16104                 break;
16105         case OP_BLOBCONST:
16106         {
16107                 unsigned char *blob;
16108                 size_t size, i;
16109                 size = size_of(state, ins->type);
16110                 blob = ins->u.blob;
16111                 for(i = 0; i < size; i++) {
16112                         fprintf(fp, ".byte 0x%02x\n",
16113                                 blob[i]);
16114                 }
16115                 break;
16116         }
16117         default:
16118                 internal_error(state, ins, "Unknown constant type");
16119                 break;
16120         }
16121 }
16122
16123 #define TEXT_SECTION ".rom.text"
16124 #define DATA_SECTION ".rom.data"
16125
16126 static void print_sdecl(struct compile_state *state,
16127         struct triple *ins, FILE *fp)
16128 {
16129         fprintf(fp, ".section \"" DATA_SECTION "\"\n");
16130         fprintf(fp, ".balign %d\n", align_of(state, ins->type));
16131         fprintf(fp, "L%lu:\n", ins->u.cval);
16132         print_const(state, MISC(ins, 0), fp);
16133         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
16134                 
16135 }
16136
16137 static void print_instruction(struct compile_state *state,
16138         struct triple *ins, FILE *fp)
16139 {
16140         /* Assumption: after I have exted the register allocator
16141          * everything is in a valid register. 
16142          */
16143         switch(ins->op) {
16144         case OP_ASM:
16145                 print_op_asm(state, ins, fp);
16146                 break;
16147         case OP_ADD:    print_binary_op(state, "add", ins, fp); break;
16148         case OP_SUB:    print_binary_op(state, "sub", ins, fp); break;
16149         case OP_AND:    print_binary_op(state, "and", ins, fp); break;
16150         case OP_XOR:    print_binary_op(state, "xor", ins, fp); break;
16151         case OP_OR:     print_binary_op(state, "or",  ins, fp); break;
16152         case OP_SL:     print_op_shift(state, "shl", ins, fp); break;
16153         case OP_USR:    print_op_shift(state, "shr", ins, fp); break;
16154         case OP_SSR:    print_op_shift(state, "sar", ins, fp); break;
16155         case OP_POS:    break;
16156         case OP_NEG:    print_unary_op(state, "neg", ins, fp); break;
16157         case OP_INVERT: print_unary_op(state, "not", ins, fp); break;
16158         case OP_INTCONST:
16159         case OP_ADDRCONST:
16160         case OP_BLOBCONST:
16161                 /* Don't generate anything here for constants */
16162         case OP_PHI:
16163                 /* Don't generate anything for variable declarations. */
16164                 break;
16165         case OP_SDECL:
16166                 print_sdecl(state, ins, fp);
16167                 break;
16168         case OP_WRITE: 
16169         case OP_COPY:   
16170                 print_op_move(state, ins, fp);
16171                 break;
16172         case OP_LOAD:
16173                 print_op_load(state, ins, fp);
16174                 break;
16175         case OP_STORE:
16176                 print_op_store(state, ins, fp);
16177                 break;
16178         case OP_SMUL:
16179                 print_op_smul(state, ins, fp);
16180                 break;
16181         case OP_CMP:    print_op_cmp(state, ins, fp); break;
16182         case OP_TEST:   print_op_test(state, ins, fp); break;
16183         case OP_JMP:
16184         case OP_JMP_EQ:      case OP_JMP_NOTEQ:
16185         case OP_JMP_SLESS:   case OP_JMP_ULESS:
16186         case OP_JMP_SMORE:   case OP_JMP_UMORE:
16187         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
16188         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
16189                 print_op_branch(state, ins, fp);
16190                 break;
16191         case OP_SET_EQ:      case OP_SET_NOTEQ:
16192         case OP_SET_SLESS:   case OP_SET_ULESS:
16193         case OP_SET_SMORE:   case OP_SET_UMORE:
16194         case OP_SET_SLESSEQ: case OP_SET_ULESSEQ:
16195         case OP_SET_SMOREEQ: case OP_SET_UMOREEQ:
16196                 print_op_set(state, ins, fp);
16197                 break;
16198         case OP_INB:  case OP_INW:  case OP_INL:
16199                 print_op_in(state, ins, fp); 
16200                 break;
16201         case OP_OUTB: case OP_OUTW: case OP_OUTL:
16202                 print_op_out(state, ins, fp); 
16203                 break;
16204         case OP_BSF:
16205         case OP_BSR:
16206                 print_op_bit_scan(state, ins, fp);
16207                 break;
16208         case OP_RDMSR:
16209                 after_lhs(state, ins);
16210                 fprintf(fp, "\trdmsr\n");
16211                 break;
16212         case OP_WRMSR:
16213                 fprintf(fp, "\twrmsr\n");
16214                 break;
16215         case OP_HLT:
16216                 fprintf(fp, "\thlt\n");
16217                 break;
16218         case OP_LABEL:
16219                 if (!ins->use) {
16220                         return;
16221                 }
16222                 fprintf(fp, "L%lu:\n", ins->u.cval);
16223                 break;
16224                 /* Ignore OP_PIECE */
16225         case OP_PIECE:
16226                 break;
16227                 /* Operations I am not yet certain how to handle */
16228         case OP_UMUL:
16229         case OP_SDIV: case OP_UDIV:
16230         case OP_SMOD: case OP_UMOD:
16231                 /* Operations that should never get here */
16232         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
16233         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
16234         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
16235         default:
16236                 internal_error(state, ins, "unknown op: %d %s",
16237                         ins->op, tops(ins->op));
16238                 break;
16239         }
16240 }
16241
16242 static void print_instructions(struct compile_state *state)
16243 {
16244         struct triple *first, *ins;
16245         int print_location;
16246         int last_line;
16247         int last_col;
16248         const char *last_filename;
16249         FILE *fp;
16250         print_location = 1;
16251         last_line = -1;
16252         last_col  = -1;
16253         last_filename = 0;
16254         fp = state->output;
16255         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
16256         first = RHS(state->main_function, 0);
16257         ins = first;
16258         do {
16259                 if (print_location &&
16260                         ((last_filename != ins->filename) ||
16261                                 (last_line != ins->line) ||
16262                                 (last_col  != ins->col))) {
16263                         fprintf(fp, "\t/* %s:%d */\n",
16264                                 ins->filename, ins->line);
16265                         last_filename = ins->filename;
16266                         last_line = ins->line;
16267                         last_col  = ins->col;
16268                 }
16269
16270                 print_instruction(state, ins, fp);
16271                 ins = ins->next;
16272         } while(ins != first);
16273         
16274 }
16275 static void generate_code(struct compile_state *state)
16276 {
16277         generate_local_labels(state);
16278         print_instructions(state);
16279         
16280 }
16281
16282 static void print_tokens(struct compile_state *state)
16283 {
16284         struct token *tk;
16285         tk = &state->token[0];
16286         do {
16287 #if 1
16288                 token(state, 0);
16289 #else
16290                 next_token(state, 0);
16291 #endif
16292                 loc(stdout, state, 0);
16293                 printf("%s <- `%s'\n",
16294                         tokens[tk->tok],
16295                         tk->ident ? tk->ident->name :
16296                         tk->str_len ? tk->val.str : "");
16297                 
16298         } while(tk->tok != TOK_EOF);
16299 }
16300
16301 static void compile(const char *filename, const char *ofilename, 
16302         int cpu, int debug, int opt)
16303 {
16304         int i;
16305         struct compile_state state;
16306         memset(&state, 0, sizeof(state));
16307         state.file = 0;
16308         for(i = 0; i < sizeof(state.token)/sizeof(state.token[0]); i++) {
16309                 memset(&state.token[i], 0, sizeof(state.token[i]));
16310                 state.token[i].tok = -1;
16311         }
16312         /* Remember the debug settings */
16313         state.cpu      = cpu;
16314         state.debug    = debug;
16315         state.optimize = opt;
16316         /* Remember the output filename */
16317         state.ofilename = ofilename;
16318         state.output    = fopen(state.ofilename, "w");
16319         if (!state.output) {
16320                 error(&state, 0, "Cannot open output file %s\n",
16321                         ofilename);
16322         }
16323         /* Prep the preprocessor */
16324         state.if_depth = 0;
16325         state.if_value = 0;
16326         /* register the C keywords */
16327         register_keywords(&state);
16328         /* register the keywords the macro preprocessor knows */
16329         register_macro_keywords(&state);
16330         /* Memorize where some special keywords are. */
16331         state.i_continue = lookup(&state, "continue", 8);
16332         state.i_break    = lookup(&state, "break", 5);
16333         /* Enter the globl definition scope */
16334         start_scope(&state);
16335         register_builtins(&state);
16336         compile_file(&state, filename, 1);
16337 #if 0
16338         print_tokens(&state);
16339 #endif  
16340         decls(&state);
16341         /* Exit the global definition scope */
16342         end_scope(&state);
16343
16344         /* Now that basic compilation has happened 
16345          * optimize the intermediate code 
16346          */
16347         optimize(&state);
16348
16349         generate_code(&state);
16350         if (state.debug) {
16351                 fprintf(stderr, "done\n");
16352         }
16353 }
16354
16355 static void version(void)
16356 {
16357         printf("romcc " VERSION " released " RELEASE_DATE "\n");
16358 }
16359
16360 static void usage(void)
16361 {
16362         version();
16363         printf(
16364                 "Usage: romcc <source>.c\n"
16365                 "Compile a C source file without using ram\n"
16366         );
16367 }
16368
16369 static void arg_error(char *fmt, ...)
16370 {
16371         va_list args;
16372         va_start(args, fmt);
16373         vfprintf(stderr, fmt, args);
16374         va_end(args);
16375         usage();
16376         exit(1);
16377 }
16378
16379 int main(int argc, char **argv)
16380 {
16381         const char *filename;
16382         const char *ofilename;
16383         int cpu;
16384         int last_argc;
16385         int debug;
16386         int optimize;
16387         cpu = CPU_DEFAULT;
16388         ofilename = "auto.inc";
16389         optimize = 0;
16390         debug = 0;
16391         last_argc = -1;
16392         while((argc > 1) && (argc != last_argc)) {
16393                 last_argc = argc;
16394                 if (strncmp(argv[1], "--debug=", 8) == 0) {
16395                         debug = atoi(argv[1] + 8);
16396                         argv++;
16397                         argc--;
16398                 }
16399                 else if ((strcmp(argv[1],"-O") == 0) ||
16400                         (strcmp(argv[1], "-O1") == 0)) {
16401                         optimize = 1;
16402                         argv++;
16403                         argc--;
16404                 }
16405                 else if (strcmp(argv[1],"-O2") == 0) {
16406                         optimize = 2;
16407                         argv++;
16408                         argc--;
16409                 }
16410                 else if ((strcmp(argv[1], "-o") == 0) && (argc > 2)) {
16411                         ofilename = argv[2];
16412                         argv += 2;
16413                         argc -= 2;
16414                 }
16415                 else if (strncmp(argv[1], "-mcpu=", 6) == 0) {
16416                         cpu = arch_encode_cpu(argv[1] + 6);
16417                         if (cpu == BAD_CPU) {
16418                                 arg_error("Invalid cpu specified: %s\n",
16419                                         argv[1] + 6);
16420                         }
16421                         argv++;
16422                         argc--;
16423                 }
16424         }
16425         if (argc != 2) {
16426                 arg_error("Wrong argument count %d\n", argc);
16427         }
16428         filename = argv[1];
16429         compile(filename, ofilename, cpu, debug, optimize);
16430
16431         return 0;
16432 }