- Checking latest version of romcc
[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 X86_4_8BIT_GPRS 1
19
20 #warning "FIXME static constant variables"
21 #warning "FIXME enable pointers"
22 #warning "FIXME enable string constants"
23
24 /*  Control flow graph of a loop without goto.
25  * 
26  *        AAA
27  *   +---/
28  *  /
29  * / +--->CCC
30  * | |    / \
31  * | |  DDD EEE    break;
32  * | |    \    \
33  * | |    FFF   \
34  *  \|    / \    \
35  *   |\ GGG HHH   |   continue;
36  *   | \  \   |   |
37  *   |  \ III |  /
38  *   |   \ | /  / 
39  *   |    vvv  /  
40  *   +----BBB /   
41  *         | /
42  *         vv
43  *        JJJ
44  *
45  * 
46  *             AAA
47  *     +-----+  |  +----+
48  *     |      \ | /     |
49  *     |       BBB  +-+ |
50  *     |       / \ /  | |
51  *     |     CCC JJJ / /
52  *     |     / \    / / 
53  *     |   DDD EEE / /  
54  *     |    |   +-/ /
55  *     |   FFF     /    
56  *     |   / \    /     
57  *     | GGG HHH /      
58  *     |  |   +-/
59  *     | III
60  *     +--+ 
61  *
62  * 
63  * DFlocal(X) = { Y <- Succ(X) | idom(Y) != X }
64  * DFup(Z)    = { Y <- DF(Z) | idom(Y) != X }
65  *
66  *
67  * [] == DFlocal(X) U DF(X)
68  * () == DFup(X)
69  *
70  * Dominator graph of the same nodes.
71  *
72  *           AAA     AAA: [ ] ()
73  *          /   \
74  *        BBB    JJJ BBB: [ JJJ ] ( JJJ )  JJJ: [ ] ()
75  *         |
76  *        CCC        CCC: [ ] ( BBB, JJJ )
77  *        / \
78  *     DDD   EEE     DDD: [ ] ( BBB ) EEE: [ JJJ ] ()
79  *      |
80  *     FFF           FFF: [ ] ( BBB )
81  *     / \         
82  *  GGG   HHH        GGG: [ ] ( BBB ) HHH: [ BBB ] ()
83  *   |
84  *  III              III: [ BBB ] ()
85  *
86  *
87  * BBB and JJJ are definitely the dominance frontier.
88  * Where do I place phi functions and how do I make that decision.
89  *   
90  */
91 static void die(char *fmt, ...)
92 {
93         va_list args;
94
95         va_start(args, fmt);
96         vfprintf(stderr, fmt, args);
97         va_end(args);
98         fflush(stdout);
99         fflush(stderr);
100         exit(1);
101 }
102
103 #define MALLOC_STRONG_DEBUG
104 static void *xmalloc(size_t size, const char *name)
105 {
106         void *buf;
107         buf = malloc(size);
108         if (!buf) {
109                 die("Cannot malloc %ld bytes to hold %s: %s\n",
110                         size + 0UL, name, strerror(errno));
111         }
112         return buf;
113 }
114
115 static void *xcmalloc(size_t size, const char *name)
116 {
117         void *buf;
118         buf = xmalloc(size, name);
119         memset(buf, 0, size);
120         return buf;
121 }
122
123 static void xfree(const void *ptr)
124 {
125         free((void *)ptr);
126 }
127
128 static char *xstrdup(const char *str)
129 {
130         char *new;
131         int len;
132         len = strlen(str);
133         new = xmalloc(len + 1, "xstrdup string");
134         memcpy(new, str, len);
135         new[len] = '\0';
136         return new;
137 }
138
139 static void xchdir(const char *path)
140 {
141         if (chdir(path) != 0) {
142                 die("chdir to %s failed: %s\n",
143                         path, strerror(errno));
144         }
145 }
146
147 static int exists(const char *dirname, const char *filename)
148 {
149         int does_exist = 1;
150         xchdir(dirname);
151         if (access(filename, O_RDONLY) < 0) {
152                 if ((errno != EACCES) && (errno != EROFS)) {
153                         does_exist = 0;
154                 }
155         }
156         return does_exist;
157 }
158
159
160 static char *slurp_file(const char *dirname, const char *filename, off_t *r_size)
161 {
162         int fd;
163         char *buf;
164         off_t size, progress;
165         ssize_t result;
166         struct stat stats;
167         
168         if (!filename) {
169                 *r_size = 0;
170                 return 0;
171         }
172         xchdir(dirname);
173         fd = open(filename, O_RDONLY);
174         if (fd < 0) {
175                 die("Cannot open '%s' : %s\n",
176                         filename, strerror(errno));
177         }
178         result = fstat(fd, &stats);
179         if (result < 0) {
180                 die("Cannot stat: %s: %s\n",
181                         filename, strerror(errno));
182         }
183         size = stats.st_size;
184         *r_size = size +1;
185         buf = xmalloc(size +2, filename);
186         buf[size] = '\n'; /* Make certain the file is newline terminated */
187         buf[size+1] = '\0'; /* Null terminate the file for good measure */
188         progress = 0;
189         while(progress < size) {
190                 result = read(fd, buf + progress, size - progress);
191                 if (result < 0) {
192                         if ((errno == EINTR) || (errno == EAGAIN))
193                                 continue;
194                         die("read on %s of %ld bytes failed: %s\n",
195                                 filename, (size - progress)+ 0UL, strerror(errno));
196                 }
197                 progress += result;
198         }
199         result = close(fd);
200         if (result < 0) {
201                 die("Close of %s failed: %s\n",
202                         filename, strerror(errno));
203         }
204         return buf;
205 }
206
207 /* Long on the destination platform */
208 typedef unsigned long ulong_t;
209 typedef long long_t;
210
211 struct file_state {
212         struct file_state *prev;
213         const char *basename;
214         char *dirname;
215         char *buf;
216         off_t size;
217         char *pos;
218         int line;
219         char *line_start;
220 };
221 struct hash_entry;
222 struct token {
223         int tok;
224         struct hash_entry *ident;
225         int str_len;
226         union {
227                 ulong_t integer;
228                 const char *str;
229         } val;
230 };
231
232 /* I have two classes of types:
233  * Operational types.
234  * Logical types.  (The type the C standard says the operation is of)
235  *
236  * The operational types are:
237  * chars
238  * shorts
239  * ints
240  * longs
241  *
242  * floats
243  * doubles
244  * long doubles
245  *
246  * pointer
247  */
248
249
250 /* Machine model.
251  * No memory is useable by the compiler.
252  * There is no floating point support.
253  * All operations take place in general purpose registers.
254  * There is one type of general purpose register.
255  * Unsigned longs are stored in that general purpose register.
256  */
257
258 /* Operations on general purpose registers.
259  */
260
261 #define OP_SMUL       0
262 #define OP_UMUL       1
263 #define OP_SDIV       2
264 #define OP_UDIV       3
265 #define OP_SMOD       4
266 #define OP_UMOD       5
267 #define OP_ADD        6
268 #define OP_SUB        7
269 #define OP_SL         8 
270 #define OP_USR        9
271 #define OP_SSR       10 
272 #define OP_AND       11 
273 #define OP_XOR       12
274 #define OP_OR        13
275 #define OP_POS       14 /* Dummy positive operator don't use it */
276 #define OP_NEG       15
277 #define OP_INVERT    16
278                      
279 #define OP_EQ        20
280 #define OP_NOTEQ     21
281 #define OP_SLESS     22
282 #define OP_ULESS     23
283 #define OP_SMORE     24
284 #define OP_UMORE     25
285 #define OP_SLESSEQ   26
286 #define OP_ULESSEQ   27
287 #define OP_SMOREEQ   28
288 #define OP_UMOREEQ   29
289                      
290 #define OP_LFALSE    30  /* Test if the expression is logically false */
291 #define OP_LTRUE     31  /* Test if the expression is logcially true */
292
293 #define OP_LOAD      32
294 #define OP_STORE     33
295
296 #define OP_NOOP      34
297
298 #define OP_MIN_CONST 50
299 #define OP_MAX_CONST 59
300 #define IS_CONST_OP(X) (((X) >= OP_MIN_CONST) && ((X) <= OP_MAX_CONST))
301 #define OP_INTCONST  50
302 #define OP_BLOBCONST 51
303 /* For OP_BLOBCONST triple->type holds the layout and size
304  * information.  u.blob holds a pointer to the raw binary
305  * data for the constant initializer.
306  */
307 #define OP_ADDRCONST 52
308 /* For OP_ADDRCONST triple->type holds the type.
309  * triple->left holds the reference to the static variable.
310  * triple->u.cval holds an offset from that value.
311  */
312
313 #define OP_WRITE     60 
314 /* OP_WRITE moves one pseudo register to another.
315  * triple->left holds the destination pseudo register,
316  * must be an OP_DECL.
317  * triple->right holds the psuedo to move.
318  */
319
320 #define OP_READ      61
321 /* OP_READ reads the value of a variable and makes
322  * it available for the pseudo operation.
323  * Useful for things like def-use chains.
324  * triple->left holds points to the triple to read from.
325  */
326 #define OP_COPY      62
327 /* OP_COPY makes a copy of the psedo register or constant in op->left.
328  */
329
330 /* Hard operations that I don't know if they are worth supporting */
331 #define OP_DEREF     65
332 /* OP_DEREF generates an lvalue from a pointer.
333  * triple->left holds the pointer value.
334  * OP_DEREF serves as a place holder to indicate all necessary
335  * checks have been done to indicate a value is an lvalue.
336  */
337 #define OP_DOT       66
338
339 #define OP_VAL       67
340 /* OP_VAL returns the value of a subexpression of the current expression.
341  * Useful for operators that have side effects.
342  * triple->left holds the expression.
343  * triple->right holds the subexpression of triple->left that is the
344  * value of the expression.
345  *
346  * Not seen outside of expressions.
347  */
348 #define OP_LAND      68
349 /* OP_LAND performs a C logical and between triple->left and triple->right.
350  * Not seen outside of expressions.
351  */
352 #define OP_LOR       69
353 /* OP_LOR performs a C logical or between triple->left and triple->right.
354  * Not seen outside of expressions.
355  */
356 #define OP_COND      70
357 /* OP_CODE performas a C ? : operation. 
358  * triple->left holds the test.
359  * triple->right holds an OP_PRODUCT triple.
360  * triple->right->left holds the expression to evaluate if
361  *     the test returns true.
362  * triple->right->right holds the expression to evaluate if
363  *     the test returns false.
364  * Not seen outside of expressions.
365  */
366 #define OP_COMMA     71
367 /* OP_COMMA performacs a C comma operation.
368  * That is triple->left is evaluated, then triple->right
369  * and the value of triple->right is returned.
370  * Not seen outside of expressions.
371  */
372
373 #define OP_CALL      72
374 /* OP_CALL performs a procedure call. 
375  * triple->left holda a pointer to the OP_LIST of a function
376  * triple->right holds a pointer either a single argument
377  *    or a list of arguments.  The list is formed by inserting
378  *    OP_PRODUCT triples inbetween the argument values.
379  * Currently not seen outside of expressions.
380  */
381 #define OP_PRODUCT   73
382 /* OP_PRODUCT is a utility triple, both triple->left and triple->right
383  * are used.  Other opcodes OP_CALL, and OP_COND use it increase
384  * the number of triple pointers in a triple.
385  * Currently Not seen outside of expressions.
386  */
387
388 /* statements */
389 #define OP_LIST      80
390 /* OP_LIST Holds a list of statements, and a result value.
391  * triple->left holds the list of statements.
392  * triple->right holds the value of the statements.
393  * triple->right must be the last statement in the list.
394  */
395
396 #define OP_BRANCH    81 /* branch */
397 /* For branch instructions
398  * triple->left holds the branch target.
399  * triple->right holds the branch condition.
400  * triple->next holds where to branch to if the branch is not taken.
401  * The branch target can only be a decl...
402  */
403
404 #define OP_LABEL     83
405 /* OP_LABEL is a triple that establishes an target for branches.
406  * triple->use is the list of all branches that use this label.
407  */
408
409 #define OP_ADECL     84 
410 /* OP_DECL is a triple that establishes an lvalue for assignments.
411  * triple->use is a list of statements that use the variable.
412  */
413
414 #define OP_SDECL     85
415 /* OP_VAR is a triple that establishes a variable of static
416  * storage duration.
417  * triple->use is a list of statements that use the variable.
418  * triple->left holds the initializer expression.
419  */
420
421
422 #define OP_PHI       86
423 /* OP_PHI is a triple used in SSA form code.  
424  * It is used when multiple code paths merge and a variable needs
425  * a single assignment from any of those code paths.
426  * The operation is a cross between OP_DECL and OP_WRITE, which
427  * is what OP_PHI is geneared from.
428  * 
429  * triple->left points to an array of pointers to triple.
430  * The size of the array is the number of control paths into the block
431  * in which OP_PHI resides.  The elements of the array point to point
432  * to the variables OP_PHI is derived from.
433  *
434  * triple->right holds a pointer to the original OP_DECL node
435  */
436
437 /* Architecture specific instructions */
438 #define OP_CMP         100
439 #define OP_TEST        101
440 #define OP_SET_EQ      102
441 #define OP_SET_NOTEQ   103
442 #define OP_SET_SLESS   104
443 #define OP_SET_ULESS   105
444 #define OP_SET_SMORE   106
445 #define OP_SET_UMORE   107
446 #define OP_SET_SLESSEQ 108
447 #define OP_SET_ULESSEQ 109
448 #define OP_SET_SMOREEQ 110
449 #define OP_SET_UMOREEQ 111
450
451 #define OP_JMP         112
452 #define OP_JMP_EQ      113
453 #define OP_JMP_NOTEQ   114
454 #define OP_JMP_SLESS   115
455 #define OP_JMP_ULESS   116
456 #define OP_JMP_SMORE   117
457 #define OP_JMP_UMORE   118
458 #define OP_JMP_SLESSEQ 119
459 #define OP_JMP_ULESSEQ 120
460 #define OP_JMP_SMOREEQ 121
461 #define OP_JMP_UMOREEQ 122
462
463 /* Builtin operators that it is just simpler to use the compiler for */
464 #define OP_INB         130
465 #define OP_INW         131
466 #define OP_INL         132
467 #define OP_OUTB        133
468 #define OP_OUTW        134
469 #define OP_OUTL        135
470 #define OP_BSF         136
471 #define OP_BSR         137
472 #warning "FIXME implement rdmsr wrmsr"
473 #if 0
474 /* I need to implement these but, I need to implment > 32bit return
475  * values first.
476  */
477 #define OP_RDMSR       138
478 #define OP_WRMSR       139
479 #endif
480 #define OP_HLT         140
481
482 static const char *table_ops[] = {
483 [OP_SMUL       ] = "smul",
484 [OP_UMUL       ] = "umul",
485 [OP_SDIV       ] = "sdiv",
486 [OP_UDIV       ] = "udiv",
487 [OP_SMOD       ] = "smod",
488 [OP_UMOD       ] = "umod",
489 [OP_ADD        ] = "add",
490 [OP_SUB        ] = "sub",
491 [OP_SL         ] = "sl", 
492 [OP_USR        ] = "usr",
493 [OP_SSR        ] = "ssr", 
494 [OP_AND        ] = "and", 
495 [OP_XOR        ] = "xor",
496 [OP_OR         ] = "or",
497 [OP_POS        ] = "pos",
498 [OP_NEG        ] = "neg",
499 [OP_INVERT     ] = "invert",
500
501 [OP_EQ         ] = "eq",
502 [OP_NOTEQ      ] = "noteq",
503 [OP_SLESS      ] = "sless",
504 [OP_ULESS      ] = "uless",
505 [OP_SMORE      ] = "smore",
506 [OP_UMORE      ] = "umore",
507 [OP_SLESSEQ    ] = "slesseq",
508 [OP_ULESSEQ    ] = "ulesseq",
509 [OP_SMOREEQ    ] = "smoreeq",
510 [OP_UMOREEQ    ] = "umoreeq",
511 [OP_LFALSE     ] = "lfalse",
512 [OP_LTRUE      ] = "ltrue",
513
514 [OP_LOAD       ] = "load",
515 [OP_STORE      ] = "store",
516
517 [OP_NOOP       ] = "noop", 
518
519 [OP_INTCONST   ] = "intconst",
520 [OP_BLOBCONST  ] = "blobconst",
521 [OP_ADDRCONST  ] = "addrconst",
522
523 [OP_WRITE      ] = "write",
524 [OP_READ       ] = "read",
525 [OP_COPY       ] = "copy",
526 [OP_DEREF      ] = "deref",
527 [OP_DOT        ] = "dot",
528
529 [OP_VAL        ] = "val",
530 [OP_LAND       ] = "land",
531 [OP_LOR        ] = "lor",
532 [OP_COND       ] = "cond",
533 [OP_COMMA      ] = "comma",
534 [OP_CALL       ] = "call",
535 [OP_PRODUCT    ] = "product",
536
537 [OP_LIST       ] = "list",
538 [OP_BRANCH     ] = "branch",
539 [OP_LABEL      ] = "label",
540 [OP_ADECL      ] = "adecl",
541 [OP_SDECL      ] = "sdecl",
542 [OP_PHI        ] = "phi",
543
544 [OP_CMP        ] = "cmp",
545 [OP_TEST       ] = "test",
546 [OP_SET_EQ     ] = "set_eq",
547 [OP_SET_NOTEQ  ] = "set_noteq",
548 [OP_SET_SLESS  ] = "set_sless",
549 [OP_SET_ULESS  ] = "set_uless",
550 [OP_SET_SMORE  ] = "set_smore",
551 [OP_SET_SMORE  ] = "set_umore",
552 [OP_SET_SLESSEQ] = "set_slesseq",
553 [OP_SET_ULESSEQ] = "set_ulesseq",
554 [OP_SET_SMOREEQ] = "set_smoreq",
555 [OP_SET_UMOREEQ] = "set_umoreq",
556 [OP_JMP        ] = "jmp",
557 [OP_JMP_EQ     ] = "jmp_eq",
558 [OP_JMP_NOTEQ  ] = "jmp_noteq",
559 [OP_JMP_SLESS  ] = "jmp_sless",
560 [OP_JMP_ULESS  ] = "jmp_uless",
561 [OP_JMP_SMORE  ] = "jmp_smore",
562 [OP_JMP_SMORE  ] = "jmp_umore",
563 [OP_JMP_SLESSEQ] = "jmp_slesseq",
564 [OP_JMP_ULESSEQ] = "jmp_ulesseq",
565 [OP_JMP_SMOREEQ] = "jmp_smoreq",
566 [OP_JMP_UMOREEQ] = "jmp_umoreq",
567
568 [OP_INB        ] = "__inb",
569 [OP_INW        ] = "__inw",
570 [OP_INL        ] = "__inl",
571 [OP_OUTB       ] = "__outb",
572 [OP_OUTW       ] = "__outw",
573 [OP_OUTL       ] = "__outl",
574 [OP_BSF        ] = "__bsf",
575 [OP_BSR        ] = "__bsr",
576 [OP_HLT        ] = "__hlt",
577
578 };
579
580 #define OP_MAX      (sizeof(table_ops)/sizeof(table_ops[0]))
581
582
583 static const char *tops(int index) 
584 {
585         static const char unknown[] = "unknown op";
586         if (index < 0) {
587                 return unknown;
588         }
589         if (index > OP_MAX) {
590                 return unknown;
591         }
592         return table_ops[index];
593 }
594
595 #warning "FIXME Finish defining struct type"
596
597 struct triple;
598 struct block;
599 struct triple_set {
600         struct triple_set *next;
601         struct triple *member;
602 };
603
604 struct triple {
605         struct triple *next, *prev;
606         struct triple_set *use;
607         struct type *type;
608         int op;
609         unsigned id; /* A scratch value and finally the register */
610         struct triple *left;
611         struct triple *right;
612         union {
613                 ulong_t cval;
614                 struct block  *block;
615                 void *blob;
616         } u;
617         const char *filename;
618         int line;
619         int col;
620 };
621
622 struct block_set {
623         struct block_set *next;
624         struct block *member;
625 };
626 struct block {
627         struct block *work_next;
628         struct block *left, *right;
629         struct triple *first, *last;
630         int users;
631         struct block_set *use;
632         struct block_set *idominates;
633         struct block_set *domfrontier;
634         struct block *idom;
635         struct block_set *ipdominates;
636         struct block_set *ipdomfrontier;
637         struct block *ipdom;
638         int vertex;
639         
640 };
641
642 struct symbol {
643         struct symbol *next;
644         struct hash_entry *ident;
645         struct triple *def;
646         struct type *type;
647         int scope_depth;
648 };
649
650 struct macro {
651         struct hash_entry *ident;
652         char *buf;
653         int buf_len;
654 };
655
656 struct hash_entry {
657         struct hash_entry *next;
658         const char *name;
659         int name_len;
660         int tok;
661         struct macro *sym_define;
662         struct symbol *sym_label;
663         struct symbol *sym_struct;
664         struct symbol *sym_ident;
665 };
666
667 #define HASH_TABLE_SIZE 2048
668
669 struct compile_state {
670         struct triple *vars;
671         struct file_state *file;
672         struct token token[4];
673         struct hash_entry *hash_table[HASH_TABLE_SIZE];
674         struct hash_entry *i_continue;
675         struct hash_entry *i_break;
676         int scope_depth;
677         int if_depth, if_value;
678         int macro_line;
679         struct file_state *macro_file;
680         struct triple *main_function;
681         struct block *first_block, *last_block;
682         int last_vertex;
683         int debug;
684         int optimize;
685 };
686
687 #define MAX_REGISTERS      75
688 #define MAX_REG_EQUIVS     16
689 #define MAX_REGC           12
690 #define REG_UNSET          0
691
692 /* Provision for 8 register classes */
693 #define REGC_MASK ((1 << MAX_REGC) - 1)
694 #define ID_REG_CLASSES(ID)      ((ID) & REGC_MASK)
695 #define ID_REG(ID)              ((ID) >> MAX_REGC)
696 #define MK_REG_ID(REG, CLASSES) (((REG) << MAX_REGC) | ((CLASSES) & REGC_MASK))
697
698 static unsigned alloc_virtual_reg(void)
699 {
700         static unsigned virtual_reg = MAX_REGISTERS;
701         virtual_reg += 1;
702         return virtual_reg;
703 }
704
705 static unsigned arch_reg_regcm(struct compile_state *state, int reg);
706 static void arch_reg_equivs(
707         struct compile_state *state, unsigned *equiv, int reg);
708 static int arch_select_free_register(
709         struct compile_state *state, char *used, int classes);
710 static unsigned arch_regc_size(struct compile_state *state, int class);
711 static int arch_regcm_intersect(unsigned regcm1, unsigned regcm2);
712 static unsigned arch_type_to_regcm(struct compile_state *state, struct type *type);
713 static const char *arch_reg_str(int reg);
714
715 #define DEBUG_INTERMEDIATE_CODE 0x0001
716 #define DEBUG_CONTROL_FLOW      0x0002
717 #define DEBUG_BASIC_BLOCKS      0x0004
718 #define DEBUG_FDOMINATORS       0x0008
719 #define DEBUG_RDOMINATORS       0x0010
720 #define DEBUG_TRIPLES           0x0020
721 #define DEBUG_INTERFERENCE      0x0040
722 #define DEBUG_ARCH_CODE         0x0080
723 #define DEBUG_CODE_ELIMINATION  0x0100
724
725 #define GLOBAL_SCOPE_DEPTH 1
726
727 static void compile_file(struct compile_state *old_state, char *filename, int local);
728
729 static int get_col(struct file_state *file)
730 {
731         int col;
732         char *ptr, *end;
733         ptr = file->line_start;
734         end = file->pos;
735         for(col = 0; ptr < end; ptr++) {
736                 if (*ptr != '\t') {
737                         col++;
738                 } 
739                 else {
740                         col = (col & ~7) + 8;
741                 }
742         }
743         return col;
744 }
745
746 static void loc(FILE *fp, struct compile_state *state, struct triple *triple)
747 {
748         int col;
749         if (triple) {
750                 fprintf(fp, "%s:%d.%d: ", 
751                         triple->filename, triple->line, triple->col);
752                 return;
753         }
754         if (!state->file) {
755                 return;
756         }
757         col = get_col(state->file);
758         fprintf(fp, "%s:%d.%d: ", 
759                 state->file->basename, state->file->line, col);
760 }
761
762 static void __internal_error(struct compile_state *state, struct triple *ptr, 
763         char *fmt, ...)
764 {
765         va_list args;
766         va_start(args, fmt);
767         loc(stderr, state, ptr);
768         fprintf(stderr, "Internal compiler error: ");
769         vfprintf(stderr, fmt, args);
770         fprintf(stderr, "\n");
771         va_end(args);
772         abort();
773 }
774
775
776 static void __internal_warning(struct compile_state *state, struct triple *ptr, 
777         char *fmt, ...)
778 {
779         va_list args;
780         va_start(args, fmt);
781         loc(stderr, state, ptr);
782         fprintf(stderr, "Internal compiler warning: ");
783         vfprintf(stderr, fmt, args);
784         fprintf(stderr, "\n");
785         va_end(args);
786 }
787
788
789
790 static void __error(struct compile_state *state, struct triple *ptr, 
791         char *fmt, ...)
792 {
793         va_list args;
794         va_start(args, fmt);
795         loc(stderr, state, ptr);
796         vfprintf(stderr, fmt, args);
797         va_end(args);
798         fprintf(stderr, "\n");
799         exit(1);
800 }
801
802 static void __warning(struct compile_state *state, struct triple *ptr, 
803         char *fmt, ...)
804 {
805         va_list args;
806         va_start(args, fmt);
807         loc(stderr, state, ptr);
808         fprintf(stderr, "warning: "); 
809         vfprintf(stderr, fmt, args);
810         fprintf(stderr, "\n");
811         va_end(args);
812 }
813
814 #if DEBUG_ERROR_MESSAGES 
815 #  define internal_error fprintf(stderr,  "@ %s.%s:%d \t", __FILE__, __func__, __LINE__),__internal_error
816 #  define internal_warning fprintf(stderr,  "@ %s.%s:%d \t", __FILE__, __func__, __LINE__),__internal_warning
817 #  define error fprintf(stderr, "@ %s.%s:%d \t", __FILE__, __func__, __LINE__),__error
818 #  define warning fprintf(stderr, "@ %s.%s:%d \t", __FILE__, __func__, __LINE__),__warning
819 #else
820 #  define internal_error __internal_error
821 #  define internal_warning __internal_warning
822 #  define error __error
823 #  define warning __warning
824 #endif
825 #define FINISHME() warning(state, 0, "FINISHME @ %s.%s:%d", __FILE__, __func__, __LINE__)
826
827
828 static void valid_op(struct compile_state *state, struct triple *ptr)
829 {
830         char *fmt = "invalid op: %d";
831         if (ptr->op >= OP_MAX) {
832                 internal_error(state, 0, fmt,   ptr->op);
833         }
834         if (ptr->op < 0) {
835                 internal_error(state, 0, fmt,   ptr->op);
836         }
837 }
838
839 static void process_trigraphs(struct compile_state *state)
840 {
841         char *src, *dest, *end;
842         struct file_state *file;
843         file = state->file;
844         src = dest = file->buf;
845         end = file->buf + file->size;
846         while((end - src) >= 3) {
847                 if ((src[0] == '?') && (src[1] == '?')) {
848                         int c = -1;
849                         switch(src[2]) {
850                         case '=': c = '#'; break;
851                         case '/': c = '\\'; break;
852                         case '\'': c = '^'; break;
853                         case '(': c = '['; break;
854                         case ')': c = ']'; break;
855                         case '!': c = '!'; break;
856                         case '<': c = '{'; break;
857                         case '>': c = '}'; break;
858                         case '-': c = '~'; break;
859                         }
860                         if (c != -1) {
861                                 *dest++ = c;
862                                 src += 3;
863                         }
864                         else {
865                                 *dest++ = *src++;
866                         }
867                 }
868                 else {
869                         *dest++ = *src++;
870                 }
871         }
872         while(src != end) {
873                 *dest++ = *src++;
874         }
875         file->size = dest - file->buf;
876 }
877
878 static void splice_lines(struct compile_state *state)
879 {
880         char *src, *dest, *end;
881         struct file_state *file;
882         file = state->file;
883         src = dest = file->buf;
884         end = file->buf + file->size;
885         while((end - src) >= 2) {
886                 if ((src[0] == '\\') && (src[1] == '\n')) {
887                         src += 2;
888                 }
889                 else {
890                         *dest++ = *src++;
891                 }
892         }
893         while(src != end) {
894                 *dest++ = *src++;
895         }
896         file->size = dest - file->buf;
897 }
898
899 static struct type void_type;
900 static void use_triple(struct triple *used, struct triple *user)
901 {
902         struct triple_set **ptr, *new;
903         if (!used)
904                 return;
905         if (!user)
906                 return;
907         ptr = &used->use;
908         while(*ptr) {
909                 if ((*ptr)->member == user) {
910                         return;
911                 }
912                 ptr = &(*ptr)->next;
913         }
914         /* Append new to the head of the list, 
915          * copy_func and rename_block_variables
916          * depends on this.
917          */
918         new = xcmalloc(sizeof(*new), "triple_set");
919         new->member = user;
920         new->next   = used->use;
921         used->use   = new;
922 }
923
924 static void unuse_triple(struct triple *used, struct triple *unuser)
925 {
926         struct triple_set *use, **ptr;
927         ptr = &used->use;
928         while(*ptr) {
929                 use = *ptr;
930                 if (use->member == unuser) {
931                         *ptr = use->next;
932                         xfree(use);
933                 }
934                 else {
935                         ptr = &use->next;
936                 }
937         }
938 }
939
940 static void push_triple(struct triple *used, struct triple *user)
941 {
942         struct triple_set *new;
943         if (!used)
944                 return;
945         if (!user)
946                 return;
947         /* Append new to the head of the list,
948          * it's the only sensible behavoir for a stack.
949          */
950         new = xcmalloc(sizeof(*new), "triple_set");
951         new->member = user;
952         new->next   = used->use;
953         used->use   = new;
954 }
955
956 static void pop_triple(struct triple *used, struct triple *unuser)
957 {
958         struct triple_set *use, **ptr;
959         ptr = &used->use;
960         while(*ptr) {
961                 use = *ptr;
962                 if (use->member == unuser) {
963                         *ptr = use->next;
964                         xfree(use);
965                         /* Only free one occurance from the stack */
966                         return;
967                 }
968                 else {
969                         ptr = &use->next;
970                 }
971         }
972 }
973
974
975 /* The zero triple is used as a place holder when we are removing pointers
976  * from a triple.  Having allows certain sanity checks to pass even
977  * when the original triple that was pointed to is gone.
978  */
979 static struct triple zero_triple = {
980         .next     = &zero_triple,
981         .prev     = &zero_triple,
982         .use      = 0,
983         .op       = OP_INTCONST,
984         .id       = -1, /* An invalid id */
985         .left     = 0,
986         .right    = 0,
987         .u = { .cval   = 0, },
988         .filename = __FILE__,
989         .line     = __LINE__,
990 };
991
992 static struct triple *build_triple(struct compile_state *state, 
993         int op, struct type *type, struct triple *left, struct triple *right,
994         const char *filename, int line, int col)
995 {
996         struct triple *ret;
997         ret = xcmalloc(sizeof(*ret), "tripple");
998         ret->op       = op;
999         ret->type     = type;
1000         ret->left     = left;
1001         ret->right    = right;
1002         ret->next     = ret;
1003         ret->prev     = ret;
1004         ret->filename = filename;
1005         ret->line     = line;
1006         ret->col      = col;
1007         return ret;
1008 }
1009
1010 static struct triple *triple(struct compile_state *state, 
1011         int op, struct type *type, struct triple *left, struct triple *right)
1012 {
1013         struct triple *ret;
1014         const char *filename;
1015         int line, col;
1016         filename = 0;
1017         line = 0;
1018         col  = 0;
1019         if (state->file) {
1020                 filename = state->file->basename;
1021                 line     = state->file->line;
1022                 col      = get_col(state->file);
1023         }
1024         ret = build_triple(state, op, type, left, right, filename, line, col);
1025         /* record the branch target was used */
1026         if (ret->op == OP_BRANCH) {
1027                 if (!left || (left->op != OP_LABEL)) {
1028                         internal_error(state, 0, "branch not to label");
1029                 }
1030                 use_triple(left, ret);
1031         }
1032         return ret;
1033 }
1034
1035 static void insert_triple(struct compile_state *state,
1036         struct triple *first, struct triple *ptr)
1037 {
1038         if (ptr) {
1039                 if (ptr->next != ptr) {
1040                         internal_error(state, ptr, "expression already used");
1041                 }
1042                 ptr->next       = first;
1043                 ptr->prev       = first->prev;
1044                 ptr->prev->next = ptr;
1045                 ptr->next->prev = ptr;
1046                 if ((ptr->prev->op == OP_BRANCH) && (ptr->prev->right)) {
1047                         unuse_triple(first, ptr->prev);
1048                         use_triple(ptr, ptr->prev);
1049                 }
1050         }
1051 }
1052
1053 static struct triple *pre_triple(struct compile_state *state,
1054         struct triple *base,
1055         int op, struct type *type, struct triple *left, struct triple *right)
1056 {
1057         /* Careful this assumes it can do the easy thing to get the block */
1058         struct triple *ret;
1059         ret = build_triple(state, op, type, left, right, 
1060                 base->filename, base->line, base->col);
1061         ret->u.block = base->u.block;
1062         insert_triple(state, base, ret);
1063         return ret;
1064 }
1065
1066 static struct triple *post_triple(struct compile_state *state,
1067         struct triple *base,
1068         int op, struct type *type, struct triple *left, struct triple *right)
1069 {
1070         /* Careful this assumes it can do the easy thing to get the block */
1071         struct triple *ret;
1072         ret = build_triple(state, op, type, left, right, 
1073                 base->filename, base->line, base->col);
1074         ret->u.block = base->u.block;
1075         insert_triple(state, base->next, ret);
1076         return ret;
1077 }
1078
1079 static struct triple *label(struct compile_state *state)
1080 {
1081         /* Labels don't get a type */
1082         struct triple *result;
1083         result = triple(state, OP_LABEL, &void_type, 0, 0);
1084         return result;
1085 }
1086
1087 static int triple_is_pure(struct compile_state *state, struct triple *ins)
1088 {
1089         /* Does the triple have no side effects.
1090          * I.e. Rexecuting the triple with the same arguments 
1091          * gives the same value.
1092          */
1093         int pure;
1094         switch(ins->op) {
1095         case OP_SMUL:    case OP_UMUL:
1096         case OP_SDIV:    case OP_UDIV:
1097         case OP_SMOD:    case OP_UMOD:
1098         case OP_ADD:     case OP_SUB:
1099         case OP_SL:
1100         case OP_USR:     case OP_SSR:
1101         case OP_AND:
1102         case OP_XOR:
1103         case OP_OR:
1104         case OP_POS:     case OP_NEG:
1105         case OP_INVERT:
1106         case OP_EQ:      case OP_NOTEQ:
1107         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
1108         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
1109         case OP_LFALSE:  case OP_LTRUE:
1110         case OP_NOOP:
1111         case OP_INTCONST:
1112         case OP_BLOBCONST:
1113         case OP_ADDRCONST:
1114
1115         case OP_WRITE:   
1116         case OP_READ:
1117         case OP_COPY:
1118         case OP_BRANCH:
1119         case OP_LABEL:
1120         case OP_ADECL:
1121         case OP_SDECL:
1122         case OP_PHI:
1123
1124
1125         case OP_CMP:
1126         case OP_TEST:
1127         case OP_SET_EQ:      case OP_SET_NOTEQ:
1128         case OP_SET_SLESS:   case OP_SET_ULESS:
1129         case OP_SET_SMORE:   case OP_SET_UMORE:
1130         case OP_SET_SLESSEQ: case OP_SET_ULESSEQ:
1131         case OP_SET_SMOREEQ: case OP_SET_UMOREEQ:
1132                 
1133         case OP_JMP:
1134         case OP_JMP_EQ:      case OP_JMP_NOTEQ:
1135         case OP_JMP_SLESS:   case OP_JMP_ULESS:
1136         case OP_JMP_SMORE:   case OP_JMP_UMORE:
1137         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
1138         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
1139
1140         case OP_BSF:         case OP_BSR:
1141                 pure = 1;
1142                 break;
1143         case OP_LOAD: case OP_STORE:
1144         case OP_INB:  case OP_INW:   case OP_INL:
1145         case OP_OUTB: case OP_OUTW:  case OP_OUTL:
1146         case OP_HLT:
1147                 pure = 0;
1148                 break;
1149         default:
1150                 internal_error(state, ins, "purity of %s not known",
1151                         tops(ins->op));
1152                 pure = 0;
1153                 break;
1154         }
1155         return pure;
1156 }
1157
1158 static int triple_is_branch(struct triple *ins)
1159 {
1160         /* This function is used to determine which triples need
1161          * a register.
1162          */
1163         int is_branch = 0;
1164         switch(ins->op) {
1165         case OP_BRANCH:
1166         case OP_JMP:
1167         case OP_JMP_EQ:      case OP_JMP_NOTEQ: 
1168         case OP_JMP_SLESS:   case OP_JMP_ULESS: 
1169         case OP_JMP_SMORE:   case OP_JMP_UMORE:
1170         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
1171         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
1172                 is_branch = 1;
1173                 break;
1174         }
1175         return is_branch;
1176 }
1177
1178 static int triple_is_def(struct triple *ins)
1179 {
1180         /* This function is used to determine which triples need
1181          * a register.
1182          */
1183         int is_def = 1;
1184         switch(ins->op) {
1185         case OP_ADECL:
1186         case OP_SDECL:
1187         case OP_LABEL:
1188         case OP_INTCONST:
1189         case OP_BLOBCONST:
1190         case OP_ADDRCONST:
1191         case OP_STORE:
1192         case OP_WRITE:
1193         case OP_NOOP:
1194         case OP_OUTB:    case OP_OUTW:    case OP_OUTL:
1195         case OP_BRANCH:
1196         case OP_JMP:
1197         case OP_JMP_EQ:      case OP_JMP_NOTEQ: 
1198         case OP_JMP_SLESS:   case OP_JMP_ULESS: 
1199         case OP_JMP_SMORE:   case OP_JMP_UMORE:
1200         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
1201         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
1202                 is_def = 0;
1203                 break;
1204         }
1205         return is_def;
1206 }
1207
1208 static struct triple **triple_targ(struct compile_state *state,
1209         struct triple *triple, struct triple **last)
1210 {
1211         struct triple **ret;
1212         ret = 0;
1213         switch(triple->op) {
1214         case OP_BRANCH:
1215         case OP_JMP:
1216         case OP_JMP_EQ:      case OP_JMP_NOTEQ:
1217         case OP_JMP_SLESS:   case OP_JMP_ULESS:
1218         case OP_JMP_SMORE:   case OP_JMP_UMORE:
1219         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
1220         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
1221                 if (!last) {
1222                         ret = &triple->left;
1223                 }
1224                 else if ((last == &triple->left) && triple->right) {
1225                         ret = &triple->next;
1226                 }
1227                 break;
1228         }
1229         return ret;
1230 }
1231
1232 static struct triple **triple_rhs(struct compile_state *state,
1233         struct triple *triple, struct triple **last)
1234 {
1235         struct triple **ret;
1236         ret = 0;
1237         switch(triple->op) {
1238                 /* binary operations */
1239         case OP_SMUL:    case OP_UMUL:    case OP_SDIV:    case OP_UDIV:
1240         case OP_SMOD:    case OP_UMOD:    case OP_ADD:     case OP_SUB:
1241         case OP_SL:      case OP_USR:     case OP_SSR:     case OP_AND:  
1242         case OP_XOR:     case OP_OR:      case OP_EQ:      case OP_NOTEQ: 
1243         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
1244         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
1245         case OP_CMP:
1246         case OP_OUTB:    case OP_OUTW:    case OP_OUTL:
1247 #if 0
1248                 if (!triple->left) {
1249                         internal_error(state, triple, "left arg missing");
1250                 }
1251                 if (!triple->right) {
1252                         internal_error(state, triple, "right arg missing");
1253                 }
1254 #endif
1255                 if (!last) {
1256                         ret = &triple->left;
1257                 }
1258                 else if (last == &triple->left){
1259                         ret = &triple->right;
1260                 }
1261                 break;
1262                 /* unary operations */
1263         case OP_POS:     case OP_NEG:
1264         case OP_INVERT:  case OP_LFALSE:  case OP_LTRUE:
1265         case OP_COPY:
1266         case OP_TEST:
1267         case OP_SET_EQ:      case OP_SET_NOTEQ:
1268         case OP_SET_SLESS:   case OP_SET_ULESS:
1269         case OP_SET_SMORE:   case OP_SET_UMORE:
1270         case OP_SET_SLESSEQ: case OP_SET_ULESSEQ:
1271         case OP_SET_SMOREEQ: case OP_SET_UMOREEQ:
1272         case OP_INB:         case OP_INW:     case OP_INL:
1273         case OP_BSF:         case OP_BSR:
1274 #if 0
1275                 if (!triple->left) {
1276                         internal_error(state, triple, "left arg missing");
1277                 }
1278                 if (triple->right) {
1279                         internal_error(state, triple, "right arg present");
1280                 }
1281 #endif
1282                 if (!last) {
1283                         ret = &triple->left;
1284                 }
1285                 break;
1286                 /* Writes */
1287         case OP_WRITE:
1288         case OP_STORE:
1289                 if (!last) {
1290                         ret = &triple->right;
1291                 }
1292                 break;
1293                 /* Reads */
1294         case OP_READ:
1295                 if (!last) {
1296                         ret = &triple->left;
1297                 }
1298                 break;
1299                 /* Branches */
1300         case OP_BRANCH:
1301         case OP_JMP:
1302         case OP_JMP_EQ:      case OP_JMP_NOTEQ:
1303         case OP_JMP_SLESS:   case OP_JMP_ULESS:
1304         case OP_JMP_SMORE:   case OP_JMP_UMORE:
1305         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
1306         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
1307                 if (!last && triple->right) {
1308                         ret = &triple->right;
1309                 }
1310                 break;
1311                 /* Phi... */
1312         case OP_PHI:
1313         {
1314                 struct triple **slot;
1315                 struct block *block;
1316                 block = triple->u.block;
1317                 slot = (struct triple **)(triple->left);
1318                 if (!last) {
1319                         ret = slot;
1320                 }
1321                 else if ((last >= slot) && (last < (slot + block->users -1))) {
1322                         ret = last + 1;
1323                         
1324                 }
1325                 break;
1326         }
1327                 /* Loads */
1328         case OP_LOAD:
1329                 /* address constant.. */
1330         case OP_ADDRCONST:
1331                 if (!last) {
1332                         ret = &triple->left;
1333                 }
1334                 break;
1335                 /* Stores */
1336                 break;
1337                 /* Variables and labels */
1338         case OP_ADECL:    case OP_SDECL:  case OP_LABEL:
1339                 /* Constants */
1340         case OP_INTCONST:
1341         case OP_BLOBCONST:
1342         case OP_NOOP:
1343         case OP_HLT:
1344                 /* These operations that have no rhs expression */
1345                 break;
1346         default:
1347                 internal_error(state, 0, "unknown expression type: %d %s",
1348                         triple->op, tops(triple->op));
1349                 break;
1350
1351         }
1352         return ret;
1353 }
1354
1355 static struct triple **triple_lhs(struct compile_state *state,
1356         struct triple *triple, struct triple **last)
1357 {
1358         struct triple **ret;
1359         ret = 0;
1360         switch(triple->op) {
1361                 /* binary operations */
1362         case OP_SMUL:    case OP_UMUL:    case OP_SDIV:    case OP_UDIV:
1363         case OP_SMOD:    case OP_UMOD:    case OP_ADD:     case OP_SUB:
1364         case OP_SL:      case OP_USR:     case OP_SSR:     case OP_AND:  
1365         case OP_XOR:     case OP_OR:      case OP_EQ:      case OP_NOTEQ: 
1366         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
1367         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
1368         case OP_CMP:
1369         case OP_OUTB:    case OP_OUTW:    case OP_OUTL:
1370                 /* unary operations */
1371         case OP_POS:     case OP_NEG:
1372         case OP_INVERT:  case OP_LFALSE:  case OP_LTRUE:
1373         case OP_COPY:
1374         case OP_TEST:
1375         case OP_SET_EQ:      case OP_SET_NOTEQ:
1376         case OP_SET_SLESS:   case OP_SET_ULESS:
1377         case OP_SET_SMORE:   case OP_SET_UMORE:
1378         case OP_SET_SLESSEQ: case OP_SET_ULESSEQ:
1379         case OP_SET_SMOREEQ: case OP_SET_UMOREEQ:
1380         case OP_INB:     case OP_INW:     case OP_INL:
1381         case OP_BSF:     case OP_BSR:
1382                 /* Variable reads */
1383         case OP_READ:    case OP_PHI:
1384                 /* Branches */
1385         case OP_BRANCH:
1386         case OP_JMP:
1387         case OP_JMP_EQ:      case OP_JMP_NOTEQ:
1388         case OP_JMP_SLESS:   case OP_JMP_ULESS:
1389         case OP_JMP_SMORE:   case OP_JMP_UMORE:
1390         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
1391         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
1392                 /* Loads */
1393         case OP_LOAD:
1394                 /* Address constants */
1395         case OP_ADDRCONST:
1396                 /* Variables and labels */
1397         case OP_ADECL:   case OP_SDECL:   case OP_LABEL:
1398                 /* Constants */
1399         case OP_INTCONST:
1400         case OP_BLOBCONST:
1401         case OP_NOOP:
1402         case OP_HLT:
1403                 /* These expressions have no lhs expression */
1404                 break;
1405                 /* Writes */
1406         case OP_WRITE:
1407                 /* Stores */
1408         case OP_STORE:
1409                 if (!last) {
1410                         ret = &triple->left;
1411                 }
1412                 break;
1413         default:
1414                 internal_error(state, 0, "unknown expression type: %d %s",
1415                         triple->op, tops(triple->op));
1416                 break;
1417         }
1418         return ret;
1419 }
1420
1421 static void free_triple(struct compile_state *state, struct triple *ptr)
1422 {
1423         ptr->prev->next = ptr->next;
1424         ptr->next->prev = ptr->prev;
1425         if (ptr->use) {
1426                 internal_error(state, ptr, "ptr->use != 0");
1427         }
1428         if (ptr->op == OP_PHI) {
1429                 xfree(ptr->left);
1430         }
1431         memset(ptr, -1, sizeof(*ptr));
1432         xfree(ptr);
1433 }
1434
1435 static void release_triple(struct compile_state *state, struct triple *ptr)
1436 {
1437         struct triple_set *set, *next;
1438         struct triple **expr;
1439         /* Remove ptr from use chains where it is the user */
1440         expr = triple_rhs(state, ptr, 0);
1441         for(; expr; expr = triple_rhs(state, ptr, expr)) {
1442                 if (*expr) {
1443                         unuse_triple(*expr, ptr);
1444                 }
1445         }
1446         expr = triple_lhs(state, ptr, 0);
1447         for(; expr; expr = triple_lhs(state, ptr, expr)) {
1448                 if (*expr) {
1449                         unuse_triple(*expr, ptr);
1450                 }
1451         }
1452         expr = triple_targ(state, ptr, 0);
1453         for(; expr; expr = triple_targ(state, ptr, expr)) {
1454                 if (*expr) {
1455                         unuse_triple(*expr, ptr);
1456                 }
1457         }
1458         /* Reomve ptr from use chains where it is used */
1459         for(set = ptr->use; set; set = next) {
1460                 next = set->next;
1461                 expr = triple_rhs(state, set->member, 0);
1462                 for(; expr; expr = triple_rhs(state, set->member, expr)) {
1463                         if (*expr == ptr) {
1464                                 *expr = &zero_triple;
1465                         }
1466                 }
1467                 expr = triple_lhs(state, set->member, 0);
1468                 for(; expr; expr = triple_lhs(state, set->member, expr)) {
1469                         if (*expr == ptr) {
1470                                 *expr = &zero_triple;
1471                         }
1472                 }
1473                 expr = triple_targ(state, set->member, 0);
1474                 for(; expr; expr = triple_targ(state, set->member, expr)) {
1475                         if (*expr == ptr) {
1476                                 *expr = &zero_triple;
1477                         }
1478                 }
1479                 unuse_triple(ptr, set->member);
1480         }
1481         free_triple(state, ptr);
1482 }
1483
1484 static void print_triple(struct compile_state *state, struct triple *ptr);
1485
1486 #define TOK_UNKNOWN     0
1487 #define TOK_SPACE       1
1488 #define TOK_SEMI        2
1489 #define TOK_LBRACE      3
1490 #define TOK_RBRACE      4
1491 #define TOK_COMMA       5
1492 #define TOK_EQ          6
1493 #define TOK_COLON       7
1494 #define TOK_LBRACKET    8
1495 #define TOK_RBRACKET    9
1496 #define TOK_LPAREN      10
1497 #define TOK_RPAREN      11
1498 #define TOK_STAR        12
1499 #define TOK_DOTS        13
1500 #define TOK_MORE        14
1501 #define TOK_LESS        15
1502 #define TOK_TIMESEQ     16
1503 #define TOK_DIVEQ       17
1504 #define TOK_MODEQ       18
1505 #define TOK_PLUSEQ      19
1506 #define TOK_MINUSEQ     20
1507 #define TOK_SLEQ        21
1508 #define TOK_SREQ        22
1509 #define TOK_ANDEQ       23
1510 #define TOK_XOREQ       24
1511 #define TOK_OREQ        25
1512 #define TOK_EQEQ        26
1513 #define TOK_NOTEQ       27
1514 #define TOK_QUEST       28
1515 #define TOK_LOGOR       29
1516 #define TOK_LOGAND      30
1517 #define TOK_OR          31
1518 #define TOK_AND         32
1519 #define TOK_XOR         33
1520 #define TOK_LESSEQ      34
1521 #define TOK_MOREEQ      35
1522 #define TOK_SL          36
1523 #define TOK_SR          37
1524 #define TOK_PLUS        38
1525 #define TOK_MINUS       39
1526 #define TOK_DIV         40
1527 #define TOK_MOD         41
1528 #define TOK_PLUSPLUS    42
1529 #define TOK_MINUSMINUS  43
1530 #define TOK_BANG        44
1531 #define TOK_ARROW       45
1532 #define TOK_DOT         46
1533 #define TOK_TILDE       47
1534 #define TOK_LIT_STRING  48
1535 #define TOK_LIT_CHAR    49
1536 #define TOK_LIT_INT     50
1537 #define TOK_LIT_FLOAT   51
1538 #define TOK_MACRO       52
1539 #define TOK_CONCATENATE 53
1540
1541 #define TOK_IDENT       54
1542 #define TOK_STRUCT_NAME 55
1543 #define TOK_ENUM_CONST  56
1544 #define TOK_TYPE_NAME   57
1545
1546 #define TOK_AUTO        58
1547 #define TOK_BREAK       59
1548 #define TOK_CASE        60
1549 #define TOK_CHAR        61
1550 #define TOK_CONST       62
1551 #define TOK_CONTINUE    63
1552 #define TOK_DEFAULT     64
1553 #define TOK_DO          65
1554 #define TOK_DOUBLE      66
1555 #define TOK_ELSE        67
1556 #define TOK_ENUM        68
1557 #define TOK_EXTERN      69
1558 #define TOK_FLOAT       70
1559 #define TOK_FOR         71
1560 #define TOK_GOTO        72
1561 #define TOK_IF          73
1562 #define TOK_INLINE      74
1563 #define TOK_INT         75
1564 #define TOK_LONG        76
1565 #define TOK_REGISTER    77
1566 #define TOK_RESTRICT    78
1567 #define TOK_RETURN      79
1568 #define TOK_SHORT       80
1569 #define TOK_SIGNED      81
1570 #define TOK_SIZEOF      82
1571 #define TOK_STATIC      83
1572 #define TOK_STRUCT      84
1573 #define TOK_SWITCH      85
1574 #define TOK_TYPEDEF     86
1575 #define TOK_UNION       87
1576 #define TOK_UNSIGNED    88
1577 #define TOK_VOID        89
1578 #define TOK_VOLATILE    90
1579 #define TOK_WHILE       91
1580 #define TOK_ASM         92
1581 #define TOK_ATTRIBUTE   93
1582 #define TOK_ALIGNOF     94
1583 #define TOK_FIRST_KEYWORD TOK_AUTO
1584 #define TOK_LAST_KEYWORD  TOK_ALIGNOF
1585
1586 #define TOK_DEFINE      100
1587 #define TOK_UNDEF       101
1588 #define TOK_INCLUDE     102
1589 #define TOK_LINE        103
1590 #define TOK_ERROR       104
1591 #define TOK_WARNING     105
1592 #define TOK_PRAGMA      106
1593 #define TOK_IFDEF       107
1594 #define TOK_IFNDEF      108
1595 #define TOK_ELIF        109
1596 #define TOK_ENDIF       110
1597
1598 #define TOK_FIRST_MACRO TOK_DEFINE
1599 #define TOK_LAST_MACRO  TOK_ENDIF
1600          
1601 #define TOK_EOF         111
1602
1603 static const char *tokens[] = {
1604 [TOK_UNKNOWN     ] = "unknown",
1605 [TOK_SPACE       ] = ":space:",
1606 [TOK_SEMI        ] = ";",
1607 [TOK_LBRACE      ] = "{",
1608 [TOK_RBRACE      ] = "}",
1609 [TOK_COMMA       ] = ",",
1610 [TOK_EQ          ] = "=",
1611 [TOK_COLON       ] = ":",
1612 [TOK_LBRACKET    ] = "[",
1613 [TOK_RBRACKET    ] = "]",
1614 [TOK_LPAREN      ] = "(",
1615 [TOK_RPAREN      ] = ")",
1616 [TOK_STAR        ] = "*",
1617 [TOK_DOTS        ] = "...",
1618 [TOK_MORE        ] = ">",
1619 [TOK_LESS        ] = "<",
1620 [TOK_TIMESEQ     ] = "*=",
1621 [TOK_DIVEQ       ] = "/=",
1622 [TOK_MODEQ       ] = "%=",
1623 [TOK_PLUSEQ      ] = "+=",
1624 [TOK_MINUSEQ     ] = "-=",
1625 [TOK_SLEQ        ] = "<<=",
1626 [TOK_SREQ        ] = ">>=",
1627 [TOK_ANDEQ       ] = "&=",
1628 [TOK_XOREQ       ] = "^=",
1629 [TOK_OREQ        ] = "|=",
1630 [TOK_EQEQ        ] = "==",
1631 [TOK_NOTEQ       ] = "!=",
1632 [TOK_QUEST       ] = "?",
1633 [TOK_LOGOR       ] = "||",
1634 [TOK_LOGAND      ] = "&&",
1635 [TOK_OR          ] = "|",
1636 [TOK_AND         ] = "&",
1637 [TOK_XOR         ] = "^",
1638 [TOK_LESSEQ      ] = "<=",
1639 [TOK_MOREEQ      ] = ">=",
1640 [TOK_SL          ] = "<<",
1641 [TOK_SR          ] = ">>",
1642 [TOK_PLUS        ] = "+",
1643 [TOK_MINUS       ] = "-",
1644 [TOK_DIV         ] = "/",
1645 [TOK_MOD         ] = "%",
1646 [TOK_PLUSPLUS    ] = "++",
1647 [TOK_MINUSMINUS  ] = "--",
1648 [TOK_BANG        ] = "!",
1649 [TOK_ARROW       ] = "->",
1650 [TOK_DOT         ] = ".",
1651 [TOK_TILDE       ] = "~",
1652 [TOK_LIT_STRING  ] = ":string:",
1653 [TOK_IDENT       ] = ":ident:",
1654 [TOK_TYPE_NAME   ] = ":typename:",
1655 [TOK_LIT_CHAR    ] = ":char:",
1656 [TOK_LIT_INT     ] = ":integer:",
1657 [TOK_LIT_FLOAT   ] = ":float:",
1658 [TOK_MACRO       ] = "#",
1659 [TOK_CONCATENATE ] = "##",
1660
1661 [TOK_AUTO        ] = "auto",
1662 [TOK_BREAK       ] = "break",
1663 [TOK_CASE        ] = "case",
1664 [TOK_CHAR        ] = "char",
1665 [TOK_CONST       ] = "const",
1666 [TOK_CONTINUE    ] = "continue",
1667 [TOK_DEFAULT     ] = "default",
1668 [TOK_DO          ] = "do",
1669 [TOK_DOUBLE      ] = "double",
1670 [TOK_ELSE        ] = "else",
1671 [TOK_ENUM        ] = "enum",
1672 [TOK_EXTERN      ] = "extern",
1673 [TOK_FLOAT       ] = "float",
1674 [TOK_FOR         ] = "for",
1675 [TOK_GOTO        ] = "goto",
1676 [TOK_IF          ] = "if",
1677 [TOK_INLINE      ] = "inline",
1678 [TOK_INT         ] = "int",
1679 [TOK_LONG        ] = "long",
1680 [TOK_REGISTER    ] = "register",
1681 [TOK_RESTRICT    ] = "restrict",
1682 [TOK_RETURN      ] = "return",
1683 [TOK_SHORT       ] = "short",
1684 [TOK_SIGNED      ] = "signed",
1685 [TOK_SIZEOF      ] = "sizeof",
1686 [TOK_STATIC      ] = "static",
1687 [TOK_STRUCT      ] = "struct",
1688 [TOK_SWITCH      ] = "switch",
1689 [TOK_TYPEDEF     ] = "typedef",
1690 [TOK_UNION       ] = "union",
1691 [TOK_UNSIGNED    ] = "unsigned",
1692 [TOK_VOID        ] = "void",
1693 [TOK_VOLATILE    ] = "volatile",
1694 [TOK_WHILE       ] = "while",
1695 [TOK_ASM         ] = "asm",
1696 [TOK_ATTRIBUTE   ] = "__attribute__",
1697 [TOK_ALIGNOF     ] = "__alignof__",
1698
1699 [TOK_DEFINE      ] = "define",
1700 [TOK_UNDEF       ] = "undef",
1701 [TOK_INCLUDE     ] = "include",
1702 [TOK_LINE        ] = "line",
1703 [TOK_ERROR       ] = "error",
1704 [TOK_WARNING     ] = "warning",
1705 [TOK_PRAGMA      ] = "pragma",
1706 [TOK_IFDEF       ] = "ifdef",
1707 [TOK_IFNDEF      ] = "ifndef",
1708 [TOK_ELIF        ] = "elif",
1709 [TOK_ENDIF       ] = "endif",
1710
1711 [TOK_EOF         ] = "EOF",
1712 };
1713
1714 static unsigned int hash(const char *str, int str_len)
1715 {
1716         unsigned int hash;
1717         const char *end;
1718         end = str + str_len;
1719         hash = 0;
1720         for(; str < end; str++) {
1721                 hash = (hash *263) + *str;
1722         }
1723         hash = hash & (HASH_TABLE_SIZE -1);
1724         return hash;
1725 }
1726
1727 static struct hash_entry *lookup(
1728         struct compile_state *state, const char *name, int name_len)
1729 {
1730         struct hash_entry *entry;
1731         unsigned int index;
1732         index = hash(name, name_len);
1733         entry = state->hash_table[index];
1734         while(entry && 
1735                 ((entry->name_len != name_len) ||
1736                         (memcmp(entry->name, name, name_len) != 0))) {
1737                 entry = entry->next;
1738         }
1739         if (!entry) {
1740                 char *new_name;
1741                 /* Get a private copy of the name */
1742                 new_name = xmalloc(name_len + 1, "hash_name");
1743                 memcpy(new_name, name, name_len);
1744                 new_name[name_len] = '\0';
1745
1746                 /* Create a new hash entry */
1747                 entry = xcmalloc(sizeof(*entry), "hash_entry");
1748                 entry->next = state->hash_table[index];
1749                 entry->name = new_name;
1750                 entry->name_len = name_len;
1751
1752                 /* Place the new entry in the hash table */
1753                 state->hash_table[index] = entry;
1754         }
1755         return entry;
1756 }
1757
1758 static void ident_to_keyword(struct compile_state *state, struct token *tk)
1759 {
1760         struct hash_entry *entry;
1761         entry = tk->ident;
1762         if (entry && ((entry->tok == TOK_TYPE_NAME) ||
1763                 (entry->tok == TOK_ENUM_CONST) ||
1764                 ((entry->tok >= TOK_FIRST_KEYWORD) && 
1765                         (entry->tok <= TOK_LAST_KEYWORD)))) {
1766                 tk->tok = entry->tok;
1767         }
1768 }
1769
1770 static void ident_to_macro(struct compile_state *state, struct token *tk)
1771 {
1772         struct hash_entry *entry;
1773         entry = tk->ident;
1774         if (entry && 
1775                 (entry->tok >= TOK_FIRST_MACRO) &&
1776                 (entry->tok <= TOK_LAST_MACRO)) {
1777                 tk->tok = entry->tok;
1778         }
1779 }
1780
1781 static void hash_keyword(
1782         struct compile_state *state, const char *keyword, int tok)
1783 {
1784         struct hash_entry *entry;
1785         entry = lookup(state, keyword, strlen(keyword));
1786         if (entry && entry->tok != TOK_UNKNOWN) {
1787                 die("keyword %s already hashed", keyword);
1788         }
1789         entry->tok  = tok;
1790 }
1791
1792 static void symbol(
1793         struct compile_state *state, struct hash_entry *ident,
1794         struct symbol **chain, struct triple *def, struct type *type)
1795 {
1796         struct symbol *sym;
1797         if (*chain && ((*chain)->scope_depth == state->scope_depth)) {
1798                 error(state, 0, "%s already defined", ident->name);
1799         }
1800         sym = xcmalloc(sizeof(*sym), "symbol");
1801         sym->ident = ident;
1802         sym->def   = def;
1803         sym->type  = type;
1804         sym->scope_depth = state->scope_depth;
1805         sym->next = *chain;
1806         *chain    = sym;
1807 }
1808
1809 static void start_scope(struct compile_state *state)
1810 {
1811         state->scope_depth++;
1812 }
1813
1814 static void end_scope_syms(struct symbol **chain, int depth)
1815 {
1816         struct symbol *sym, *next;
1817         sym = *chain;
1818         while(sym && (sym->scope_depth == depth)) {
1819                 next = sym->next;
1820                 xfree(sym);
1821                 sym = next;
1822         }
1823         *chain = sym;
1824 }
1825
1826 static void end_scope(struct compile_state *state)
1827 {
1828         int i;
1829         int depth;
1830         /* Walk through the hash table and remove all symbols
1831          * in the current scope. 
1832          */
1833         depth = state->scope_depth;
1834         for(i = 0; i < HASH_TABLE_SIZE; i++) {
1835                 struct hash_entry *entry;
1836                 entry = state->hash_table[i];
1837                 while(entry) {
1838                         end_scope_syms(&entry->sym_label,  depth);
1839                         end_scope_syms(&entry->sym_struct, depth);
1840                         end_scope_syms(&entry->sym_ident,  depth);
1841                         entry = entry->next;
1842                 }
1843         }
1844         state->scope_depth = depth - 1;
1845 }
1846
1847 static void register_keywords(struct compile_state *state)
1848 {
1849         hash_keyword(state, "auto",          TOK_AUTO);
1850         hash_keyword(state, "break",         TOK_BREAK);
1851         hash_keyword(state, "case",          TOK_CASE);
1852         hash_keyword(state, "char",          TOK_CHAR);
1853         hash_keyword(state, "const",         TOK_CONST);
1854         hash_keyword(state, "continue",      TOK_CONTINUE);
1855         hash_keyword(state, "default",       TOK_DEFAULT);
1856         hash_keyword(state, "do",            TOK_DO);
1857         hash_keyword(state, "double",        TOK_DOUBLE);
1858         hash_keyword(state, "else",          TOK_ELSE);
1859         hash_keyword(state, "enum",          TOK_ENUM);
1860         hash_keyword(state, "extern",        TOK_EXTERN);
1861         hash_keyword(state, "float",         TOK_FLOAT);
1862         hash_keyword(state, "for",           TOK_FOR);
1863         hash_keyword(state, "goto",          TOK_GOTO);
1864         hash_keyword(state, "if",            TOK_IF);
1865         hash_keyword(state, "inline",        TOK_INLINE);
1866         hash_keyword(state, "int",           TOK_INT);
1867         hash_keyword(state, "long",          TOK_LONG);
1868         hash_keyword(state, "register",      TOK_REGISTER);
1869         hash_keyword(state, "restrict",      TOK_RESTRICT);
1870         hash_keyword(state, "return",        TOK_RETURN);
1871         hash_keyword(state, "short",         TOK_SHORT);
1872         hash_keyword(state, "signed",        TOK_SIGNED);
1873         hash_keyword(state, "sizeof",        TOK_SIZEOF);
1874         hash_keyword(state, "static",        TOK_STATIC);
1875         hash_keyword(state, "struct",        TOK_STRUCT);
1876         hash_keyword(state, "switch",        TOK_SWITCH);
1877         hash_keyword(state, "typedef",       TOK_TYPEDEF);
1878         hash_keyword(state, "union",         TOK_UNION);
1879         hash_keyword(state, "unsigned",      TOK_UNSIGNED);
1880         hash_keyword(state, "void",          TOK_VOID);
1881         hash_keyword(state, "volatile",      TOK_VOLATILE);
1882         hash_keyword(state, "while",         TOK_WHILE);
1883         hash_keyword(state, "asm",           TOK_ASM);
1884         hash_keyword(state, "__attribute__", TOK_ATTRIBUTE);
1885         hash_keyword(state, "__alignof__",   TOK_ALIGNOF);
1886 }
1887
1888 static void register_macro_keywords(struct compile_state *state)
1889 {
1890         hash_keyword(state, "define",        TOK_DEFINE);
1891         hash_keyword(state, "undef",         TOK_UNDEF);
1892         hash_keyword(state, "include",       TOK_INCLUDE);
1893         hash_keyword(state, "line",          TOK_LINE);
1894         hash_keyword(state, "error",         TOK_ERROR);
1895         hash_keyword(state, "warning",       TOK_WARNING);
1896         hash_keyword(state, "pragma",        TOK_PRAGMA);
1897         hash_keyword(state, "ifdef",         TOK_IFDEF);
1898         hash_keyword(state, "ifndef",        TOK_IFNDEF);
1899         hash_keyword(state, "elif",          TOK_ELIF);
1900         hash_keyword(state, "endif",         TOK_ENDIF);
1901 }
1902
1903 static int spacep(int c)
1904 {
1905         int ret = 0;
1906         switch(c) {
1907         case ' ':
1908         case '\t':
1909         case '\f':
1910         case '\v':
1911         case '\r':
1912         case '\n':
1913                 ret = 1;
1914                 break;
1915         }
1916         return ret;
1917 }
1918
1919 static int digitp(int c)
1920 {
1921         int ret = 0;
1922         switch(c) {
1923         case '0': case '1': case '2': case '3': case '4': 
1924         case '5': case '6': case '7': case '8': case '9':
1925                 ret = 1;
1926                 break;
1927         }
1928         return ret;
1929 }
1930
1931 static int hexdigitp(int c)
1932 {
1933         int ret = 0;
1934         switch(c) {
1935         case '0': case '1': case '2': case '3': case '4': 
1936         case '5': case '6': case '7': case '8': case '9':
1937         case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
1938         case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
1939                 ret = 1;
1940                 break;
1941         }
1942         return ret;
1943 }
1944 static int hexdigval(int c) 
1945 {
1946         int val = -1;
1947         if ((c >= '0') && (c <= '9')) {
1948                 val = c - '0';
1949         }
1950         else if ((c >= 'A') && (c <= 'F')) {
1951                 val = 10 + (c - 'A');
1952         }
1953         else if ((c >= 'a') && (c <= 'f')) {
1954                 val = 10 + (c - 'a');
1955         }
1956         return val;
1957 }
1958
1959 static int octdigitp(int c)
1960 {
1961         int ret = 0;
1962         switch(c) {
1963         case '0': case '1': case '2': case '3': 
1964         case '4': case '5': case '6': case '7':
1965                 ret = 1;
1966                 break;
1967         }
1968         return ret;
1969 }
1970 static int octdigval(int c)
1971 {
1972         int val = -1;
1973         if ((c >= '0') && (c <= '7')) {
1974                 val = c - '0';
1975         }
1976         return val;
1977 }
1978
1979 static int letterp(int c)
1980 {
1981         int ret = 0;
1982         switch(c) {
1983         case 'a': case 'b': case 'c': case 'd': case 'e':
1984         case 'f': case 'g': case 'h': case 'i': case 'j':
1985         case 'k': case 'l': case 'm': case 'n': case 'o':
1986         case 'p': case 'q': case 'r': case 's': case 't':
1987         case 'u': case 'v': case 'w': case 'x': case 'y':
1988         case 'z':
1989         case 'A': case 'B': case 'C': case 'D': case 'E':
1990         case 'F': case 'G': case 'H': case 'I': case 'J':
1991         case 'K': case 'L': case 'M': case 'N': case 'O':
1992         case 'P': case 'Q': case 'R': case 'S': case 'T':
1993         case 'U': case 'V': case 'W': case 'X': case 'Y':
1994         case 'Z':
1995         case '_':
1996                 ret = 1;
1997                 break;
1998         }
1999         return ret;
2000 }
2001
2002 static int char_value(struct compile_state *state,
2003         const signed char **strp, const signed char *end)
2004 {
2005         const signed char *str;
2006         int c;
2007         str = *strp;
2008         c = *str++;
2009         if ((c == '\\') && (str < end)) {
2010                 switch(*str) {
2011                 case 'n':  c = '\n'; str++; break;
2012                 case 't':  c = '\t'; str++; break;
2013                 case 'v':  c = '\v'; str++; break;
2014                 case 'b':  c = '\b'; str++; break;
2015                 case 'r':  c = '\r'; str++; break;
2016                 case 'f':  c = '\f'; str++; break;
2017                 case 'a':  c = '\a'; str++; break;
2018                 case '\\': c = '\\'; str++; break;
2019                 case '?':  c = '?';  str++; break;
2020                 case '\'': c = '\''; str++; break;
2021                 case '"':  c = '"';  break;
2022                 case 'x': 
2023                         c = 0;
2024                         str++;
2025                         while((str < end) && hexdigitp(*str)) {
2026                                 c <<= 4;
2027                                 c += hexdigval(*str);
2028                                 str++;
2029                         }
2030                         break;
2031                 case '0': case '1': case '2': case '3': 
2032                 case '4': case '5': case '6': case '7':
2033                         c = 0;
2034                         while((str < end) && octdigitp(*str)) {
2035                                 c <<= 3;
2036                                 c += octdigval(*str);
2037                                 str++;
2038                         }
2039                         break;
2040                 default:
2041                         error(state, 0, "Invalid character constant");
2042                         break;
2043                 }
2044         }
2045         *strp = str;
2046         return c;
2047 }
2048
2049 static char *after_digits(char *ptr, char *end)
2050 {
2051         while((ptr < end) && digitp(*ptr)) {
2052                 ptr++;
2053         }
2054         return ptr;
2055 }
2056
2057 static char *after_octdigits(char *ptr, char *end)
2058 {
2059         while((ptr < end) && octdigitp(*ptr)) {
2060                 ptr++;
2061         }
2062         return ptr;
2063 }
2064
2065 static char *after_hexdigits(char *ptr, char *end)
2066 {
2067         while((ptr < end) && hexdigitp(*ptr)) {
2068                 ptr++;
2069         }
2070         return ptr;
2071 }
2072
2073 static void save_string(struct compile_state *state, 
2074         struct token *tk, char *start, char *end, const char *id)
2075 {
2076         char *str;
2077         int str_len;
2078         /* Create a private copy of the string */
2079         str_len = end - start + 1;
2080         str = xmalloc(str_len + 1, id);
2081         memcpy(str, start, str_len);
2082         str[str_len] = '\0';
2083
2084         /* Store the copy in the token */
2085         tk->val.str = str;
2086         tk->str_len = str_len;
2087 }
2088 static void next_token(struct compile_state *state, int index)
2089 {
2090         struct file_state *file;
2091         struct token *tk;
2092         char *token;
2093         int c, c1, c2, c3;
2094         char *tokp, *end;
2095         int tok;
2096 next_token:
2097         file = state->file;
2098         tk = &state->token[index];
2099         tk->str_len = 0;
2100         tk->ident = 0;
2101         token = tokp = file->pos;
2102         end = file->buf + file->size;
2103         tok = TOK_UNKNOWN;
2104         c = -1;
2105         if (tokp < end) {
2106                 c = *tokp;
2107         }
2108         c1 = -1;
2109         if ((tokp + 1) < end) {
2110                 c1 = tokp[1];
2111         }
2112         c2 = -1;
2113         if ((tokp + 2) < end) {
2114                 c2 = tokp[2];
2115         }
2116         c3 = -1;
2117         if ((tokp + 3) < end) {
2118                 c3 = tokp[3];
2119         }
2120         if (tokp >= end) {
2121                 tok = TOK_EOF;
2122                 tokp = end;
2123         }
2124         /* Whitespace */
2125         else if (spacep(c)) {
2126                 tok = TOK_SPACE;
2127                 while ((tokp < end) && spacep(c)) {
2128                         if (c == '\n') {
2129                                 file->line++;
2130                                 file->line_start = tokp + 1;
2131                         }
2132                         c = *(++tokp);
2133                 }
2134                 if (!spacep(c)) {
2135                         tokp--;
2136                 }
2137         }
2138         /* EOL Comments */
2139         else if ((c == '/') && (c1 == '/')) {
2140                 tok = TOK_SPACE;
2141                 for(tokp += 2; tokp < end; tokp++) {
2142                         c = *tokp;
2143                         if (c == '\n') {
2144                                 file->line++;
2145                                 file->line_start = tokp +1;
2146                                 break;
2147                         }
2148                 }
2149         }
2150         /* Comments */
2151         else if ((c == '/') && (c1 == '*')) {
2152                 int line;
2153                 char *line_start;
2154                 line = file->line;
2155                 line_start = file->line_start;
2156                 for(tokp += 2; (end - tokp) >= 2; tokp++) {
2157                         c = *tokp;
2158                         if (c == '\n') {
2159                                 line++;
2160                                 line_start = tokp +1;
2161                         }
2162                         else if ((c == '*') && (tokp[1] == '/')) {
2163                                 tok = TOK_SPACE;
2164                                 tokp += 1;
2165                                 break;
2166                         }
2167                 }
2168                 if (tok == TOK_UNKNOWN) {
2169                         error(state, 0, "unterminated comment");
2170                 }
2171                 file->line = line;
2172                 file->line_start = line_start;
2173         }
2174         /* string constants */
2175         else if ((c == '"') ||
2176                 ((c == 'L') && (c1 == '"'))) {
2177                 int line;
2178                 char *line_start;
2179                 int wchar;
2180                 line = file->line;
2181                 line_start = file->line_start;
2182                 wchar = 0;
2183                 if (c == 'L') {
2184                         wchar = 1;
2185                         tokp++;
2186                 }
2187                 for(tokp += 1; tokp < end; tokp++) {
2188                         c = *tokp;
2189                         if (c == '\n') {
2190                                 line++;
2191                                 line_start = tokp + 1;
2192                         }
2193                         else if ((c == '\\') && (tokp +1 < end)) {
2194                                 tokp++;
2195                         }
2196                         else if (c == '"') {
2197                                 tok = TOK_LIT_STRING;
2198                                 break;
2199                         }
2200                 }
2201                 if (tok == TOK_UNKNOWN) {
2202                         error(state, 0, "unterminated string constant");
2203                 }
2204                 if (line != file->line) {
2205                         warning(state, 0, "multiline string constant");
2206                 }
2207                 file->line = line;
2208                 file->line_start = line_start;
2209
2210                 /* Save the string value */
2211                 save_string(state, tk, token, tokp, "literal string");
2212         }
2213         /* character constants */
2214         else if ((c == '\'') ||
2215                 ((c == 'L') && (c1 == '\''))) {
2216                 int line;
2217                 char *line_start;
2218                 int wchar;
2219                 line = file->line;
2220                 line_start = file->line_start;
2221                 wchar = 0;
2222                 if (c == 'L') {
2223                         wchar = 1;
2224                         tokp++;
2225                 }
2226                 for(tokp += 1; tokp < end; tokp++) {
2227                         c = *tokp;
2228                         if (c == '\n') {
2229                                 line++;
2230                                 line_start = tokp + 1;
2231                         }
2232                         else if ((c == '\\') && (tokp +1 < end)) {
2233                                 tokp++;
2234                         }
2235                         else if (c == '\'') {
2236                                 tok = TOK_LIT_CHAR;
2237                                 break;
2238                         }
2239                 }
2240                 if (tok == TOK_UNKNOWN) {
2241                         error(state, 0, "unterminated character constant");
2242                 }
2243                 if (line != file->line) {
2244                         warning(state, 0, "multiline character constant");
2245                 }
2246                 file->line = line;
2247                 file->line_start = line_start;
2248
2249                 /* Save the character value */
2250                 save_string(state, tk, token, tokp, "literal character");
2251         }
2252         /* integer and floating constants 
2253          * Integer Constants
2254          * {digits}
2255          * 0[Xx]{hexdigits}
2256          * 0{octdigit}+
2257          * 
2258          * Floating constants
2259          * {digits}.{digits}[Ee][+-]?{digits}
2260          * {digits}.{digits}
2261          * {digits}[Ee][+-]?{digits}
2262          * .{digits}[Ee][+-]?{digits}
2263          * .{digits}
2264          */
2265         
2266         else if (digitp(c) || ((c == '.') && (digitp(c1)))) {
2267                 char *next, *new;
2268                 int is_float;
2269                 is_float = 0;
2270                 if (c != '.') {
2271                         next = after_digits(tokp, end);
2272                 }
2273                 else {
2274                         next = tokp;
2275                 }
2276                 if (next[0] == '.') {
2277                         new = after_digits(next, end);
2278                         is_float = (new != next);
2279                         next = new;
2280                 }
2281                 if ((next[0] == 'e') || (next[0] == 'E')) {
2282                         if (((next + 1) < end) && 
2283                                 ((next[1] == '+') || (next[1] == '-'))) {
2284                                 next++;
2285                         }
2286                         new = after_digits(next, end);
2287                         is_float = (new != next);
2288                         next = new;
2289                 }
2290                 if (is_float) {
2291                         tok = TOK_LIT_FLOAT;
2292                         if ((next < end) && (
2293                                 (next[0] == 'f') ||
2294                                 (next[0] == 'F') ||
2295                                 (next[0] == 'l') ||
2296                                 (next[0] == 'L'))
2297                                 ) {
2298                                 next++;
2299                         }
2300                 }
2301                 if (!is_float && digitp(c)) {
2302                         tok = TOK_LIT_INT;
2303                         if ((c == '0') && ((c1 == 'x') || (c1 == 'X'))) {
2304                                 next = after_hexdigits(tokp + 2, end);
2305                         }
2306                         else if (c == '0') {
2307                                 next = after_octdigits(tokp, end);
2308                         }
2309                         else {
2310                                 next = after_digits(tokp, end);
2311                         }
2312                         /* crazy integer suffixes */
2313                         if ((next < end) && 
2314                                 ((next[0] == 'u') || (next[0] == 'U'))) { 
2315                                 next++;
2316                                 if ((next < end) &&
2317                                         ((next[0] == 'l') || (next[0] == 'L'))) {
2318                                         next++;
2319                                 }
2320                         }
2321                         else if ((next < end) &&
2322                                 ((next[0] == 'l') || (next[0] == 'L'))) {
2323                                 next++;
2324                                 if ((next < end) && 
2325                                         ((next[0] == 'u') || (next[0] == 'U'))) { 
2326                                         next++;
2327                                 }
2328                         }
2329                 }
2330                 tokp = next - 1;
2331
2332                 /* Save the integer/floating point value */
2333                 save_string(state, tk, token, tokp, "literal number");
2334         }
2335         /* identifiers */
2336         else if (letterp(c)) {
2337                 tok = TOK_IDENT;
2338                 for(tokp += 1; tokp < end; tokp++) {
2339                         c = *tokp;
2340                         if (!letterp(c) && !digitp(c)) {
2341                                 break;
2342                         }
2343                 }
2344                 tokp -= 1;
2345                 tk->ident = lookup(state, token, tokp +1 - token);
2346         }
2347         /* C99 alternate macro characters */
2348         else if ((c == '%') && (c1 == ':') && (c2 == '%') && (c3 == ':')) { 
2349                 tokp += 3; 
2350                 tok = TOK_CONCATENATE; 
2351         }
2352         else if ((c == '.') && (c1 == '.') && (c2 == '.')) { tokp += 2; tok = TOK_DOTS; }
2353         else if ((c == '<') && (c1 == '<') && (c2 == '=')) { tokp += 2; tok = TOK_SLEQ; }
2354         else if ((c == '>') && (c1 == '>') && (c2 == '=')) { tokp += 2; tok = TOK_SREQ; }
2355         else if ((c == '*') && (c1 == '=')) { tokp += 1; tok = TOK_TIMESEQ; }
2356         else if ((c == '/') && (c1 == '=')) { tokp += 1; tok = TOK_DIVEQ; }
2357         else if ((c == '%') && (c1 == '=')) { tokp += 1; tok = TOK_MODEQ; }
2358         else if ((c == '+') && (c1 == '=')) { tokp += 1; tok = TOK_PLUSEQ; }
2359         else if ((c == '-') && (c1 == '=')) { tokp += 1; tok = TOK_MINUSEQ; }
2360         else if ((c == '&') && (c1 == '=')) { tokp += 1; tok = TOK_ANDEQ; }
2361         else if ((c == '^') && (c1 == '=')) { tokp += 1; tok = TOK_XOREQ; }
2362         else if ((c == '|') && (c1 == '=')) { tokp += 1; tok = TOK_OREQ; }
2363         else if ((c == '=') && (c1 == '=')) { tokp += 1; tok = TOK_EQEQ; }
2364         else if ((c == '!') && (c1 == '=')) { tokp += 1; tok = TOK_NOTEQ; }
2365         else if ((c == '|') && (c1 == '|')) { tokp += 1; tok = TOK_LOGOR; }
2366         else if ((c == '&') && (c1 == '&')) { tokp += 1; tok = TOK_LOGAND; }
2367         else if ((c == '<') && (c1 == '=')) { tokp += 1; tok = TOK_LESSEQ; }
2368         else if ((c == '>') && (c1 == '=')) { tokp += 1; tok = TOK_MOREEQ; }
2369         else if ((c == '<') && (c1 == '<')) { tokp += 1; tok = TOK_SL; }
2370         else if ((c == '>') && (c1 == '>')) { tokp += 1; tok = TOK_SR; }
2371         else if ((c == '+') && (c1 == '+')) { tokp += 1; tok = TOK_PLUSPLUS; }
2372         else if ((c == '-') && (c1 == '-')) { tokp += 1; tok = TOK_MINUSMINUS; }
2373         else if ((c == '-') && (c1 == '>')) { tokp += 1; tok = TOK_ARROW; }
2374         else if ((c == '<') && (c1 == ':')) { tokp += 1; tok = TOK_LBRACKET; }
2375         else if ((c == ':') && (c1 == '>')) { tokp += 1; tok = TOK_RBRACKET; }
2376         else if ((c == '<') && (c1 == '%')) { tokp += 1; tok = TOK_LBRACE; }
2377         else if ((c == '%') && (c1 == '>')) { tokp += 1; tok = TOK_RBRACE; }
2378         else if ((c == '%') && (c1 == ':')) { tokp += 1; tok = TOK_MACRO; }
2379         else if ((c == '#') && (c1 == '#')) { tokp += 1; tok = TOK_CONCATENATE; }
2380         else if (c == ';') { tok = TOK_SEMI; }
2381         else if (c == '{') { tok = TOK_LBRACE; }
2382         else if (c == '}') { tok = TOK_RBRACE; }
2383         else if (c == ',') { tok = TOK_COMMA; }
2384         else if (c == '=') { tok = TOK_EQ; }
2385         else if (c == ':') { tok = TOK_COLON; }
2386         else if (c == '[') { tok = TOK_LBRACKET; }
2387         else if (c == ']') { tok = TOK_RBRACKET; }
2388         else if (c == '(') { tok = TOK_LPAREN; }
2389         else if (c == ')') { tok = TOK_RPAREN; }
2390         else if (c == '*') { tok = TOK_STAR; }
2391         else if (c == '>') { tok = TOK_MORE; }
2392         else if (c == '<') { tok = TOK_LESS; }
2393         else if (c == '?') { tok = TOK_QUEST; }
2394         else if (c == '|') { tok = TOK_OR; }
2395         else if (c == '&') { tok = TOK_AND; }
2396         else if (c == '^') { tok = TOK_XOR; }
2397         else if (c == '+') { tok = TOK_PLUS; }
2398         else if (c == '-') { tok = TOK_MINUS; }
2399         else if (c == '/') { tok = TOK_DIV; }
2400         else if (c == '%') { tok = TOK_MOD; }
2401         else if (c == '!') { tok = TOK_BANG; }
2402         else if (c == '.') { tok = TOK_DOT; }
2403         else if (c == '~') { tok = TOK_TILDE; }
2404         else if (c == '#') { tok = TOK_MACRO; }
2405         if (tok == TOK_MACRO) {
2406                 /* Only match preprocessor directives at the start of a line */
2407                 char *ptr;
2408                 for(ptr = file->line_start; spacep(*ptr); ptr++)
2409                         ;
2410                 if (ptr != tokp) {
2411                         tok = TOK_UNKNOWN;
2412                 }
2413         }
2414         if (tok == TOK_UNKNOWN) {
2415                 error(state, 0, "unknown token");
2416         }
2417
2418         file->pos = tokp + 1;
2419         tk->tok = tok;
2420         if (tok == TOK_IDENT) {
2421                 ident_to_keyword(state, tk);
2422         }
2423         /* Don't return space tokens. */
2424         if (tok == TOK_SPACE) {
2425                 goto next_token;
2426         }
2427 }
2428
2429 static void compile_macro(struct compile_state *state, struct token *tk)
2430 {
2431         struct file_state *file;
2432         struct hash_entry *ident;
2433         ident = tk->ident;
2434         file = xmalloc(sizeof(*file), "file_state");
2435         file->basename = xstrdup(tk->ident->name);
2436         file->dirname = xstrdup("");
2437         file->size = ident->sym_define->buf_len;
2438         file->buf = xmalloc(file->size +2,  file->basename);
2439         memcpy(file->buf, ident->sym_define->buf, file->size);
2440         file->buf[file->size] = '\n';
2441         file->buf[file->size + 1] = '\0';
2442         file->pos = file->buf;
2443         file->line_start = file->pos;
2444         file->line = 1;
2445         file->prev = state->file;
2446         state->file = file;
2447 }
2448
2449
2450 static int mpeek(struct compile_state *state, int index)
2451 {
2452         struct token *tk;
2453         int rescan;
2454         tk = &state->token[index + 1];
2455         if (tk->tok == -1) {
2456                 next_token(state, index + 1);
2457         }
2458         do {
2459                 rescan = 0;
2460                 if ((tk->tok == TOK_EOF) && 
2461                         (state->file != state->macro_file) &&
2462                         (state->file->prev)) {
2463                         struct file_state *file = state->file;
2464                         state->file = file->prev;
2465                         /* file->basename is used keep it */
2466                         xfree(file->dirname);
2467                         xfree(file->buf);
2468                         xfree(file);
2469                         next_token(state, index + 1);
2470                         rescan = 1;
2471                 }
2472                 else if (tk->ident && tk->ident->sym_define) {
2473                         compile_macro(state, tk);
2474                         next_token(state, index + 1);
2475                         rescan = 1;
2476                 }
2477         } while(rescan);
2478         /* Don't show the token on the next line */
2479         if (state->macro_line < state->macro_file->line) {
2480                 return TOK_EOF;
2481         }
2482         return state->token[index +1].tok;
2483 }
2484
2485 static void meat(struct compile_state *state, int index, int tok)
2486 {
2487         int next_tok;
2488         int i;
2489         next_tok = mpeek(state, index);
2490         if (next_tok != tok) {
2491                 const char *name1, *name2;
2492                 name1 = tokens[next_tok];
2493                 name2 = "";
2494                 if (next_tok == TOK_IDENT) {
2495                         name2 = state->token[index + 1].ident->name;
2496                 }
2497                 error(state, 0, "found %s %s expected %s", 
2498                         name1, name2, tokens[tok]);
2499         }
2500         /* Free the old token value */
2501         if (state->token[index].str_len) {
2502                 memset((void *)(state->token[index].val.str), -1, 
2503                         state->token[index].str_len);
2504                 xfree(state->token[index].val.str);
2505         }
2506         for(i = index; i < sizeof(state->token)/sizeof(state->token[0]) - 1; i++) {
2507                 state->token[i] = state->token[i + 1];
2508         }
2509         memset(&state->token[i], 0, sizeof(state->token[i]));
2510         state->token[i].tok = -1;
2511 }
2512
2513 static long_t mcexpr(struct compile_state *state, int index);
2514
2515 static long_t mprimary_expr(struct compile_state *state, int index)
2516 {
2517         long_t val;
2518         int tok;
2519         tok = mpeek(state, index);
2520         while(state->token[index + 1].ident && 
2521                 state->token[index + 1].ident->sym_define) {
2522                 meat(state, index, tok);
2523                 compile_macro(state, &state->token[index]);
2524                 tok = mpeek(state, index);
2525         }
2526         switch(tok) {
2527         case TOK_LPAREN:
2528                 meat(state, index, TOK_LPAREN);
2529                 val = mcexpr(state, index);
2530                 meat(state, index, TOK_RPAREN);
2531                 break;
2532         case TOK_LIT_INT:
2533         {
2534                 char *end;
2535                 meat(state, index, TOK_LIT_INT);
2536                 errno = 0;
2537                 val = strtol(state->token[index].val.str, &end, 0);
2538                 if (((val == LONG_MIN) || (val == LONG_MAX)) &&
2539                         (errno == ERANGE)) {
2540                         error(state, 0, "Integer constant to large");
2541                 }
2542                 break;
2543         }
2544         default:
2545                 meat(state, index, TOK_LIT_INT);
2546                 val = 0;
2547         }
2548         return val;
2549 }
2550 static long_t munary_expr(struct compile_state *state, int index)
2551 {
2552         long_t val;
2553         switch(mpeek(state, index)) {
2554         case TOK_PLUS:
2555                 meat(state, index, TOK_PLUS);
2556                 val = munary_expr(state, index);
2557                 val = + val;
2558                 break;
2559         case TOK_MINUS:
2560                 meat(state, index, TOK_MINUS);
2561                 val = munary_expr(state, index);
2562                 val = - val;
2563                 break;
2564         case TOK_TILDE:
2565                 meat(state, index, TOK_BANG);
2566                 val = munary_expr(state, index);
2567                 val = ~ val;
2568                 break;
2569         case TOK_BANG:
2570                 meat(state, index, TOK_BANG);
2571                 val = munary_expr(state, index);
2572                 val = ! val;
2573                 break;
2574         default:
2575                 val = mprimary_expr(state, index);
2576                 break;
2577         }
2578         return val;
2579         
2580 }
2581 static long_t mmul_expr(struct compile_state *state, int index)
2582 {
2583         long_t val;
2584         int done;
2585         val = munary_expr(state, index);
2586         do {
2587                 long_t right;
2588                 done = 0;
2589                 switch(mpeek(state, index)) {
2590                 case TOK_STAR:
2591                         meat(state, index, TOK_STAR);
2592                         right = munary_expr(state, index);
2593                         val = val * right;
2594                         break;
2595                 case TOK_DIV:
2596                         meat(state, index, TOK_DIV);
2597                         right = munary_expr(state, index);
2598                         val = val / right;
2599                         break;
2600                 case TOK_MOD:
2601                         meat(state, index, TOK_MOD);
2602                         right = munary_expr(state, index);
2603                         val = val % right;
2604                         break;
2605                 default:
2606                         done = 1;
2607                         break;
2608                 }
2609         } while(!done);
2610
2611         return val;
2612 }
2613
2614 static long_t madd_expr(struct compile_state *state, int index)
2615 {
2616         long_t val;
2617         int done;
2618         val = mmul_expr(state, index);
2619         do {
2620                 long_t right;
2621                 done = 0;
2622                 switch(mpeek(state, index)) {
2623                 case TOK_PLUS:
2624                         meat(state, index, TOK_PLUS);
2625                         right = mmul_expr(state, index);
2626                         val = val + right;
2627                         break;
2628                 case TOK_MINUS:
2629                         meat(state, index, TOK_MINUS);
2630                         right = mmul_expr(state, index);
2631                         val = val - right;
2632                         break;
2633                 default:
2634                         done = 1;
2635                         break;
2636                 }
2637         } while(!done);
2638
2639         return val;
2640 }
2641
2642 static long_t mshift_expr(struct compile_state *state, int index)
2643 {
2644         long_t val;
2645         int done;
2646         val = madd_expr(state, index);
2647         do {
2648                 long_t right;
2649                 done = 0;
2650                 switch(mpeek(state, index)) {
2651                 case TOK_SL:
2652                         meat(state, index, TOK_SL);
2653                         right = madd_expr(state, index);
2654                         val = val << right;
2655                         break;
2656                 case TOK_SR:
2657                         meat(state, index, TOK_SR);
2658                         right = madd_expr(state, index);
2659                         val = val >> right;
2660                         break;
2661                 default:
2662                         done = 1;
2663                         break;
2664                 }
2665         } while(!done);
2666
2667         return val;
2668 }
2669
2670 static long_t mrel_expr(struct compile_state *state, int index)
2671 {
2672         long_t val;
2673         int done;
2674         val = mshift_expr(state, index);
2675         do {
2676                 long_t right;
2677                 done = 0;
2678                 switch(mpeek(state, index)) {
2679                 case TOK_LESS:
2680                         meat(state, index, TOK_LESS);
2681                         right = mshift_expr(state, index);
2682                         val = val < right;
2683                         break;
2684                 case TOK_MORE:
2685                         meat(state, index, TOK_MORE);
2686                         right = mshift_expr(state, index);
2687                         val = val > right;
2688                         break;
2689                 case TOK_LESSEQ:
2690                         meat(state, index, TOK_LESSEQ);
2691                         right = mshift_expr(state, index);
2692                         val = val <= right;
2693                         break;
2694                 case TOK_MOREEQ:
2695                         meat(state, index, TOK_MOREEQ);
2696                         right = mshift_expr(state, index);
2697                         val = val >= right;
2698                         break;
2699                 default:
2700                         done = 1;
2701                         break;
2702                 }
2703         } while(!done);
2704         return val;
2705 }
2706
2707 static long_t meq_expr(struct compile_state *state, int index)
2708 {
2709         long_t val;
2710         int done;
2711         val = mrel_expr(state, index);
2712         do {
2713                 long_t right;
2714                 done = 0;
2715                 switch(mpeek(state, index)) {
2716                 case TOK_EQEQ:
2717                         meat(state, index, TOK_EQEQ);
2718                         right = mrel_expr(state, index);
2719                         val = val == right;
2720                         break;
2721                 case TOK_NOTEQ:
2722                         meat(state, index, TOK_NOTEQ);
2723                         right = mrel_expr(state, index);
2724                         val = val != right;
2725                         break;
2726                 default:
2727                         done = 1;
2728                         break;
2729                 }
2730         } while(!done);
2731         return val;
2732 }
2733
2734 static long_t mand_expr(struct compile_state *state, int index)
2735 {
2736         long_t val;
2737         val = meq_expr(state, index);
2738         if (mpeek(state, index) == TOK_AND) {
2739                 long_t right;
2740                 meat(state, index, TOK_AND);
2741                 right = meq_expr(state, index);
2742                 val = val & right;
2743         }
2744         return val;
2745 }
2746
2747 static long_t mxor_expr(struct compile_state *state, int index)
2748 {
2749         long_t val;
2750         val = mand_expr(state, index);
2751         if (mpeek(state, index) == TOK_XOR) {
2752                 long_t right;
2753                 meat(state, index, TOK_XOR);
2754                 right = mand_expr(state, index);
2755                 val = val ^ right;
2756         }
2757         return val;
2758 }
2759
2760 static long_t mor_expr(struct compile_state *state, int index)
2761 {
2762         long_t val;
2763         val = mxor_expr(state, index);
2764         if (mpeek(state, index) == TOK_OR) {
2765                 long_t right;
2766                 meat(state, index, TOK_OR);
2767                 right = mxor_expr(state, index);
2768                 val = val | right;
2769         }
2770         return val;
2771 }
2772
2773 static long_t mland_expr(struct compile_state *state, int index)
2774 {
2775         long_t val;
2776         val = mor_expr(state, index);
2777         if (mpeek(state, index) == TOK_LOGAND) {
2778                 long_t right;
2779                 meat(state, index, TOK_LOGAND);
2780                 right = mor_expr(state, index);
2781                 val = val && right;
2782         }
2783         return val;
2784 }
2785 static long_t mlor_expr(struct compile_state *state, int index)
2786 {
2787         long_t val;
2788         val = mland_expr(state, index);
2789         if (mpeek(state, index) == TOK_LOGOR) {
2790                 long_t right;
2791                 meat(state, index, TOK_LOGOR);
2792                 right = mland_expr(state, index);
2793                 val = val || right;
2794         }
2795         return val;
2796 }
2797
2798 static long_t mcexpr(struct compile_state *state, int index)
2799 {
2800         return mlor_expr(state, index);
2801 }
2802 static void preprocess(struct compile_state *state, int index)
2803 {
2804         /* Doing much more with the preprocessor would require
2805          * a parser and a major restructuring.
2806          * Postpone that for later.
2807          */
2808         struct file_state *file;
2809         struct token *tk;
2810         int line;
2811         int tok;
2812         
2813         file = state->file;
2814         tk = &state->token[index];
2815         state->macro_line = line = file->line;
2816         state->macro_file = file;
2817
2818         next_token(state, index);
2819         ident_to_macro(state, tk);
2820         if (tk->tok == TOK_IDENT) {
2821                 error(state, 0, "undefined preprocessing directive `%s'",
2822                         tk->ident->name);
2823         }
2824         switch(tk->tok) {
2825         case TOK_UNDEF:
2826         case TOK_LINE:
2827         case TOK_PRAGMA:
2828                 if (state->if_value < 0) {
2829                         break;
2830                 }
2831                 warning(state, 0, "Ignoring preprocessor directive: %s", 
2832                         tk->ident->name);
2833                 break;
2834         case TOK_ELIF:
2835                 error(state, 0, "#elif not supported");
2836 #warning "FIXME multiple #elif and #else in an #if do not work properly"
2837                 if (state->if_depth == 0) {
2838                         error(state, 0, "#elif without #if");
2839                 }
2840                 /* If the #if was taken the #elif just disables the following code */
2841                 if (state->if_value >= 0) {
2842                         state->if_value = - state->if_value;
2843                 }
2844                 /* If the previous #if was not taken see if the #elif enables the 
2845                  * trailing code.
2846                  */
2847                 else if ((state->if_value < 0) && 
2848                         (state->if_depth == - state->if_value))
2849                 {
2850                         if (mcexpr(state, index) != 0) {
2851                                 state->if_value = state->if_depth;
2852                         }
2853                         else {
2854                                 state->if_value = - state->if_depth;
2855                         }
2856                 }
2857                 break;
2858         case TOK_IF:
2859                 state->if_depth++;
2860                 if (state->if_value < 0) {
2861                         break;
2862                 }
2863                 if (mcexpr(state, index) != 0) {
2864                         state->if_value = state->if_depth;
2865                 }
2866                 else {
2867                         state->if_value = - state->if_depth;
2868                 }
2869                 break;
2870         case TOK_IFNDEF:
2871                 state->if_depth++;
2872                 if (state->if_value < 0) {
2873                         break;
2874                 }
2875                 next_token(state, index);
2876                 if ((line != file->line) || (tk->tok != TOK_IDENT)) {
2877                         error(state, 0, "Invalid macro name");
2878                 }
2879                 if (tk->ident->sym_define == 0) {
2880                         state->if_value = state->if_depth;
2881                 } 
2882                 else {
2883                         state->if_value = - state->if_depth;
2884                 }
2885                 break;
2886         case TOK_IFDEF:
2887                 state->if_depth++;
2888                 if (state->if_value < 0) {
2889                         break;
2890                 }
2891                 next_token(state, index);
2892                 if ((line != file->line) || (tk->tok != TOK_IDENT)) {
2893                         error(state, 0, "Invalid macro name");
2894                 }
2895                 if (tk->ident->sym_define != 0) {
2896                         state->if_value = state->if_depth;
2897                 }
2898                 else {
2899                         state->if_value = - state->if_depth;
2900                 }
2901                 break;
2902         case TOK_ELSE:
2903                 if (state->if_depth == 0) {
2904                         error(state, 0, "#else without #if");
2905                 }
2906                 if ((state->if_value >= 0) ||
2907                         ((state->if_value < 0) && 
2908                                 (state->if_depth == -state->if_value)))
2909                 {
2910                         state->if_value = - state->if_value;
2911                 }
2912                 break;
2913         case TOK_ENDIF:
2914                 if (state->if_depth == 0) {
2915                         error(state, 0, "#endif without #if");
2916                 }
2917                 if ((state->if_value >= 0) ||
2918                         ((state->if_value < 0) &&
2919                                 (state->if_depth == -state->if_value))) 
2920                 {
2921                         state->if_value = state->if_depth - 1;
2922                 }
2923                 state->if_depth--;
2924                 break;
2925         case TOK_DEFINE:
2926         {
2927                 struct hash_entry *ident;
2928                 struct macro *macro;
2929                 char *ptr;
2930                 
2931                 if (state->if_value < 0) /* quit early when #if'd out */
2932                         break;
2933
2934                 meat(state, index, TOK_IDENT);
2935                 ident = tk->ident;
2936                 
2937
2938                 if (*file->pos == '(') {
2939 #warning "FIXME macros with arguments not supported"
2940                         error(state, 0, "Macros with arguments not supported");
2941                 }
2942
2943                 /* Find the end of the line to get an estimate of
2944                  * the macro's length.
2945                  */
2946                 for(ptr = file->pos; *ptr != '\n'; ptr++)  
2947                         ;
2948
2949                 if (ident->sym_define != 0) {
2950                         error(state, 0, "macro %s already defined\n", ident->name);
2951                 }
2952                 macro = xmalloc(sizeof(*macro), "macro");
2953                 macro->ident = ident;
2954                 macro->buf_len = ptr - file->pos +1;
2955                 macro->buf = xmalloc(macro->buf_len +2, "macro buf");
2956
2957                 memcpy(macro->buf, file->pos, macro->buf_len);
2958                 macro->buf[macro->buf_len] = '\n';
2959                 macro->buf[macro->buf_len +1] = '\0';
2960
2961                 ident->sym_define = macro;
2962                 break;
2963         }
2964         case TOK_ERROR:
2965         {
2966                 char *end;
2967                 int len;
2968                 /* Find the end of the line */
2969                 for(end = file->pos; *end != '\n'; end++)
2970                         ;
2971                 len = (end - file->pos);
2972                 if (state->if_value >= 0) {
2973                         error(state, 0, "%*.*s", len, len, file->pos);
2974                 }
2975                 file->pos = end;
2976                 break;
2977         }
2978         case TOK_WARNING:
2979         {
2980                 char *end;
2981                 int len;
2982                 /* Find the end of the line */
2983                 for(end = file->pos; *end != '\n'; end++)
2984                         ;
2985                 len = (end - file->pos);
2986                 if (state->if_value >= 0) {
2987                         warning(state, 0, "%*.*s", len, len, file->pos);
2988                 }
2989                 file->pos = end;
2990                 break;
2991         }
2992         case TOK_INCLUDE:
2993         {
2994                 char *name;
2995                 char *ptr;
2996                 int local;
2997                 local = 0;
2998                 name = 0;
2999                 next_token(state, index);
3000                 if (tk->tok == TOK_LIT_STRING) {
3001                         const char *token;
3002                         int name_len;
3003                         name = xmalloc(tk->str_len, "include");
3004                         token = tk->val.str +1;
3005                         name_len = tk->str_len -2;
3006                         if (*token == '"') {
3007                                 token++;
3008                                 name_len--;
3009                         }
3010                         memcpy(name, token, name_len);
3011                         name[name_len] = '\0';
3012                         local = 1;
3013                 }
3014                 else if (tk->tok == TOK_LESS) {
3015                         char *start, *end;
3016                         start = file->pos;
3017                         for(end = start; *end != '\n'; end++) {
3018                                 if (*end == '>') {
3019                                         break;
3020                                 }
3021                         }
3022                         if (*end == '\n') {
3023                                 error(state, 0, "Unterminated included directive");
3024                         }
3025                         name = xmalloc(end - start + 1, "include");
3026                         memcpy(name, start, end - start);
3027                         name[end - start] = '\0';
3028                         file->pos = end +1;
3029                         local = 0;
3030                 }
3031                 else {
3032                         error(state, 0, "Invalid include directive");
3033                 }
3034                 /* Error if there are any characters after the include */
3035                 for(ptr = file->pos; *ptr != '\n'; ptr++) {
3036                         if (!isspace(*ptr)) {
3037                                 error(state, 0, "garbage after include directive");
3038                         }
3039                 }
3040                 if (state->if_value >= 0) {
3041                         compile_file(state, name, local);
3042                 }
3043                 xfree(name);
3044                 next_token(state, index);
3045                 return;
3046         }
3047         default:
3048                 /* Ignore # without a following ident */
3049                 if (tk->tok == TOK_IDENT) {
3050                         error(state, 0, "Invalid preprocessor directive: %s", 
3051                                 tk->ident->name);
3052                 }
3053                 break;
3054         }
3055         /* Consume the rest of the macro line */
3056         do {
3057                 tok = mpeek(state, index);
3058                 meat(state, index, tok);
3059         } while(tok != TOK_EOF);
3060         return;
3061 }
3062
3063 static void token(struct compile_state *state, int index)
3064 {
3065         struct file_state *file;
3066         struct token *tk;
3067         int rescan;
3068
3069         tk = &state->token[index];
3070         next_token(state, index);
3071         do {
3072                 rescan = 0;
3073                 file = state->file;
3074                 if (tk->tok == TOK_EOF && file->prev) {
3075                         state->file = file->prev;
3076                         /* file->basename is used keep it */
3077                         xfree(file->dirname);
3078                         xfree(file->buf);
3079                         xfree(file);
3080                         next_token(state, index);
3081                         rescan = 1;
3082                 }
3083                 else if (tk->tok == TOK_MACRO) {
3084                         preprocess(state, index);
3085                         rescan = 1;
3086                 }
3087                 else if (tk->ident && tk->ident->sym_define) {
3088                         compile_macro(state, tk);
3089                         next_token(state, index);
3090                         rescan = 1;
3091                 }
3092                 else if (state->if_value < 0) {
3093                         next_token(state, index);
3094                         rescan = 1;
3095                 }
3096         } while(rescan);
3097 }
3098
3099 static int peek(struct compile_state *state)
3100 {
3101         if (state->token[1].tok == -1) {
3102                 token(state, 1);
3103         }
3104         return state->token[1].tok;
3105 }
3106
3107 static int peek2(struct compile_state *state)
3108 {
3109         if (state->token[1].tok == -1) {
3110                 token(state, 1);
3111         }
3112         if (state->token[2].tok == -1) {
3113                 token(state, 2);
3114         }
3115         return state->token[2].tok;
3116 }
3117
3118 static void __eat(
3119         const char *file, const char *func, int line,
3120         struct compile_state *state, int tok)
3121 {
3122         int next_tok;
3123         int i;
3124         next_tok = peek(state);
3125         if (next_tok != tok) {
3126                 const char *name1, *name2;
3127                 name1 = tokens[next_tok];
3128                 name2 = "";
3129                 if (next_tok == TOK_IDENT) {
3130                         name2 = state->token[1].ident->name;
3131                 }
3132                 internal_error(state, 0, "@ %s.%s:%d \tfound %s %s expected %s", 
3133                         file, func, line,
3134                         name1, name2, tokens[tok]);
3135         }
3136         /* Free the old token value */
3137         if (state->token[0].str_len) {
3138                 xfree((void *)(state->token[0].val.str));
3139         }
3140         for(i = 0; i < sizeof(state->token)/sizeof(state->token[0]) - 1; i++) {
3141                 state->token[i] = state->token[i + 1];
3142         }
3143         memset(&state->token[i], 0, sizeof(state->token[i]));
3144         state->token[i].tok = -1;
3145 }
3146 #define eat(state, tok) __eat(__FILE__, __func__, __LINE__, state, tok)
3147
3148 #warning "FIXME do not hardcode the include paths"
3149 static char *include_paths[] = {
3150         "/home/eric/projects/linuxbios/checkin/solo/freebios2/src/include",
3151         "/home/eric/projects/linuxbios/checkin/solo/freebios2/src/arch/i386/include",
3152         "/home/eric/projects/linuxbios/checkin/solo/freebios2/src",
3153         0
3154 };
3155
3156 static void compile_file(struct compile_state *state, char *filename, int local)
3157 {
3158         char cwd[4096];
3159         char *subdir, *base;
3160         int subdir_len;
3161         struct file_state *file;
3162         char *basename;
3163         file = xmalloc(sizeof(*file), "file_state");
3164
3165         base = strrchr(filename, '/');
3166         subdir = filename;
3167         if (base != 0) {
3168                 subdir_len = base - filename;
3169                 base++;
3170         }
3171         else {
3172                 base = filename;
3173                 subdir_len = 0;
3174         }
3175         basename = xmalloc(strlen(base) +1, "basename");
3176         strcpy(basename, base);
3177         file->basename = basename;
3178
3179         if (getcwd(cwd, sizeof(cwd)) == 0) {
3180                 die("cwd buffer to small");
3181         }
3182         
3183         if (subdir[0] == '/') {
3184                 file->dirname = xmalloc(subdir_len + 1, "dirname");
3185                 memcpy(file->dirname, subdir, subdir_len);
3186                 file->dirname[subdir_len] = '\0';
3187         }
3188         else {
3189                 char *dir;
3190                 int dirlen;
3191                 char **path;
3192                 /* Find the appropriate directory... */
3193                 dir = 0;
3194                 if (!state->file && exists(cwd, filename)) {
3195                         dir = cwd;
3196                 }
3197                 if (local && state->file && exists(state->file->dirname, filename)) {
3198                         dir = state->file->dirname;
3199                 }
3200                 for(path = include_paths; !dir && *path; path++) {
3201                         if (exists(*path, filename)) {
3202                                 dir = *path;
3203                         }
3204                 }
3205                 if (!dir) {
3206                         error(state, 0, "Cannot find `%s'\n", filename);
3207                 }
3208                 dirlen = strlen(dir);
3209                 file->dirname = xmalloc(dirlen + 1 + subdir_len + 1, "dirname");
3210                 memcpy(file->dirname, dir, dirlen);
3211                 file->dirname[dirlen] = '/';
3212                 memcpy(file->dirname + dirlen + 1, subdir, subdir_len);
3213                 file->dirname[dirlen + 1 + subdir_len] = '\0';
3214         }
3215         file->buf = slurp_file(file->dirname, file->basename, &file->size);
3216         xchdir(cwd);
3217
3218         file->pos = file->buf;
3219         file->line_start = file->pos;
3220         file->line = 1;
3221
3222         file->prev = state->file;
3223         state->file = file;
3224         
3225         process_trigraphs(state);
3226         splice_lines(state);
3227 }
3228
3229 /* visibility global/local */
3230 /* static/auto duration */
3231 /* typedef, register, inline */
3232 #define STOR_SHIFT         0
3233 #define STOR_MASK     0x000f
3234 /* Visibility */
3235 #define STOR_GLOBAL   0x0001
3236 /* Duration */
3237 #define STOR_PERM     0x0002
3238 /* Storage specifiers */
3239 #define STOR_AUTO     0x0000
3240 #define STOR_STATIC   0x0002
3241 #define STOR_EXTERN   0x0003
3242 #define STOR_REGISTER 0x0004
3243 #define STOR_TYPEDEF  0x0008
3244 #define STOR_INLINE   0x000c
3245
3246 #define QUAL_SHIFT         4
3247 #define QUAL_MASK     0x0070
3248 #define QUAL_NONE     0x0000
3249 #define QUAL_CONST    0x0010
3250 #define QUAL_VOLATILE 0x0020
3251 #define QUAL_RESTRICT 0x0040
3252
3253 #define TYPE_SHIFT         8
3254 #define TYPE_MASK     0x1f00
3255 #define TYPE_INTEGER(TYPE)    (((TYPE) >= TYPE_CHAR) && ((TYPE) <= TYPE_ULLONG))
3256 #define TYPE_ARITHMETIC(TYPE) (((TYPE) >= TYPE_CHAR) && ((TYPE) <= TYPE_LDOUBLE))
3257 #define TYPE_UNSIGNED(TYPE)   ((TYPE) & 0x0100)
3258 #define TYPE_SIGNED(TYPE)     (!TYPE_UNSIGNED(TYPE))
3259 #define TYPE_MKUNSIGNED(TYPE) ((TYPE) | 0x0100)
3260 #define TYPE_RANK(TYPE)       ((TYPE) & ~0x0100)
3261 #define TYPE_PTR(TYPE)        (((TYPE) & TYPE_MASK) == TYPE_POINTER)
3262 #define TYPE_DEFAULT  0x0000
3263 #define TYPE_VOID     0x0100
3264 #define TYPE_CHAR     0x0200
3265 #define TYPE_UCHAR    0x0300
3266 #define TYPE_SHORT    0x0400
3267 #define TYPE_USHORT   0x0500
3268 #define TYPE_INT      0x0600
3269 #define TYPE_UINT     0x0700
3270 #define TYPE_LONG     0x0800
3271 #define TYPE_ULONG    0x0900
3272 #define TYPE_LLONG    0x0a00 /* long long */
3273 #define TYPE_ULLONG   0x0b00
3274 #define TYPE_FLOAT    0x0c00
3275 #define TYPE_DOUBLE   0x0d00
3276 #define TYPE_LDOUBLE  0x0e00 /* long double */
3277 #define TYPE_STRUCT   0x1000
3278 #define TYPE_ENUM     0x1100
3279 #define TYPE_POINTER  0x1200 
3280 /* For TYPE_POINTER:
3281  * type->left holds the type pointed to.
3282  */
3283 #define TYPE_FUNCTION 0x1300 
3284 /* For TYPE_FUNCTION:
3285  * type->left holds the return type.
3286  * type->right holds the...
3287  */
3288 #define TYPE_PRODUCT  0x1400
3289 /* TYPE_PRODUCT is a basic building block when defining structures
3290  * type->left holds the type that appears first in memory.
3291  * type->right holds the type that appears next in memory.
3292  */
3293 #define TYPE_OVERLAP  0x1500
3294 /* TYPE_OVERLAP is a basic building block when defining unions
3295  * type->left and type->right holds to types that overlap
3296  * each other in memory.
3297  */
3298 #define TYPE_ARRAY    0x1600
3299 /* TYPE_ARRAY is a basic building block when definitng arrays.
3300  * type->left holds the type we are an array of.
3301  * type-> holds the number of elements.
3302  */
3303
3304 #define ELEMENT_COUNT_UNSPECIFIED (~0UL)
3305
3306 struct type {
3307         unsigned int type;
3308         struct type *left, *right;
3309         ulong_t elements;
3310         struct hash_entry *ident;
3311 };
3312
3313 static struct type *new_type(
3314         unsigned int type, struct type *left, struct type *right)
3315 {
3316         struct type *result;
3317         result = xmalloc(sizeof(*result), "type");
3318         result->type = type;
3319         result->left = left;
3320         result->right = right;
3321         result->ident = 0;
3322         return result;
3323 }
3324
3325 static struct type *clone_type(unsigned int specifiers, struct type *old)
3326 {
3327         struct type *result;
3328         result = xmalloc(sizeof(*result), "type");
3329         memcpy(result, old, sizeof(*result));
3330         result->type &= TYPE_MASK;
3331         result->type |= specifiers;
3332         return result;
3333 }
3334
3335 #define SIZEOF_SHORT 2
3336 #define SIZEOF_INT   4
3337 #define SIZEOF_LONG  (sizeof(long_t))
3338
3339 #define ALIGNOF_SHORT 2
3340 #define ALIGNOF_INT   4
3341 #define ALIGNOF_LONG  (sizeof(long_t))
3342
3343 #define MASK_UCHAR(X)    ((X) & ((ulong_t)0xff))
3344 #define MASK_USHORT(X)   ((X) & (((ulong_t)1 << (SIZEOF_SHORT*8)) - 1))
3345 static inline ulong_t mask_uint(ulong_t x)
3346 {
3347         if (SIZEOF_INT < SIZEOF_LONG) {
3348                 ulong_t mask = (((ulong_t)1) << ((ulong_t)(SIZEOF_INT*8))) -1;
3349                 x &= mask;
3350         }
3351         return x;
3352 }
3353 #define MASK_UINT(X)      (mask_uint(X))
3354 #define MASK_ULONG(X)    (X)
3355
3356
3357 static struct type void_type   = { .type  = TYPE_VOID };
3358 static struct type char_type   = { .type  = TYPE_CHAR };
3359 static struct type uchar_type  = { .type  = TYPE_UCHAR };
3360 static struct type short_type  = { .type  = TYPE_SHORT };
3361 static struct type ushort_type = { .type  = TYPE_USHORT };
3362 static struct type int_type    = { .type  = TYPE_INT };
3363 static struct type uint_type   = { .type  = TYPE_UINT };
3364 static struct type long_type   = { .type  = TYPE_LONG };
3365 static struct type ulong_type  = { .type  = TYPE_ULONG };
3366
3367 static struct triple *variable(struct compile_state *state, struct type *type)
3368 {
3369         struct triple *result;
3370         if ((type->type & STOR_MASK) != STOR_PERM) {
3371                 result = triple(state, OP_ADECL, type, 0, 0);
3372         }
3373         else {
3374                 result = triple(state, OP_SDECL, type, 0, 0);
3375         }
3376         return result;
3377 }
3378
3379 static void stor_of(FILE *fp, struct type *type)
3380 {
3381         switch(type->type & STOR_MASK) {
3382         case STOR_AUTO:
3383                 fprintf(fp, "auto ");
3384                 break;
3385         case STOR_STATIC:
3386                 fprintf(fp, "static ");
3387                 break;
3388         case STOR_EXTERN:
3389                 fprintf(fp, "extern ");
3390                 break;
3391         case STOR_REGISTER:
3392                 fprintf(fp, "register ");
3393                 break;
3394         case STOR_TYPEDEF:
3395                 fprintf(fp, "typedef ");
3396                 break;
3397         case STOR_INLINE:
3398                 fprintf(fp, "inline ");
3399                 break;
3400         }
3401 }
3402 static void qual_of(FILE *fp, struct type *type)
3403 {
3404         if (type->type & QUAL_CONST) {
3405                 fprintf(fp, " const");
3406         }
3407         if (type->type & QUAL_VOLATILE) {
3408                 fprintf(fp, " volatile");
3409         }
3410         if (type->type & QUAL_RESTRICT) {
3411                 fprintf(fp, " restrict");
3412         }
3413 }
3414 static void name_of(FILE *fp, struct type *type)
3415 {
3416         stor_of(fp, type);
3417         switch(type->type & TYPE_MASK) {
3418         case TYPE_VOID:
3419                 fprintf(fp, "void");
3420                 qual_of(fp, type);
3421                 break;
3422         case TYPE_CHAR:
3423                 fprintf(fp, "signed char");
3424                 qual_of(fp, type);
3425                 break;
3426         case TYPE_UCHAR:
3427                 fprintf(fp, "unsigned char");
3428                 qual_of(fp, type);
3429                 break;
3430         case TYPE_SHORT:
3431                 fprintf(fp, "signed short");
3432                 qual_of(fp, type);
3433                 break;
3434         case TYPE_USHORT:
3435                 fprintf(fp, "unsigned short");
3436                 qual_of(fp, type);
3437                 break;
3438         case TYPE_INT:
3439                 fprintf(fp, "signed int");
3440                 qual_of(fp, type);
3441                 break;
3442         case TYPE_UINT:
3443                 fprintf(fp, "unsigned int");
3444                 qual_of(fp, type);
3445                 break;
3446         case TYPE_LONG:
3447                 fprintf(fp, "signed long");
3448                 qual_of(fp, type);
3449                 break;
3450         case TYPE_ULONG:
3451                 fprintf(fp, "unsigned long");
3452                 qual_of(fp, type);
3453                 break;
3454         case TYPE_POINTER:
3455                 name_of(fp, type->left);
3456                 fprintf(fp, " * ");
3457                 qual_of(fp, type);
3458                 break;
3459         case TYPE_PRODUCT:
3460         case TYPE_OVERLAP:
3461                 name_of(fp, type->left);
3462                 fprintf(fp, ", ");
3463                 name_of(fp, type->right);
3464                 break;
3465         case TYPE_ENUM:
3466                 fprintf(fp, "enum %s", type->ident->name);
3467                 qual_of(fp, type);
3468                 break;
3469         case TYPE_STRUCT:
3470                 fprintf(fp, "struct %s", type->ident->name);
3471                 qual_of(fp, type);
3472                 break;
3473         case TYPE_FUNCTION:
3474         {
3475                 name_of(fp, type->left);
3476                 fprintf(fp, " (*)(");
3477                 name_of(fp, type->right);
3478                 fprintf(fp, ")");
3479                 break;
3480         }
3481         case TYPE_ARRAY:
3482                 name_of(fp, type->left);
3483                 fprintf(fp, " [%ld]", type->elements);
3484                 break;
3485         default:
3486                 fprintf(fp, "????: %x", type->type & TYPE_MASK);
3487                 break;
3488         }
3489 }
3490
3491 static size_t align_of(struct compile_state *state, struct type *type)
3492 {
3493         size_t align;
3494         align = 0;
3495         switch(type->type & TYPE_MASK) {
3496         case TYPE_VOID:
3497                 align = 1;
3498                 break;
3499         case TYPE_CHAR:
3500         case TYPE_UCHAR:
3501                 align = 1;
3502                 break;
3503         case TYPE_SHORT:
3504         case TYPE_USHORT:
3505                 align = ALIGNOF_SHORT;
3506                 break;
3507         case TYPE_INT:
3508         case TYPE_UINT:
3509         case TYPE_ENUM:
3510                 align = ALIGNOF_INT;
3511                 break;
3512         case TYPE_LONG:
3513         case TYPE_ULONG:
3514         case TYPE_POINTER:
3515                 align = ALIGNOF_LONG;
3516                 break;
3517         case TYPE_PRODUCT:
3518         case TYPE_OVERLAP:
3519         {
3520                 size_t left_align, right_align;
3521                 left_align  = align_of(state, type->left);
3522                 right_align = align_of(state, type->right);
3523                 align = (left_align >= right_align) ? left_align : right_align;
3524                 break;
3525         }
3526         case TYPE_ARRAY:
3527                 align = align_of(state, type->left);
3528                 break;
3529         default:
3530                 error(state, 0, "alignof not yet defined for type\n");
3531                 break;
3532         }
3533         return align;
3534 }
3535
3536 static size_t size_of(struct compile_state *state, struct type *type)
3537 {
3538         size_t size;
3539         size = 0;
3540         switch(type->type & TYPE_MASK) {
3541         case TYPE_VOID:
3542                 size = 0;
3543                 break;
3544         case TYPE_CHAR:
3545         case TYPE_UCHAR:
3546                 size = 1;
3547                 break;
3548         case TYPE_SHORT:
3549         case TYPE_USHORT:
3550                 size = SIZEOF_SHORT;
3551                 break;
3552         case TYPE_INT:
3553         case TYPE_UINT:
3554         case TYPE_ENUM:
3555                 size = SIZEOF_INT;
3556                 break;
3557         case TYPE_LONG:
3558         case TYPE_ULONG:
3559         case TYPE_POINTER:
3560                 size = SIZEOF_LONG;
3561                 break;
3562         case TYPE_PRODUCT:
3563         {
3564                 size_t align, pad;
3565                 size = size_of(state, type->left);
3566                 while((type->right->type & TYPE_MASK) == TYPE_PRODUCT) {
3567                         type = type->right;
3568                         align = align_of(state, type->left);
3569                         pad = align - (size % align);
3570                         size = size + pad + size_of(state, type->left);
3571                 }
3572                 align = align_of(state, type->right);
3573                 pad = align - (size % align);
3574                 size = size + pad + sizeof(type->right);
3575                 break;
3576         }
3577         case TYPE_OVERLAP:
3578         {
3579                 size_t size_left, size_right;
3580                 size_left = size_of(state, type->left);
3581                 size_right = size_of(state, type->right);
3582                 size = (size_left >= size_right)? size_left : size_right;
3583                 break;
3584         }
3585         case TYPE_ARRAY:
3586                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
3587                         internal_error(state, 0, "Invalid array type");
3588                 } else {
3589                         size = size_of(state, type->left) * type->elements;
3590                 }
3591                 break;
3592         default:
3593                 error(state, 0, "sizeof not yet defined for type\n");
3594                 break;
3595         }
3596         return size;
3597 }
3598
3599 static void arrays_complete(struct compile_state *state, struct type *type)
3600 {
3601         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
3602                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
3603                         error(state, 0, "array size not specified");
3604                 }
3605                 arrays_complete(state, type->left);
3606         }
3607 }
3608
3609 static unsigned int do_integral_promotion(unsigned int type)
3610 {
3611         type &= TYPE_MASK;
3612         if (TYPE_INTEGER(type) && 
3613                 TYPE_RANK(type) < TYPE_RANK(TYPE_INT)) {
3614                 type = TYPE_INT;
3615         }
3616         return type;
3617 }
3618
3619 static unsigned int do_arithmetic_conversion(
3620         unsigned int left, unsigned int right)
3621 {
3622         left &= TYPE_MASK;
3623         right &= TYPE_MASK;
3624         if ((left == TYPE_LDOUBLE) || (right == TYPE_LDOUBLE)) {
3625                 return TYPE_LDOUBLE;
3626         }
3627         else if ((left == TYPE_DOUBLE) || (right == TYPE_DOUBLE)) {
3628                 return TYPE_DOUBLE;
3629         }
3630         else if ((left == TYPE_FLOAT) || (right == TYPE_FLOAT)) {
3631                 return TYPE_FLOAT;
3632         }
3633         left = do_integral_promotion(left);
3634         right = do_integral_promotion(right);
3635         /* If both operands have the same size done */
3636         if (left == right) {
3637                 return left;
3638         }
3639         /* If both operands have the same signedness pick the larger */
3640         else if (!!TYPE_UNSIGNED(left) == !!TYPE_UNSIGNED(right)) {
3641                 return (TYPE_RANK(left) >= TYPE_RANK(right)) ? left : right;
3642         }
3643         /* If the signed type can hold everything use it */
3644         else if (TYPE_SIGNED(left) && (TYPE_RANK(left) > TYPE_RANK(right))) {
3645                 return left;
3646         }
3647         else if (TYPE_SIGNED(right) && (TYPE_RANK(right) > TYPE_RANK(left))) {
3648                 return right;
3649         }
3650         /* Convert to the unsigned type with the same rank as the signed type */
3651         else if (TYPE_SIGNED(left)) {
3652                 return TYPE_MKUNSIGNED(left);
3653         }
3654         else {
3655                 return TYPE_MKUNSIGNED(right);
3656         }
3657 }
3658
3659 /* see if two types are the same except for qualifiers */
3660 static int equiv_types(struct type *left, struct type *right)
3661 {
3662         unsigned int type;
3663         /* Error if the basic types do not match */
3664         if ((left->type & TYPE_MASK) != (right->type & TYPE_MASK)) {
3665                 return 0;
3666         }
3667         type = left->type & TYPE_MASK;
3668         /* if the basic types match and it is an arithmetic type we are done */
3669         if (TYPE_ARITHMETIC(type)) {
3670                 return 1;
3671         }
3672         /* If it is a pointer type recurse and keep testing */
3673         if (type == TYPE_POINTER) {
3674                 return equiv_types(left->left, right->left);
3675         }
3676         else if (type == TYPE_ARRAY) {
3677                 return (left->elements == right->elements) &&
3678                         equiv_types(left->left, right->left);
3679         }
3680         /* test for struct/union equality */
3681         else if (type == TYPE_STRUCT) {
3682                 return left->ident == right->ident;
3683         }
3684         /* Test for equivalent functions */
3685         else if (type == TYPE_FUNCTION) {
3686                 return equiv_types(left->left, right->left) &&
3687                         equiv_types(left->right, right->right);
3688         }
3689         /* We only see TYPE_PRODUCT as part of function equivalence matching */
3690         else if (type == TYPE_PRODUCT) {
3691                 return equiv_types(left->left, right->left) &&
3692                         equiv_types(left->right, right->right);
3693         }
3694         /* We should see TYPE_OVERLAP */
3695         else {
3696                 return 0;
3697         }
3698 }
3699
3700 static int equiv_ptrs(struct type *left, struct type *right)
3701 {
3702         if (((left->type & TYPE_MASK) != TYPE_POINTER) ||
3703                 ((right->type & TYPE_MASK) != TYPE_POINTER)) {
3704                 return 0;
3705         }
3706         return equiv_types(left->left, right->left);
3707 }
3708
3709 static struct type *compatible_types(struct type *left, struct type *right)
3710 {
3711         struct type *result;
3712         unsigned int type, qual_type;
3713         /* Error if the basic types do not match */
3714         if ((left->type & TYPE_MASK) != (right->type & TYPE_MASK)) {
3715                 return 0;
3716         }
3717         type = left->type & TYPE_MASK;
3718         qual_type = (left->type & ~STOR_MASK) | (right->type & ~STOR_MASK);
3719         result = 0;
3720         /* if the basic types match and it is an arithmetic type we are done */
3721         if (TYPE_ARITHMETIC(type)) {
3722                 result = new_type(qual_type, 0, 0);
3723         }
3724         /* If it is a pointer type recurse and keep testing */
3725         else if (type == TYPE_POINTER) {
3726                 result = compatible_types(left->left, right->left);
3727                 if (result) {
3728                         result = new_type(qual_type, result, 0);
3729                 }
3730         }
3731         /* test for struct/union equality */
3732         else if (type == TYPE_STRUCT) {
3733                 if (left->ident == right->ident) {
3734                         result = left;
3735                 }
3736         }
3737         /* Test for equivalent functions */
3738         else if (type == TYPE_FUNCTION) {
3739                 struct type *lf, *rf;
3740                 lf = compatible_types(left->left, right->left);
3741                 rf = compatible_types(left->right, right->right);
3742                 if (lf && rf) {
3743                         result = new_type(qual_type, lf, rf);
3744                 }
3745         }
3746         /* We only see TYPE_PRODUCT as part of function equivalence matching */
3747         else if (type == TYPE_PRODUCT) {
3748                 struct type *lf, *rf;
3749                 lf = compatible_types(left->left, right->left);
3750                 rf = compatible_types(left->right, right->right);
3751                 if (lf && rf) {
3752                         result = new_type(qual_type, lf, rf);
3753                 }
3754         }
3755         else {
3756                 /* Nothing else is compatible */
3757         }
3758         return result;
3759 }
3760
3761 static struct type *compatible_ptrs(struct type *left, struct type *right)
3762 {
3763         struct type *result;
3764         if (((left->type & TYPE_MASK) != TYPE_POINTER) ||
3765                 ((right->type & TYPE_MASK) != TYPE_POINTER)) {
3766                 return 0;
3767         }
3768         result = compatible_types(left->left, right->left);
3769         if (result) {
3770                 unsigned int qual_type;
3771                 qual_type = (left->type & ~STOR_MASK) | (right->type & ~STOR_MASK);
3772                 result = new_type(qual_type, result, 0);
3773         }
3774         return result;
3775         
3776 }
3777 static struct triple *integral_promotion(
3778         struct compile_state *state, struct triple *def)
3779 {
3780         struct type *type;
3781         type = def->type;
3782         /* As all operations are carried out in registers
3783          * the values are converted on load I just convert
3784          * logical type of the operand.
3785          */
3786         if (TYPE_INTEGER(type->type)) {
3787                 unsigned int int_type;
3788                 int_type = type->type & ~TYPE_MASK;
3789                 int_type |= do_integral_promotion(type->type);
3790                 if (int_type != type->type) {
3791                         def->type = new_type(int_type, 0, 0);
3792                 }
3793         }
3794         return def;
3795 }
3796
3797
3798 static void arithmetic(struct compile_state *state, struct triple *def)
3799 {
3800         if (!TYPE_ARITHMETIC(def->type->type)) {
3801                 error(state, def, "arithmetic type expexted");
3802         }
3803 }
3804
3805 static void ptr_arithmetic(struct compile_state *state, struct triple *def)
3806 {
3807         if (!TYPE_PTR(def->type->type) && !TYPE_ARITHMETIC(def->type->type)) {
3808                 error(state, def, "pointer or arithmetic type expected");
3809         }
3810 }
3811
3812 static int is_integral(struct triple *ins)
3813 {
3814         return TYPE_INTEGER(ins->type->type);
3815 }
3816
3817 static void integral(struct compile_state *state, struct triple *def)
3818 {
3819         if (!is_integral(def)) {
3820                 error(state, 0, "integral type expected");
3821         }
3822 }
3823
3824
3825 static void bool(struct compile_state *state, struct triple *def)
3826 {
3827         if (!TYPE_ARITHMETIC(def->type->type) &&
3828                 ((def->type->type & TYPE_MASK) != TYPE_POINTER)) {
3829                 error(state, 0, "arithmetic or pointer type expected");
3830         }
3831 }
3832
3833 static int is_signed(struct type *type)
3834 {
3835         return !!TYPE_SIGNED(type->type);
3836 }
3837
3838 /* Is this a stable variable location otherwise it must be a temporary */
3839 static int is_stable(struct triple *def)
3840 {
3841         int ret;
3842         ret = 0;
3843         if (!def) {
3844                 return 0;
3845         }
3846         if ((def->op == OP_ADECL) || 
3847                 (def->op == OP_SDECL) || 
3848                 (def->op == OP_DEREF) ||
3849                 (def->op == OP_BLOBCONST)) {
3850                 ret = 1;
3851         }
3852         else if (def->op == OP_DOT) {
3853                 ret = is_stable(def->left);
3854         }
3855         return ret;
3856 }
3857
3858 static int is_lvalue(struct triple *def)
3859 {
3860         int ret;
3861         ret = 1;
3862         if (!def) {
3863                 return 0;
3864         }
3865         if (!is_stable(def)) {
3866                 return 0;
3867         }
3868         if (def->type->type & QUAL_CONST) {
3869                 ret = 0;
3870         }
3871         else if (def->op == OP_DOT) {
3872                 ret = is_lvalue(def->left);
3873         }
3874         return ret;
3875 }
3876
3877 static void lvalue(struct compile_state *state, struct triple *def)
3878 {
3879         if (!def) {
3880                 internal_error(state, def, "nothing where lvalue expected?");
3881         }
3882         if (!is_lvalue(def)) { 
3883                 error(state, def, "lvalue expected");
3884         }
3885 }
3886
3887 static int is_pointer(struct triple *def)
3888 {
3889         return (def->type->type & TYPE_MASK) == TYPE_POINTER;
3890 }
3891
3892 static void pointer(struct compile_state *state, struct triple *def)
3893 {
3894         if (!is_pointer(def)) {
3895                 error(state, def, "pointer expected");
3896         }
3897 }
3898
3899 static struct triple *int_const(
3900         struct compile_state *state, struct type *type, ulong_t value)
3901 {
3902         struct triple *result;
3903         switch(type->type & TYPE_MASK) {
3904         case TYPE_CHAR:
3905         case TYPE_INT:   case TYPE_UINT:
3906         case TYPE_LONG:  case TYPE_ULONG:
3907                 break;
3908         default:
3909                 internal_error(state, 0, "constant for unkown type");
3910         }
3911         result = triple(state, OP_INTCONST, type, 0, 0);
3912         result->u.cval = value;
3913         return result;
3914 }
3915
3916
3917 static struct triple *mk_addr_expr(
3918         struct compile_state *state, struct triple *expr, ulong_t offset)
3919 {
3920         struct triple *result;
3921         struct type *type;
3922         
3923         lvalue(state, expr);
3924         type = new_type(
3925                 TYPE_POINTER | (expr->type->type & QUAL_MASK),
3926                 expr->type, 0);
3927
3928         result = 0;
3929         if (expr->op == OP_ADECL) {
3930                 error(state, expr, "address of auto variables not supported");
3931         }
3932         else if (expr->op == OP_SDECL) {
3933                 result = triple(state, OP_ADDRCONST, type, expr, 0);
3934                 result->u.cval = offset;
3935         }
3936         else if (expr->op == OP_DEREF) {
3937                 result = triple(state, OP_ADD, type,
3938                         expr->left,
3939                         int_const(state, &ulong_type, offset));
3940         }
3941         return result;
3942 }
3943
3944 static struct triple *mk_deref_expr(
3945         struct compile_state *state, struct triple *expr)
3946 {
3947         struct type *base_type;
3948         pointer(state, expr);
3949         base_type = expr->type->left;
3950         if (!TYPE_PTR(base_type->type) && !TYPE_ARITHMETIC(base_type->type)) {
3951                 error(state, 0, 
3952                         "Only pointer and arithmetic values can be dereferenced");
3953         }
3954         return triple(state, OP_DEREF, base_type, expr, 0);
3955 }
3956
3957 static struct triple *read_expr(struct compile_state *state, struct triple *def)
3958 {
3959         int op;
3960         if  (!def) {
3961                 return 0;
3962         }
3963         if (!is_stable(def)) {
3964                 return def;
3965         }
3966         /* Tranform an array to a pointer to the first element */
3967 #warning "CHECK_ME is this the right place to transform arrays to pointers?"
3968         if ((def->type->type & TYPE_MASK) == TYPE_ARRAY) {
3969                 struct type *type;
3970                 type = new_type(
3971                         TYPE_POINTER | (def->type->type & QUAL_MASK),
3972                         def->type->left, 0);
3973                 return triple(state, OP_ADDRCONST, type, def, 0);
3974         }
3975         /* Only values in variables need to be read */
3976         if (def->op == OP_ADECL) {
3977                 op = OP_READ;
3978         }
3979         else if ((def->op == OP_SDECL) || (def->op == OP_DEREF)) {
3980                 op = OP_LOAD;
3981         }
3982         else {
3983                 internal_error(state, 0, "unhandled read expr type");
3984                 op = -1;
3985         }
3986         return  triple(state, op, def->type, def, 0);
3987 }
3988
3989 static void write_compatible(struct compile_state *state,
3990         struct type *dest, struct type *rval)
3991 {
3992         int compatible = 0;
3993         /* Both operands have arithmetic type */
3994         if (TYPE_ARITHMETIC(dest->type) && TYPE_ARITHMETIC(rval->type)) {
3995                 compatible = 1;
3996         }
3997         /* One operand is a pointer and the other is a pointer to void */
3998         else if (((dest->type & TYPE_MASK) == TYPE_POINTER) &&
3999                 ((rval->type & TYPE_MASK) == TYPE_POINTER) &&
4000                 (((dest->left->type & TYPE_MASK) == TYPE_VOID) ||
4001                         ((rval->left->type & TYPE_MASK) == TYPE_VOID))) {
4002                 compatible = 1;
4003         }
4004         /* If both types are the same without qualifiers we are good */
4005         else if (equiv_ptrs(dest, rval)) {
4006                 compatible = 1;
4007         }
4008         if (!compatible) {
4009                 error(state, 0, "Incompatible types in assignment");
4010         }
4011 }
4012
4013 static struct triple *write_expr(
4014         struct compile_state *state, struct triple *dest, struct triple *rval)
4015 {
4016         struct triple *def;
4017         int op;
4018
4019         def = 0;
4020         if (!rval) {
4021                 internal_error(state, 0, "missing rval");
4022         }
4023
4024         if (rval->op == OP_LIST) {
4025                 internal_error(state, 0, "expression of type OP_LIST?");
4026         }
4027         if (!is_lvalue(dest)) {
4028                 internal_error(state, 0, "writing to a non lvalue?");
4029         }
4030
4031         write_compatible(state, dest->type, rval->type);
4032
4033         /* Now figure out which assignment operator to use */
4034         op = -1;
4035         if (dest->op == OP_ADECL) {
4036                 op = OP_WRITE;
4037         }
4038         else if ((dest->op == OP_SDECL) || (dest->op == OP_DEREF)) {
4039                 op = OP_STORE;
4040         }
4041         else {
4042                 internal_error(state, 0, "unimplemented lvalue type");
4043         }
4044 #warning "FIXME walk through a list of OP_DOT entries and generate a pointer addition"
4045         def = triple(state, op, dest->type, dest, rval);
4046         return def;
4047 }
4048
4049 static struct triple *init_expr(
4050         struct compile_state *state, struct triple *dest, struct triple *rval)
4051 {
4052         struct triple *def;
4053
4054         def = 0;
4055         if (!rval) {
4056                 internal_error(state, 0, "missing rval");
4057         }
4058         if ((dest->type->type & STOR_MASK) != STOR_PERM) {
4059                 rval = read_expr(state, rval);
4060                 def = write_expr(state, dest, rval);
4061         }
4062         else {
4063                 /* Fill in the array size if necessary */
4064                 if (((dest->type->type & TYPE_MASK) == TYPE_ARRAY) &&
4065                         ((rval->type->type & TYPE_MASK) == TYPE_ARRAY)) {
4066                         if (dest->type->elements == ELEMENT_COUNT_UNSPECIFIED) {
4067                                 dest->type->elements = rval->type->elements;
4068                         }
4069                 }
4070                 if (!equiv_types(dest->type, rval->type)) {
4071                         error(state, 0, "Incompatible types in inializer");
4072                 }
4073                 dest->left = rval;
4074         }
4075         return def;
4076 }
4077
4078 struct type *arithmetic_result(
4079         struct compile_state *state, struct triple *left, struct triple *right)
4080 {
4081         struct type *type;
4082         /* Sanity checks to ensure I am working with arithmetic types */
4083         arithmetic(state, left);
4084         arithmetic(state, right);
4085         type = new_type(
4086                 do_arithmetic_conversion(
4087                         left->type->type, 
4088                         right->type->type), 0, 0);
4089         return type;
4090 }
4091
4092 struct type *ptr_arithmetic_result(
4093         struct compile_state *state, struct triple *left, struct triple *right)
4094 {
4095         struct type *type;
4096         /* Sanity checks to ensure I am working with the proper types */
4097         ptr_arithmetic(state, left);
4098         arithmetic(state, right);
4099         if (TYPE_ARITHMETIC(left->type->type) && 
4100                 TYPE_ARITHMETIC(right->type->type)) {
4101                 type = arithmetic_result(state, left, right);
4102         }
4103         else if (TYPE_PTR(left->type->type)) {
4104                 type = left->type;
4105         }
4106         else {
4107                 internal_error(state, 0, "huh?");
4108                 type = 0;
4109         }
4110         return type;
4111 }
4112
4113
4114 /* boolean helper function */
4115
4116 static struct triple *ltrue_expr(struct compile_state *state, 
4117         struct triple *expr)
4118 {
4119         switch(expr->op) {
4120         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
4121         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
4122         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
4123                 /* If the expression is already boolean do nothing */
4124                 break;
4125         default:
4126                 expr = triple(state, OP_LTRUE, &int_type, expr, 0);
4127                 break;
4128         }
4129         return expr;
4130 }
4131
4132 static struct triple *lfalse_expr(struct compile_state *state, 
4133         struct triple *expr)
4134 {
4135         return triple(state, OP_LFALSE, &int_type, expr, 0);
4136 }
4137
4138 static struct triple *cond_expr(
4139         struct compile_state *state, 
4140         struct triple *test, struct triple *left, struct triple *right)
4141 {
4142         struct triple *def;
4143         struct type *result_type;
4144         unsigned int left_type, right_type;
4145         bool(state, test);
4146         left_type = left->type->type;
4147         right_type = right->type->type;
4148         result_type = 0;
4149         /* Both operands have arithmetic type */
4150         if (TYPE_ARITHMETIC(left_type) && TYPE_ARITHMETIC(right_type)) {
4151                 result_type = arithmetic_result(state, left, right);
4152         }
4153         /* Both operands have void type */
4154         else if (((left_type & TYPE_MASK) == TYPE_VOID) &&
4155                 ((right_type & TYPE_MASK) == TYPE_VOID)) {
4156                 result_type = &void_type;
4157         }
4158         /* pointers to the same type... */
4159         else if ((result_type = compatible_ptrs(left->type, right->type))) {
4160                 ;
4161         }
4162         /* Both operands are pointers and left is a pointer to void */
4163         else if (((left_type & TYPE_MASK) == TYPE_POINTER) &&
4164                 ((right_type & TYPE_MASK) == TYPE_POINTER) &&
4165                 ((left->type->left->type & TYPE_MASK) == TYPE_VOID)) {
4166                 result_type = right->type;
4167         }
4168         /* Both operands are pointers and right is a pointer to void */
4169         else if (((left_type & TYPE_MASK) == TYPE_POINTER) &&
4170                 ((right_type & TYPE_MASK) == TYPE_POINTER) &&
4171                 ((right->type->left->type & TYPE_MASK) == TYPE_VOID)) {
4172                 result_type = left->type;
4173         }
4174         if (!result_type) {
4175                 error(state, 0, "Incompatible types in conditional expression");
4176         }
4177         def = triple(state, OP_COND, result_type, test,
4178                 triple(state, OP_PRODUCT, &void_type, left, right));
4179         return def;
4180 }
4181
4182
4183 static int expr_depth(struct compile_state *state, struct triple *triple)
4184 {
4185         int count;
4186         count = 0;
4187         if (!triple) {
4188                 return 0;
4189         }
4190         /* All of the internal helper ops that are not removed by
4191          * flatten must be present here.
4192          */
4193         if (triple->op == OP_READ) {
4194                 ;
4195         }
4196         else if (triple->op == OP_DEREF) {
4197                 count = expr_depth(state, triple->left) - 1;
4198         }
4199         else if (triple->op == OP_VAL) {
4200                 count = expr_depth(state, triple->left) - 1;
4201         }
4202         else if (triple->op == OP_COMMA) {
4203                 int left, right;
4204                 left = expr_depth(state, triple->left);
4205                 right = expr_depth(state, triple->right);
4206                 count = (left >= right)? left : right;
4207         }
4208         else if (triple->op == OP_CALL) {
4209                 /* Don't figure the depth of a call just guess it is huge */
4210                 count = 1000;
4211         }
4212         else {
4213                 struct triple **expr;
4214                 expr = triple_rhs(state, triple, 0);
4215                 for(;expr; expr = triple_rhs(state, triple, expr)) {
4216                         int depth;
4217                         depth = expr_depth(state, *expr);
4218                         if (depth > count) {
4219                                 count = depth;
4220                         }
4221                 }
4222         }
4223         return count + 1;
4224 }
4225
4226 static struct triple *flatten(
4227         struct compile_state *state, struct triple *first, struct triple *ptr);
4228
4229 static struct triple *flatten_rhs(
4230         struct compile_state *state, struct triple *first, struct triple *ptr)
4231 {
4232         struct triple **left, **right, **last;
4233         /* Only operations with a rhs should come here */
4234         last = triple_lhs(state, ptr, 0);
4235         if (last) {
4236                 internal_error(state, ptr, "unexpected rhs for: %d %s",
4237                         ptr->op, tops(ptr->op));
4238         }
4239         /* Collect up the rhs */
4240         left  = triple_rhs(state, ptr, 0);
4241         right = last = 0;
4242         if (left) {
4243                 right = triple_rhs(state, ptr, left);
4244         }
4245         if (right) {
4246                 last  = triple_rhs(state, ptr, right);
4247         }
4248         if (last) {
4249                 internal_error(state, ptr, "too many rhs arguments for: %d %s",
4250                         ptr->op, tops(ptr->op));
4251         }
4252         if (left && right) {
4253                 if (expr_depth(state, *left) >= expr_depth(state, *right)) {
4254                         *left  = flatten(state, first, *left);
4255                         *right = flatten(state, first, *right);
4256                 }
4257                 else {
4258                         *right = flatten(state, first, *right);
4259                         *left  = flatten(state, first, *left);
4260                 }
4261                 use_triple(*left, ptr);
4262                 use_triple(*right, ptr);
4263         }
4264         else if (left) {
4265                 *left = flatten(state, first, *left);
4266                 use_triple(*left, ptr);
4267         }
4268         return ptr;
4269 }
4270
4271 static struct triple *flatten_land(
4272         struct compile_state *state, struct triple *first, struct triple *ptr)
4273 {
4274         struct triple *left, *right;
4275         struct triple *val, *test, *jmp, *label1, *end;
4276
4277         /* Find the triples */
4278         left = ptr->left;
4279         right = ptr->right;
4280
4281         /* Generate the needed triples */
4282         end = label(state);
4283
4284         /* Thread the triples together */
4285         val         = flatten(state, first, variable(state, ptr->type));
4286         left        = flatten(state, first, write_expr(state, val, left));
4287         test        = flatten(state, first, 
4288                 lfalse_expr(state, read_expr(state, val)));
4289         jmp         = flatten(state, first, 
4290                 triple(state, OP_BRANCH, &void_type, end, test));
4291         label1      = flatten(state, first, label(state));
4292         right       = flatten(state, first, write_expr(state, val, right));
4293         jmp->left   = flatten(state, first, end);
4294        
4295         
4296         /* Now give the caller something to chew on */
4297         return read_expr(state, val);
4298 }
4299
4300 static struct triple *flatten_lor(
4301         struct compile_state *state, struct triple *first, struct triple *ptr)
4302 {
4303         struct triple *left, *right;
4304         struct triple *val, *jmp, *label1, *end;
4305
4306         /* Find the triples */
4307         left = ptr->left;
4308         right = ptr->right;
4309
4310         /* Generate the needed triples */
4311         end = label(state);
4312
4313         /* Thread the triples together */
4314         val         = flatten(state, first, variable(state, ptr->type));
4315         left        = flatten(state, first, write_expr(state, val, left));
4316         jmp         = flatten(state, first, 
4317                 triple(state, OP_BRANCH, &void_type, end, left));
4318         label1      = flatten(state, first, label(state));
4319         right       = flatten(state, first, write_expr(state, val, right));
4320         jmp->left   = flatten(state, first, end);
4321        
4322         
4323         /* Now give the caller something to chew on */
4324         return read_expr(state, val);
4325 }
4326
4327 static struct triple *flatten_cond(
4328         struct compile_state *state, struct triple *first, struct triple *ptr)
4329 {
4330         struct triple *test, *left, *right;
4331         struct triple *val, *mv1, *jmp1, *label1, *mv2, *middle, *jmp2, *end;
4332         if (ptr->right->op != OP_PRODUCT) {
4333                 internal_error(state, 0, "Improper conditional expression");
4334         }
4335
4336         /* Find the triples */
4337         test = ptr->left;
4338         left = ptr->right->left;
4339         right = ptr->right->right;
4340
4341         /* Generate the needed triples */
4342         end = label(state);
4343         middle = label(state);
4344
4345         /* Thread the triples together */
4346         val         = flatten(state, first, variable(state, ptr->type));
4347         test        = flatten(state, first, test);
4348         jmp1        = flatten(state, first, 
4349                 triple(state, OP_BRANCH, &void_type, middle, test));
4350         label1      = flatten(state, first, label(state));
4351         left        = flatten(state, first, left);
4352         mv1         = flatten(state, first, write_expr(state, val, left));
4353         jmp2        = flatten(state, first, 
4354                 triple(state, OP_BRANCH, &void_type, end, 0));
4355         jmp1->left  = flatten(state, first, middle);
4356         right       = flatten(state, first, right);
4357         mv2         = flatten(state, first, write_expr(state, val, right));
4358         jmp2->left  = flatten(state, first, end);
4359        
4360         
4361         /* Now give the caller something to chew on */
4362         return read_expr(state, val);
4363 }
4364
4365 struct triple *copy_func(struct compile_state *state, struct triple *ofunc)
4366 {
4367         struct triple *nfunc;
4368         struct triple *nfirst, *ofirst;
4369         struct triple *new, *old;
4370
4371 #if 0
4372         fprintf(stdout, "\n");
4373         loc(stdout, state, 0);
4374         fprintf(stdout, "\n__________ copy_func _________\n");
4375         print_triple(state, ofunc);
4376         fprintf(stdout, "__________ copy_func _________ done\n\n");
4377 #endif
4378
4379         /* Make a new copy of the old function */
4380         nfunc = triple(state, OP_LIST, ofunc->type, 0, 0);
4381         nfirst = 0;
4382         ofirst = old = ofunc->left;
4383         do {
4384                 struct triple *new;
4385                 new = build_triple(state, old->op, old->type, 0, 0, 
4386                         old->filename, old->line, old->col);
4387                 if (IS_CONST_OP(new->op)) {
4388                         memcpy(&new->u, &old->u, sizeof(new->u));
4389                 }
4390 #warning "WISHLIST find a way to handle SDECL without a special case..."
4391                 else if (new->op == OP_SDECL) {
4392                         new->left = old->left;
4393                 }
4394                 if (!nfirst) {
4395                         nfunc->left = nfirst = new;
4396                 }
4397                 else {
4398                         insert_triple(state, nfirst, new);
4399                 }
4400                 
4401                 /* During the copy remember new as user of old */
4402                 use_triple(old, new);
4403
4404                 /* Populate the return type if present */
4405                 if (old == ofunc->right) {
4406                         nfunc->right = new;
4407                 }
4408                 old = old->next;
4409         } while(old != ofirst);
4410
4411         /* Make a second pass to fix up any unresolved references */
4412         old = ofirst;
4413         new = nfirst;
4414         do {
4415                 /* Lookup where the copy is, to join pointers */
4416                 if (!new->left && old->left && old->left->use) {
4417                         new->left = old->left->use->member;
4418                         if (new->left == old) {
4419                                 internal_error(state, 0, "new == old?");
4420                         }
4421                 }
4422                 if (!new->right && old->right && old->right->use) {
4423                         new->right = old->right->use->member;
4424                         if (new->right == old) {
4425                                 internal_error(state, 0, "new == old?");
4426                         }
4427                 }
4428                 if (!new->left && old->left) {
4429                         internal_error(state, 0, "Could not copy left");
4430                 }
4431                 if (!new->right && old->right) {
4432                         internal_error(state, 0, "Could not copy right");
4433                 }
4434                 if (new->op != old->op) {
4435                         internal_error(state, 0, "Could not copy op?");
4436                 }
4437                 if (!new->next && old->next) {
4438                         internal_error(state, 0, "Could not copy next");
4439                 }
4440                 use_triple(new->left, new);
4441                 use_triple(new->right, new);
4442                 if (new->op == OP_BRANCH) {
4443                         if (new->right) {
4444                                 use_triple(new->next, new);
4445                         }
4446                 }
4447                 old = old->next;
4448                 new = new->next;
4449         } while((old != ofirst) && (new != nfirst));
4450         
4451         /* Make a third pass to cleanup the extra useses */
4452         old = ofirst;
4453         new = nfirst;
4454         do {
4455                 unuse_triple(old, new);
4456                 old = old->next;
4457                 new = new->next;
4458         } while ((old != ofirst) && (new != nfirst));
4459         return nfunc;
4460 }
4461
4462 static struct triple *flatten_call(
4463         struct compile_state *state, struct triple *first, struct triple *ptr)
4464 {
4465         /* Inline the function call */
4466         struct triple *ofunc, *nfunc, *nfirst, *args, *param, *result;
4467         struct triple *end, *nend;
4468         int done;
4469
4470         /* Find the triples */
4471         ofunc = ptr->left;
4472         args  = ptr->right;
4473         if (ofunc->op != OP_LIST) {
4474                 internal_error(state, 0, "improper function");
4475         }
4476         nfunc = copy_func(state, ofunc);
4477         nfirst = nfunc->left->next;
4478         param = nfunc->left->next;
4479         /* Prepend the parameter reading into the new function list */
4480         while(args) {
4481                 struct triple *arg;
4482                 arg = args;
4483                 done = 1;
4484                 if (args->op == OP_PRODUCT) {
4485                         arg = args->left;
4486                 }
4487                 flatten(state, nfirst,
4488                         write_expr(state, param, arg));
4489                 param = param->next;
4490                 args = (args->op == OP_PRODUCT)? args->right : 0;
4491         } 
4492         result = 0;
4493         if ((nfunc->type->left->type & TYPE_MASK) != TYPE_VOID) {
4494                 result = read_expr(state, nfunc->right);
4495         }
4496 #if 0
4497         fprintf(stdout, "\n");
4498         loc(stdout, state, 0);
4499         fprintf(stdout, "\n__________ flatten_call _________\n");
4500         print_triple(state, nfunc);
4501         fprintf(stdout, "__________ flatten_call _________ done\n\n");
4502 #endif
4503
4504         /* Get rid of the extra triples */
4505         nfirst = nfunc->left->next;
4506         free_triple(state, nfunc->left); 
4507         nfunc->left = 0;
4508         free_triple(state, nfunc);
4509
4510         /* Append the new function list onto the return list */
4511         end = first->prev;
4512         nend = nfirst->prev;
4513         end->next    = nfirst;
4514         nfirst->prev = end;
4515         nend->next   = first;
4516         first->prev  = nend;
4517
4518         return result;
4519 }
4520
4521 static struct triple *flatten(
4522         struct compile_state *state, struct triple *first, struct triple *ptr)
4523 {
4524         struct triple *orig_ptr;
4525         if (!ptr)
4526                 return 0;
4527         do {
4528                 orig_ptr = ptr;
4529                 switch(ptr->op) {
4530                 case OP_WRITE:
4531                 case OP_STORE:
4532                         ptr->right = flatten(state, first, ptr->right);
4533                         ptr->left = flatten(state, first, ptr->left);
4534                         use_triple(ptr->left, ptr);
4535                         use_triple(ptr->right, ptr);
4536                         break;
4537                 case OP_COMMA:
4538                         ptr->left = flatten(state, first, ptr->left);
4539                         ptr = ptr->right;
4540                         break;
4541                 case OP_VAL:
4542                         ptr->left = flatten(state, first, ptr->left);
4543                         return ptr->right;
4544                         break;
4545                 case OP_LAND:
4546                         ptr = flatten_land(state, first, ptr);
4547                         break;
4548                 case OP_LOR:
4549                         ptr = flatten_lor(state, first, ptr);
4550                         break;
4551                 case OP_COND:
4552                         ptr = flatten_cond(state, first, ptr);
4553                         break;
4554                 case OP_CALL:
4555                         ptr = flatten_call(state, first, ptr);
4556                         break;
4557                 case OP_READ:
4558                 case OP_LOAD:
4559                         ptr->left = flatten(state, first, ptr->left);
4560                         use_triple(ptr->left, ptr);
4561                         break;
4562                 case OP_BRANCH:
4563                         use_triple(ptr->left, ptr);
4564                         use_triple(ptr->right, ptr);
4565                         if (ptr->next != ptr) {
4566                                 use_triple(ptr->next, ptr);
4567                         }
4568                         break;
4569                 case OP_ADDRCONST:
4570                         ptr->left = flatten(state, first, ptr->left);
4571                         use_triple(ptr->left, ptr);
4572                         break;
4573                 case OP_BLOBCONST:
4574                         ptr = triple(state, OP_SDECL, ptr->type, ptr, 0);
4575                         use_triple(ptr->left, ptr);
4576                         break;
4577                 case OP_DEREF:
4578                         /* Since OP_DEREF is just a marker delete it when I flatten it */
4579                         ptr = ptr->left;
4580                         orig_ptr->left = 0;
4581                         free_triple(state, orig_ptr);
4582                         break;
4583                 case OP_PRODUCT:
4584                 case OP_DOT:
4585                         internal_error(state, 0, "unknown expression type: %d %s",
4586                                 ptr->op, tops(ptr->op));
4587                         break;
4588                 case OP_SDECL:
4589                 case OP_ADECL:
4590                         /* Don't flatten already flattened decls */
4591                         if ((ptr->next != ptr) || (ptr->prev != ptr)) {
4592                                 return ptr;
4593                         }
4594                         break;
4595                 default:
4596                         /* Flatten the easy cases we don't override */
4597                         ptr = flatten_rhs(state, first, ptr);
4598                         break;
4599                 }
4600         } while(ptr && (ptr != orig_ptr));
4601         insert_triple(state, first, ptr);
4602         return ptr;
4603 }
4604
4605 static void release_expr(struct compile_state *state, struct triple *expr)
4606 {
4607         struct triple *head;
4608         head = label(state);
4609         flatten(state, head, expr);
4610         while(head->next != head) {
4611                 release_triple(state, head->next);
4612         }
4613         free_triple(state, head);
4614 }
4615
4616 static int replace_rhs_use(struct compile_state *state,
4617         struct triple *orig, struct triple *new, struct triple *use)
4618 {
4619         struct triple **expr;
4620         int found;
4621         found = 0;
4622         expr = triple_rhs(state, use, 0);
4623         for(;expr; expr = triple_rhs(state, use, expr)) {
4624                 if (*expr == orig) {
4625                         *expr = new;
4626                         found = 1;
4627                 }
4628         }
4629         if (found) {
4630                 unuse_triple(orig, use);
4631                 use_triple(new, use);
4632         }
4633         return found;
4634 }
4635
4636 static int replace_lhs_use(struct compile_state *state,
4637         struct triple *orig, struct triple *new, struct triple *use)
4638 {
4639         struct triple **expr;
4640         int found;
4641         found = 0;
4642         expr = triple_lhs(state, use, 0);
4643         for(;expr; expr = triple_lhs(state, use, expr)) {
4644                 if (*expr == orig) {
4645                         *expr = new;
4646                         found = 1;
4647                 }
4648         }
4649         if (found) {
4650                 unuse_triple(orig, use);
4651                 use_triple(new, use);
4652         }
4653         return found;
4654 }
4655
4656 static void propogate_use(struct compile_state *state,
4657         struct triple *orig, struct triple *new)
4658 {
4659         struct triple_set *user, *next;
4660         for(user = orig->use; user; user = next) {
4661                 struct triple *use;
4662                 int found;
4663                 next = user->next;
4664                 use = user->member;
4665                 found = 0;
4666                 found |= replace_rhs_use(state, orig, new, use);
4667                 found |= replace_lhs_use(state, orig, new, use);
4668                 if (!found) {
4669                         internal_error(state, use, "use without use");
4670                 }
4671         }
4672         if (orig->use) {
4673                 internal_error(state, orig, "used after propogate_use");
4674         }
4675 }
4676
4677 /*
4678  * Code generators
4679  * ===========================
4680  */
4681
4682 static struct triple *mk_add_expr(
4683         struct compile_state *state, struct triple *left, struct triple *right)
4684 {
4685         struct type *result_type;
4686         /* Put pointer operands on the left */
4687         if (is_pointer(right)) {
4688                 struct triple *tmp;
4689                 tmp = left;
4690                 left = right;
4691                 right = tmp;
4692         }
4693         result_type = ptr_arithmetic_result(state, left, right);
4694         left  = read_expr(state, left);
4695         right = read_expr(state, right);
4696         if (is_pointer(left)) {
4697                 right = triple(state, 
4698                         is_signed(right->type)? OP_SMUL : OP_UMUL, 
4699                         &ulong_type, 
4700                         right, 
4701                         int_const(state, &ulong_type, 
4702                                 size_of(state, left->type->left)));
4703         }
4704         return triple(state, OP_ADD, result_type, left, right);
4705 }
4706
4707 static struct triple *mk_sub_expr(
4708         struct compile_state *state, struct triple *left, struct triple *right)
4709 {
4710         struct type *result_type;
4711         result_type = ptr_arithmetic_result(state, left, right);
4712         left  = read_expr(state, left);
4713         right = read_expr(state, right);
4714         if (is_pointer(left)) {
4715                 right = triple(state, 
4716                         is_signed(right->type)? OP_SMUL : OP_UMUL, 
4717                         &ulong_type, 
4718                         right, 
4719                         int_const(state, &ulong_type, 
4720                                 size_of(state, left->type->left)));
4721         }
4722         return triple(state, OP_SUB, result_type, left, right);
4723 }
4724
4725 static struct triple *mk_pre_inc_expr(
4726         struct compile_state *state, struct triple *def)
4727 {
4728         struct triple *val;
4729         lvalue(state, def);
4730         val = mk_add_expr(state, def, int_const(state, &int_type, 1));
4731         return triple(state, OP_VAL, def->type,
4732                 write_expr(state, def, val),
4733                 val);
4734 }
4735
4736 static struct triple *mk_pre_dec_expr(
4737         struct compile_state *state, struct triple *def)
4738 {
4739         struct triple *val;
4740         lvalue(state, def);
4741         val = mk_sub_expr(state, def, int_const(state, &int_type, 1));
4742         return triple(state, OP_VAL, def->type,
4743                 write_expr(state, def, val),
4744                 val);
4745 }
4746
4747 static struct triple *mk_post_inc_expr(
4748         struct compile_state *state, struct triple *def)
4749 {
4750         struct triple *val;
4751         lvalue(state, def);
4752         val = read_expr(state, def);
4753         return triple(state, OP_VAL, def->type,
4754                 write_expr(state, def,
4755                         mk_add_expr(state, val, int_const(state, &int_type, 1)))
4756                 , val);
4757 }
4758
4759 static struct triple *mk_post_dec_expr(
4760         struct compile_state *state, struct triple *def)
4761 {
4762         struct triple *val;
4763         lvalue(state, def);
4764         val = read_expr(state, def);
4765         return triple(state, OP_VAL, def->type, 
4766                 write_expr(state, def,
4767                         mk_sub_expr(state, val, int_const(state, &int_type, 1)))
4768                 , val);
4769 }
4770
4771 static struct triple *mk_subscript_expr(
4772         struct compile_state *state, struct triple *left, struct triple *right)
4773 {
4774         left  = read_expr(state, left);
4775         right = read_expr(state, right);
4776         if (!is_pointer(left) && !is_pointer(right)) {
4777                 error(state, left, "subscripted value is not a pointer");
4778         }
4779         return mk_deref_expr(state, mk_add_expr(state, left, right));
4780 }
4781
4782 /*
4783  * Compile time evaluation
4784  * ===========================
4785  */
4786 static int is_const(struct triple *ins)
4787 {
4788         return IS_CONST_OP(ins->op);
4789 }
4790
4791 static int constants_equal(struct compile_state *state, 
4792         struct triple *left, struct triple *right)
4793 {
4794         int equal;
4795         if (!is_const(left) || !is_const(right)) {
4796                 equal = 0;
4797         }
4798         else if (left->op != right->op) {
4799                 equal = 0;
4800         }
4801         else if (!equiv_types(left->type, right->type)) {
4802                 equal = 0;
4803         }
4804         else {
4805                 equal = 0;
4806                 switch(left->op) {
4807                 case OP_INTCONST:
4808                         if (left->u.cval == right->u.cval) {
4809                                 equal = 1;
4810                         }
4811                         break;
4812                 case OP_BLOBCONST:
4813                 {
4814                         size_t lsize, rsize;
4815                         lsize = size_of(state, left->type);
4816                         rsize = size_of(state, right->type);
4817                         if (lsize != rsize) {
4818                                 break;
4819                         }
4820                         if (memcmp(left->u.blob, right->u.blob, lsize) == 0) {
4821                                 equal = 1;
4822                         }
4823                         break;
4824                 }
4825                 case OP_ADDRCONST:
4826                         if ((left->left == right->left) &&
4827                                 (left->u.cval == right->u.cval)) {
4828                                 equal = 1;
4829                         }
4830                         break;
4831                 default:
4832                         internal_error(state, left, "uknown constant type");
4833                         break;
4834                 }
4835         }
4836         return equal;
4837 }
4838
4839 static int is_zero(struct triple *ins)
4840 {
4841         return is_const(ins) && (ins->u.cval == 0);
4842 }
4843
4844 static int is_one(struct triple *ins)
4845 {
4846         return is_const(ins) && (ins->u.cval == 1);
4847 }
4848
4849 static long_t bsr(ulong_t value)
4850 {
4851         int i;
4852         for(i = (sizeof(ulong_t)*8) -1; i >= 0; i--) {
4853                 ulong_t mask;
4854                 mask = 1;
4855                 mask <<= i;
4856                 if (value & mask) {
4857                         return i;
4858                 }
4859         }
4860         return -1;
4861 }
4862
4863 static long_t bsf(ulong_t value)
4864 {
4865         int i;
4866         for(i = 0; i < (sizeof(ulong_t)*8); i++) {
4867                 ulong_t mask;
4868                 mask = 1;
4869                 mask <<= 1;
4870                 if (value & mask) {
4871                         return i;
4872                 }
4873         }
4874         return -1;
4875 }
4876
4877 static long_t log2(ulong_t value)
4878 {
4879         return bsr(value);
4880 }
4881
4882 static long_t tlog2(struct triple *ins)
4883 {
4884         return log2(ins->u.cval);
4885 }
4886
4887 static int is_pow2(struct triple *ins)
4888 {
4889         ulong_t value, mask;
4890         long_t log;
4891         if (!is_const(ins)) {
4892                 return 0;
4893         }
4894         value = ins->u.cval;
4895         log = log2(value);
4896         if (log == -1) {
4897                 return 0;
4898         }
4899         mask = 1;
4900         mask <<= log;
4901         return  ((value & mask) == value);
4902 }
4903
4904 static ulong_t read_const(struct compile_state *state,
4905         struct triple *ins, struct triple **expr)
4906 {
4907         struct triple *rhs;
4908         rhs = *expr;
4909         switch(rhs->type->type &TYPE_MASK) {
4910         case TYPE_CHAR:   
4911         case TYPE_SHORT:
4912         case TYPE_INT:
4913         case TYPE_LONG:
4914         case TYPE_UCHAR:   
4915         case TYPE_USHORT:  
4916         case TYPE_UINT:
4917         case TYPE_ULONG:
4918         case TYPE_POINTER:
4919                 break;
4920         default:
4921                 internal_error(state, rhs, "bad type to read_const\n");
4922                 break;
4923         }
4924         return rhs->u.cval;
4925 }
4926
4927 static long_t read_sconst(struct triple *ins, struct triple **expr)
4928 {
4929         struct triple *rhs;
4930         rhs = *expr;
4931         return (long_t)(rhs->u.cval);
4932 }
4933
4934 static void unuse_rhs(struct compile_state *state, struct triple *ins)
4935 {
4936         struct triple **expr;
4937         expr = triple_rhs(state, ins, 0);
4938         for(;expr;expr = triple_rhs(state, ins, expr)) {
4939                 unuse_triple(*expr, ins);
4940                 *expr = 0;
4941         }
4942 }
4943 static void check_lhs(struct compile_state *state, struct triple *ins)
4944 {
4945         struct triple **expr;
4946         expr = triple_lhs(state, ins, 0);
4947         for(;expr;expr = triple_lhs(state, ins, expr)) {
4948                 internal_error(state, ins, "unexpected lhs");
4949         }
4950         
4951 }
4952 static void check_targ(struct compile_state *state, struct triple *ins)
4953 {
4954         struct triple **expr;
4955         expr = triple_targ(state, ins, 0);
4956         for(;expr;expr = triple_targ(state, ins, expr)) {
4957                 internal_error(state, ins, "unexpected targ");
4958         }
4959 }
4960
4961 static void wipe_ins(struct compile_state *state, struct triple *ins)
4962 {
4963         check_lhs(state, ins);
4964         check_targ(state, ins);
4965         unuse_rhs(state, ins);
4966         if (ins->op == OP_PHI) {
4967                 xfree(ins->left);
4968                 ins->left = 0;
4969         }
4970 }
4971
4972 static void mkcopy(struct compile_state *state, 
4973         struct triple *ins, struct triple *rhs)
4974 {
4975         wipe_ins(state, ins);
4976         ins->op = OP_COPY;
4977         ins->left = rhs;
4978         use_triple(ins->left, ins);
4979 }
4980
4981 static void mkconst(struct compile_state *state, 
4982         struct triple *ins, ulong_t value)
4983 {
4984         if (!is_integral(ins) && !is_pointer(ins)) {
4985                 internal_error(state, ins, "unknown type to make constant\n");
4986         }
4987         wipe_ins(state, ins);
4988         ins->op = OP_INTCONST;
4989         ins->u.cval = value;
4990 }
4991
4992 static void mkaddr_const(struct compile_state *state,
4993         struct triple *ins, struct triple *sdecl, ulong_t value)
4994 {
4995         wipe_ins(state, ins);
4996         ins->op = OP_ADDRCONST;
4997         ins->left = sdecl;
4998         ins->u.cval = value;
4999         use_triple(sdecl, ins);
5000 }
5001
5002 /* For those operations that cannot be simplified */
5003 static void simplify_noop(struct compile_state *state, struct triple *ins)
5004 {
5005         return;
5006 }
5007
5008 static void simplify_smul(struct compile_state *state, struct triple *ins)
5009 {
5010         if (is_const(ins->left) && !is_const(ins->right)) {
5011                 struct triple *tmp;
5012                 tmp = ins->left;
5013                 ins->left = ins->right;
5014                 ins->right = tmp;
5015         }
5016         if (is_const(ins->left) && is_const(ins->right)) {
5017                 long_t left, right;
5018                 left  = read_sconst(ins, &ins->left);
5019                 right = read_sconst(ins, &ins->right);
5020                 mkconst(state, ins, left * right);
5021         }
5022         else if (is_zero(ins->right)) {
5023                 mkconst(state, ins, 0);
5024         }
5025         else if (is_one(ins->right)) {
5026                 mkcopy(state, ins, ins->left);
5027         }
5028         else if (is_pow2(ins->right)) {
5029                 struct triple *val;
5030                 val = int_const(state, ins->type, tlog2(ins->right));
5031                 ins->op = OP_SL;
5032                 insert_triple(state, ins, val);
5033                 unuse_triple(ins->right, ins);
5034                 use_triple(val, ins);
5035                 ins->right = val;
5036         }
5037 }
5038
5039 static void simplify_umul(struct compile_state *state, struct triple *ins)
5040 {
5041         if (is_const(ins->left) && !is_const(ins->right)) {
5042                 struct triple *tmp;
5043                 tmp = ins->left;
5044                 ins->left = ins->right;
5045                 ins->right = tmp;
5046         }
5047         if (is_const(ins->left) && is_const(ins->right)) {
5048                 ulong_t left, right;
5049                 left  = read_const(state, ins, &ins->left);
5050                 right = read_const(state, ins, &ins->right);
5051                 mkconst(state, ins, left * right);
5052         }
5053         else if (is_zero(ins->right)) {
5054                 mkconst(state, ins, 0);
5055         }
5056         else if (is_one(ins->right)) {
5057                 mkcopy(state, ins, ins->left);
5058         }
5059         else if (is_pow2(ins->right)) {
5060                 struct triple *val;
5061                 val = int_const(state, ins->type, tlog2(ins->right));
5062                 ins->op = OP_SL;
5063                 insert_triple(state, ins, val);
5064                 unuse_triple(ins->right, ins);
5065                 use_triple(val, ins);
5066                 ins->right = val;
5067         }
5068 }
5069
5070 static void simplify_sdiv(struct compile_state *state, struct triple *ins)
5071 {
5072         if (is_const(ins->left) && is_const(ins->right)) {
5073                 long_t left, right;
5074                 left  = read_sconst(ins, &ins->left);
5075                 right = read_sconst(ins, &ins->right);
5076                 mkconst(state, ins, left / right);
5077         }
5078         else if (is_zero(ins->left)) {
5079                 mkconst(state, ins, 0);
5080         }
5081         else if (is_zero(ins->right)) {
5082                 error(state, ins, "division by zero");
5083         }
5084         else if (is_one(ins->right)) {
5085                 mkcopy(state, ins, ins->left);
5086         }
5087         else if (is_pow2(ins->right)) {
5088                 struct triple *val;
5089                 val = int_const(state, ins->type, tlog2(ins->right));
5090                 ins->op = OP_SSR;
5091                 insert_triple(state, ins, val);
5092                 unuse_triple(ins->right, ins);
5093                 use_triple(val, ins);
5094                 ins->right = val;
5095         }
5096 }
5097
5098 static void simplify_udiv(struct compile_state *state, struct triple *ins)
5099 {
5100         if (is_const(ins->left) && is_const(ins->right)) {
5101                 ulong_t left, right;
5102                 left  = read_const(state, ins, &ins->left);
5103                 right = read_const(state, ins, &ins->right);
5104                 mkconst(state, ins, left / right);
5105         }
5106         else if (is_zero(ins->left)) {
5107                 mkconst(state, ins, 0);
5108         }
5109         else if (is_zero(ins->right)) {
5110                 error(state, ins, "division by zero");
5111         }
5112         else if (is_one(ins->right)) {
5113                 mkcopy(state, ins, ins->left);
5114         }
5115         else if (is_pow2(ins->right)) {
5116                 struct triple *val;
5117                 val = int_const(state, ins->type, tlog2(ins->right));
5118                 ins->op = OP_USR;
5119                 insert_triple(state, ins, val);
5120                 unuse_triple(ins->right, ins);
5121                 use_triple(val, ins);
5122                 ins->right = val;
5123         }
5124 }
5125
5126 static void simplify_smod(struct compile_state *state, struct triple *ins)
5127 {
5128         if (is_const(ins->left) && is_const(ins->right)) {
5129                 long_t left, right;
5130                 left  = read_const(state, ins, &ins->left);
5131                 right = read_const(state, ins, &ins->right);
5132                 mkconst(state, ins, left % right);
5133         }
5134         else if (is_zero(ins->left)) {
5135                 mkconst(state, ins, 0);
5136         }
5137         else if (is_zero(ins->right)) {
5138                 error(state, ins, "division by zero");
5139         }
5140         else if (is_one(ins->right)) {
5141                 mkconst(state, ins, 0);
5142         }
5143         else if (is_pow2(ins->right)) {
5144                 struct triple *val;
5145                 val = int_const(state, ins->type, ins->right->u.cval - 1);
5146                 ins->op = OP_AND;
5147                 insert_triple(state, ins, val);
5148                 unuse_triple(ins->right, ins);
5149                 use_triple(val, ins);
5150                 ins->right = val;
5151         }
5152 }
5153 static void simplify_umod(struct compile_state *state, struct triple *ins)
5154 {
5155         if (is_const(ins->left) && is_const(ins->right)) {
5156                 ulong_t left, right;
5157                 left  = read_const(state, ins, &ins->left);
5158                 right = read_const(state, ins, &ins->right);
5159                 mkconst(state, ins, left % right);
5160         }
5161         else if (is_zero(ins->left)) {
5162                 mkconst(state, ins, 0);
5163         }
5164         else if (is_zero(ins->right)) {
5165                 error(state, ins, "division by zero");
5166         }
5167         else if (is_one(ins->right)) {
5168                 mkconst(state, ins, 0);
5169         }
5170         else if (is_pow2(ins->right)) {
5171                 struct triple *val;
5172                 val = int_const(state, ins->type, ins->right->u.cval - 1);
5173                 ins->op = OP_AND;
5174                 insert_triple(state, ins, val);
5175                 unuse_triple(ins->right, ins);
5176                 use_triple(val, ins);
5177                 ins->right = val;
5178         }
5179 }
5180
5181 static void simplify_add(struct compile_state *state, struct triple *ins)
5182 {
5183         /* start with the pointer on the left */
5184         if (is_pointer(ins->right)) {
5185                 struct triple *tmp;
5186                 tmp = ins->left;
5187                 ins->left = ins->right;
5188                 ins->right = tmp;
5189         }
5190         if (is_const(ins->left) && is_const(ins->right)) {
5191                 if (!is_pointer(ins->left)) {
5192                         ulong_t left, right;
5193                         left  = read_const(state, ins, &ins->left);
5194                         right = read_const(state, ins, &ins->right);
5195                         mkconst(state, ins, left + right);
5196                 }
5197                 else {
5198                         struct triple *sdecl;
5199                         ulong_t left, right;
5200                         sdecl = ins->left->left;
5201                         left  = ins->left->u.cval;
5202                         right = ins->right->u.cval;
5203                         mkaddr_const(state, ins, sdecl, left + right);
5204                 }
5205         }
5206         else if (is_const(ins->left) && !is_const(ins->right)) {
5207                 struct triple *tmp;
5208                 tmp = ins->right;
5209                 ins->right = ins->left;
5210                 ins->left  = tmp;
5211         }
5212 }
5213
5214 static void simplify_sub(struct compile_state *state, struct triple *ins)
5215 {
5216         if (is_const(ins->left) && is_const(ins->right)) {
5217                 if (!is_pointer(ins->left)) {
5218                         ulong_t left, right;
5219                         left  = read_const(state, ins, &ins->left);
5220                         right = read_const(state, ins, &ins->right);
5221                         mkconst(state, ins, left - right);
5222                 }
5223                 else {
5224                         struct triple *sdecl;
5225                         ulong_t left, right;
5226                         sdecl = ins->left->left;
5227                         left  = ins->left->u.cval;
5228                         right = ins->right->u.cval;
5229                         mkaddr_const(state, ins, sdecl, left - right);
5230                 }
5231         }
5232 }
5233
5234 static void simplify_sl(struct compile_state *state, struct triple *ins)
5235 {
5236         if (is_const(ins->right)) {
5237                 ulong_t right;
5238                 right = read_const(state, ins, &ins->right);
5239                 if (right >= (size_of(state, ins->type)*8)) {
5240                         warning(state, ins, "left shift count >= width of type");
5241                 }
5242         }
5243         if (is_const(ins->left) && is_const(ins->right)) {
5244                 ulong_t left, right;
5245                 left  = read_const(state, ins, &ins->left);
5246                 right = read_const(state, ins, &ins->right);
5247                 mkconst(state, ins,  left << right);
5248         }
5249 }
5250
5251 static void simplify_usr(struct compile_state *state, struct triple *ins)
5252 {
5253         if (is_const(ins->right)) {
5254                 ulong_t right;
5255                 right = read_const(state, ins, &ins->right);
5256                 if (right >= (size_of(state, ins->type)*8)) {
5257                         warning(state, ins, "right shift count >= width of type");
5258                 }
5259         }
5260         if (is_const(ins->left) && is_const(ins->right)) {
5261                 ulong_t left, right;
5262                 left  = read_const(state, ins, &ins->left);
5263                 right = read_const(state, ins, &ins->right);
5264                 mkconst(state, ins, left >> right);
5265         }
5266 }
5267
5268 static void simplify_ssr(struct compile_state *state, struct triple *ins)
5269 {
5270         if (is_const(ins->right)) {
5271                 ulong_t right;
5272                 right = read_const(state, ins, &ins->right);
5273                 if (right >= (size_of(state, ins->type)*8)) {
5274                         warning(state, ins, "right shift count >= width of type");
5275                 }
5276         }
5277         if (is_const(ins->left) && is_const(ins->right)) {
5278                 long_t left, right;
5279                 left  = read_sconst(ins, &ins->left);
5280                 right = read_sconst(ins, &ins->right);
5281                 mkconst(state, ins, left >> right);
5282         }
5283 }
5284
5285 static void simplify_and(struct compile_state *state, struct triple *ins)
5286 {
5287         if (is_const(ins->left) && is_const(ins->right)) {
5288                 ulong_t left, right;
5289                 left  = read_const(state, ins, &ins->left);
5290                 right = read_const(state, ins, &ins->right);
5291                 mkconst(state, ins, left & right);
5292         }
5293 }
5294
5295 static void simplify_or(struct compile_state *state, struct triple *ins)
5296 {
5297         if (is_const(ins->left) && is_const(ins->right)) {
5298                 ulong_t left, right;
5299                 left  = read_const(state, ins, &ins->left);
5300                 right = read_const(state, ins, &ins->right);
5301                 mkconst(state, ins, left | right);
5302         }
5303 }
5304
5305 static void simplify_xor(struct compile_state *state, struct triple *ins)
5306 {
5307         if (is_const(ins->left) && is_const(ins->right)) {
5308                 ulong_t left, right;
5309                 left  = read_const(state, ins, &ins->left);
5310                 right = read_const(state, ins, &ins->right);
5311                 mkconst(state, ins, left ^ right);
5312         }
5313 }
5314
5315 static void simplify_pos(struct compile_state *state, struct triple *ins)
5316 {
5317         if (is_const(ins->left)) {
5318                 mkconst(state, ins, ins->left->u.cval);
5319         }
5320         else {
5321                 mkcopy(state, ins, ins->left);
5322         }
5323 }
5324
5325 static void simplify_neg(struct compile_state *state, struct triple *ins)
5326 {
5327         if (is_const(ins->left)) {
5328                 ulong_t left;
5329                 left = read_const(state, ins, &ins->left);
5330                 mkconst(state, ins, -left);
5331         }
5332         else if (ins->left->op == OP_NEG) {
5333                 mkcopy(state, ins, ins->left->left);
5334         }
5335 }
5336
5337 static void simplify_invert(struct compile_state *state, struct triple *ins)
5338 {
5339         if (is_const(ins->left)) {
5340                 ulong_t left;
5341                 left = read_const(state, ins, &ins->left);
5342                 mkconst(state, ins, ~left);
5343         }
5344 }
5345
5346 static void simplify_eq(struct compile_state *state, struct triple *ins)
5347 {
5348         if (is_const(ins->left) && is_const(ins->right)) {
5349                 ulong_t left, right;
5350                 left  = read_const(state, ins, &ins->left);
5351                 right = read_const(state, ins, &ins->right);
5352                 mkconst(state, ins, left == right);
5353         }
5354         else if (ins->left == ins->right) {
5355                 mkconst(state, ins, 1);
5356         }
5357 }
5358
5359 static void simplify_noteq(struct compile_state *state, struct triple *ins)
5360 {
5361         if (is_const(ins->left) && is_const(ins->right)) {
5362                 ulong_t left, right;
5363                 left  = read_const(state, ins, &ins->left);
5364                 right = read_const(state, ins, &ins->right);
5365                 mkconst(state, ins, left != right);
5366         }
5367         else if (ins->left == ins->right) {
5368                 mkconst(state, ins, 0);
5369         }
5370 }
5371
5372 static void simplify_sless(struct compile_state *state, struct triple *ins)
5373 {
5374         if (is_const(ins->left) && is_const(ins->right)) {
5375                 long_t left, right;
5376                 left  = read_sconst(ins, &ins->left);
5377                 right = read_sconst(ins, &ins->right);
5378                 mkconst(state, ins, left < right);
5379         }
5380         else if (ins->left == ins->right) {
5381                 mkconst(state, ins, 0);
5382         }
5383 }
5384
5385 static void simplify_uless(struct compile_state *state, struct triple *ins)
5386 {
5387         if (is_const(ins->left) && is_const(ins->right)) {
5388                 ulong_t left, right;
5389                 left  = read_const(state, ins, &ins->left);
5390                 right = read_const(state, ins, &ins->right);
5391                 mkconst(state, ins, left < right);
5392         }
5393         else if (is_zero(ins->left)) {
5394                 mkconst(state, ins, 1);
5395         }
5396         else if (ins->left == ins->right) {
5397                 mkconst(state, ins, 0);
5398         }
5399 }
5400
5401 static void simplify_smore(struct compile_state *state, struct triple *ins)
5402 {
5403         if (is_const(ins->left) && is_const(ins->right)) {
5404                 long_t left, right;
5405                 left  = read_sconst(ins, &ins->left);
5406                 right = read_sconst(ins, &ins->right);
5407                 mkconst(state, ins, left > right);
5408         }
5409         else if (ins->left == ins->right) {
5410                 mkconst(state, ins, 0);
5411         }
5412 }
5413
5414 static void simplify_umore(struct compile_state *state, struct triple *ins)
5415 {
5416         if (is_const(ins->left) && is_const(ins->right)) {
5417                 ulong_t left, right;
5418                 left  = read_const(state, ins, &ins->left);
5419                 right = read_const(state, ins, &ins->right);
5420                 mkconst(state, ins, left > right);
5421         }
5422         else if (is_zero(ins->right)) {
5423                 mkconst(state, ins, 1);
5424         }
5425         else if (ins->left == ins->right) {
5426                 mkconst(state, ins, 0);
5427         }
5428 }
5429
5430
5431 static void simplify_slesseq(struct compile_state *state, struct triple *ins)
5432 {
5433         if (is_const(ins->left) && is_const(ins->right)) {
5434                 long_t left, right;
5435                 left  = read_sconst(ins, &ins->left);
5436                 right = read_sconst(ins, &ins->right);
5437                 mkconst(state, ins, left <= right);
5438         }
5439         else if (ins->left == ins->right) {
5440                 mkconst(state, ins, 1);
5441         }
5442 }
5443
5444 static void simplify_ulesseq(struct compile_state *state, struct triple *ins)
5445 {
5446         if (is_const(ins->left) && is_const(ins->right)) {
5447                 ulong_t left, right;
5448                 left  = read_const(state, ins, &ins->left);
5449                 right = read_const(state, ins, &ins->right);
5450                 mkconst(state, ins, left <= right);
5451         }
5452         else if (is_zero(ins->left)) {
5453                 mkconst(state, ins, 1);
5454         }
5455         else if (ins->left == ins->right) {
5456                 mkconst(state, ins, 1);
5457         }
5458 }
5459
5460 static void simplify_smoreeq(struct compile_state *state, struct triple *ins)
5461 {
5462         if (is_const(ins->left) && is_const(ins->right)) {
5463                 long_t left, right;
5464                 left  = read_sconst(ins, &ins->left);
5465                 right = read_sconst(ins, &ins->right);
5466                 mkconst(state, ins, left >= right);
5467         }
5468         else if (ins->left == ins->right) {
5469                 mkconst(state, ins, 1);
5470         }
5471 }
5472
5473 static void simplify_umoreeq(struct compile_state *state, struct triple *ins)
5474 {
5475         if (is_const(ins->left) && is_const(ins->right)) {
5476                 ulong_t left, right;
5477                 left  = read_const(state, ins, &ins->left);
5478                 right = read_const(state, ins, &ins->right);
5479                 mkconst(state, ins, left >= right);
5480         }
5481         else if (is_zero(ins->right)) {
5482                 mkconst(state, ins, 1);
5483         }
5484         else if (ins->left == ins->right) {
5485                 mkconst(state, ins, 1);
5486         }
5487 }
5488
5489 static void simplify_lfalse(struct compile_state *state, struct triple *ins)
5490 {
5491         if (is_const(ins->left)) {
5492                 ulong_t left;
5493                 left = read_const(state, ins, &ins->left);
5494                 mkconst(state, ins, left == 0);
5495         }
5496         /* Otherwise if I am the only user... */
5497         else if ((ins->left->use->member == ins) && (ins->left->use->next == 0)) {
5498                 int need_copy = 1;
5499                 /* Invert a boolean operation */
5500                 switch(ins->left->op) {
5501                 case OP_LTRUE:   ins->left->op = OP_LFALSE;  break;
5502                 case OP_LFALSE:  ins->left->op = OP_LTRUE;   break;
5503                 case OP_EQ:      ins->left->op = OP_NOTEQ;   break;
5504                 case OP_NOTEQ:   ins->left->op = OP_EQ;      break;
5505                 case OP_SLESS:   ins->left->op = OP_SMOREEQ; break;
5506                 case OP_ULESS:   ins->left->op = OP_UMOREEQ; break;
5507                 case OP_SMORE:   ins->left->op = OP_SLESSEQ; break;
5508                 case OP_UMORE:   ins->left->op = OP_ULESSEQ; break;
5509                 case OP_SLESSEQ: ins->left->op = OP_SMORE;   break;
5510                 case OP_ULESSEQ: ins->left->op = OP_UMORE;   break;
5511                 case OP_SMOREEQ: ins->left->op = OP_SLESS;   break;
5512                 case OP_UMOREEQ: ins->left->op = OP_ULESS;   break;
5513                 default:
5514                         need_copy = 0;
5515                         break;
5516                 }
5517                 if (need_copy) {
5518                         mkcopy(state, ins, ins->left);
5519                 }
5520         }
5521 }
5522
5523 static void simplify_ltrue (struct compile_state *state, struct triple *ins)
5524 {
5525         if (is_const(ins->left)) {
5526                 ulong_t left;
5527                 left = read_const(state, ins, &ins->left);
5528                 mkconst(state, ins, left != 0);
5529         }
5530         else switch(ins->left->op) {
5531         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
5532         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
5533         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
5534                 mkcopy(state, ins, ins->left);
5535         }
5536
5537 }
5538
5539 static void simplify_copy(struct compile_state *state, struct triple *ins)
5540 {
5541         if (is_const(ins->left)) {
5542                 switch(ins->left->op) {
5543                 case OP_INTCONST:
5544                 {
5545                         ulong_t left;
5546                         left = read_const(state, ins, &ins->left);
5547                         mkconst(state, ins, left);
5548                         break;
5549                 }
5550                 case OP_ADDRCONST:
5551                 {
5552                         struct triple *sdecl;
5553                         ulong_t offset;
5554                         sdecl  = ins->left;
5555                         offset = ins->u.cval;
5556                         mkaddr_const(state, ins, sdecl, offset);
5557                         break;
5558                 }
5559                 default:
5560                         internal_error(state, ins, "uknown constant");
5561                         break;
5562                 }
5563         }
5564 }
5565
5566 static void simplify_dot(struct compile_state *state, struct triple *ins)
5567 {
5568         FINISHME();
5569 }
5570
5571 static void simplify_branch(struct compile_state *state, struct triple *ins)
5572 {
5573         struct block *block;
5574         if (ins->op != OP_BRANCH) {
5575                 internal_error(state, ins, "not branch");
5576         }
5577         if (ins->use != 0) {
5578                 internal_error(state, ins, "branch use");
5579         }
5580 #warning "FIXME implement simplify branch."
5581         /* The challenge here with simplify branch is that I need to 
5582          * make modifications to the control flow graph as well
5583          * as to the branch instruction itself.
5584          */
5585         block = ins->u.block;
5586         
5587         if (ins->right && is_const(ins->right)) {
5588                 ulong_t value;
5589                 value = read_const(state, ins, &ins->right);
5590                 unuse_triple(ins->right, ins);
5591                 ins->right = 0;
5592                 if (value) {
5593                         unuse_triple(ins->next, ins);
5594                 }
5595                 else {
5596                         unuse_triple(ins->left, ins);
5597                         ins->left = ins->next;
5598                 }
5599 #warning "FIXME handle the case of making a branch unconditional"
5600         }
5601         if (ins->left == ins->next) {
5602                 unuse_triple(ins->left, ins);
5603                 if (ins->right) {
5604                         unuse_triple(ins->right, ins);
5605                         unuse_triple(ins->next, ins);
5606                 }
5607                 ins->op    = OP_NOOP;
5608                 ins->left  = 0;
5609                 ins->right = 0;
5610                 if (ins->use) {
5611                         internal_error(state, ins, "noop use != 0");
5612                 }
5613 #warning "FIXME handle the case of killing a branch"
5614         }
5615 }
5616
5617 static void simplify_phi(struct compile_state *state, struct triple *ins)
5618 {
5619         struct triple **expr;
5620         ulong_t value;
5621         expr = triple_rhs(state, ins, 0);
5622         if (!is_const(*expr)) {
5623                 return;
5624         }
5625         value = read_const(state, ins, expr);
5626         for(;expr;expr = triple_rhs(state, ins, expr)) {
5627                 if (!is_const(*expr)) {
5628                         return;
5629                 }
5630                 if (value != read_const(state, ins, expr)) {
5631                         return;
5632                 }
5633         }
5634         mkconst(state, ins, value);
5635 }
5636
5637
5638 static void simplify_bsf(struct compile_state *state, struct triple *ins)
5639 {
5640         if (is_const(ins->left)) {
5641                 ulong_t left;
5642                 left = read_const(state, ins, &ins->left);
5643                 mkconst(state, ins, bsf(left));
5644         }
5645 }
5646
5647 static void simplify_bsr(struct compile_state *state, struct triple *ins)
5648 {
5649         if (is_const(ins->left)) {
5650                 ulong_t left;
5651                 left = read_const(state, ins, &ins->left);
5652                 mkconst(state, ins, bsr(left));
5653         }
5654 }
5655
5656
5657 typedef void (*simplify_t)(struct compile_state *state, struct triple *ins);
5658 static const simplify_t table_simplify[] = {
5659 #if 0
5660 #define simplify_smul     simplify_noop
5661 #define simplify_umul     simplify_noop
5662 #define simplify_sdiv     simplify_noop
5663 #define simplify_udiv     simplify_noop
5664 #define simplify_smod     simplify_noop
5665 #define simplify_umod     simplify_noop
5666 #endif
5667 #if 0
5668 #define simplify_add      simplify_noop
5669 #define simplify_sub      simplify_noop
5670 #endif
5671 #if 0
5672 #define simplify_sl       simplify_noop
5673 #define simplify_usr      simplify_noop
5674 #define simplify_ssr      simplify_noop
5675 #endif
5676 #if 0
5677 #define simplify_and      simplify_noop
5678 #define simplify_xor      simplify_noop
5679 #define simplify_or       simplify_noop
5680 #endif
5681 #if 0
5682 #define simplify_pos      simplify_noop
5683 #define simplify_neg      simplify_noop
5684 #define simplify_invert   simplify_noop
5685 #endif
5686
5687 #if 0
5688 #define simplify_eq       simplify_noop
5689 #define simplify_noteq    simplify_noop
5690 #endif
5691 #if 0
5692 #define simplify_sless    simplify_noop
5693 #define simplify_uless    simplify_noop
5694 #define simplify_smore    simplify_noop
5695 #define simplify_umore    simplify_noop
5696 #endif
5697 #if 0
5698 #define simplify_slesseq  simplify_noop
5699 #define simplify_ulesseq  simplify_noop
5700 #define simplify_smoreeq  simplify_noop
5701 #define simplify_umoreeq  simplify_noop
5702 #endif
5703 #if 0
5704 #define simplify_lfalse   simplify_noop
5705 #endif
5706 #if 0
5707 #define simplify_ltrue    simplify_noop
5708 #endif
5709
5710 #if 0
5711 #define simplify_copy     simplify_noop
5712 #endif
5713
5714 #if 0
5715 #define simplify_dot      simplify_noop
5716 #endif
5717
5718 #if 0
5719 #define simplify_branch   simplify_noop
5720 #endif
5721
5722 #if 0
5723 #define simplify_phi      simplify_noop
5724 #endif
5725
5726 #if 0
5727 #define simplify_bsf      simplify_noop
5728 #define simplify_bsr      simplify_noop
5729 #endif
5730
5731 [OP_SMUL       ] = simplify_smul,
5732 [OP_UMUL       ] = simplify_umul,
5733 [OP_SDIV       ] = simplify_sdiv,
5734 [OP_UDIV       ] = simplify_udiv,
5735 [OP_SMOD       ] = simplify_smod,
5736 [OP_UMOD       ] = simplify_umod,
5737 [OP_ADD        ] = simplify_add,
5738 [OP_SUB        ] = simplify_sub,
5739 [OP_SL         ] = simplify_sl,
5740 [OP_USR        ] = simplify_usr,
5741 [OP_SSR        ] = simplify_ssr,
5742 [OP_AND        ] = simplify_and,
5743 [OP_XOR        ] = simplify_xor,
5744 [OP_OR         ] = simplify_or,
5745 [OP_POS        ] = simplify_pos,
5746 [OP_NEG        ] = simplify_neg,
5747 [OP_INVERT     ] = simplify_invert,
5748
5749 [OP_EQ         ] = simplify_eq,
5750 [OP_NOTEQ      ] = simplify_noteq,
5751 [OP_SLESS      ] = simplify_sless,
5752 [OP_ULESS      ] = simplify_uless,
5753 [OP_SMORE      ] = simplify_smore,
5754 [OP_UMORE      ] = simplify_umore,
5755 [OP_SLESSEQ    ] = simplify_slesseq,
5756 [OP_ULESSEQ    ] = simplify_ulesseq,
5757 [OP_SMOREEQ    ] = simplify_smoreeq,
5758 [OP_UMOREEQ    ] = simplify_umoreeq,
5759 [OP_LFALSE     ] = simplify_lfalse,
5760 [OP_LTRUE      ] = simplify_ltrue,
5761
5762 [OP_LOAD       ] = simplify_noop,
5763 [OP_STORE      ] = simplify_noop,
5764
5765 [OP_NOOP       ] = simplify_noop,
5766
5767 [OP_INTCONST   ] = simplify_noop,
5768 [OP_BLOBCONST  ] = simplify_noop,
5769 [OP_ADDRCONST  ] = simplify_noop,
5770
5771 [OP_WRITE      ] = simplify_noop,
5772 [OP_READ       ] = simplify_noop,
5773 [OP_COPY       ] = simplify_copy,
5774 [OP_DOT        ] = simplify_dot,
5775
5776 [OP_LIST       ] = simplify_noop,
5777 [OP_BRANCH     ] = simplify_branch,
5778 [OP_LABEL      ] = simplify_noop,
5779 [OP_ADECL      ] = simplify_noop,
5780 [OP_SDECL      ] = simplify_noop,
5781 [OP_PHI        ] = simplify_phi,
5782
5783 [OP_INB        ] = simplify_noop,
5784 [OP_INW        ] = simplify_noop,
5785 [OP_INL        ] = simplify_noop,
5786 [OP_OUTB       ] = simplify_noop,
5787 [OP_OUTW       ] = simplify_noop,
5788 [OP_OUTL       ] = simplify_noop,
5789 [OP_BSF        ] = simplify_bsf,
5790 [OP_BSR        ] = simplify_bsr,                    
5791 };
5792
5793 static void simplify(struct compile_state *state, struct triple *ins)
5794 {
5795         int op;
5796         simplify_t do_simplify;
5797         do {
5798                 op = ins->op;
5799                 do_simplify = 0;
5800                 if ((op < 0) || (op > sizeof(table_simplify)/sizeof(table_simplify[0]))) {
5801                         do_simplify = 0;
5802                 }
5803                 else {
5804                         do_simplify = table_simplify[op];
5805                 }
5806                 if (!do_simplify) {
5807                         internal_error(state, ins, "cannot simplify op: %d %s\n",
5808                                 op, tops(op));
5809                         return;
5810                 }
5811                 do_simplify(state, ins);
5812         } while(ins->op != op);
5813 }
5814
5815 static void simplify_all(struct compile_state *state)
5816 {
5817         struct triple *ins, *first;
5818         first = state->main_function->left;
5819         ins = first;
5820         do {
5821                 simplify(state, ins);
5822                 ins = ins->next;
5823         } while(ins != first);
5824 }
5825
5826 /*
5827  * Builtins....
5828  * ============================
5829  */
5830
5831 static void register_builtin_unary(struct compile_state *state, 
5832         const char *name, int op, struct type *result, struct type *a1type)
5833 {
5834         struct type *ftype, *rtype, *atype;
5835         struct triple *def, *arg1, *work, *last, *first;
5836         struct hash_entry *ident;
5837         int name_len;
5838
5839         /* Dummy file state to get debug handling right */
5840         struct file_state file;
5841         memset(&file, 0, sizeof(file));
5842         file.basename = name;
5843         file.line = 1;
5844         file.prev = state->file;
5845         state->file = &file;
5846         
5847         atype = a1type;
5848         rtype = result;
5849         ftype = new_type(TYPE_FUNCTION, rtype, atype);
5850         /* Generate the needed triples */
5851         def = triple(state, OP_LIST, ftype, 0, 0);
5852         first = label(state);
5853         def->left = first;
5854         /* Now string them together into a list */
5855         arg1 = 0;
5856         if ((atype->type & TYPE_MASK) != TYPE_VOID) {
5857                 arg1 = flatten(state, first, variable(state, a1type));
5858         }
5859         def->right = 0;
5860         if ((rtype->type & TYPE_MASK) != TYPE_VOID) {
5861                 def->right = flatten(state, first, variable(state, rtype));
5862         }
5863         work = triple(state, op, rtype, read_expr(state, arg1), 0);
5864         if (def->right) {
5865                 work = write_expr(state, def->right, work);
5866         }
5867         work = flatten(state, first, work);
5868         last = flatten(state, first, label(state));
5869         name_len = strlen(name);
5870         ident = lookup(state, name, name_len);
5871         symbol(state, ident, &ident->sym_ident, def, ftype);
5872
5873         state->file = file.prev;
5874
5875 #if 0
5876         fprintf(stdout, "\n");
5877         loc(stdout, state, 0);
5878         fprintf(stdout, "\n__________ builtin_unary _________\n");
5879         print_triple(state, def);
5880         fprintf(stdout, "__________ builtin_unary _________ done\n\n");
5881 #endif
5882 }
5883
5884 static void register_builtin_binary(struct compile_state *state, 
5885         const char *name, int op, 
5886         struct type *result, struct type *a1type, struct type *a2type)
5887 {
5888         struct type *ftype, *rtype, *atype;
5889         struct triple *def, *arg1, *arg2, *work, *last, *first;
5890         struct hash_entry *ident;
5891         int name_len;
5892         /* Dummy file state to get debug handling right */
5893         struct file_state file;
5894         memset(&file, 0, sizeof(file));
5895         file.basename = name;
5896         file.line = 1;
5897         file.prev = state->file;
5898         state->file = &file;
5899         
5900         atype = new_type(TYPE_PRODUCT, a1type, a2type);
5901         rtype = result;
5902         ftype = new_type(TYPE_FUNCTION, rtype, atype);
5903         /* Generate the needed triples */
5904         def = triple(state, OP_LIST, ftype, 0, 0);
5905         first = label(state);
5906         def->left = first;
5907         /* String them togher */
5908         arg1 = flatten(state, first, variable(state, a1type));
5909         arg2 = flatten(state, first, variable(state, a2type));
5910         def->right = 0;
5911         if ((rtype->type & TYPE_MASK) != TYPE_VOID) {
5912                 def->right = flatten(state, first, variable(state, rtype));
5913         }
5914         work = triple(state, op, rtype,
5915                         read_expr(state, arg1), read_expr(state, arg2));
5916         if (def->right) {
5917                 work = write_expr(state, def->right, work);
5918         }
5919         work = flatten(state, first, work);
5920         last = flatten(state, first, label(state));
5921         name_len = strlen(name);
5922         ident = lookup(state, name, name_len);
5923         symbol(state, ident, &ident->sym_ident, def, ftype);
5924
5925         state->file = file.prev;
5926
5927 #if 0
5928         fprintf(stdout, "\n");
5929         loc(stdout, state, 0);
5930         fprintf(stdout, "\n__________ builtin_binary _________\n");
5931         print_triple(state, def);
5932         fprintf(stdout, "__________ builtin_binary _________ done\n\n");
5933 #endif
5934 }
5935
5936 static void register_builtins(struct compile_state *state)
5937 {
5938         register_builtin_unary(state, "__builtin_inb", OP_INB, 
5939                 &uchar_type, &ushort_type);
5940         register_builtin_unary(state, "__builtin_inw", OP_INW, 
5941                 &ushort_type, &ushort_type);
5942         register_builtin_unary( state, "__builtin_inl", OP_INL, 
5943                 &uint_type, &ushort_type);
5944
5945         register_builtin_binary(state, "__builtin_outb", OP_OUTB,
5946                 &void_type, &uchar_type, &ushort_type);
5947         register_builtin_binary(state, "__builtin_outw", OP_OUTW,
5948                 &void_type, &ushort_type, &ushort_type);
5949         register_builtin_binary(state, "__builtin_outl", OP_OUTL,
5950                 &void_type, &uint_type, &ushort_type);
5951         
5952         register_builtin_unary(state, "__builtin_bsf", OP_BSF,
5953                 &int_type, &int_type);
5954         register_builtin_unary(state, "__builtin_bsr", OP_BSR,
5955                 &int_type, &int_type);
5956         
5957         register_builtin_unary(state, "__builtin_hlt", OP_HLT,
5958                 &void_type, &void_type);
5959 }
5960
5961 static struct type *declarator(
5962         struct compile_state *state, struct type *type, 
5963         struct hash_entry **ident, int need_ident);
5964 static void decl(struct compile_state *state, struct triple *first);
5965 static struct type *specifier_qualifier_list(struct compile_state *state);
5966 static int isdecl_specifier(int tok);
5967 static struct type *decl_specifiers(struct compile_state *state);
5968 static int istype(int tok);
5969 static struct triple *expr(struct compile_state *state);
5970 static struct triple *assignment_expr(struct compile_state *state);
5971 static struct type *type_name(struct compile_state *state);
5972 static void statement(struct compile_state *state, struct triple *fist);
5973
5974 static struct triple *call_expr(
5975         struct compile_state *state, struct triple *func)
5976 {
5977         struct triple *def, **next;
5978         struct type *type;
5979
5980         if ((func->type->type & TYPE_MASK) != TYPE_FUNCTION) {
5981                 error(state, 0, "Called object is not a function");
5982         }
5983         if (func->op != OP_LIST) {
5984                 internal_error(state, 0, "improper function");
5985         }
5986         eat(state, TOK_LPAREN);
5987         /* Find the return type without any specifiers */
5988         type = clone_type(0, func->type->left);
5989         def = triple(state, OP_CALL, type, func, 0);
5990         next = &def->right;
5991         if (peek(state) != TOK_RPAREN) {
5992                 struct triple *val;
5993                 struct type *param, *arg_type;
5994                 val = read_expr(state, assignment_expr(state));
5995                 param = func->type->right;
5996                 arg_type = param;
5997                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
5998                         arg_type = param->left;
5999                 }
6000                 else if ((param->type & TYPE_MASK) == TYPE_VOID) {
6001                         error(state, 0, "Too many arguments");
6002                 }
6003                 write_compatible(state, arg_type, val->type);
6004                 *next = val;
6005                 while(peek(state) == TOK_COMMA) {
6006                         eat(state, TOK_COMMA);
6007                         val = read_expr(state, assignment_expr(state));
6008                         if (arg_type == param) {
6009                                 error(state, 0, "Too many arguments");
6010                         }
6011                         arg_type = param = param->right;
6012                         if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
6013                                 arg_type = param->left;
6014                         }
6015                         write_compatible(state, arg_type, val->type);
6016                         *next = triple(state, OP_PRODUCT, &void_type, *next, val);
6017                         next = &((*next)->right);
6018                 }
6019         }
6020         eat(state, TOK_RPAREN);
6021         return def;
6022 }
6023
6024
6025 static struct triple *character_constant(struct compile_state *state)
6026 {
6027         struct triple *def;
6028         struct token *tk;
6029         const signed char *str, *end;
6030         int c;
6031         int str_len;
6032         eat(state, TOK_LIT_CHAR);
6033         tk = &state->token[0];
6034         str = tk->val.str + 1;
6035         str_len = tk->str_len - 2;
6036         if (str_len <= 0) {
6037                 error(state, 0, "empty character constant");
6038         }
6039         end = str + str_len;
6040         c = char_value(state, &str, end);
6041         if (str != end) {
6042                 error(state, 0, "multibyte character constant not supported");
6043         }
6044         def = int_const(state, &char_type, (ulong_t)((long_t)c));
6045         return def;
6046 }
6047
6048 static struct triple *string_constant(struct compile_state *state)
6049 {
6050         struct triple *def;
6051         struct token *tk;
6052         struct type *type;
6053         const signed char *str, *end;
6054         signed char *buf, *ptr;
6055         int str_len;
6056
6057         buf = 0;
6058         type = new_type(TYPE_ARRAY, &char_type, 0);
6059         type->elements = 0;
6060         /* The while loop handles string concatenation */
6061         do {
6062                 eat(state, TOK_LIT_STRING);
6063                 tk = &state->token[0];
6064                 str = tk->val.str + 1;
6065                 str_len = tk->str_len - 2;
6066                 if (str_len <= 0) {
6067                         error(state, 0, "empty string constant");
6068                 }
6069                 end = str + str_len;
6070                 ptr = buf;
6071                 buf = xmalloc(type->elements + str_len + 1, "string_constant");
6072                 memcpy(buf, ptr, type->elements);
6073                 ptr = buf + type->elements;
6074                 do {
6075                         *ptr++ = char_value(state, &str, end);
6076                 } while(str < end);
6077                 type->elements = ptr - buf;
6078         } while(peek(state) == TOK_LIT_STRING);
6079         *ptr = '\0';
6080         type->elements += 1;
6081         def = triple(state, OP_BLOBCONST, type, 0, 0);
6082         def->u.blob = buf;
6083         return def;
6084 }
6085
6086
6087 static struct triple *integer_constant(struct compile_state *state)
6088 {
6089         struct triple *def;
6090         unsigned long val;
6091         struct token *tk;
6092         char *end;
6093         int u, l, decimal;
6094         struct type *type;
6095
6096         eat(state, TOK_LIT_INT);
6097         tk = &state->token[0];
6098         errno = 0;
6099         decimal = (tk->val.str[0] != '0');
6100         val = strtoul(tk->val.str, &end, 0);
6101         if ((val == ULONG_MAX) && (errno == ERANGE)) {
6102                 error(state, 0, "Integer constant to large");
6103         }
6104         u = l = 0;
6105         if ((*end == 'u') || (*end == 'U')) {
6106                 u = 1;
6107                         end++;
6108         }
6109         if ((*end == 'l') || (*end == 'L')) {
6110                 l = 1;
6111                 end++;
6112         }
6113         if ((*end == 'u') || (*end == 'U')) {
6114                 u = 1;
6115                 end++;
6116         }
6117         if (*end) {
6118                 error(state, 0, "Junk at end of integer constant");
6119         }
6120         if (u && l)  {
6121                 type = &ulong_type;
6122         }
6123         else if (l) {
6124                 type = &long_type;
6125                 if (!decimal && (val > LONG_MAX)) {
6126                         type = &ulong_type;
6127                 }
6128         }
6129         else if (u) {
6130                 type = &uint_type;
6131                 if (val > UINT_MAX) {
6132                         type = &ulong_type;
6133                 }
6134         }
6135         else {
6136                 type = &int_type;
6137                 if (!decimal && (val > INT_MAX) && (val <= UINT_MAX)) {
6138                         type = &uint_type;
6139                 }
6140                 else if (!decimal && (val > LONG_MAX)) {
6141                         type = &ulong_type;
6142                 }
6143                 else if (val > INT_MAX) {
6144                         type = &long_type;
6145                 }
6146         }
6147         def = int_const(state, type, val);
6148         return def;
6149 }
6150
6151 static struct triple *primary_expr(struct compile_state *state)
6152 {
6153         struct triple *def;
6154         int tok;
6155         tok = peek(state);
6156         switch(tok) {
6157         case TOK_IDENT:
6158         {
6159                 struct hash_entry *ident;
6160                 /* Here ident is either:
6161                  * a varable name
6162                  * a function name
6163                  * an enumeration constant.
6164                  */
6165                 eat(state, TOK_IDENT);
6166                 ident = state->token[0].ident;
6167                 if (!ident->sym_ident) {
6168                         error(state, 0, "%s undeclared", ident->name);
6169                 }
6170                 def = ident->sym_ident->def;
6171                 break;
6172         }
6173         case TOK_ENUM_CONST:
6174                 /* Here ident is an enumeration constant */
6175                 eat(state, TOK_ENUM_CONST);
6176                 def = 0;
6177                 FINISHME();
6178                 break;
6179         case TOK_LPAREN:
6180                 eat(state, TOK_LPAREN);
6181                 def = expr(state);
6182                 eat(state, TOK_RPAREN);
6183                 break;
6184         case TOK_LIT_INT:
6185                 def = integer_constant(state);
6186                 break;
6187         case TOK_LIT_FLOAT:
6188                 eat(state, TOK_LIT_FLOAT);
6189                 error(state, 0, "Floating point constants not supported");
6190                 def = 0;
6191                 FINISHME();
6192                 break;
6193         case TOK_LIT_CHAR:
6194                 def = character_constant(state);
6195                 break;
6196         case TOK_LIT_STRING:
6197                 def = string_constant(state);
6198                 break;
6199         default:
6200                 def = 0;
6201                 error(state, 0, "Unexpected token: %s\n", tokens[tok]);
6202         }
6203         return def;
6204 }
6205
6206 static struct triple *postfix_expr(struct compile_state *state)
6207 {
6208         struct triple *def;
6209         int postfix;
6210         def = primary_expr(state);
6211         do {
6212                 struct triple *left;
6213                 int tok;
6214                 postfix = 1;
6215                 left = def;
6216                 switch((tok = peek(state))) {
6217                 case TOK_LBRACKET:
6218                         eat(state, TOK_LBRACKET);
6219                         def = mk_subscript_expr(state, left, expr(state));
6220                         eat(state, TOK_RBRACKET);
6221                         break;
6222                 case TOK_LPAREN:
6223                         def = call_expr(state, def);
6224                         break;
6225                 case TOK_DOT:
6226                         eat(state, TOK_DOT);
6227                         eat(state, TOK_IDENT);
6228                         FINISHME();
6229                         break;
6230                 case TOK_ARROW:
6231                         eat(state, TOK_ARROW);
6232                         eat(state, TOK_IDENT);
6233                         FINISHME();
6234                         break;
6235                 case TOK_PLUSPLUS:
6236                         eat(state, TOK_PLUSPLUS);
6237                         def = mk_post_inc_expr(state, left);
6238                         break;
6239                 case TOK_MINUSMINUS:
6240                         eat(state, TOK_MINUSMINUS);
6241                         def = mk_post_dec_expr(state, left);
6242                         break;
6243                 default:
6244                         postfix = 0;
6245                         break;
6246                 }
6247         } while(postfix);
6248         return def;
6249 }
6250
6251 static struct triple *cast_expr(struct compile_state *state);
6252
6253 static struct triple *unary_expr(struct compile_state *state)
6254 {
6255         struct triple *def, *right;
6256         int tok;
6257         switch((tok = peek(state))) {
6258         case TOK_PLUSPLUS:
6259                 eat(state, TOK_PLUSPLUS);
6260                 def = mk_pre_inc_expr(state, unary_expr(state));
6261                 break;
6262         case TOK_MINUSMINUS:
6263                 eat(state, TOK_MINUSMINUS);
6264                 def = mk_pre_dec_expr(state, unary_expr(state));
6265                 break;
6266         case TOK_AND:
6267                 eat(state, TOK_AND);
6268                 def = mk_addr_expr(state, cast_expr(state), 0);
6269                 break;
6270         case TOK_STAR:
6271                 eat(state, TOK_STAR);
6272                 def = mk_deref_expr(state, read_expr(state, cast_expr(state)));
6273                 break;
6274         case TOK_PLUS:
6275                 eat(state, TOK_PLUS);
6276                 right = read_expr(state, cast_expr(state));
6277                 arithmetic(state, right);
6278                 def = integral_promotion(state, right);
6279                 break;
6280         case TOK_MINUS:
6281                 eat(state, TOK_MINUS);
6282                 right = read_expr(state, cast_expr(state));
6283                 arithmetic(state, right);
6284                 def = integral_promotion(state, right);
6285                 def = triple(state, OP_NEG, def->type, def, 0);
6286                 break;
6287         case TOK_TILDE:
6288                 eat(state, TOK_TILDE);
6289                 right = read_expr(state, cast_expr(state));
6290                 integral(state, right);
6291                 def = integral_promotion(state, right);
6292                 def = triple(state, OP_INVERT, def->type, def, 0);
6293                 break;
6294         case TOK_BANG:
6295                 eat(state, TOK_BANG);
6296                 right = read_expr(state, cast_expr(state));
6297                 bool(state, right);
6298                 def = lfalse_expr(state, right);
6299                 break;
6300         case TOK_SIZEOF:
6301         {
6302                 struct type *type;
6303                 int tok1, tok2;
6304                 eat(state, TOK_SIZEOF);
6305                 tok1 = peek(state);
6306                 tok2 = peek2(state);
6307                 if ((tok1 == TOK_LPAREN) && istype(tok2)) {
6308                         eat(state, TOK_LPAREN);
6309                         type = type_name(state);
6310                         eat(state, TOK_RPAREN);
6311                 }
6312                 else {
6313                         struct triple *expr;
6314                         expr = unary_expr(state);
6315                         type = expr->type;
6316                         release_expr(state, expr);
6317                 }
6318                 def = int_const(state, &ulong_type, size_of(state, type));
6319                 break;
6320         }
6321         case TOK_ALIGNOF:
6322         {
6323                 struct type *type;
6324                 int tok1, tok2;
6325                 eat(state, TOK_ALIGNOF);
6326                 tok1 = peek(state);
6327                 tok2 = peek2(state);
6328                 if ((tok1 == TOK_LPAREN) && istype(tok2)) {
6329                         eat(state, TOK_LPAREN);
6330                         type = type_name(state);
6331                         eat(state, TOK_RPAREN);
6332                 }
6333                 else {
6334                         struct triple *expr;
6335                         expr = unary_expr(state);
6336                         type = expr->type;
6337                         release_expr(state, expr);
6338                 }
6339                 def = int_const(state, &ulong_type, align_of(state, type));
6340                 break;
6341         }
6342         default:
6343                 def = postfix_expr(state);
6344                 break;
6345         }
6346         return def;
6347 }
6348
6349 static struct triple *cast_expr(struct compile_state *state)
6350 {
6351         struct triple *def;
6352         int tok1, tok2;
6353         tok1 = peek(state);
6354         tok2 = peek2(state);
6355         if ((tok1 == TOK_LPAREN) && istype(tok2)) {
6356                 struct type *type;
6357                 eat(state, TOK_LPAREN);
6358                 type = type_name(state);
6359                 eat(state, TOK_RPAREN);
6360                 def = read_expr(state, cast_expr(state));
6361                 def = triple(state, OP_COPY, type, def, 0);
6362 #warning "FIXME do I need an OP_CAST expr to be semantically correct here?"
6363         }
6364         else {
6365                 def = unary_expr(state);
6366         }
6367         return def;
6368 }
6369
6370 static struct triple *mult_expr(struct compile_state *state)
6371 {
6372         struct triple *def;
6373         int done;
6374         def = cast_expr(state);
6375         do {
6376                 struct triple *left, *right;
6377                 struct type *result_type;
6378                 int tok, op, sign;
6379                 done = 0;
6380                 switch(tok = (peek(state))) {
6381                 case TOK_STAR:
6382                 case TOK_DIV:
6383                 case TOK_MOD:
6384                         left = read_expr(state, def);
6385                         arithmetic(state, left);
6386
6387                         eat(state, tok);
6388
6389                         right = read_expr(state, cast_expr(state));
6390                         arithmetic(state, right);
6391
6392                         result_type = arithmetic_result(state, left, right);
6393                         sign = is_signed(result_type);
6394                         op = -1;
6395                         switch(tok) {
6396                         case TOK_STAR: op = sign? OP_SMUL : OP_UMUL; break;
6397                         case TOK_DIV:  op = sign? OP_SDIV : OP_UDIV; break;
6398                         case TOK_MOD:  op = sign? OP_SMOD : OP_UMOD; break;
6399                         }
6400                         def = triple(state, op, result_type, left, right);
6401                         break;
6402                 default:
6403                         done = 1;
6404                         break;
6405                 }
6406         } while(!done);
6407         return def;
6408 }
6409
6410 static struct triple *add_expr(struct compile_state *state)
6411 {
6412         struct triple *def;
6413         int done;
6414         def = mult_expr(state);
6415         do {
6416                 done = 0;
6417                 switch( peek(state)) {
6418                 case TOK_PLUS:
6419                         eat(state, TOK_PLUS);
6420                         def = mk_add_expr(state, def, mult_expr(state));
6421                         break;
6422                 case TOK_MINUS:
6423                         eat(state, TOK_MINUS);
6424                         def = mk_sub_expr(state, def, mult_expr(state));
6425                         break;
6426                 default:
6427                         done = 1;
6428                         break;
6429                 }
6430         } while(!done);
6431         return def;
6432 }
6433
6434 static struct triple *shift_expr(struct compile_state *state)
6435 {
6436         struct triple *def;
6437         int done;
6438         def = add_expr(state);
6439         do {
6440                 struct triple *left, *right;
6441                 int tok, op;
6442                 done = 0;
6443                 switch((tok = peek(state))) {
6444                 case TOK_SL:
6445                 case TOK_SR:
6446                         left = read_expr(state, def);
6447                         integral(state, left);
6448                         left = integral_promotion(state, left);
6449
6450                         eat(state, tok);
6451
6452                         right = read_expr(state, add_expr(state));
6453                         integral(state, right);
6454                         right = integral_promotion(state, right);
6455                         
6456                         op = (tok == TOK_SL)? OP_SL : 
6457                                 is_signed(left->type)? OP_SSR: OP_USR;
6458
6459                         def = triple(state, op, left->type, left, right);
6460                         break;
6461                 default:
6462                         done = 1;
6463                         break;
6464                 }
6465         } while(!done);
6466         return def;
6467 }
6468
6469 static struct triple *relational_expr(struct compile_state *state)
6470 {
6471 #warning "Extend relational exprs to work on more than arithmetic types"
6472         struct triple *def;
6473         int done;
6474         def = shift_expr(state);
6475         do {
6476                 struct triple *left, *right;
6477                 struct type *arg_type;
6478                 int tok, op, sign;
6479                 done = 0;
6480                 switch((tok = peek(state))) {
6481                 case TOK_LESS:
6482                 case TOK_MORE:
6483                 case TOK_LESSEQ:
6484                 case TOK_MOREEQ:
6485                         left = read_expr(state, def);
6486                         arithmetic(state, left);
6487
6488                         eat(state, tok);
6489
6490                         right = read_expr(state, shift_expr(state));
6491                         arithmetic(state, right);
6492
6493                         arg_type = arithmetic_result(state, left, right);
6494                         sign = is_signed(arg_type);
6495                         op = -1;
6496                         switch(tok) {
6497                         case TOK_LESS:   op = sign? OP_SLESS : OP_ULESS; break;
6498                         case TOK_MORE:   op = sign? OP_SMORE : OP_UMORE; break;
6499                         case TOK_LESSEQ: op = sign? OP_SLESSEQ : OP_ULESSEQ; break;
6500                         case TOK_MOREEQ: op = sign? OP_SMOREEQ : OP_UMOREEQ; break;
6501                         }
6502                         def = triple(state, op, &int_type, left, right);
6503                         break;
6504                 default:
6505                         done = 1;
6506                         break;
6507                 }
6508         } while(!done);
6509         return def;
6510 }
6511
6512 static struct triple *equality_expr(struct compile_state *state)
6513 {
6514 #warning "Extend equality exprs to work on more than arithmetic types"
6515         struct triple *def;
6516         int done;
6517         def = relational_expr(state);
6518         do {
6519                 struct triple *left, *right;
6520                 int tok, op;
6521                 done = 0;
6522                 switch((tok = peek(state))) {
6523                 case TOK_EQEQ:
6524                 case TOK_NOTEQ:
6525                         left = read_expr(state, def);
6526                         arithmetic(state, left);
6527                         eat(state, tok);
6528                         right = read_expr(state, relational_expr(state));
6529                         arithmetic(state, right);
6530                         op = (tok == TOK_EQEQ) ? OP_EQ: OP_NOTEQ;
6531                         def = triple(state, op, &int_type, left, right);
6532                         break;
6533                 default:
6534                         done = 1;
6535                         break;
6536                 }
6537         } while(!done);
6538         return def;
6539 }
6540
6541 static struct triple *and_expr(struct compile_state *state)
6542 {
6543         struct triple *def;
6544         def = equality_expr(state);
6545         while(peek(state) == TOK_AND) {
6546                 struct triple *left, *right;
6547                 struct type *result_type;
6548                 left = read_expr(state, def);
6549                 integral(state, left);
6550                 eat(state, TOK_AND);
6551                 right = read_expr(state, equality_expr(state));
6552                 integral(state, right);
6553                 result_type = arithmetic_result(state, left, right);
6554                 def = triple(state, OP_AND, result_type, left, right);
6555         }
6556         return def;
6557 }
6558
6559 static struct triple *xor_expr(struct compile_state *state)
6560 {
6561         struct triple *def;
6562         def = and_expr(state);
6563         while(peek(state) == TOK_XOR) {
6564                 struct triple *left, *right;
6565                 struct type *result_type;
6566                 left = read_expr(state, def);
6567                 integral(state, left);
6568                 eat(state, TOK_XOR);
6569                 right = read_expr(state, and_expr(state));
6570                 integral(state, right);
6571                 result_type = arithmetic_result(state, left, right);
6572                 def = triple(state, OP_XOR, result_type, left, right);
6573         }
6574         return def;
6575 }
6576
6577 static struct triple *or_expr(struct compile_state *state)
6578 {
6579         struct triple *def;
6580         def = xor_expr(state);
6581         while(peek(state) == TOK_OR) {
6582                 struct triple *left, *right;
6583                 struct type *result_type;
6584                 left = read_expr(state, def);
6585                 integral(state, left);
6586                 eat(state, TOK_OR);
6587                 right = read_expr(state, xor_expr(state));
6588                 integral(state, right);
6589                 result_type = arithmetic_result(state, left, right);
6590                 def = triple(state, OP_OR, result_type, left, right);
6591         }
6592         return def;
6593 }
6594
6595 static struct triple *land_expr(struct compile_state *state)
6596 {
6597         struct triple *def;
6598         def = or_expr(state);
6599         while(peek(state) == TOK_LOGAND) {
6600                 struct triple *left, *right;
6601                 left = read_expr(state, def);
6602                 bool(state, left);
6603                 eat(state, TOK_LOGAND);
6604                 right = read_expr(state, or_expr(state));
6605                 bool(state, right);
6606
6607                 def = triple(state, OP_LAND, &int_type,
6608                         ltrue_expr(state, left),
6609                         ltrue_expr(state, right));
6610         }
6611         return def;
6612 }
6613
6614 static struct triple *lor_expr(struct compile_state *state)
6615 {
6616         struct triple *def;
6617         def = land_expr(state);
6618         while(peek(state) == TOK_LOGOR) {
6619                 struct triple *left, *right;
6620                 left = read_expr(state, def);
6621                 bool(state, left);
6622                 eat(state, TOK_LOGOR);
6623                 right = read_expr(state, land_expr(state));
6624                 bool(state, right);
6625                 
6626                 def = triple(state, OP_LOR, &int_type,
6627                         ltrue_expr(state, left),
6628                         ltrue_expr(state, right));
6629         }
6630         return def;
6631 }
6632
6633 static struct triple *conditional_expr(struct compile_state *state)
6634 {
6635         struct triple *def;
6636         def = lor_expr(state);
6637         if (peek(state) == TOK_QUEST) {
6638                 struct triple *test, *left, *right;
6639                 bool(state, def);
6640                 test = ltrue_expr(state, read_expr(state, def));
6641                 eat(state, TOK_QUEST);
6642                 left = read_expr(state, expr(state));
6643                 eat(state, TOK_COLON);
6644                 right = read_expr(state, conditional_expr(state));
6645
6646                 def = cond_expr(state, test, left, right);
6647         }
6648         return def;
6649 }
6650
6651 static struct triple *eval_const_expr(
6652         struct compile_state *state, struct triple *expr)
6653 {
6654         struct triple *def;
6655         struct triple *head, *ptr;
6656         head = label(state); /* dummy initial triple */
6657         flatten(state, head, expr);
6658         for(ptr = head->next; ptr != head; ptr = ptr->next) {
6659                 simplify(state, ptr);
6660         }
6661         /* Remove the constant value the tail of the list */
6662         def = head->prev;
6663         def->prev->next = def->next;
6664         def->next->prev = def->prev;
6665         def->next = def->prev = def;
6666         if (!is_const(def)) {
6667                 internal_error(state, 0, "Not a constant expression");
6668         }
6669         /* Free the intermediate expressions */
6670         while(head->next != head) {
6671                 release_triple(state, head->next);
6672         }
6673         free_triple(state, head);
6674         return def;
6675 }
6676
6677 static struct triple *constant_expr(struct compile_state *state)
6678 {
6679         return eval_const_expr(state, conditional_expr(state));
6680 }
6681
6682 static struct triple *assignment_expr(struct compile_state *state)
6683 {
6684         struct triple *def, *left, *right;
6685         int tok, op, sign;
6686         /* The C grammer in K&R shows assignment expressions
6687          * only taking unary expressions as input on their
6688          * left hand side.  But specifies the precedence of
6689          * assignemnt as the lowest operator except for comma.
6690          *
6691          * Allowing conditional expressions on the left hand side
6692          * of an assignement results in a grammar that accepts
6693          * a larger set of statements than standard C.   As long
6694          * as the subset of the grammar that is standard C behaves
6695          * correctly this should cause no problems.
6696          * 
6697          * For the extra token strings accepted by the grammar
6698          * none of them should produce a valid lvalue, so they
6699          * should not produce functioning programs.
6700          *
6701          * GCC has this bug as well, so surprises should be minimal.
6702          */
6703         def = conditional_expr(state);
6704         left = def;
6705         switch((tok = peek(state))) {
6706         case TOK_EQ:
6707                 lvalue(state, left);
6708                 eat(state, TOK_EQ);
6709                 def = write_expr(state, left, 
6710                         read_expr(state, assignment_expr(state)));
6711                 break;
6712         case TOK_TIMESEQ:
6713         case TOK_DIVEQ:
6714         case TOK_MODEQ:
6715         case TOK_PLUSEQ:
6716         case TOK_MINUSEQ:
6717                 lvalue(state, left);
6718                 arithmetic(state, left);
6719                 eat(state, tok);
6720                 right = read_expr(state, assignment_expr(state));
6721                 arithmetic(state, right);
6722
6723                 sign = is_signed(left->type);
6724                 op = -1;
6725                 switch(tok) {
6726                 case TOK_TIMESEQ: op = sign? OP_SMUL : OP_UMUL; break;
6727                 case TOK_DIVEQ:   op = sign? OP_SDIV : OP_UDIV; break;
6728                 case TOK_MODEQ:   op = sign? OP_SMOD : OP_UMOD; break;
6729                 case TOK_PLUSEQ:  op = OP_ADD; break;
6730                 case TOK_MINUSEQ: op = OP_SUB; break;
6731                 }
6732                 def = write_expr(state, left,
6733                         triple(state, op, left->type, 
6734                                 read_expr(state, left), right));
6735                 break;
6736         case TOK_SLEQ:
6737         case TOK_SREQ:
6738         case TOK_ANDEQ:
6739         case TOK_XOREQ:
6740         case TOK_OREQ:
6741                 lvalue(state, left);
6742                 integral(state, left);
6743                 eat(state, tok);
6744                 right = read_expr(state, assignment_expr(state));
6745                 integral(state, right);
6746                 right = integral_promotion(state, right);
6747                 sign = is_signed(left->type);
6748                 op = -1;
6749                 switch(tok) {
6750                 case TOK_SLEQ:  op = OP_SL; break;
6751                 case TOK_SREQ:  op = sign? OP_SSR: OP_USR; break;
6752                 case TOK_ANDEQ: op = OP_AND; break;
6753                 case TOK_XOREQ: op = OP_XOR; break;
6754                 case TOK_OREQ:  op = OP_OR; break;
6755                 }
6756                 def = write_expr(state, left,
6757                         triple(state, op, left->type, 
6758                                 read_expr(state, left), right));
6759                 break;
6760         }
6761         return def;
6762 }
6763
6764 static struct triple *expr(struct compile_state *state)
6765 {
6766         struct triple *def;
6767         def = assignment_expr(state);
6768         while(peek(state) == TOK_COMMA) {
6769                 struct triple *left, *right;
6770                 left = def;
6771                 eat(state, TOK_COMMA);
6772                 right = assignment_expr(state);
6773                 def = triple(state, OP_COMMA, right->type, left, right);
6774         }
6775         return def;
6776 }
6777
6778 static void expr_statement(struct compile_state *state, struct triple *first)
6779 {
6780         if (peek(state) != TOK_SEMI) {
6781                 flatten(state, first, expr(state));
6782         }
6783         eat(state, TOK_SEMI);
6784 }
6785
6786 static void if_statement(struct compile_state *state, struct triple *first)
6787 {
6788         struct triple *test, *jmp1, *jmp2, *middle, *end;
6789
6790         jmp1 = jmp2 = middle = 0;
6791         eat(state, TOK_IF);
6792         eat(state, TOK_LPAREN);
6793         test = expr(state);
6794         bool(state, test);
6795         /* Cleanup and invert the test */
6796         test = lfalse_expr(state, read_expr(state, test));
6797         eat(state, TOK_RPAREN);
6798         /* Generate the needed pieces */
6799         middle = label(state);
6800         jmp1 = triple(state, OP_BRANCH, &void_type, middle, test);
6801         /* Thread the pieces together */
6802         flatten(state, first, test);
6803         flatten(state, first, jmp1);
6804         flatten(state, first, label(state));
6805         statement(state, first);
6806         if (peek(state) == TOK_ELSE) {
6807                 eat(state, TOK_ELSE);
6808                 /* Generate the rest of the pieces */
6809                 end = label(state);
6810                 jmp2 = triple(state, OP_BRANCH, &void_type, end, 0);
6811                 /* Thread them together */
6812                 flatten(state, first, jmp2);
6813                 flatten(state, first, middle);
6814                 statement(state, first);
6815                 flatten(state, first, end);
6816         }
6817         else {
6818                 flatten(state, first, middle);
6819         }
6820 }
6821
6822 static void for_statement(struct compile_state *state, struct triple *first)
6823 {
6824         struct triple *head, *test, *tail, *jmp1, *jmp2, *end;
6825         struct triple *label1, *label2, *label3;
6826         struct hash_entry *ident;
6827
6828         eat(state, TOK_FOR);
6829         eat(state, TOK_LPAREN);
6830         head = test = tail = jmp1 = jmp2 = 0;
6831         if (peek(state) != TOK_SEMI) {
6832                 head = expr(state);
6833         } 
6834         eat(state, TOK_SEMI);
6835         if (peek(state) != TOK_SEMI) {
6836                 test = expr(state);
6837                 bool(state, test);
6838                 test = ltrue_expr(state, read_expr(state, test));
6839         }
6840         eat(state, TOK_SEMI);
6841         if (peek(state) != TOK_RPAREN) {
6842                 tail = expr(state);
6843         }
6844         eat(state, TOK_RPAREN);
6845         /* Generate the needed pieces */
6846         label1 = label(state);
6847         label2 = label(state);
6848         label3 = label(state);
6849         if (test) {
6850                 jmp1 = triple(state, OP_BRANCH, &void_type, label3, 0);
6851                 jmp2 = triple(state, OP_BRANCH, &void_type, label1, test);
6852         }
6853         else {
6854                 jmp2 = triple(state, OP_BRANCH, &void_type, label1, 0);
6855         }
6856         end = label(state);
6857         /* Remember where break and continue go */
6858         start_scope(state);
6859         ident = state->i_break;
6860         symbol(state, ident, &ident->sym_ident, end, end->type);
6861         ident = state->i_continue;
6862         symbol(state, ident, &ident->sym_ident, label2, label2->type);
6863         /* Now include the body */
6864         flatten(state, first, head);
6865         flatten(state, first, jmp1);
6866         flatten(state, first, label1);
6867         statement(state, first);
6868         flatten(state, first, label2);
6869         flatten(state, first, tail);
6870         flatten(state, first, label3);
6871         flatten(state, first, test);
6872         flatten(state, first, jmp2);
6873         flatten(state, first, end);
6874         /* Cleanup the break/continue scope */
6875         end_scope(state);
6876 }
6877
6878 static void while_statement(struct compile_state *state, struct triple *first)
6879 {
6880         struct triple *label1, *test, *label2, *jmp1, *jmp2, *end;
6881         struct hash_entry *ident;
6882         eat(state, TOK_WHILE);
6883         eat(state, TOK_LPAREN);
6884         test = expr(state);
6885         bool(state, test);
6886         test = ltrue_expr(state, read_expr(state, test));
6887         eat(state, TOK_RPAREN);
6888         /* Generate the needed pieces */
6889         label1 = label(state);
6890         label2 = label(state);
6891         jmp1 = triple(state, OP_BRANCH, &void_type, label2, 0);
6892         jmp2 = triple(state, OP_BRANCH, &void_type, label1, test);
6893         end = label(state);
6894         /* Remember where break and continue go */
6895         start_scope(state);
6896         ident = state->i_break;
6897         symbol(state, ident, &ident->sym_ident, end, end->type);
6898         ident = state->i_continue;
6899         symbol(state, ident, &ident->sym_ident, label2, label2->type);
6900         /* Thread them together */
6901         flatten(state, first, jmp1);
6902         flatten(state, first, label1);
6903         statement(state, first);
6904         flatten(state, first, label2);
6905         flatten(state, first, test);
6906         flatten(state, first, jmp2);
6907         flatten(state, first, end);
6908         /* Cleanup the break/continue scope */
6909         end_scope(state);
6910 }
6911
6912 static void do_statement(struct compile_state *state, struct triple *first)
6913 {
6914         struct triple *label1, *label2, *test, *end;
6915         struct hash_entry *ident;
6916         eat(state, TOK_DO);
6917         /* Generate the needed pieces */
6918         label1 = label(state);
6919         label2 = label(state);
6920         end = label(state);
6921         /* Remember where break and continue go */
6922         start_scope(state);
6923         ident = state->i_break;
6924         symbol(state, ident, &ident->sym_ident, end, end->type);
6925         ident = state->i_continue;
6926         symbol(state, ident, &ident->sym_ident, label2, label2->type);
6927         /* Now include the body */
6928         flatten(state, first, label1);
6929         statement(state, first);
6930         /* Cleanup the break/continue scope */
6931         end_scope(state);
6932         /* Eat the rest of the loop */
6933         eat(state, TOK_WHILE);
6934         eat(state, TOK_LPAREN);
6935         test = read_expr(state, expr(state));
6936         bool(state, test);
6937         eat(state, TOK_RPAREN);
6938         eat(state, TOK_SEMI);
6939         /* Thread the pieces together */
6940         test = ltrue_expr(state, test);
6941         flatten(state, first, label2);
6942         flatten(state, first, test);
6943         flatten(state, first, 
6944                 triple(state, OP_BRANCH, &void_type, label1, test));
6945         flatten(state, first, end);
6946 }
6947
6948
6949 static void return_statement(struct compile_state *state, struct triple *first)
6950 {
6951         struct triple *jmp, *mv, *dest, *var, *val;
6952         int last;
6953         eat(state, TOK_RETURN);
6954
6955 #warning "FIXME implement a more general excess branch elimination"
6956         val = 0;
6957         /* If we have a return value do some more work */
6958         if (peek(state) != TOK_SEMI) {
6959                 val = read_expr(state, expr(state));
6960         }
6961         eat(state, TOK_SEMI);
6962
6963         /* See if this last statement in a function */
6964         last = ((peek(state) == TOK_RBRACE) && 
6965                 (state->scope_depth == GLOBAL_SCOPE_DEPTH +2));
6966
6967         /* Find the return variable */
6968         var = state->main_function->right;
6969         /* Find the return destination */
6970         dest = state->main_function->left->prev;
6971         mv = jmp = 0;
6972         /* If needed generate a jump instruction */
6973         if (!last) {
6974                 jmp = triple(state, OP_BRANCH, &void_type, dest, 0);
6975         }
6976         /* If needed generate an assignment instruction */
6977         if (val) {
6978                 mv = write_expr(state, var, val);
6979         }
6980         /* Now put the code together */
6981         if (mv) {
6982                 flatten(state, first, mv);
6983                 flatten(state, first, jmp);
6984         }
6985         else if (jmp) {
6986                 flatten(state, first, jmp);
6987         }
6988 }
6989
6990 static void break_statement(struct compile_state *state, struct triple *first)
6991 {
6992         struct triple *dest;
6993         eat(state, TOK_BREAK);
6994         eat(state, TOK_SEMI);
6995         if (!state->i_break->sym_ident) {
6996                 error(state, 0, "break statement not within loop or switch");
6997         }
6998         dest = state->i_break->sym_ident->def;
6999         flatten(state, first, triple(state, OP_BRANCH, &void_type, dest, 0));
7000 }
7001
7002 static void continue_statement(struct compile_state *state, struct triple *first)
7003 {
7004         struct triple *dest;
7005         eat(state, TOK_CONTINUE);
7006         eat(state, TOK_SEMI);
7007         if (!state->i_continue->sym_ident) {
7008                 error(state, 0, "continue statement outside of a loop");
7009         }
7010         dest = state->i_continue->sym_ident->def;
7011         flatten(state, first, triple(state, OP_BRANCH, &void_type, dest, 0));
7012 }
7013
7014 static void goto_statement(struct compile_state *state, struct triple *first)
7015 {
7016         FINISHME();
7017         eat(state, TOK_GOTO);
7018         eat(state, TOK_IDENT);
7019         eat(state, TOK_SEMI);
7020         error(state, 0, "goto is not implemeted");
7021         FINISHME();
7022 }
7023
7024 static void labeled_statement(struct compile_state *state, struct triple *first)
7025 {
7026         FINISHME();
7027         eat(state, TOK_IDENT);
7028         eat(state, TOK_COLON);
7029         statement(state, first);
7030         error(state, 0, "labeled statements are not implemented");
7031         FINISHME();
7032 }
7033
7034 static void switch_statement(struct compile_state *state, struct triple *first)
7035 {
7036         FINISHME();
7037         eat(state, TOK_SWITCH);
7038         eat(state, TOK_LPAREN);
7039         expr(state);
7040         eat(state, TOK_RPAREN);
7041         statement(state, first);
7042         error(state, 0, "switch statements are not implemented");
7043         FINISHME();
7044 }
7045
7046 static void case_statement(struct compile_state *state, struct triple *first)
7047 {
7048         FINISHME();
7049         eat(state, TOK_CASE);
7050         constant_expr(state);
7051         eat(state, TOK_COLON);
7052         statement(state, first);
7053         error(state, 0, "case statements are not implemented");
7054         FINISHME();
7055 }
7056
7057 static void default_statement(struct compile_state *state, struct triple *first)
7058 {
7059         FINISHME();
7060         eat(state, TOK_DEFAULT);
7061         eat(state, TOK_COLON);
7062         statement(state, first);
7063         error(state, 0, "default statements are not implemented");
7064         FINISHME();
7065 }
7066
7067 static void asm_statement(struct compile_state *state, struct triple *first)
7068 {
7069         FINISHME();
7070         error(state, 0, "FIXME finish asm_statement");
7071 }
7072
7073
7074 static int isdecl(int tok)
7075 {
7076         switch(tok) {
7077         case TOK_AUTO:
7078         case TOK_REGISTER:
7079         case TOK_STATIC:
7080         case TOK_EXTERN:
7081         case TOK_TYPEDEF:
7082         case TOK_CONST:
7083         case TOK_RESTRICT:
7084         case TOK_VOLATILE:
7085         case TOK_VOID:
7086         case TOK_CHAR:
7087         case TOK_SHORT:
7088         case TOK_INT:
7089         case TOK_LONG:
7090         case TOK_FLOAT:
7091         case TOK_DOUBLE:
7092         case TOK_SIGNED:
7093         case TOK_UNSIGNED:
7094         case TOK_STRUCT:
7095         case TOK_UNION:
7096         case TOK_ENUM:
7097         case TOK_TYPE_NAME: /* typedef name */
7098                 return 1;
7099         default:
7100                 return 0;
7101         }
7102 }
7103
7104 static void compound_statement(struct compile_state *state, struct triple *first)
7105 {
7106         eat(state, TOK_LBRACE);
7107         start_scope(state);
7108
7109         /* statement-list opt */
7110         while (peek(state) != TOK_RBRACE) {
7111                 statement(state, first);
7112         }
7113         end_scope(state);
7114         eat(state, TOK_RBRACE);
7115 }
7116
7117 static void statement(struct compile_state *state, struct triple *first)
7118 {
7119         int tok;
7120         tok = peek(state);
7121         if (tok == TOK_LBRACE) {
7122                 compound_statement(state, first);
7123         }
7124         else if (tok == TOK_IF) {
7125                 if_statement(state, first); 
7126         }
7127         else if (tok == TOK_FOR) {
7128                 for_statement(state, first);
7129         }
7130         else if (tok == TOK_WHILE) {
7131                 while_statement(state, first);
7132         }
7133         else if (tok == TOK_DO) {
7134                 do_statement(state, first);
7135         }
7136         else if (tok == TOK_RETURN) {
7137                 return_statement(state, first);
7138         }
7139         else if (tok == TOK_BREAK) {
7140                 break_statement(state, first);
7141         }
7142         else if (tok == TOK_CONTINUE) {
7143                 continue_statement(state, first);
7144         }
7145         else if (tok == TOK_GOTO) {
7146                 goto_statement(state, first);
7147         }
7148         else if (tok == TOK_SWITCH) {
7149                 switch_statement(state, first);
7150         }
7151         else if (tok == TOK_ASM) {
7152                 asm_statement(state, first);
7153         }
7154         else if ((tok == TOK_IDENT) && (peek2(state) == TOK_COLON)) {
7155                 labeled_statement(state, first); 
7156         }
7157         else if (tok == TOK_CASE) {
7158                 case_statement(state, first);
7159         }
7160         else if (tok == TOK_DEFAULT) {
7161                 default_statement(state, first);
7162         }
7163         else if (isdecl(tok)) {
7164                 /* This handles C99 intermixing of statements and decls */
7165                 decl(state, first);
7166         }
7167         else {
7168                 expr_statement(state, first);
7169         }
7170 }
7171
7172 static struct type *param_decl(struct compile_state *state)
7173 {
7174         struct type *type;
7175         struct hash_entry *ident;
7176         /* Cheat so the declarator will know we are not global */
7177         start_scope(state); 
7178         ident = 0;
7179         type = decl_specifiers(state);
7180         type = declarator(state, type, &ident, 0);
7181         type->ident = ident;
7182         end_scope(state);
7183         return type;
7184 }
7185
7186 static struct type *param_type_list(struct compile_state *state, struct type *type)
7187 {
7188         struct type *ftype, **next;
7189         ftype = new_type(TYPE_FUNCTION, type, param_decl(state));
7190         next = &ftype->right;
7191         while(peek(state) == TOK_COMMA) {
7192                 eat(state, TOK_COMMA);
7193                 if (peek(state) == TOK_DOTS) {
7194                         eat(state, TOK_DOTS);
7195                         error(state, 0, "variadic functions not supported");
7196                 }
7197                 else {
7198                         *next = new_type(TYPE_PRODUCT, *next, param_decl(state));
7199                         next = &((*next)->right);
7200                 }
7201         }
7202         return ftype;
7203 }
7204
7205
7206 static struct type *type_name(struct compile_state *state)
7207 {
7208         struct type *type;
7209         type = specifier_qualifier_list(state);
7210         /* abstract-declarator (may consume no tokens) */
7211         type = declarator(state, type, 0, 0);
7212         return type;
7213 }
7214
7215 static struct type *direct_declarator(
7216         struct compile_state *state, struct type *type, 
7217         struct hash_entry **ident, int need_ident)
7218 {
7219         struct type *outer;
7220         int op;
7221         outer = 0;
7222         arrays_complete(state, type);
7223         switch(peek(state)) {
7224         case TOK_IDENT:
7225                 eat(state, TOK_IDENT);
7226                 if (!ident) {
7227                         error(state, 0, "Unexpected identifier found");
7228                 }
7229                 /* The name of what we are declaring */
7230                 *ident = state->token[0].ident;
7231                 break;
7232         case TOK_LPAREN:
7233                 eat(state, TOK_LPAREN);
7234                 outer = declarator(state, type, ident, need_ident);
7235                 eat(state, TOK_RPAREN);
7236                 break;
7237         default:
7238                 if (need_ident) {
7239                         error(state, 0, "Identifier expected");
7240                 }
7241                 break;
7242         }
7243         do {
7244                 op = 1;
7245                 arrays_complete(state, type);
7246                 switch(peek(state)) {
7247                 case TOK_LPAREN:
7248                         eat(state, TOK_LPAREN);
7249                         type = param_type_list(state, type);
7250                         eat(state, TOK_RPAREN);
7251                         break;
7252                 case TOK_LBRACKET:
7253                 {
7254                         unsigned int qualifiers;
7255                         struct triple *value;
7256                         value = 0;
7257                         eat(state, TOK_LBRACKET);
7258                         if (peek(state) != TOK_RBRACKET) {
7259                                 value = constant_expr(state);
7260                                 integral(state, value);
7261                         }
7262                         eat(state, TOK_RBRACKET);
7263
7264                         qualifiers = type->type & (QUAL_MASK | STOR_MASK);
7265                         type = new_type(TYPE_ARRAY | qualifiers, type, 0);
7266                         if (value) {
7267                                 type->elements = value->u.cval;
7268                                 free_triple(state, value);
7269                         } else {
7270                                 type->elements = ELEMENT_COUNT_UNSPECIFIED;
7271                                 op = 0;
7272                         }
7273                 }
7274                         break;
7275                 default:
7276                         op = 0;
7277                         break;
7278                 }
7279         } while(op);
7280         if (outer) {
7281                 struct type *inner;
7282                 arrays_complete(state, type);
7283                 FINISHME();
7284                 for(inner = outer; inner->left; inner = inner->left)
7285                         ;
7286                 inner->left = type;
7287                 type = outer;
7288         }
7289         return type;
7290 }
7291
7292 static struct type *declarator(
7293         struct compile_state *state, struct type *type, 
7294         struct hash_entry **ident, int need_ident)
7295 {
7296         while(peek(state) == TOK_STAR) {
7297                 eat(state, TOK_STAR);
7298                 type = new_type(TYPE_POINTER | (type->type & STOR_MASK), type, 0);
7299         }
7300         type = direct_declarator(state, type, ident, need_ident);
7301         return type;
7302 }
7303
7304
7305 static struct type *typedef_name(
7306         struct compile_state *state, unsigned int specifiers)
7307 {
7308         struct hash_entry *ident;
7309         struct type *type;
7310         eat(state, TOK_TYPE_NAME);
7311         ident = state->token[0].ident;
7312         type = ident->sym_ident->type;
7313         specifiers |= type->type & QUAL_MASK;
7314         if ((specifiers & (STOR_MASK | QUAL_MASK)) != 
7315                 (type->type & (STOR_MASK | QUAL_MASK))) {
7316                 type = clone_type(specifiers, type);
7317         }
7318         FINISHME();
7319         return type;
7320 }
7321
7322 static struct type *enum_specifier(
7323         struct compile_state *state, unsigned int specifiers)
7324 {
7325         int tok;
7326         struct type *type;
7327         type = 0;
7328         FINISHME();
7329         eat(state, TOK_ENUM);
7330         tok = peek(state);
7331         if (tok == TOK_IDENT) {
7332                 eat(state, TOK_IDENT);
7333         }
7334         if ((tok != TOK_IDENT) || (peek(state) == TOK_LBRACE)) {
7335                 eat(state, TOK_LBRACE);
7336                 do {
7337                         eat(state, TOK_IDENT);
7338                         if (peek(state) == TOK_EQ) {
7339                                 eat(state, TOK_EQ);
7340                                 constant_expr(state);
7341                         }
7342                         if (peek(state) == TOK_COMMA) {
7343                                 eat(state, TOK_COMMA);
7344                         }
7345                 } while(peek(state) != TOK_RBRACE);
7346                 eat(state, TOK_RBRACE);
7347         }
7348         FINISHME();
7349         return type;
7350 }
7351
7352 #if 0
7353 static struct type *struct_declarator(
7354         struct compile_state *state, struct type *type, struct hash_entry **ident)
7355 {
7356         int tok;
7357 #warning "struct_declarator is complicated because of bitfields, kill them?"
7358         tok = peek(state);
7359         if (tok != TOK_COLON) {
7360                 type = declarator(state, type, ident, 1);
7361         }
7362         if ((tok == TOK_COLON) || (peek(state) == TOK_COLON)) {
7363                 eat(state, TOK_COLON);
7364                 constant_expr(state);
7365         }
7366         FINISHME();
7367         return type;
7368 }
7369 #endif
7370
7371 static struct type *struct_or_union_specifier(
7372         struct compile_state *state, unsigned int specifiers)
7373 {
7374         struct type *type;
7375         int tok;
7376         FINISHME();
7377         type = 0;
7378         switch(peek(state)) {
7379         case TOK_STRUCT:
7380                 eat(state, TOK_STRUCT);
7381                 break;
7382         case TOK_UNION:
7383                 eat(state, TOK_UNION);
7384                 break;
7385         default:
7386                 eat(state, TOK_STRUCT);
7387                 break;
7388         }
7389         tok = peek(state);
7390         if (tok == TOK_IDENT) {
7391                 eat(state, TOK_IDENT);
7392                 FINISHME();
7393         }
7394         if ((tok != TOK_IDENT) || (peek(state) == TOK_LBRACE)) {
7395                 eat(state, TOK_LBRACE);
7396                 do {
7397                         struct type *base_type;
7398                         int done;
7399                         FINISHME();
7400                         base_type = specifier_qualifier_list(state);
7401                         do {
7402                                 struct type *type;
7403                                 struct hash_entry *ident;
7404                                 done = 1;
7405                                 type = declarator(state, base_type, &ident, 1);
7406                                 if (peek(state) == TOK_COMMA) {
7407                                         done = 0;
7408                                         eat(state, TOK_COMMA);
7409                                 }
7410                         } while(!done);
7411                         eat(state, TOK_SEMI);
7412                 } while(peek(state) != TOK_RBRACE);
7413                 eat(state, TOK_RBRACE);
7414         }
7415         FINISHME();
7416         return type;
7417 }
7418
7419 static unsigned int storage_class_specifier_opt(struct compile_state *state)
7420 {
7421         unsigned int specifiers;
7422         switch(peek(state)) {
7423         case TOK_AUTO:
7424                 eat(state, TOK_AUTO);
7425                 specifiers = STOR_AUTO;
7426                 break;
7427         case TOK_REGISTER:
7428                 eat(state, TOK_REGISTER);
7429                 specifiers = STOR_REGISTER;
7430                 break;
7431         case TOK_STATIC:
7432                 eat(state, TOK_STATIC);
7433                 specifiers = STOR_STATIC;
7434                 break;
7435         case TOK_EXTERN:
7436                 eat(state, TOK_EXTERN);
7437                 specifiers = STOR_EXTERN;
7438                 break;
7439         case TOK_TYPEDEF:
7440                 eat(state, TOK_TYPEDEF);
7441                 specifiers = STOR_TYPEDEF;
7442                 break;
7443         default:
7444                 if (state->scope_depth <= GLOBAL_SCOPE_DEPTH) {
7445                         specifiers = STOR_STATIC;
7446                 }
7447                 else {
7448                         specifiers = STOR_AUTO;
7449                 }
7450         }
7451         return specifiers;
7452 }
7453
7454 static unsigned int function_specifier_opt(struct compile_state *state)
7455 {
7456         /* Ignore the inline keyword */
7457         unsigned int specifiers;
7458         specifiers = 0;
7459         switch(peek(state)) {
7460         case TOK_INLINE:
7461                 eat(state, TOK_INLINE);
7462                 specifiers = STOR_INLINE;
7463         }
7464         return specifiers;
7465 }
7466
7467 static unsigned int type_qualifiers(struct compile_state *state)
7468 {
7469         unsigned int specifiers;
7470         int done;
7471         done = 0;
7472         specifiers = QUAL_NONE;
7473         do {
7474                 switch(peek(state)) {
7475                 case TOK_CONST:
7476                         eat(state, TOK_CONST);
7477                         specifiers = QUAL_CONST;
7478                         break;
7479                 case TOK_VOLATILE:
7480                         eat(state, TOK_VOLATILE);
7481                         specifiers = QUAL_VOLATILE;
7482                         break;
7483                 case TOK_RESTRICT:
7484                         eat(state, TOK_RESTRICT);
7485                         specifiers = QUAL_RESTRICT;
7486                         break;
7487                 default:
7488                         done = 1;
7489                         break;
7490                 }
7491         } while(!done);
7492         return specifiers;
7493 }
7494
7495 static struct type *type_specifier(
7496         struct compile_state *state, unsigned int spec)
7497 {
7498         struct type *type;
7499         type = 0;
7500         switch(peek(state)) {
7501         case TOK_VOID:
7502                 eat(state, TOK_VOID);
7503                 type = new_type(TYPE_VOID | spec, 0, 0);
7504                 break;
7505         case TOK_CHAR:
7506                 eat(state, TOK_CHAR);
7507                 type = new_type(TYPE_CHAR | spec, 0, 0);
7508                 break;
7509         case TOK_SHORT:
7510                 eat(state, TOK_SHORT);
7511                 if (peek(state) == TOK_INT) {
7512                         eat(state, TOK_INT);
7513                 }
7514                 type = new_type(TYPE_SHORT | spec, 0, 0);
7515                 break;
7516         case TOK_INT:
7517                 eat(state, TOK_INT);
7518                 type = new_type(TYPE_INT | spec, 0, 0);
7519                 break;
7520         case TOK_LONG:
7521                 eat(state, TOK_LONG);
7522                 switch(peek(state)) {
7523                 case TOK_LONG:
7524                         eat(state, TOK_LONG);
7525                         error(state, 0, "long long not supported");
7526                         break;
7527                 case TOK_DOUBLE:
7528                         eat(state, TOK_DOUBLE);
7529                         error(state, 0, "long double not supported");
7530                         break;
7531                 case TOK_INT:
7532                         eat(state, TOK_INT);
7533                         type = new_type(TYPE_LONG | spec, 0, 0);
7534                         break;
7535                 default:
7536                         type = new_type(TYPE_LONG | spec, 0, 0);
7537                         break;
7538                 }
7539                 break;
7540         case TOK_FLOAT:
7541                 eat(state, TOK_FLOAT);
7542                 error(state, 0, "type float not supported");
7543                 break;
7544         case TOK_DOUBLE:
7545                 eat(state, TOK_DOUBLE);
7546                 error(state, 0, "type double not supported");
7547                 break;
7548         case TOK_SIGNED:
7549                 eat(state, TOK_SIGNED);
7550                 switch(peek(state)) {
7551                 case TOK_LONG:
7552                         eat(state, TOK_LONG);
7553                         switch(peek(state)) {
7554                         case TOK_LONG:
7555                                 eat(state, TOK_LONG);
7556                                 error(state, 0, "type long long not supported");
7557                                 break;
7558                         case TOK_INT:
7559                                 eat(state, TOK_INT);
7560                                 type = new_type(TYPE_LONG | spec, 0, 0);
7561                                 break;
7562                         default:
7563                                 type = new_type(TYPE_LONG | spec, 0, 0);
7564                                 break;
7565                         }
7566                         break;
7567                 case TOK_INT:
7568                         eat(state, TOK_INT);
7569                         type = new_type(TYPE_INT | spec, 0, 0);
7570                         break;
7571                 case TOK_SHORT:
7572                         eat(state, TOK_SHORT);
7573                         type = new_type(TYPE_SHORT | spec, 0, 0);
7574                         break;
7575                 case TOK_CHAR:
7576                         eat(state, TOK_CHAR);
7577                         type = new_type(TYPE_CHAR | spec, 0, 0);
7578                         break;
7579                 default:
7580                         type = new_type(TYPE_INT | spec, 0, 0);
7581                         break;
7582                 }
7583                 break;
7584         case TOK_UNSIGNED:
7585                 eat(state, TOK_UNSIGNED);
7586                 switch(peek(state)) {
7587                 case TOK_LONG:
7588                         eat(state, TOK_LONG);
7589                         switch(peek(state)) {
7590                         case TOK_LONG:
7591                                 eat(state, TOK_LONG);
7592                                 error(state, 0, "unsigned long long not supported");
7593                                 break;
7594                         case TOK_INT:
7595                                 eat(state, TOK_INT);
7596                                 type = new_type(TYPE_ULONG | spec, 0, 0);
7597                                 break;
7598                         default:
7599                                 type = new_type(TYPE_ULONG | spec, 0, 0);
7600                                 break;
7601                         }
7602                         break;
7603                 case TOK_INT:
7604                         eat(state, TOK_INT);
7605                         type = new_type(TYPE_UINT | spec, 0, 0);
7606                         break;
7607                 case TOK_SHORT:
7608                         eat(state, TOK_SHORT);
7609                         type = new_type(TYPE_USHORT | spec, 0, 0);
7610                         break;
7611                 case TOK_CHAR:
7612                         eat(state, TOK_CHAR);
7613                         type = new_type(TYPE_UCHAR | spec, 0, 0);
7614                         break;
7615                 default:
7616                         type = new_type(TYPE_UINT | spec, 0, 0);
7617                         break;
7618                 }
7619                 break;
7620                 /* struct or union specifier */
7621         case TOK_STRUCT:
7622         case TOK_UNION:
7623                 type = struct_or_union_specifier(state, spec);
7624                 break;
7625                 /* enum-spefifier */
7626         case TOK_ENUM:
7627                 type = enum_specifier(state, spec);
7628                 break;
7629                 /* typedef name */
7630         case TOK_TYPE_NAME:
7631                 type = typedef_name(state, spec);
7632                 break;
7633         default:
7634                 error(state, 0, "bad type specifier %s", 
7635                         tokens[peek(state)]);
7636                 break;
7637         }
7638         return type;
7639 }
7640
7641 static int istype(int tok)
7642 {
7643         switch(tok) {
7644         case TOK_CONST:
7645         case TOK_RESTRICT:
7646         case TOK_VOLATILE:
7647         case TOK_VOID:
7648         case TOK_CHAR:
7649         case TOK_SHORT:
7650         case TOK_INT:
7651         case TOK_LONG:
7652         case TOK_FLOAT:
7653         case TOK_DOUBLE:
7654         case TOK_SIGNED:
7655         case TOK_UNSIGNED:
7656         case TOK_STRUCT:
7657         case TOK_UNION:
7658         case TOK_ENUM:
7659         case TOK_TYPE_NAME:
7660                 return 1;
7661         default:
7662                 return 0;
7663         }
7664 }
7665
7666
7667 static struct type *specifier_qualifier_list(struct compile_state *state)
7668 {
7669         struct type *type;
7670         unsigned int specifiers = 0;
7671
7672         /* type qualifiers */
7673         specifiers |= type_qualifiers(state);
7674
7675         /* type specifier */
7676         type = type_specifier(state, specifiers);
7677
7678         return type;
7679 }
7680
7681 static int isdecl_specifier(int tok)
7682 {
7683         switch(tok) {
7684                 /* storage class specifier */
7685         case TOK_AUTO:
7686         case TOK_REGISTER:
7687         case TOK_STATIC:
7688         case TOK_EXTERN:
7689         case TOK_TYPEDEF:
7690                 /* type qualifier */
7691         case TOK_CONST:
7692         case TOK_RESTRICT:
7693         case TOK_VOLATILE:
7694                 /* type specifiers */
7695         case TOK_VOID:
7696         case TOK_CHAR:
7697         case TOK_SHORT:
7698         case TOK_INT:
7699         case TOK_LONG:
7700         case TOK_FLOAT:
7701         case TOK_DOUBLE:
7702         case TOK_SIGNED:
7703         case TOK_UNSIGNED:
7704                 /* struct or union specifier */
7705         case TOK_STRUCT:
7706         case TOK_UNION:
7707                 /* enum-spefifier */
7708         case TOK_ENUM:
7709                 /* typedef name */
7710         case TOK_TYPE_NAME:
7711                 /* function specifiers */
7712         case TOK_INLINE:
7713                 return 1;
7714         default:
7715                 return 0;
7716         }
7717 }
7718
7719 static struct type *decl_specifiers(struct compile_state *state)
7720 {
7721         struct type *type;
7722         unsigned int specifiers;
7723         /* I am overly restrictive in the arragement of specifiers supported.
7724          * C is overly flexible in this department it makes interpreting
7725          * the parse tree difficult.
7726          */
7727         specifiers = 0;
7728
7729         /* storage class specifier */
7730         specifiers |= storage_class_specifier_opt(state);
7731
7732         /* function-specifier */
7733         specifiers |= function_specifier_opt(state);
7734
7735         /* type qualifier */
7736         specifiers |= type_qualifiers(state);
7737
7738         /* type specifier */
7739         type = type_specifier(state, specifiers);
7740         return type;
7741 }
7742
7743 static unsigned designator(struct compile_state *state)
7744 {
7745         int tok;
7746         unsigned index;
7747         index = -1U;
7748         do {
7749                 switch(peek(state)) {
7750                 case TOK_LBRACKET:
7751                 {
7752                         struct triple *value;
7753                         eat(state, TOK_LBRACKET);
7754                         value = constant_expr(state);
7755                         eat(state, TOK_RBRACKET);
7756                         index = value->u.cval;
7757                         break;
7758                 }
7759                 case TOK_DOT:
7760                         eat(state, TOK_DOT);
7761                         eat(state, TOK_IDENT);
7762                         error(state, 0, "Struct Designators not currently supported");
7763                         break;
7764                 default:
7765                         error(state, 0, "Invalid designator");
7766                 }
7767                 tok = peek(state);
7768         } while((tok == TOK_LBRACKET) || (tok == TOK_DOT));
7769         eat(state, TOK_EQ);
7770         return index;
7771 }
7772
7773 static struct triple *initializer(
7774         struct compile_state *state, struct type *type)
7775 {
7776         struct triple *result;
7777         if (peek(state) != TOK_LBRACE) {
7778                 result = assignment_expr(state);
7779         }
7780         else {
7781                 int comma;
7782                 unsigned index, max_index;
7783                 void *buf;
7784                 max_index = index = 0;
7785                 if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
7786                         max_index = type->elements;
7787                         if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
7788                                 type->elements = 0;
7789                         }
7790                 } else {
7791                         error(state, 0, "Struct initializers not currently supported");
7792                 }
7793                 buf = xcmalloc(size_of(state, type), "initializer");
7794                 eat(state, TOK_LBRACE);
7795                 do {
7796                         struct triple *value;
7797                         struct type *value_type;
7798                         size_t value_size;
7799                         int tok;
7800                         comma = 0;
7801                         tok = peek(state);
7802                         if ((tok == TOK_LBRACKET) || (tok == TOK_DOT)) {
7803                                 index = designator(state);
7804                         }
7805                         if ((max_index != ELEMENT_COUNT_UNSPECIFIED) &&
7806                                 (index > max_index)) {
7807                                 error(state, 0, "element beyond bounds");
7808                         }
7809                         value_type = 0;
7810                         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
7811                                 value_type = type->left;
7812                         }
7813                         value = eval_const_expr(state, initializer(state, value_type));
7814                         value_size = size_of(state, value_type);
7815                         if (((type->type & TYPE_MASK) == TYPE_ARRAY) &&
7816                                 (max_index == ELEMENT_COUNT_UNSPECIFIED) &&
7817                                 (type->elements <= index)) {
7818                                 void *old_buf;
7819                                 size_t old_size;
7820                                 old_buf = buf;
7821                                 old_size = size_of(state, type);
7822                                 type->elements = index + 1;
7823                                 buf = xmalloc(size_of(state, type), "initializer");
7824                                 memcpy(buf, old_buf, old_size);
7825                                 xfree(old_buf);
7826                         }
7827                         if (value->op == OP_BLOBCONST) {
7828                                 memcpy((char *)buf + index * value_size, value->u.blob, value_size);
7829                         }
7830                         else if ((value->op == OP_INTCONST) && (value_size == 1)) {
7831                                 *(((uint8_t *)buf) + index) = value->u.cval & 0xff;
7832                         }
7833                         else if ((value->op == OP_INTCONST) && (value_size == 2)) {
7834                                 *(((uint16_t *)buf) + index) = value->u.cval & 0xffff;
7835                         }
7836                         else if ((value->op == OP_INTCONST) && (value_size == 4)) {
7837                                 *(((uint32_t *)buf) + index) = value->u.cval & 0xffffffff;
7838                         }
7839                         else {
7840                                 fprintf(stderr, "%d %d\n",
7841                                         value->op, value_size);
7842                                 internal_error(state, 0, "unhandled constant initializer");
7843                         }
7844                         if (peek(state) == TOK_COMMA) {
7845                                 eat(state, TOK_COMMA);
7846                                 comma = 1;
7847                         }
7848                         index += 1;
7849                 } while(comma && (peek(state) != TOK_RBRACE));
7850                 eat(state, TOK_RBRACE);
7851                 result = triple(state, OP_BLOBCONST, type, 0, 0);
7852                 result->u.blob = buf;
7853         }
7854         return result;
7855 }
7856
7857 static struct triple *function_definition(
7858         struct compile_state *state, struct type *type)
7859 {
7860         struct triple *def, *tmp, *first, *end;
7861         struct hash_entry *ident;
7862         struct type *param;
7863         int i;
7864         if ((type->type &TYPE_MASK) != TYPE_FUNCTION) {
7865                 error(state, 0, "Invalid function header");
7866         }
7867
7868         /* Verify the function type */
7869         if (((type->right->type & TYPE_MASK) != TYPE_VOID)  &&
7870                 ((type->right->type & TYPE_MASK) != TYPE_PRODUCT) &&
7871                 (type->right->ident == 0)) {
7872                 error(state, 0, "Invalid function parameters");
7873         }
7874         param = type->right;
7875         i = 0;
7876         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
7877                 i++;
7878                 if (!param->left->ident) {
7879                         error(state, 0, "No identifier for parameter %d\n", i);
7880                 }
7881                 param = param->right;
7882         }
7883         i++;
7884         if (((param->type & TYPE_MASK) != TYPE_VOID) && !param->ident) {
7885                 error(state, 0, "No identifier for paramter %d\n", i);
7886         }
7887         
7888         /* Get a list of statements for this function. */
7889         def = triple(state, OP_LIST, type, 0, 0);
7890
7891         /* Start a new scope for the passed parameters */
7892         start_scope(state);
7893
7894         /* Put a label at the very start of a function */
7895         first = label(state);
7896         def->left = first;
7897
7898         /* Put a label at the very end of a function */
7899         end = label(state);
7900         flatten(state, first, end);
7901
7902         /* Walk through the parameters and create symbol table entries
7903          * for them.
7904          */
7905         param = type->right;
7906         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
7907                 ident = param->left->ident;
7908                 tmp = variable(state, param->left);
7909                 symbol(state, ident, &ident->sym_ident, tmp, tmp->type);
7910                 flatten(state, end, tmp);
7911                 param = param->right;
7912         }
7913         if ((param->type & TYPE_MASK) != TYPE_VOID) {
7914                 /* And don't forget the last parameter */
7915                 ident = param->ident;
7916                 tmp = variable(state, param);
7917                 symbol(state, ident, &ident->sym_ident, tmp, tmp->type);
7918                 flatten(state, end, tmp);
7919         }
7920         /* Add a variable for the return value */
7921         def->right = 0;
7922         if ((type->left->type & TYPE_MASK) != TYPE_VOID) {
7923                 /* Remove all type qualifiers from the return type */
7924                 tmp = variable(state, clone_type(0, type->left));
7925                 flatten(state, end, tmp);
7926                 /* Remember where the return value is */
7927                 def->right = tmp;
7928         }
7929
7930         /* Remember which function I am compiling.
7931          * Also assume the last defined function is the main function.
7932          */
7933         state->main_function = def;
7934
7935         /* Now get the actual function definition */
7936         compound_statement(state, end);
7937
7938         /* Remove the parameter scope */
7939         end_scope(state);
7940 #if 0
7941         fprintf(stdout, "\n");
7942         loc(stdout, state, 0);
7943         fprintf(stdout, "\n__________ function_definition _________\n");
7944         print_triple(state, def);
7945         fprintf(stdout, "__________ function_definition _________ done\n\n");
7946 #endif
7947
7948         return def;
7949 }
7950
7951 static struct triple *do_decl(struct compile_state *state, 
7952         struct type *type, struct hash_entry *ident)
7953 {
7954         struct triple *def;
7955         def = 0;
7956         /* Clean up the storage types used */
7957         switch (type->type & STOR_MASK) {
7958         case STOR_AUTO:
7959         case STOR_STATIC:
7960                 /* These are the good types I am aiming for */
7961                 break;
7962         case STOR_REGISTER:
7963                 type->type &= ~STOR_MASK;
7964                 type->type |= STOR_AUTO;
7965                 break;
7966         case STOR_EXTERN:
7967                 type->type &= ~STOR_MASK;
7968                 type->type |= STOR_STATIC;
7969                 break;
7970         case STOR_TYPEDEF:
7971 #warning "FIXME support typedefs"
7972                 error(state, 0, "typedefs not currently supported");
7973                 break;
7974         default:
7975                 internal_error(state, 0, "Undefined storage class");
7976         }
7977         if (((type->type & STOR_MASK) == STOR_STATIC) &&
7978                 ((type->type & QUAL_CONST) == 0)) {
7979                 error(state, 0, "non const static variables not supported");
7980         }
7981         if (ident) {
7982                 def = variable(state, type);
7983                 symbol(state, ident, &ident->sym_ident, def, type);
7984         }
7985         return def;
7986 }
7987
7988 static void decl(struct compile_state *state, struct triple *first)
7989 {
7990         struct type *base_type, *type;
7991         struct hash_entry *ident;
7992         struct triple *def;
7993         int global;
7994         global = (state->scope_depth <= GLOBAL_SCOPE_DEPTH);
7995         base_type = decl_specifiers(state);
7996         ident = 0;
7997         type = declarator(state, base_type, &ident, 0);
7998         if (global && ident && (peek(state) == TOK_LBRACE)) {
7999                 /* function */
8000                 def = function_definition(state, type);
8001                 symbol(state, ident, &ident->sym_ident, def, type);
8002         }
8003         else {
8004                 int done;
8005                 flatten(state, first, do_decl(state, type, ident));
8006                 /* type or variable definition */
8007                 do {
8008                         done = 1;
8009                         if (peek(state) == TOK_EQ) {
8010                                 if (!ident) {
8011                                         error(state, 0, "cannot assign to a type");
8012                                 }
8013                                 eat(state, TOK_EQ);
8014                                 flatten(state, first,
8015                                         init_expr(state, 
8016                                                 ident->sym_ident->def, 
8017                                                 initializer(state, type)));
8018                         }
8019                         arrays_complete(state, type);
8020                         if (peek(state) == TOK_COMMA) {
8021                                 eat(state, TOK_COMMA);
8022                                 ident = 0;
8023                                 type = declarator(state, base_type, &ident, 0);
8024                                 flatten(state, first, do_decl(state, type, ident));
8025                                 done = 0;
8026                         }
8027                 } while(!done);
8028                 eat(state, TOK_SEMI);
8029         }
8030 }
8031
8032 static void decls(struct compile_state *state)
8033 {
8034         struct triple *list;
8035         int tok;
8036         list = label(state);
8037         while(1) {
8038                 tok = peek(state);
8039                 if (tok == TOK_EOF) {
8040                         return;
8041                 }
8042                 if (tok == TOK_SPACE) {
8043                         eat(state, TOK_SPACE);
8044                 }
8045                 decl(state, list);
8046                 if (list->next != list) {
8047                         error(state, 0, "global variables not supported");
8048                 }
8049         }
8050 }
8051
8052 /*
8053  * Data structurs for optimation.
8054  */
8055
8056 static void do_use_block(
8057         struct block *used, struct block_set **head, struct block *user, 
8058         int front)
8059 {
8060         struct block_set **ptr, *new;
8061         if (!used)
8062                 return;
8063         if (!user)
8064                 return;
8065         ptr = head;
8066         while(*ptr) {
8067                 if ((*ptr)->member == user) {
8068                         return;
8069                 }
8070                 ptr = &(*ptr)->next;
8071         }
8072         new = xcmalloc(sizeof(*new), "block_set");
8073         new->member = user;
8074         if (front) {
8075                 new->next = *head;
8076                 *head = new;
8077         }
8078         else {
8079                 new->next = 0;
8080                 *ptr = new;
8081         }
8082 }
8083 static void do_unuse_block(
8084         struct block *used, struct block_set **head, struct block *unuser)
8085 {
8086         struct block_set *use, **ptr;
8087         ptr = head;
8088         while(*ptr) {
8089                 use = *ptr;
8090                 if (use->member == unuser) {
8091                         *ptr = use->next;
8092                         memset(use, -1, sizeof(*use));
8093                         xfree(use);
8094                 }
8095                 else {
8096                         ptr = &use->next;
8097                 }
8098         }
8099 }
8100
8101 static void use_block(struct block *used, struct block *user)
8102 {
8103         /* Append new to the head of the list, print_block
8104          * depends on this.
8105          */
8106         do_use_block(used, &used->use, user, 1); 
8107         used->users++;
8108 }
8109 static void unuse_block(struct block *used, struct block *unuser)
8110 {
8111         do_unuse_block(used, &used->use, unuser); 
8112         used->users--;
8113 }
8114
8115 static void idom_block(struct block *idom, struct block *user)
8116 {
8117         do_use_block(idom, &idom->idominates, user, 0);
8118 }
8119
8120 static void unidom_block(struct block *idom, struct block *unuser)
8121 {
8122         do_unuse_block(idom, &idom->idominates, unuser);
8123 }
8124
8125 static void domf_block(struct block *block, struct block *domf)
8126 {
8127         do_use_block(block, &block->domfrontier, domf, 0);
8128 }
8129
8130 static void undomf_block(struct block *block, struct block *undomf)
8131 {
8132         do_unuse_block(block, &block->domfrontier, undomf);
8133 }
8134
8135 static void ipdom_block(struct block *ipdom, struct block *user)
8136 {
8137         do_use_block(ipdom, &ipdom->ipdominates, user, 0);
8138 }
8139
8140 static void unipdom_block(struct block *ipdom, struct block *unuser)
8141 {
8142         do_unuse_block(ipdom, &ipdom->ipdominates, unuser);
8143 }
8144
8145 static void ipdomf_block(struct block *block, struct block *ipdomf)
8146 {
8147         do_use_block(block, &block->ipdomfrontier, ipdomf, 0);
8148 }
8149
8150 static void unipdomf_block(struct block *block, struct block *unipdomf)
8151 {
8152         do_unuse_block(block, &block->ipdomfrontier, unipdomf);
8153 }
8154
8155
8156
8157 static int do_walk_triple(struct compile_state *state,
8158         struct triple *ptr, int depth,
8159         int (*cb)(struct compile_state *state, struct triple *ptr, int depth)) 
8160 {
8161         int result;
8162         result = cb(state, ptr, depth);
8163         if ((result == 0) && (ptr->op == OP_LIST)) {
8164                 struct triple *list;
8165                 list = ptr;
8166                 ptr = list->left;
8167                 do {
8168                         result = do_walk_triple(state, ptr, depth + 1, cb);
8169                         if (ptr->next->prev != ptr) {
8170                                 internal_error(state, ptr->next, "bad prev");
8171                         }
8172                         ptr = ptr->next;
8173                         
8174                 } while((result == 0) && (ptr != list->left));
8175         }
8176         return result;
8177 }
8178
8179 static int walk_triple(
8180         struct compile_state *state, 
8181         struct triple *ptr, 
8182         int (*cb)(struct compile_state *state, struct triple *ptr, int depth))
8183 {
8184         return do_walk_triple(state, ptr, 0, cb);
8185 }
8186
8187 static void do_print_prefix(int depth)
8188 {
8189         int i;
8190         for(i = 0; i < depth; i++) {
8191                 printf("  ");
8192         }
8193 }
8194
8195 #define PRINT_LIST 1
8196 static int do_print_triple(struct compile_state *state, struct triple *ins, int depth)
8197 {
8198         int op;
8199         op = ins->op;
8200         if (op == OP_LIST) {
8201 #if !PRINT_LIST
8202                 return 0;
8203 #endif
8204         }
8205         else if ((op == OP_LABEL) && (ins->use)) {
8206                 printf("\n%p:\n", ins);
8207         }
8208         else if (op == OP_INTCONST) {
8209                 do_print_prefix(depth);
8210                 printf("(%p) %-7s %08lx             @ %s:%d.%d\n",
8211                         ins, tops(ins->op), ins->u.cval,
8212                         ins->filename, ins->line, ins->col);
8213                 return 0;
8214         }
8215         else if (op == OP_SDECL) {
8216                 do_print_prefix(depth);
8217                 printf("(%p) %-7s %-10p            @ %s:%d.%d\n",
8218                         ins, tops(ins->op), ins->left,
8219                         ins->filename, ins->line, ins->col);
8220                 do_print_triple(state, ins->left, depth + 1);
8221         }
8222         do_print_prefix(depth);
8223         printf("%s(%p) %-7s %-10p %-10p @ %s:%d.%d\n",
8224                 (op == OP_LIST)? "list: ": "", 
8225                 ins, tops(ins->op), ins->left, ins->right,
8226                 ins->filename, ins->line, ins->col);
8227         if ((ins->op == OP_BRANCH) && ins->use) {
8228                 internal_error(state, ins, "branch used?");
8229         }
8230 #if 0
8231         {
8232                 struct triple_set *user;
8233                 for(user = ins->use; user; user = user->next) {
8234                         printf("use: %p\n", user->member);
8235                 }
8236         }
8237 #endif
8238         if (triple_is_branch(ins)) {
8239                 printf("\n");
8240         }
8241         return 0;
8242 }
8243
8244 static void print_triple(struct compile_state *state, struct triple *ins)
8245 {
8246         walk_triple(state, ins, do_print_triple);
8247 }
8248
8249 static void print_triples(struct compile_state *state)
8250 {
8251         print_triple(state, state->main_function);
8252 }
8253
8254 struct cf_block {
8255         struct block *block;
8256 };
8257 static void find_cf_blocks(struct cf_block *cf, struct block *block)
8258 {
8259         if (!block || (cf[block->vertex].block == block)) {
8260                 return;
8261         }
8262         cf[block->vertex].block = block;
8263         find_cf_blocks(cf, block->left);
8264         find_cf_blocks(cf, block->right);
8265 }
8266
8267 static void print_control_flow(struct compile_state *state)
8268 {
8269         struct cf_block *cf;
8270         int i;
8271         printf("\ncontrol flow\n");
8272         cf = xcmalloc(sizeof(*cf) * (state->last_vertex + 1), "cf_block");
8273         find_cf_blocks(cf, state->first_block);
8274
8275         for(i = 1; i <= state->last_vertex; i++) {
8276                 struct block *block;
8277                 block = cf[i].block;
8278                 if (!block)
8279                         continue;
8280                 printf("(%p) %d:", block, block->vertex);
8281                 if (block->left) {
8282                         printf(" %d", block->left->vertex);
8283                 }
8284                 if (block->right && (block->right != block->left)) {
8285                         printf(" %d", block->right->vertex);
8286                 }
8287                 printf("\n");
8288         }
8289
8290         xfree(cf);
8291 }
8292
8293
8294 static struct block *basic_block(struct compile_state *state,
8295         struct triple *first)
8296 {
8297         struct block *block;
8298         struct triple *ptr;
8299         int op;
8300         if (first->op != OP_LABEL) {
8301                 internal_error(state, 0, "block does not start with a label");
8302         }
8303         /* See if this basic block has already been setup */
8304         if (first->u.block != 0) {
8305                 return first->u.block;
8306         }
8307         /* Allocate another basic block structure */
8308         state->last_vertex += 1;
8309         block = xcmalloc(sizeof(*block), "block");
8310         block->first = block->last = first;
8311         block->vertex = state->last_vertex;
8312         ptr = first;
8313         do {
8314                 if ((ptr != first) && (ptr->op == OP_LABEL) && ptr->use) {
8315                         break;
8316                 }
8317                 block->last = ptr;
8318                 /* If ptr->u is not used remember where the baic block is */
8319                 if (!is_const(ptr)) {
8320                         ptr->u.block = block;
8321                 }
8322                 if (ptr->op == OP_BRANCH) {
8323                         break;
8324                 }
8325                 ptr = ptr->next;
8326         } while (ptr != state->main_function->left);
8327         if (ptr == state->main_function->left)
8328                 return block;
8329         op = ptr->op;
8330         if (op == OP_LABEL) {
8331                 block->left = basic_block(state, ptr);
8332                 block->right = 0;
8333                 use_block(block->left, block);
8334         }
8335         else if (op == OP_BRANCH) {
8336                 block->left = 0;
8337                 /* Trace the branch target */
8338                 block->right = basic_block(state, ptr->left);
8339                 use_block(block->right, block);
8340                 /* If there is a test trace the branch as well */
8341                 if (ptr->right) {
8342                         block->left = basic_block(state, ptr->next);
8343                         use_block(block->left, block);
8344                 }
8345         }
8346         else {
8347                 internal_error(state, 0, "Bad basic block split");
8348         }
8349         return block;
8350 }
8351
8352
8353 static void walk_blocks(struct compile_state *state,
8354         void (*cb)(struct compile_state *state, struct block *block, void *arg),
8355         void *arg)
8356 {
8357         struct triple *ptr, *first;
8358         struct block *last_block;
8359         last_block = 0;
8360         first = state->main_function->left;
8361         ptr = first;
8362         do {
8363                 struct block *block;
8364                 if (ptr->op == OP_LABEL) {
8365                         block = ptr->u.block;
8366                         if (block && (block != last_block)) {
8367                                 cb(state, block, arg);
8368                         }
8369                         last_block = block;
8370                 }
8371                 ptr = ptr->next;
8372         } while(ptr != first);
8373 }
8374
8375 static void print_block(
8376         struct compile_state *state, struct block *block, void *arg)
8377 {
8378         struct triple *ptr;
8379
8380         printf("\nblock: %p (%d), %p<-%p %p<-%p\n", 
8381                 block, 
8382                 block->vertex,
8383                 block->left, 
8384                 block->left && block->left->use?block->left->use->member : 0,
8385                 block->right, 
8386                 block->right && block->right->use?block->right->use->member : 0);
8387         if (block->first->op == OP_LABEL) {
8388                 printf("%p:\n", block->first);
8389         }
8390         for(ptr = block->first; ; ptr = ptr->next) {
8391                 struct triple_set *user;
8392                 int op = ptr->op;
8393                 
8394                 if (!IS_CONST_OP(op)) {
8395                         if (ptr->u.block != block) {
8396                                 internal_error(state, ptr, 
8397                                         "Wrong block pointer: %p\n",
8398                                         ptr->u.block);
8399                         }
8400                 }
8401                 if (op == OP_ADECL) {
8402                         for(user = ptr->use; user; user = user->next) {
8403                                 if (!user->member->u.block) {
8404                                         internal_error(state, user->member, 
8405                                                 "Use %p not in a block?\n",
8406                                                 user->member);
8407                                 }
8408                         }
8409                 }
8410                 if (op == OP_INTCONST) {
8411                         printf("(%p) %3d %-7s %08lx              @ %s:%d.%d\n",
8412                                 ptr, ID_REG(ptr->id), tops(ptr->op), 
8413                                 ptr->u.cval,
8414                                 ptr->filename, ptr->line, ptr->col);
8415                 }
8416                 else if (op == OP_PHI) {
8417                         struct triple **slot;
8418                         struct block *block;
8419                         int edge;
8420                         block = ptr->u.block;
8421                         slot  = (struct triple **)(ptr->left);
8422                         printf("(%p) %3d %-7s",
8423                                 ptr, ID_REG(ptr->id), tops(ptr->op));
8424                         for(edge = 0; edge < block->users; edge++) {
8425                                 printf(" %-10p", slot[edge]);
8426                         }
8427                         printf(" @%s:%d.%d\n", 
8428                                 ptr->filename, ptr->line, ptr->col);
8429                 }
8430                 else {
8431                         printf("(%p) %3d %-7s %-10p %-10p @ %s:%d.%d\n",
8432                                 ptr, ID_REG(ptr->id), tops(ptr->op), 
8433                                 ptr->left, ptr->right,
8434                                 ptr->filename, ptr->line, ptr->col);
8435                 }
8436                 /* Sanity checks... */
8437                 valid_op(state, ptr);
8438                 for(user = ptr->use; user; user = user->next) {
8439                         struct triple *use;
8440                         use = user->member;
8441                         valid_op(state, use);
8442                         if (!IS_CONST_OP(user->member->op) &&
8443                                 !user->member->u.block) {
8444                                 internal_error(state, user->member,
8445                                         "Use %p not in a block?",
8446                                         user->member);
8447                         }
8448                 }
8449
8450                 if (ptr == block->last)
8451                         break;
8452         }
8453         printf("\n");
8454 }
8455
8456
8457 static void print_blocks(struct compile_state *state)
8458 {
8459         printf("--------------- blocks ---------------\n");
8460         walk_blocks(state, print_block, 0);
8461 }
8462
8463 static void prune_nonblock_triples(struct compile_state *state)
8464 {
8465         struct block *block;
8466         struct triple *first, *ins;
8467         /* Delete the triples not in a basic block */
8468         first = state->main_function->left;
8469         block = 0;
8470         ins = first;
8471         do {
8472                 if (ins->op == OP_LABEL) {
8473                         block = ins->u.block;
8474                 }
8475                 ins = ins->next;
8476                 if (!block) {
8477                         release_triple(state, ins->prev);
8478                 }
8479         } while(ins != first);
8480 }
8481
8482 static void setup_basic_blocks(struct compile_state *state)
8483 {
8484         /* Find the basic blocks */
8485         state->last_vertex = 0;
8486         state->first_block = basic_block(state, state->main_function->left);
8487         /* Delete the triples not in a basic block */
8488         prune_nonblock_triples(state);
8489         /* Find the last basic block */
8490         state->last_block = state->main_function->left->prev->u.block;
8491         if (!state->last_block) {
8492                 internal_error(state, 0, "end not used?");
8493         }
8494         /* Insert an extra unused edge from start to the end 
8495          * This helps with reverse control flow calculations.
8496          */
8497         use_block(state->first_block, state->last_block);
8498         /* If we are debugging print what I have just done */
8499         if (state->debug & DEBUG_BASIC_BLOCKS) {
8500                 print_blocks(state);
8501                 print_control_flow(state);
8502         }
8503 }
8504
8505 static void free_basic_block(struct compile_state *state, struct block *block)
8506 {
8507         struct block_set *entry, *next;
8508         struct block *child;
8509         if (!block) {
8510                 return;
8511         }
8512         if (block->vertex == -1) {
8513                 return;
8514         }
8515         block->vertex = -1;
8516         if (block->left) {
8517                 unuse_block(block->left, block);
8518         }
8519         if (block->right) {
8520                 unuse_block(block->right, block);
8521         }
8522         if (block->idom) {
8523                 unidom_block(block->idom, block);
8524         }
8525         block->idom = 0;
8526         if (block->ipdom) {
8527                 unipdom_block(block->ipdom, block);
8528         }
8529         block->ipdom = 0;
8530         for(entry = block->use; entry; entry = next) {
8531                 next = entry->next;
8532                 child = entry->member;
8533                 unuse_block(block, child);
8534                 if (child->left == block) {
8535                         child->left = 0;
8536                 }
8537                 if (child->right == block) {
8538                         child->right = 0;
8539                 }
8540         }
8541         for(entry = block->idominates; entry; entry = next) {
8542                 next = entry->next;
8543                 child = entry->member;
8544                 unidom_block(block, child);
8545                 child->idom = 0;
8546         }
8547         for(entry = block->domfrontier; entry; entry = next) {
8548                 next = entry->next;
8549                 child = entry->member;
8550                 undomf_block(block, child);
8551         }
8552         for(entry = block->ipdominates; entry; entry = next) {
8553                 next = entry->next;
8554                 child = entry->member;
8555                 unipdom_block(block, child);
8556                 child->ipdom = 0;
8557         }
8558         for(entry = block->ipdomfrontier; entry; entry = next) {
8559                 next = entry->next;
8560                 child = entry->member;
8561                 unipdomf_block(block, child);
8562         }
8563         if (block->users != 0) {
8564                 internal_error(state, 0, "block still has users");
8565         }
8566         free_basic_block(state, block->left);
8567         block->left = 0;
8568         free_basic_block(state, block->right);
8569         block->right = 0;
8570         memset(block, -1, sizeof(*block));
8571         xfree(block);
8572 }
8573
8574 static void free_basic_blocks(struct compile_state *state)
8575 {
8576         struct triple *first, *ins;
8577         free_basic_block(state, state->first_block);
8578         state->last_vertex = 0;
8579         state->first_block = state->last_block = 0;
8580         first = state->main_function->left;
8581         ins = first;
8582         do {
8583                 if (!is_const(ins)) {
8584                         ins->u.block = 0;
8585                 }
8586                 ins = ins->next;
8587         } while(ins != first);
8588         
8589 }
8590
8591 struct sdom_block {
8592         struct block *block;
8593         struct sdom_block *sdominates;
8594         struct sdom_block *sdom_next;
8595         struct sdom_block *sdom;
8596         struct sdom_block *label;
8597         struct sdom_block *parent;
8598         struct sdom_block *ancestor;
8599         int vertex;
8600 };
8601
8602
8603 static void unsdom_block(struct sdom_block *block)
8604 {
8605         struct sdom_block **ptr;
8606         if (!block->sdom_next) {
8607                 return;
8608         }
8609         ptr = &block->sdom->sdominates;
8610         while(*ptr) {
8611                 if ((*ptr) == block) {
8612                         *ptr = block->sdom_next;
8613                         return;
8614                 }
8615                 ptr = &(*ptr)->sdom_next;
8616         }
8617 }
8618
8619 static void sdom_block(struct sdom_block *sdom, struct sdom_block *block)
8620 {
8621         unsdom_block(block);
8622         block->sdom = sdom;
8623         block->sdom_next = sdom->sdominates;
8624         sdom->sdominates = block;
8625 }
8626
8627
8628
8629 static int initialize_sdblock(struct sdom_block *sd,
8630         struct block *parent, struct block *block, int vertex)
8631 {
8632         if (!block || (sd[block->vertex].block == block)) {
8633                 return vertex;
8634         }
8635         vertex += 1;
8636         /* Renumber the blocks in a convinient fashion */
8637         block->vertex = vertex;
8638         sd[vertex].block    = block;
8639         sd[vertex].sdom     = &sd[vertex];
8640         sd[vertex].label    = &sd[vertex];
8641         sd[vertex].parent   = parent? &sd[parent->vertex] : 0;
8642         sd[vertex].ancestor = 0;
8643         sd[vertex].vertex   = vertex;
8644         vertex = initialize_sdblock(sd, block, block->left, vertex);
8645         vertex = initialize_sdblock(sd, block, block->right, vertex);
8646         return vertex;
8647 }
8648
8649 static int initialize_sdpblock(struct sdom_block *sd,
8650         struct block *parent, struct block *block, int vertex)
8651 {
8652         struct block_set *user;
8653         if (!block || (sd[block->vertex].block == block)) {
8654                 return vertex;
8655         }
8656         vertex += 1;
8657         /* Renumber the blocks in a convinient fashion */
8658         block->vertex = vertex;
8659         sd[vertex].block    = block;
8660         sd[vertex].sdom     = &sd[vertex];
8661         sd[vertex].label    = &sd[vertex];
8662         sd[vertex].parent   = parent? &sd[parent->vertex] : 0;
8663         sd[vertex].ancestor = 0;
8664         sd[vertex].vertex   = vertex;
8665         for(user = block->use; user; user = user->next) {
8666                 vertex = initialize_sdpblock(sd, block, user->member, vertex);
8667         }
8668         return vertex;
8669 }
8670
8671 static void compress_ancestors(struct sdom_block *v)
8672 {
8673         /* This procedure assumes ancestor(v) != 0 */
8674         /* if (ancestor(ancestor(v)) != 0) {
8675          *      compress(ancestor(ancestor(v)));
8676          *      if (semi(label(ancestor(v))) < semi(label(v))) {
8677          *              label(v) = label(ancestor(v));
8678          *      }
8679          *      ancestor(v) = ancestor(ancestor(v));
8680          * }
8681          */
8682         if (!v->ancestor) {
8683                 return;
8684         }
8685         if (v->ancestor->ancestor) {
8686                 compress_ancestors(v->ancestor->ancestor);
8687                 if (v->ancestor->label->sdom->vertex < v->label->sdom->vertex) {
8688                         v->label = v->ancestor->label;
8689                 }
8690                 v->ancestor = v->ancestor->ancestor;
8691         }
8692 }
8693
8694 static void compute_sdom(struct compile_state *state, struct sdom_block *sd)
8695 {
8696         int i;
8697         /* // step 2 
8698          *  for each v <= pred(w) {
8699          *      u = EVAL(v);
8700          *      if (semi[u] < semi[w] { 
8701          *              semi[w] = semi[u]; 
8702          *      } 
8703          * }
8704          * add w to bucket(vertex(semi[w]));
8705          * LINK(parent(w), w);
8706          *
8707          * // step 3
8708          * for each v <= bucket(parent(w)) {
8709          *      delete v from bucket(parent(w));
8710          *      u = EVAL(v);
8711          *      dom(v) = (semi[u] < semi[v]) ? u : parent(w);
8712          * }
8713          */
8714         for(i = state->last_vertex; i >= 2; i--) {
8715                 struct sdom_block *v, *parent, *next;
8716                 struct block_set *user;
8717                 struct block *block;
8718                 block = sd[i].block;
8719                 parent = sd[i].parent;
8720                 /* Step 2 */
8721                 for(user = block->use; user; user = user->next) {
8722                         struct sdom_block *v, *u;
8723                         v = &sd[user->member->vertex];
8724                         u = !(v->ancestor)? v : (compress_ancestors(v), v->label);
8725                         if (u->sdom->vertex < sd[i].sdom->vertex) {
8726                                 sd[i].sdom = u->sdom;
8727                         }
8728                 }
8729                 sdom_block(sd[i].sdom, &sd[i]);
8730                 sd[i].ancestor = parent;
8731                 /* Step 3 */
8732                 for(v = parent->sdominates; v; v = next) {
8733                         struct sdom_block *u;
8734                         next = v->sdom_next;
8735                         unsdom_block(v);
8736                         u = (!v->ancestor) ? v : (compress_ancestors(v), v->label);
8737                         v->block->idom = (u->sdom->vertex < v->sdom->vertex)? 
8738                                 u->block : parent->block;
8739                 }
8740         }
8741 }
8742
8743 static void compute_spdom(struct compile_state *state, struct sdom_block *sd)
8744 {
8745         int i;
8746         /* // step 2 
8747          *  for each v <= pred(w) {
8748          *      u = EVAL(v);
8749          *      if (semi[u] < semi[w] { 
8750          *              semi[w] = semi[u]; 
8751          *      } 
8752          * }
8753          * add w to bucket(vertex(semi[w]));
8754          * LINK(parent(w), w);
8755          *
8756          * // step 3
8757          * for each v <= bucket(parent(w)) {
8758          *      delete v from bucket(parent(w));
8759          *      u = EVAL(v);
8760          *      dom(v) = (semi[u] < semi[v]) ? u : parent(w);
8761          * }
8762          */
8763         for(i = state->last_vertex; i >= 2; i--) {
8764                 struct sdom_block *u, *v, *parent, *next;
8765                 struct block *block;
8766                 block = sd[i].block;
8767                 parent = sd[i].parent;
8768                 /* Step 2 */
8769                 if (block->left) {
8770                         v = &sd[block->left->vertex];
8771                         u = !(v->ancestor)? v : (compress_ancestors(v), v->label);
8772                         if (u->sdom->vertex < sd[i].sdom->vertex) {
8773                                 sd[i].sdom = u->sdom;
8774                         }
8775                 }
8776                 if (block->right && (block->right != block->left)) {
8777                         v = &sd[block->right->vertex];
8778                         u = !(v->ancestor)? v : (compress_ancestors(v), v->label);
8779                         if (u->sdom->vertex < sd[i].sdom->vertex) {
8780                                 sd[i].sdom = u->sdom;
8781                         }
8782                 }
8783                 sdom_block(sd[i].sdom, &sd[i]);
8784                 sd[i].ancestor = parent;
8785                 /* Step 3 */
8786                 for(v = parent->sdominates; v; v = next) {
8787                         struct sdom_block *u;
8788                         next = v->sdom_next;
8789                         unsdom_block(v);
8790                         u = (!v->ancestor) ? v : (compress_ancestors(v), v->label);
8791                         v->block->ipdom = (u->sdom->vertex < v->sdom->vertex)? 
8792                                 u->block : parent->block;
8793                 }
8794         }
8795 }
8796
8797 static void compute_idom(struct compile_state *state, struct sdom_block *sd)
8798 {
8799         int i;
8800         for(i = 2; i <= state->last_vertex; i++) {
8801                 struct block *block;
8802                 block = sd[i].block;
8803                 if (block->idom->vertex != sd[i].sdom->vertex) {
8804                         block->idom = block->idom->idom;
8805                 }
8806                 idom_block(block->idom, block);
8807         }
8808         sd[1].block->idom = 0;
8809 }
8810
8811 static void compute_ipdom(struct compile_state *state, struct sdom_block *sd)
8812 {
8813         int i;
8814         for(i = 2; i <= state->last_vertex; i++) {
8815                 struct block *block;
8816                 block = sd[i].block;
8817                 if (block->ipdom->vertex != sd[i].sdom->vertex) {
8818                         block->ipdom = block->ipdom->ipdom;
8819                 }
8820                 ipdom_block(block->ipdom, block);
8821         }
8822         sd[1].block->ipdom = 0;
8823 }
8824
8825         /* Theorem 1:
8826          *   Every vertex of a flowgraph G = (V, E, r) except r has
8827          *   a unique immediate dominator.  
8828          *   The edges {(idom(w), w) |w <= V - {r}} form a directed tree
8829          *   rooted at r, called the dominator tree of G, such that 
8830          *   v dominates w if and only if v is a proper ancestor of w in
8831          *   the dominator tree.
8832          */
8833         /* Lemma 1:  
8834          *   If v and w are vertices of G such that v <= w,
8835          *   than any path from v to w must contain a common ancestor
8836          *   of v and w in T.
8837          */
8838         /* Lemma 2:  For any vertex w != r, idom(w) -> w */
8839         /* Lemma 3:  For any vertex w != r, sdom(w) -> w */
8840         /* Lemma 4:  For any vertex w != r, idom(w) -> sdom(w) */
8841         /* Theorem 2:
8842          *   Let w != r.  Suppose every u for which sdom(w) -> u -> w satisfies
8843          *   sdom(u) >= sdom(w).  Then idom(w) = sdom(w).
8844          */
8845         /* Theorem 3:
8846          *   Let w != r and let u be a vertex for which sdom(u) is 
8847          *   minimum amoung vertices u satisfying sdom(w) -> u -> w.
8848          *   Then sdom(u) <= sdom(w) and idom(u) = idom(w).
8849          */
8850         /* Lemma 5:  Let vertices v,w satisfy v -> w.
8851          *           Then v -> idom(w) or idom(w) -> idom(v)
8852          */
8853
8854 static void find_immediate_dominators(struct compile_state *state)
8855 {
8856         struct sdom_block *sd;
8857         /* w->sdom = min{v| there is a path v = v0,v1,...,vk = w such that:
8858          *           vi > w for (1 <= i <= k - 1}
8859          */
8860         /* Theorem 4:
8861          *   For any vertex w != r.
8862          *   sdom(w) = min(
8863          *                 {v|(v,w) <= E  and v < w } U 
8864          *                 {sdom(u) | u > w and there is an edge (v, w) such that u -> v})
8865          */
8866         /* Corollary 1:
8867          *   Let w != r and let u be a vertex for which sdom(u) is 
8868          *   minimum amoung vertices u satisfying sdom(w) -> u -> w.
8869          *   Then:
8870          *                   { sdom(w) if sdom(w) = sdom(u),
8871          *        idom(w) = {
8872          *                   { idom(u) otherwise
8873          */
8874         /* The algorithm consists of the following 4 steps.
8875          * Step 1.  Carry out a depth-first search of the problem graph.  
8876          *    Number the vertices from 1 to N as they are reached during
8877          *    the search.  Initialize the variables used in succeeding steps.
8878          * Step 2.  Compute the semidominators of all vertices by applying
8879          *    theorem 4.   Carry out the computation vertex by vertex in
8880          *    decreasing order by number.
8881          * Step 3.  Implicitly define the immediate dominator of each vertex
8882          *    by applying Corollary 1.
8883          * Step 4.  Explicitly define the immediate dominator of each vertex,
8884          *    carrying out the computation vertex by vertex in increasing order
8885          *    by number.
8886          */
8887         /* Step 1 initialize the basic block information */
8888         sd = xcmalloc(sizeof(*sd) * (state->last_vertex + 1), "sdom_state");
8889         initialize_sdblock(sd, 0, state->first_block, 0);
8890 #if 0
8891         sd[1].size  = 0;
8892         sd[1].label = 0;
8893         sd[1].sdom  = 0;
8894 #endif
8895         /* Step 2 compute the semidominators */
8896         /* Step 3 implicitly define the immediate dominator of each vertex */
8897         compute_sdom(state, sd);
8898         /* Step 4 explicitly define the immediate dominator of each vertex */
8899         compute_idom(state, sd);
8900         xfree(sd);
8901 }
8902
8903 static void find_post_dominators(struct compile_state *state)
8904 {
8905         struct sdom_block *sd;
8906         /* Step 1 initialize the basic block information */
8907         sd = xcmalloc(sizeof(*sd) * (state->last_vertex + 1), "sdom_state");
8908
8909         initialize_sdpblock(sd, 0, state->last_block, 0);
8910
8911         /* Step 2 compute the semidominators */
8912         /* Step 3 implicitly define the immediate dominator of each vertex */
8913         compute_spdom(state, sd);
8914         /* Step 4 explicitly define the immediate dominator of each vertex */
8915         compute_ipdom(state, sd);
8916         xfree(sd);
8917 }
8918
8919
8920
8921 static void find_block_domf(struct compile_state *state, struct block *block)
8922 {
8923         struct block *child;
8924         struct block_set *user;
8925         if (block->domfrontier != 0) {
8926                 internal_error(state, block->first, "domfrontier present?");
8927         }
8928         for(user = block->idominates; user; user = user->next) {
8929                 child = user->member;
8930                 if (child->idom != block) {
8931                         internal_error(state, block->first, "bad idom");
8932                 }
8933                 find_block_domf(state, child);
8934         }
8935         if (block->left && block->left->idom != block) {
8936                 domf_block(block, block->left);
8937         }
8938         if (block->right && block->right->idom != block) {
8939                 domf_block(block, block->right);
8940         }
8941         for(user = block->idominates; user; user = user->next) {
8942                 struct block_set *frontier;
8943                 child = user->member;
8944                 for(frontier = child->domfrontier; frontier; frontier = frontier->next) {
8945                         if (frontier->member->idom != block) {
8946                                 domf_block(block, frontier->member);
8947                         }
8948                 }
8949         }
8950 }
8951
8952 static void find_block_ipdomf(struct compile_state *state, struct block *block)
8953 {
8954         struct block *child;
8955         struct block_set *user;
8956         if (block->ipdomfrontier != 0) {
8957                 internal_error(state, block->first, "ipdomfrontier present?");
8958         }
8959         for(user = block->ipdominates; user; user = user->next) {
8960                 child = user->member;
8961                 if (child->ipdom != block) {
8962                         internal_error(state, block->first, "bad ipdom");
8963                 }
8964                 find_block_ipdomf(state, child);
8965         }
8966         if (block->left && block->left->ipdom != block) {
8967                 ipdomf_block(block, block->left);
8968         }
8969         if (block->right && block->right->ipdom != block) {
8970                 ipdomf_block(block, block->right);
8971         }
8972         for(user = block->idominates; user; user = user->next) {
8973                 struct block_set *frontier;
8974                 child = user->member;
8975                 for(frontier = child->ipdomfrontier; frontier; frontier = frontier->next) {
8976                         if (frontier->member->ipdom != block) {
8977                                 ipdomf_block(block, frontier->member);
8978                         }
8979                 }
8980         }
8981 }
8982
8983 static int print_dominated(
8984         struct compile_state *state, struct block *block, int vertex)
8985 {
8986         struct block_set *user;
8987
8988         if (!block || (block->vertex != vertex + 1)) {
8989                 return vertex;
8990         }
8991         vertex += 1;
8992
8993         printf("%d:", block->vertex);
8994         for(user = block->idominates; user; user = user->next) {
8995                 printf(" %d", user->member->vertex);
8996                 if (user->member->idom != block) {
8997                         internal_error(state, user->member->first, "bad idom");
8998                 }
8999         }
9000         printf("\n");
9001         vertex = print_dominated(state, block->left, vertex);
9002         vertex = print_dominated(state, block->right, vertex);
9003         return vertex;
9004 }
9005
9006 static void print_dominators(struct compile_state *state)
9007 {
9008         printf("\ndominates\n");
9009         print_dominated(state, state->first_block, 0);
9010 }
9011
9012
9013 static int print_frontiers(
9014         struct compile_state *state, struct block *block, int vertex)
9015 {
9016         struct block_set *user;
9017
9018         if (!block || (block->vertex != vertex + 1)) {
9019                 return vertex;
9020         }
9021         vertex += 1;
9022
9023         printf("%d:", block->vertex);
9024         for(user = block->domfrontier; user; user = user->next) {
9025                 printf(" %d", user->member->vertex);
9026         }
9027         printf("\n");
9028
9029         vertex = print_frontiers(state, block->left, vertex);
9030         vertex = print_frontiers(state, block->right, vertex);
9031         return vertex;
9032 }
9033 static void print_dominance_frontiers(struct compile_state *state)
9034 {
9035         printf("\ndominance frontiers\n");
9036         print_frontiers(state, state->first_block, 0);
9037         
9038 }
9039
9040 static void analyze_idominators(struct compile_state *state)
9041 {
9042         /* Find the immediate dominators */
9043         find_immediate_dominators(state);
9044         /* Find the dominance frontiers */
9045         find_block_domf(state, state->first_block);
9046         /* If debuging print the print what I have just found */
9047         if (state->debug & DEBUG_FDOMINATORS) {
9048                 print_dominators(state);
9049                 print_dominance_frontiers(state);
9050                 print_control_flow(state);
9051         }
9052 }
9053
9054
9055
9056 static int print_ipdominated(
9057         struct compile_state *state, struct block *block, int vertex)
9058 {
9059         struct block_set *user;
9060
9061         if (!block || (block->vertex != vertex + 1)) {
9062                 return vertex;
9063         }
9064         vertex += 1;
9065
9066         printf("%d:", block->vertex);
9067         for(user = block->ipdominates; user; user = user->next) {
9068                 printf(" %d", user->member->vertex);
9069                 if (user->member->ipdom != block) {
9070                         internal_error(state, user->member->first, "bad ipdom");
9071                 }
9072         }
9073         printf("\n");
9074         for(user = block->use; user; user = user->next) {
9075                 vertex = print_ipdominated(state, user->member, vertex);
9076         }
9077         return vertex;
9078 }
9079
9080 static void print_ipdominators(struct compile_state *state)
9081 {
9082         printf("\nipdominates\n");
9083         print_ipdominated(state, state->last_block, 0);
9084 }
9085
9086 static int print_pfrontiers(
9087         struct compile_state *state, struct block *block, int vertex)
9088 {
9089         struct block_set *user;
9090
9091         if (!block || (block->vertex != vertex + 1)) {
9092                 return vertex;
9093         }
9094         vertex += 1;
9095
9096         printf("%d:", block->vertex);
9097         for(user = block->ipdomfrontier; user; user = user->next) {
9098                 printf(" %d", user->member->vertex);
9099         }
9100         printf("\n");
9101         for(user = block->use; user; user = user->next) {
9102                 vertex = print_pfrontiers(state, user->member, vertex);
9103         }
9104         return vertex;
9105 }
9106 static void print_ipdominance_frontiers(struct compile_state *state)
9107 {
9108         printf("\nipdominance frontiers\n");
9109         print_pfrontiers(state, state->last_block, 0);
9110         
9111 }
9112
9113 static void analyze_ipdominators(struct compile_state *state)
9114 {
9115         /* Find the post dominators */
9116         find_post_dominators(state);
9117         /* Find the control dependencies (post dominance frontiers) */
9118         find_block_ipdomf(state, state->last_block);
9119         /* If debuging print the print what I have just found */
9120         if (state->debug & DEBUG_RDOMINATORS) {
9121                 print_ipdominators(state);
9122                 print_ipdominance_frontiers(state);
9123                 print_control_flow(state);
9124         }
9125 }
9126
9127
9128 static void insert_phi_operations(struct compile_state *state)
9129 {
9130         size_t size;
9131         struct triple *first;
9132         int *has_already, *work;
9133         struct block *work_list, **work_list_tail;
9134         int iter;
9135         struct triple *var;
9136
9137         size = sizeof(int) * (state->last_vertex + 1);
9138         has_already = xcmalloc(size, "has_already");
9139         work =        xcmalloc(size, "work");
9140         iter = 0;
9141
9142         first = state->main_function->left;
9143         for(var = first->next; var != first ; var = var->next) {
9144                 struct block *block;
9145                 struct triple_set *user;
9146                 if ((var->op != OP_ADECL) || !var->use) {
9147                         continue;
9148                 }
9149                 iter += 1;
9150                 work_list = 0;
9151                 work_list_tail = &work_list;
9152                 for(user = var->use; user; user = user->next) {
9153                         if (user->member->op == OP_READ) {
9154                                 continue;
9155                         }
9156                         if (user->member->op != OP_WRITE) {
9157                                 internal_error(state, user->member, 
9158                                         "bad variable access");
9159                         }
9160                         block = user->member->u.block;
9161                         if (!block) {
9162                                 warning(state, user->member, "dead code");
9163                         }
9164                         work[block->vertex] = iter;
9165                         *work_list_tail = block;
9166                         block->work_next = 0;
9167                         work_list_tail = &block->work_next;
9168                 }
9169                 for(block = work_list; block; block = block->work_next) {
9170                         struct block_set *df;
9171                         for(df = block->domfrontier; df; df = df->next) {
9172                                 struct triple *phi;
9173                                 struct block *front;
9174                                 int in_edges;
9175                                 front = df->member;
9176
9177                                 if (has_already[front->vertex] >= iter) {
9178                                         continue;
9179                                 }
9180                                 /* Count how many edges flow into this block */
9181                                 in_edges = front->users;
9182                                 /* Insert a phi function for this variable */
9183                                 phi = xcmalloc(in_edges * sizeof(*phi),"phi");
9184                                 phi = triple(state, OP_PHI, var->type, 
9185                                         phi, var);
9186                                 phi->filename = front->first->filename;
9187                                 phi->line = front->first->line;
9188                                 phi->col  = front->first->col;
9189                                 phi->u.block = front;
9190                                 use_triple(var, phi);
9191                                 /* Insert the phi functions immediately after the label */
9192                                 insert_triple(state, front->first->next, phi);
9193                                 if (front->first == front->last) {
9194                                         front->last = front->first->next;
9195                                 }
9196                                 has_already[front->vertex] = iter;
9197                                 
9198                                 /* If necessary plan to visit the basic block */
9199                                 if (work[front->vertex] >= iter) {
9200                                         continue;
9201                                 }
9202                                 work[front->vertex] = iter;
9203                                 *work_list_tail = front;
9204                                 front->work_next = 0;
9205                                 work_list_tail = &front->work_next;
9206                         }
9207                 }
9208         }
9209         xfree(has_already);
9210         xfree(work);
9211 }
9212
9213 /*
9214  * C(V)
9215  * S(V)
9216  */
9217 static void fixup_block_phi_variables(
9218         struct compile_state *state, struct block *parent, struct block *block)
9219 {
9220         struct block_set *set;
9221         struct triple *ptr;
9222         int edge;
9223         if (!parent || !block)
9224                 return;
9225         /* Find the edge I am coming in on */
9226         edge = 0;
9227         for(set = block->use; set; set = set->next, edge++) {
9228                 if (set->member == parent) {
9229                         break;
9230                 }
9231         }
9232         if (!set) {
9233                 internal_error(state, 0, "phi input is not on a control predecessor");
9234         }
9235         for(ptr = block->first; ; ptr = ptr->next) {
9236                 if (ptr->op == OP_PHI) {
9237                         struct triple *var, *val, **slot;
9238                         var = ptr->right;
9239                         /* Find the current value of the variable */
9240                         val = var->use->member;
9241                         if ((val->op == OP_WRITE) || (val->op == OP_READ)) {
9242                                 internal_error(state, val, "bad value in phi");
9243                         }
9244                         slot = (struct triple **)(ptr->left);
9245                         slot += edge;
9246                         if ((*slot != 0) && (*slot != val)) {
9247                                 internal_error(state, ptr, "phi already bound on this edge");
9248                         }
9249                         *slot = val;
9250                         use_triple(val, ptr);
9251                 }
9252                 if (ptr == block->last) {
9253                         break;
9254                 }
9255         }
9256 }
9257
9258
9259 static void rename_block_variables(
9260         struct compile_state *state, struct block *block)
9261 {
9262         struct block_set *user;
9263         struct triple *ptr, *next, *last;
9264         int done;
9265         if (!block)
9266                 return;
9267         last = block->first;
9268         done = 0;
9269         for(ptr = block->first; !done; ptr = next) {
9270                 next = ptr->next;
9271                 if (ptr == block->last) {
9272                         done = 1;
9273                 }
9274                 /* RHS(A) */
9275                 if (ptr->op == OP_READ) {
9276                         struct triple *var, *val;
9277                         var = ptr->left;
9278                         unuse_triple(var, ptr);
9279                         if (!var->use) {
9280                                 error(state, ptr, "variable used without being set");
9281                         }
9282                         /* Find the current value of the variable */
9283                         val = var->use->member;
9284                         if ((val->op == OP_WRITE) || (val->op == OP_READ)) {
9285                                 internal_error(state, val, "bad value in read");
9286                         }
9287                         propogate_use(state, ptr, val);
9288                         release_triple(state, ptr);
9289                         continue;
9290                 }
9291                 /* LHS(A) */
9292                 if (ptr->op == OP_WRITE) {
9293                         struct triple *var, *val;
9294                         var = ptr->left;
9295                         val = ptr->right;
9296                         if ((val->op == OP_WRITE) || (val->op == OP_READ)) {
9297                                 internal_error(state, val, "bad value in write");
9298                         }
9299                         propogate_use(state, ptr, val);
9300                         unuse_triple(var, ptr);
9301                         /* Push OP_WRITE ptr->right onto a stack of variable uses */
9302                         push_triple(var, val);
9303                 }
9304                 if (ptr->op == OP_PHI) {
9305                         struct triple *var;
9306                         var = ptr->right;
9307                         /* Push OP_PHI onto a stack of variable uses */
9308                         push_triple(var, ptr);
9309                 }
9310                 last = ptr;
9311         }
9312         block->last = last;
9313
9314         /* Fixup PHI functions in the cf successors */
9315         fixup_block_phi_variables(state, block, block->left);
9316         fixup_block_phi_variables(state, block, block->right);
9317         /* rename variables in the dominated nodes */
9318         for(user = block->idominates; user; user = user->next) {
9319                 rename_block_variables(state, user->member);
9320         }
9321         /* pop the renamed variable stack */
9322         last = block->first;
9323         done = 0;
9324         for(ptr = block->first; !done ; ptr = next) {
9325                 next = ptr->next;
9326                 if (ptr == block->last) {
9327                         done = 1;
9328                 }
9329                 if (ptr->op == OP_WRITE) {
9330                         struct triple *var;
9331                         var = ptr->left;
9332                         /* Pop OP_WRITE ptr->right from the stack of variable uses */
9333                         pop_triple(var, ptr->right);
9334                         release_triple(state, ptr);
9335                         continue;
9336                 }
9337                 if (ptr->op == OP_PHI) {
9338                         struct triple *var;
9339                         var = ptr->right;
9340                         /* Pop OP_WRITE ptr->right from the stack of variable uses */
9341                         pop_triple(var, ptr);
9342                 }
9343                 last = ptr;
9344         }
9345         block->last = last;
9346 }
9347
9348 static void prune_block_variables(struct compile_state *state,
9349         struct block *block)
9350 {
9351         struct block_set *user;
9352         struct triple *next, *last, *ptr;
9353         int done;
9354         last = block->first;
9355         done = 0;
9356         for(ptr = block->first; !done; ptr = next) {
9357                 next = ptr->next;
9358                 if (ptr == block->last) {
9359                         done = 1;
9360                 }
9361                 if (ptr->op == OP_ADECL) {
9362                         struct triple_set *user, *next;
9363                         for(user = ptr->use; user; user = next) {
9364                                 struct triple *use;
9365                                 next = user->next;
9366                                 use = user->member;
9367                                 if (use->op != OP_PHI) {
9368                                         internal_error(state, use, "decl still used");
9369                                 }
9370                                 if (use->right != ptr) {
9371                                         internal_error(state, use, "bad phi use of decl");
9372                                 }
9373                                 unuse_triple(ptr, use);
9374                                 use->right = 0;
9375                         }
9376                         release_triple(state, ptr);
9377                         continue;
9378                 }
9379                 last = ptr;
9380         }
9381         block->last = last;
9382         for(user = block->idominates; user; user = user->next) {
9383                 prune_block_variables(state, user->member);
9384         }
9385 }
9386
9387 static void transform_to_ssa_form(struct compile_state *state)
9388 {
9389         insert_phi_operations(state);
9390 #if 0
9391         printf("@%s:%d\n", __FILE__, __LINE__);
9392         print_blocks(state);
9393 #endif
9394         rename_block_variables(state, state->first_block);
9395         prune_block_variables(state, state->first_block);
9396 }
9397
9398
9399 static void transform_from_ssa_form(struct compile_state *state)
9400 {
9401         /* To get out of ssa form we insert moves on the incoming
9402          * edges to blocks containting phi functions.
9403          */
9404         struct triple *first;
9405         struct triple *phi, *next;
9406
9407         /* Walk all of the operations to find the phi functions */
9408         first = state->main_function->left;
9409         for(phi = first->next; phi != first ; phi = next) {
9410                 struct block_set *set;
9411                 struct block *block;
9412                 struct triple **slot;
9413                 struct triple *var, *read;
9414                 int edge;
9415                 next = phi->next;
9416                 if (phi->op != OP_PHI) {
9417                         continue;
9418                 }
9419                 block = phi->u.block;
9420                 slot  = (struct triple **)(phi->left);
9421
9422                 /* A variable to replace the phi function */
9423                 var = post_triple(state, phi, OP_ADECL, phi->type, 0,0);
9424                 /* A read of the single value that is set into the variable */
9425                 read = post_triple(state, var, OP_READ, phi->type, var, 0);
9426                 use_triple(var, read);
9427
9428                 /* Replaces uses of the phi with variable reads */
9429                 propogate_use(state, phi, read);
9430
9431                 /* Walk all of the incoming edges/blocks and insert moves.
9432                  */
9433                 for(edge = 0, set = block->use; set; set = set->next, edge++) {
9434                         struct block *eblock;
9435                         struct triple *move;
9436                         struct triple *val;
9437                         eblock = set->member;
9438                         val = slot[edge];
9439                         unuse_triple(val, phi);
9440
9441                         if (val == phi) {
9442                                 continue;
9443                         }
9444
9445                         move = post_triple(state, 
9446                                 val, OP_WRITE, phi->type, var, val);
9447                         use_triple(val, move);
9448                         use_triple(var, move);
9449                 }
9450                 release_triple(state, phi);
9451         }
9452         
9453 }
9454
9455 static void insert_copies_to_phi(struct compile_state *state)
9456 {
9457         /* To get out of ssa form we insert moves on the incoming
9458          * edges to blocks containting phi functions.
9459          */
9460         struct triple *first;
9461         struct triple *phi;
9462
9463         /* Walk all of the operations to find the phi functions */
9464         first = state->main_function->left;
9465         for(phi = first->next; phi != first ; phi = phi->next) {
9466                 struct block_set *set;
9467                 struct block *block;
9468                 struct triple **slot;
9469                 int edge;
9470                 if (phi->op != OP_PHI) {
9471                         continue;
9472                 }
9473                 if (ID_REG(phi->id) == REG_UNSET) {
9474                         phi->id = MK_REG_ID(alloc_virtual_reg(), 
9475                                 ID_REG_CLASSES(phi->id));
9476                 }
9477                 block = phi->u.block;
9478                 slot  = (struct triple **)(phi->left);
9479                 /* Walk all of the incoming edges/blocks and insert moves.
9480                  */
9481                 for(edge = 0, set = block->use; set; set = set->next, edge++) {
9482                         struct block *eblock;
9483                         struct triple *move;
9484                         struct triple *val;
9485                         struct triple *ptr;
9486                         eblock = set->member;
9487                         val = slot[edge];
9488
9489                         if (val == phi) {
9490                                 continue;
9491                         }
9492
9493                         move = build_triple(state, OP_COPY, phi->type, val, 0,
9494                                 val->filename, val->line, val->col);
9495                         move->u.block = eblock;
9496                         move->id = phi->id;
9497                         use_triple(val, move);
9498                         
9499                         slot[edge] = move;
9500                         unuse_triple(val, phi);
9501                         use_triple(move, phi);
9502
9503                         /* Walk through the block backwards to find
9504                          * an appropriate location for the OP_COPY.
9505                          */
9506                         for(ptr = eblock->last; ptr != eblock->first; ptr = ptr->prev) {
9507                                 struct triple **expr;
9508                                 if ((ptr == phi) || (ptr == val)) {
9509                                         goto out;
9510                                 }
9511                                 expr = triple_rhs(state, ptr, 0);
9512                                 for(;expr; expr = triple_rhs(state, ptr, expr)) {
9513                                         if ((*expr) == phi) {
9514                                                 goto out;
9515                                         }
9516                                 }
9517                         }
9518                 out:
9519                         if (triple_is_branch(ptr)) {
9520                                 internal_error(state, ptr,
9521                                         "Could not insert write to phi");
9522                         }
9523                         insert_triple(state, ptr->next, move);
9524                         if (eblock->last == ptr) {
9525                                 eblock->last = move;
9526                         }
9527                 }
9528         }
9529 }
9530
9531 struct triple_reg_set {
9532         struct triple_reg_set *next;
9533         struct triple *member;
9534         struct triple *new;
9535 };
9536
9537 struct reg_block {
9538         struct block *block;
9539         struct triple_reg_set *in;
9540         struct triple_reg_set *out;
9541         int vertex;
9542 };
9543
9544 static int do_triple_set(struct triple_reg_set **head, 
9545         struct triple *member, struct triple *new_member)
9546 {
9547         struct triple_reg_set **ptr, *new;
9548         if (!member)
9549                 return 0;
9550         ptr = head;
9551         while(*ptr) {
9552                 if ((*ptr)->member == member) {
9553                         return 0;
9554                 }
9555                 ptr = &(*ptr)->next;
9556         }
9557         new = xcmalloc(sizeof(*new), "triple_set");
9558         new->member = member;
9559         new->new    = new_member;
9560         new->next   = *head;
9561         *head       = new;
9562         return 1;
9563 }
9564
9565 static void do_triple_unset(struct triple_reg_set **head, struct triple *member)
9566 {
9567         struct triple_reg_set *entry, **ptr;
9568         ptr = head;
9569         while(*ptr) {
9570                 entry = *ptr;
9571                 if (entry->member == member) {
9572                         *ptr = entry->next;
9573                         xfree(entry);
9574                         return;
9575                 }
9576                 else {
9577                         ptr = &entry->next;
9578                 }
9579         }
9580 }
9581
9582 static int in_triple(struct reg_block *rb, struct triple *in)
9583 {
9584         return do_triple_set(&rb->in, in, 0);
9585 }
9586 static void unin_triple(struct reg_block *rb, struct triple *unin)
9587 {
9588         do_triple_unset(&rb->in, unin);
9589 }
9590
9591 static int out_triple(struct reg_block *rb, struct triple *out)
9592 {
9593         return do_triple_set(&rb->out, out, 0);
9594 }
9595 static void unout_triple(struct reg_block *rb, struct triple *unout)
9596 {
9597         do_triple_unset(&rb->out, unout);
9598 }
9599
9600 static int initialize_regblock(struct reg_block *blocks,
9601         struct block *block, int vertex)
9602 {
9603         struct block_set *user;
9604         if (!block || (blocks[block->vertex].block == block)) {
9605                 return vertex;
9606         }
9607         vertex += 1;
9608         /* Renumber the blocks in a convinient fashion */
9609         block->vertex = vertex;
9610         blocks[vertex].block    = block;
9611         blocks[vertex].vertex   = vertex;
9612         for(user = block->use; user; user = user->next) {
9613                 vertex = initialize_regblock(blocks, user->member, vertex);
9614         }
9615         return vertex;
9616 }
9617
9618 static int phi_in(struct compile_state *state, struct reg_block *blocks,
9619         struct reg_block *rb, struct block *suc)
9620 {
9621         /* Read the conditional input set of a successor block
9622          * (i.e. the input to the phi nodes) and place it in the
9623          * current blocks output set.
9624          */
9625         struct block_set *set;
9626         struct triple *ptr;
9627         int edge;
9628         int done, change;
9629         change = 0;
9630         /* Find the edge I am coming in on */
9631         for(edge = 0, set = suc->use; set; set = set->next, edge++) {
9632                 if (set->member == rb->block) {
9633                         break;
9634                 }
9635         }
9636         if (!set) {
9637                 internal_error(state, 0, "Not coming on a control edge?");
9638         }
9639         for(done = 0, ptr = suc->first; !done; ptr = ptr->next) {
9640                 struct triple **slot, *expr, *ptr2;
9641                 int out_change, done2;
9642                 done = (ptr == suc->last);
9643                 if (ptr->op != OP_PHI) {
9644                         continue;
9645                 }
9646                 slot = (struct triple **)(ptr->left);
9647                 expr = slot[edge];
9648                 out_change = out_triple(rb, expr);
9649                 if (!out_change) {
9650                         continue;
9651                 }
9652                 /* If we don't define the variable also plast it
9653                  * in the current blocks input set.
9654                  */
9655                 ptr2 = rb->block->first;
9656                 for(done2 = 0; !done2; ptr2 = ptr2->next) {
9657                         if (ptr2 == expr) {
9658                                 break;
9659                         }
9660                         done2 = (ptr2 == rb->block->last);
9661                 }
9662                 if (!done2) {
9663                         continue;
9664                 }
9665                 change |= in_triple(rb, expr);
9666         }
9667         return change;
9668 }
9669
9670 static int reg_in(struct compile_state *state, struct reg_block *blocks,
9671         struct reg_block *rb, struct block *suc)
9672 {
9673         struct triple_reg_set *in_set;
9674         int change;
9675         change = 0;
9676         /* Read the input set of a successor block
9677          * and place it in the current blocks output set.
9678          */
9679         in_set = blocks[suc->vertex].in;
9680         for(; in_set; in_set = in_set->next) {
9681                 int out_change, done;
9682                 struct triple *first, *last, *ptr;
9683                 out_change = out_triple(rb, in_set->member);
9684                 if (!out_change) {
9685                         continue;
9686                 }
9687                 /* If we don't define the variable also place it
9688                  * in the current blocks input set.
9689                  */
9690                 first = rb->block->first;
9691                 last = rb->block->last;
9692                 done = 0;
9693                 for(ptr = first; !done; ptr = ptr->next) {
9694                         if (ptr == in_set->member) {
9695                                 break;
9696                         }
9697                         done = (ptr == last);
9698                 }
9699                 if (!done) {
9700                         continue;
9701                 }
9702                 change |= in_triple(rb, in_set->member);
9703         }
9704         change |= phi_in(state, blocks, rb, suc);
9705         return change;
9706 }
9707
9708
9709 static int use_in(struct compile_state *state, struct reg_block *rb)
9710 {
9711         /* Find the variables we use but don't define and add
9712          * it to the current blocks input set.
9713          */
9714 #warning "FIXME is this O(N^2) algorithm bad?"
9715         struct block *block;
9716         struct triple *ptr;
9717         int done;
9718         int change;
9719         block = rb->block;
9720         change = 0;
9721         for(done = 0, ptr = block->last; !done; ptr = ptr->prev) {
9722                 struct triple **expr;
9723                 done = (ptr == block->first);
9724                 /* The variable a phi function uses depends on the
9725                  * control flow, and is handled in phi_in, not
9726                  * here.
9727                  */
9728                 if (ptr->op == OP_PHI) {
9729                         continue;
9730                 }
9731                 expr = triple_rhs(state, ptr, 0);
9732                 for(;expr; expr = triple_rhs(state, ptr, expr)) {
9733                         struct triple *rhs, *test;
9734                         int tdone;
9735                         rhs = *expr;
9736                         /* See if rhs is defined in this block */
9737                         for(tdone = 0, test = ptr; !tdone; test = test->prev) {
9738                                 tdone = (test == block->first);
9739                                 if (test == rhs) {
9740                                         rhs = 0;
9741                                         break;
9742                                 }
9743                         }
9744                         /* If the triple is not a definition skip it. */
9745                         if (!triple_is_def(ptr)) {
9746                                 continue;
9747                         }
9748                         /* If I still have a valid rhs add it to in */
9749                         change |= in_triple(rb, rhs);
9750                 }
9751         }
9752         return change;
9753 }
9754
9755 static struct reg_block *compute_variable_lifetimes(
9756         struct compile_state *state)
9757 {
9758         struct reg_block *blocks;
9759         int change;
9760         blocks = xcmalloc(
9761                 sizeof(*blocks)*(state->last_vertex + 1), "reg_block");
9762         initialize_regblock(blocks, state->last_block, 0);
9763         do {
9764                 int i;
9765                 change = 0;
9766                 for(i = 1; i <= state->last_vertex; i++) {
9767                         struct reg_block *rb;
9768                         rb = &blocks[i];
9769                         /* Add the left successor's input set to in */
9770                         if (rb->block->left) {
9771                                 change |= reg_in(state, blocks, rb, rb->block->left);
9772                         }
9773                         /* Add the right successor's input set to in */
9774                         if ((rb->block->right) && 
9775                                 (rb->block->right != rb->block->left)) {
9776                                 change |= reg_in(state, blocks, rb, rb->block->right);
9777                         }
9778                         /* Add use to in... */
9779                         change |= use_in(state, rb);
9780                 }
9781         } while(change);
9782         return blocks;
9783 }
9784
9785 static void free_variable_lifetimes(
9786         struct compile_state *state, struct reg_block *blocks)
9787 {
9788         int i;
9789         /* free in_set && out_set on each block */
9790         for(i = 1; i <= state->last_vertex; i++) {
9791                 struct triple_reg_set *entry, *next;
9792                 struct reg_block *rb;
9793                 rb = &blocks[i];
9794                 for(entry = rb->in; entry ; entry = next) {
9795                         next = entry->next;
9796                         do_triple_unset(&rb->in, entry->member);
9797                 }
9798                 for(entry = rb->out; entry; entry = next) {
9799                         next = entry->next;
9800                         do_triple_unset(&rb->out, entry->member);
9801                 }
9802         }
9803         xfree(blocks);
9804
9805 }
9806
9807 typedef struct triple *(*wvl_cb_t)(
9808         struct compile_state *state, 
9809         struct reg_block *blocks, struct triple_reg_set *live, 
9810         struct reg_block *rb, struct triple *ins, void *arg);
9811
9812 static void walk_variable_lifetimes(struct compile_state *state,
9813         struct reg_block *blocks, wvl_cb_t cb, void *arg)
9814 {
9815         int i;
9816         
9817         for(i = 1; i <= state->last_vertex; i++) {
9818                 struct triple_reg_set *live;
9819                 struct triple_reg_set *entry, *next;
9820                 struct triple *ptr, *prev;
9821                 struct reg_block *rb;
9822                 struct block *block;
9823                 int done;
9824
9825                 /* Get the blocks */
9826                 rb = &blocks[i];
9827                 block = rb->block;
9828
9829                 /* Copy out into live */
9830                 live = 0;
9831                 for(entry = rb->out; entry; entry = next) {
9832                         next = entry->next;
9833                         do_triple_set(&live, entry->member, entry->new);
9834                 }
9835                 /* Walk through the basic block calculating live */
9836                 for(done = 0, ptr = block->last; !done; ptr = prev) {
9837                         struct triple **expr;
9838
9839                         prev = ptr->prev;
9840                         done = (ptr == block->first);
9841                         
9842                         /* Remove the current definition from live */
9843                         do_triple_unset(&live, ptr);
9844                         
9845                         /* If the current instruction was deleted continue */
9846                         if (!cb(state, blocks, live, rb, ptr, arg)) {
9847                                 if (block->last == ptr) {
9848                                         block->last = prev;
9849                                 }
9850                                 continue;
9851                         }
9852                         
9853                         /* Add the current uses to live.
9854                          *
9855                          * It is safe to skip phi functions because they do
9856                          * not have any block local uses, and the block
9857                          * output sets already properly account for what
9858                          * control flow depedent uses phi functions do have.
9859                          */
9860                         if (ptr->op == OP_PHI) {
9861                                 continue;
9862                         }
9863                         expr = triple_rhs(state, ptr, 0);
9864                         for(;expr; expr = triple_rhs(state, ptr, expr)) {
9865                                 /* If the triple is not a definition skip it. */
9866                                 if (!triple_is_def(*expr)) {
9867                                         continue;
9868                                 }
9869                                 do_triple_set(&live, *expr, 0);
9870                         }
9871
9872                 }
9873                 /* Free live */
9874                 for(entry = live; entry; entry = next) {
9875                         next = entry->next;
9876                         do_triple_unset(&live, entry->member);
9877                 }
9878         }
9879 }
9880
9881 static int count_triples(struct compile_state *state)
9882 {
9883         struct triple *first, *ins;
9884         int triples = 0;
9885         first = state->main_function->left;
9886         ins = first;
9887         do {
9888                 triples++;
9889                 ins = ins->next;
9890         } while (ins != first);
9891         return triples;
9892 }
9893 struct dead_triple {
9894         struct triple *triple;
9895         struct dead_triple *work_next;
9896         struct block *block;
9897         int color;
9898         int flags;
9899 #define TRIPLE_FLAG_ALIVE 1
9900 };
9901
9902
9903 static void awaken(
9904         struct compile_state *state,
9905         struct dead_triple *dtriple, struct triple **expr,
9906         struct dead_triple ***work_list_tail)
9907 {
9908         struct triple *triple;
9909         struct dead_triple *dt;
9910         if (!expr) {
9911                 return;
9912         }
9913         triple = *expr;
9914         if (!triple) {
9915                 return;
9916         }
9917         if (triple->id <= 0)  {
9918                 internal_error(state, triple, "bad triple id: %d",
9919                         triple->id);
9920         }
9921         if (triple->op == OP_NOOP) {
9922                 internal_warning(state, triple, "awakening noop?");
9923                 return;
9924         }
9925         dt = &dtriple[triple->id];
9926         if (!(dt->flags & TRIPLE_FLAG_ALIVE)) {
9927                 dt->flags |= TRIPLE_FLAG_ALIVE;
9928                 if (!dt->work_next) {
9929                         **work_list_tail = dt;
9930                         *work_list_tail = &dt->work_next;
9931                 }
9932         }
9933 }
9934
9935 static void eliminate_inefectual_code(struct compile_state *state)
9936 {
9937         struct block *block;
9938         struct dead_triple *dtriple, *work_list, **work_list_tail, *dt;
9939         int triples, i;
9940         struct triple *first, *ins;
9941
9942         /* Setup the work list */
9943         work_list = 0;
9944         work_list_tail = &work_list;
9945
9946         first = state->main_function->left;
9947
9948         /* Count how many triples I have */
9949         triples = count_triples(state);
9950
9951         /* Now put then in an array and mark all of the triples dead */
9952         dtriple = xcmalloc(sizeof(*dtriple) * (triples + 1), "dtriples");
9953         
9954         ins = first;
9955         i = 1;
9956         block = 0;
9957         do {
9958                 if (ins->op == OP_LABEL) {
9959                         block = ins->u.block;
9960                 }
9961                 dtriple[i].triple = ins;
9962                 dtriple[i].block  = block;
9963                 dtriple[i].flags  = 0;
9964                 dtriple[i].color  = ins->id;
9965                 ins->id = i;
9966                 /* See if it is an operation we always keep */
9967 #warning "FIXME handle the case of killing a branch instruction"
9968                 if (!triple_is_pure(state, ins) || triple_is_branch(ins)) {
9969                         awaken(state, dtriple, &ins, &work_list_tail);
9970                 }
9971                 i++;
9972                 ins = ins->next;
9973         } while(ins != first);
9974         while(work_list) {
9975                 struct dead_triple *dt;
9976                 struct block_set *user;
9977                 struct triple **expr;
9978                 dt = work_list;
9979                 work_list = dt->work_next;
9980                 if (!work_list) {
9981                         work_list_tail = &work_list;
9982                 }
9983                 /* Wake up the data depencencies of this triple */
9984                 expr = 0;
9985                 do {
9986                         expr = triple_rhs(state, dt->triple, expr);
9987                         awaken(state, dtriple, expr, &work_list_tail);
9988                 } while(expr);
9989                 do {
9990                         expr = triple_lhs(state, dt->triple, expr);
9991                         awaken(state, dtriple, expr, &work_list_tail);
9992                 } while(expr);
9993                 /* Wake up the forward control dependencies */
9994                 do {
9995                         expr = triple_targ(state, dt->triple, expr);
9996                         awaken(state, dtriple, expr, &work_list_tail);
9997                 } while(expr);
9998                 /* Wake up the reverse control dependencies of this triple */
9999                 for(user = dt->block->ipdomfrontier; user; user = user->next) {
10000                         awaken(state, dtriple, &user->member->last, &work_list_tail);
10001                 }
10002         }
10003         for(dt = &dtriple[1]; dt <= &dtriple[triples]; dt++) {
10004                 if ((dt->triple->op == OP_NOOP) && 
10005                         (dt->flags & TRIPLE_FLAG_ALIVE)) {
10006                         internal_error(state, dt->triple, "noop effective?");
10007                 }
10008                 dt->triple->id = dt->color;     /* Restore the color */
10009                 if (!(dt->flags & TRIPLE_FLAG_ALIVE)) {
10010 #warning "FIXME handle the case of killing a basic block"
10011                         if (dt->block->first == dt->triple) {
10012                                 continue;
10013                         }
10014                         if (dt->block->last == dt->triple) {
10015                                 dt->block->last = dt->triple->prev;
10016                         }
10017                         release_triple(state, dt->triple);
10018                 }
10019         }
10020         xfree(dtriple);
10021 }
10022
10023
10024 struct live_range_edge;
10025 struct live_range {
10026         struct live_range_edge *edges;
10027         struct triple *def;
10028         unsigned color;
10029         unsigned classes;
10030         unsigned degree;
10031         struct live_range *group_next, **group_prev;
10032 };
10033
10034 struct live_range_edge {
10035         struct live_range_edge *next;
10036         struct live_range *node;
10037 };
10038
10039 #define LRE_HASH_SIZE 2048
10040 struct lre_hash {
10041         struct lre_hash *next;
10042         struct live_range *left;
10043         struct live_range *right;
10044 };
10045
10046
10047 struct reg_state {
10048         struct lre_hash *hash[LRE_HASH_SIZE];
10049         struct reg_block *blocks;
10050         struct live_range *lr;
10051         struct live_range *low, **low_tail;
10052         struct live_range *high, **high_tail;
10053         unsigned ranges;
10054 };
10055
10056
10057 static unsigned regc_max_size(struct compile_state *state, int classes)
10058 {
10059         unsigned max_size;
10060         int i;
10061         max_size = 0;
10062         for(i = 0; i < MAX_REGC; i++) {
10063                 if (classes & (1 << i)) {
10064                         unsigned size;
10065                         size = arch_regc_size(state, i);
10066                         if (size > max_size) {
10067                                 max_size = size;
10068                         }
10069                 }
10070         }
10071         return max_size;
10072 }
10073
10074 static int reg_is_reg(struct compile_state *state, int reg1, int reg2)
10075 {
10076         unsigned equivs[MAX_REG_EQUIVS];
10077         int i;
10078         if ((reg1 < 0) || (reg1 >= MAX_REGISTERS)) {
10079                 internal_error(state, 0, "invalid register");
10080         }
10081         if ((reg2 < 0) || (reg2 >= MAX_REGISTERS)) {
10082                 internal_error(state, 0, "invalid register");
10083         }
10084         arch_reg_equivs(state, equivs, reg1);
10085         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
10086                 if (equivs[i] == reg2) {
10087                         return 1;
10088                 }
10089         }
10090         return 0;
10091 }
10092
10093 static void reg_fill_used(struct compile_state *state, char *used, int reg)
10094 {
10095         unsigned equivs[MAX_REG_EQUIVS];
10096         int i;
10097         arch_reg_equivs(state, equivs, reg);
10098         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
10099                 used[equivs[i]] = 1;
10100         }
10101         return;
10102 }
10103
10104 static unsigned int hash_live_edge(
10105         struct live_range *left, struct live_range *right)
10106 {
10107         unsigned int hash, val;
10108         unsigned long lval, rval;
10109         lval = ((unsigned long)left)/sizeof(struct live_range);
10110         rval = ((unsigned long)right)/sizeof(struct live_range);
10111         hash = 0;
10112         while(lval) {
10113                 val = lval & 0xff;
10114                 lval >>= 8;
10115                 hash = (hash *263) + val;
10116         }
10117         while(rval) {
10118                 val = rval & 0xff;
10119                 rval >>= 8;
10120                 hash = (hash *263) + val;
10121         }
10122         hash = hash & (LRE_HASH_SIZE - 1);
10123         return hash;
10124 }
10125
10126 static struct lre_hash **lre_probe(struct reg_state *rstate,
10127         struct live_range *left, struct live_range *right)
10128 {
10129         struct lre_hash **ptr;
10130         unsigned int index;
10131         /* Ensure left <= right */
10132         if (left > right) {
10133                 struct live_range *tmp;
10134                 tmp = left;
10135                 left = right;
10136                 right = tmp;
10137         }
10138         index = hash_live_edge(left, right);
10139         
10140         ptr = &rstate->hash[index];
10141         while((*ptr) && ((*ptr)->left != left) && ((*ptr)->right != right)) {
10142                 ptr = &(*ptr)->next;
10143         }
10144         return ptr;
10145 }
10146
10147 static int interfere(struct reg_state *rstate,
10148         struct live_range *left, struct live_range *right)
10149 {
10150         struct lre_hash **ptr;
10151         ptr = lre_probe(rstate, left, right);
10152         return ptr && *ptr;
10153 }
10154
10155 static void add_live_edge(struct reg_state *rstate, 
10156         struct live_range *left, struct live_range *right)
10157 {
10158         /* FIXME the memory allocation overhead is noticeable here... */
10159         struct lre_hash **ptr, *new_hash;
10160         struct live_range_edge *edge;
10161
10162         if (left == right) {
10163                 return;
10164         }
10165         if ((left == &rstate->lr[0]) || (right == &rstate->lr[0])) {
10166                 return;
10167         }
10168         /* Ensure left <= right */
10169         if (left > right) {
10170                 struct live_range *tmp;
10171                 tmp = left;
10172                 left = right;
10173                 right = tmp;
10174         }
10175         ptr = lre_probe(rstate, left, right);
10176         if (*ptr) {
10177                 return;
10178         }
10179         new_hash = xmalloc(sizeof(*new_hash), "lre_hash");
10180         new_hash->next  = *ptr;
10181         new_hash->left  = left;
10182         new_hash->right = right;
10183         *ptr = new_hash;
10184
10185         edge = xmalloc(sizeof(*edge), "live_range_edge");
10186         edge->next   = left->edges;
10187         edge->node   = right;
10188         left->edges  = edge;
10189         left->degree += 1;
10190         
10191         edge = xmalloc(sizeof(*edge), "live_range_edge");
10192         edge->next    = right->edges;
10193         edge->node    = left;
10194         right->edges  = edge;
10195         right->degree += 1;
10196 }
10197
10198 static void remove_live_edge(struct reg_state *rstate,
10199         struct live_range *left, struct live_range *right)
10200 {
10201         struct live_range_edge *edge, **ptr;
10202         struct lre_hash **hptr, *entry;
10203         hptr = lre_probe(rstate, left, right);
10204         if (!hptr || !*hptr) {
10205                 return;
10206         }
10207         entry = *hptr;
10208         *hptr = entry->next;
10209         xfree(entry);
10210
10211         for(ptr = &left->edges; *ptr; ptr = &(*ptr)->next) {
10212                 edge = *ptr;
10213                 if (edge->node == right) {
10214                         *ptr = edge->next;
10215                         memset(edge, 0, sizeof(*edge));
10216                         xfree(edge);
10217                         break;
10218                 }
10219         }
10220         for(ptr = &right->edges; *ptr; ptr = &(*ptr)->next) {
10221                 edge = *ptr;
10222                 if (edge->node == left) {
10223                         *ptr = edge->next;
10224                         memset(edge, 0, sizeof(*edge));
10225                         xfree(edge);
10226                         break;
10227                 }
10228         }
10229 }
10230
10231 static void remove_live_edges(struct reg_state *rstate, struct live_range *range)
10232 {
10233         struct live_range_edge *edge, *next;
10234         for(edge = range->edges; edge; edge = next) {
10235                 next = edge->next;
10236                 remove_live_edge(rstate, range, edge->node);
10237         }
10238 }
10239
10240
10241 /* Interference graph...
10242  * 
10243  * new(n) --- Return a graph with n nodes but no edges.
10244  * add(g,x,y) --- Return a graph including g with an between x and y
10245  * interfere(g, x, y) --- Return true if there exists an edge between the nodes
10246  *                x and y in the graph g
10247  * degree(g, x) --- Return the degree of the node x in the graph g
10248  * neighbors(g, x, f) --- Apply function f to each neighbor of node x in the graph g
10249  *
10250  * Implement with a hash table && a set of adjcency vectors.
10251  * The hash table supports constant time implementations of add and interfere.
10252  * The adjacency vectors support an efficient implementation of neighbors.
10253  */
10254
10255 /* 
10256  *     +---------------------------------------------------+
10257  *     |         +--------------+                          |
10258  *     v         v              |                          |
10259  * renumber -> build graph -> colalesce -> spill_costs -> simplify -> select 
10260  *
10261  * -- In simplify implment optimistic coloring... (No backtracking)
10262  * -- Implement Rematerialization it is the only form of spilling we can perform
10263  *    Essentially this means dropping a constant from a register because
10264  *    we can regenerate it later.
10265  *
10266  * --- Very conservative colalescing (don't colalesce just mark the opportunities)
10267  *     coalesce at phi points...
10268  * --- Bias coloring if at all possible do the coalesing a compile time.
10269  *
10270  *
10271  */
10272
10273 static void different_colored(
10274         struct compile_state *state, struct reg_state *rstate, 
10275         struct triple *parent, struct triple *ins)
10276 {
10277         struct live_range *lr;
10278         struct triple **expr;
10279         lr = &rstate->lr[ins->id];
10280         expr = triple_rhs(state, ins, 0);
10281         for(;expr; expr = triple_rhs(state, ins, expr)) {
10282                 struct live_range *lr2;
10283                 if ((*expr == parent) || (*expr == ins)) {
10284                         continue;
10285                 }
10286                 lr2 = &rstate->lr[(*expr)->id];
10287                 if (lr->color == lr2->color) {
10288                         internal_error(state, ins, "live range too big");
10289                 }
10290         }
10291 }
10292
10293 static void initialize_live_ranges(
10294         struct compile_state *state, struct reg_state *rstate)
10295 {
10296         struct triple *ins, *first;
10297         size_t size;
10298         int i;
10299
10300         first = state->main_function->left;
10301         /* First count how many live ranges I will need.
10302          */
10303         rstate->ranges = count_triples(state);
10304         size = sizeof(rstate->lr[0]) * (rstate->ranges + 1);
10305         rstate->lr = xcmalloc(size, "live_range");
10306         /* Setup the dummy live range */
10307         rstate->lr[0].classes = 0;
10308         rstate->lr[0].color = REG_UNSET;
10309         rstate->lr[0].def = 0;
10310         i = 0;
10311         ins = first;
10312         do {
10313                 unsigned color, classes;
10314                 /* Find the architecture specific color information */
10315                 color = ID_REG(ins->id);
10316                 classes = ID_REG_CLASSES(ins->id);
10317                 if ((color != REG_UNSET) && (color < MAX_REGISTERS)) {
10318                         classes = arch_reg_regcm(state, color);
10319                 }
10320
10321                 /* If the triple is a variable definition give it a live range. */
10322                 if (triple_is_def(ins)) {
10323                         i++;
10324                         ins->id = i;
10325                         rstate->lr[i].def     = ins;
10326                         rstate->lr[i].color   = color;
10327                         rstate->lr[i].classes = classes;
10328                         rstate->lr[i].degree  = 0;
10329                         if (!classes) {
10330                                 internal_error(state, ins, 
10331                                         "live range without a class");
10332                         }
10333                 }
10334                 /* Otherwise give the triple the dummy live range. */
10335                 else {
10336                         ins->id = 0;
10337                 }
10338                 ins = ins->next;
10339         } while(ins != first);
10340         rstate->ranges = i;
10341         /* Make a second pass to handle achitecture specific register
10342          * constraints.
10343          */
10344         ins = first;
10345         do {
10346                 struct live_range *lr;
10347                 lr = &rstate->lr[ins->id];
10348                 if (lr->color != REG_UNSET) {
10349                         struct triple **expr;
10350                         /* This assumes the virtual register is only
10351                          * used by one input operation.
10352                          */
10353                         expr = triple_rhs(state, ins, 0);
10354                         for(;expr; expr = triple_rhs(state, ins, expr)) {
10355                                 struct live_range *lr2;
10356                                 if (ins == *expr) {
10357                                         continue;
10358                                 }
10359                                 lr2 = &rstate->lr[(*expr)->id];
10360                                 if (lr->color == lr2->color) {
10361                                         different_colored(state, rstate, 
10362                                                 ins, *expr);
10363                                         (*expr)->id = ins->id;
10364                                         
10365                                 }
10366                         }
10367                 }
10368                 ins = ins->next;
10369         } while(ins != first);
10370
10371         /* Make a third pass and forget the virtual registers */
10372         for(i = 1; i <= rstate->ranges; i++) {
10373                 if (rstate->lr[i].color >= MAX_REGISTERS) {
10374                         rstate->lr[i].color = REG_UNSET;
10375                 }
10376         }
10377 }
10378
10379 static struct triple *graph_ins(
10380         struct compile_state *state, 
10381         struct reg_block *blocks, struct triple_reg_set *live, 
10382         struct reg_block *rb, struct triple *ins, void *arg)
10383 {
10384         struct reg_state *rstate = arg;
10385         struct live_range *def;
10386         struct triple_reg_set *entry;
10387
10388         /* If the triple does not start a live range
10389          * we do not have a definition to add to
10390          * the interference graph.
10391          */
10392         if (ins->id <= 0) {
10393                 return ins;
10394         }
10395         def = &rstate->lr[ins->id];
10396         
10397         /* Create an edge between ins and everything that is
10398          * alive, unless the live_range cannot share
10399          * a physical register with ins.
10400          */
10401         for(entry = live; entry; entry = entry->next) {
10402                 struct live_range *lr;
10403                 lr= &rstate->lr[entry->member->id];
10404                 if (!arch_regcm_intersect(def->classes, lr->classes)) {
10405                         continue;
10406                 }
10407                 add_live_edge(rstate, def, lr);
10408         }
10409         return ins;
10410 }
10411
10412
10413 static struct triple *print_interference_ins(
10414         struct compile_state *state, 
10415         struct reg_block *blocks, struct triple_reg_set *live, 
10416         struct reg_block *rb, struct triple *ins, void *arg)
10417 {
10418         struct reg_state *rstate = arg;
10419         struct live_range *lr;
10420
10421         lr = &rstate->lr[ins->id];
10422         if ((ins->op == OP_LABEL) && (ins->use)) {
10423                 printf("\n%p:\n", ins);
10424         }
10425         else if (ins->op == OP_INTCONST) {
10426                 printf("(%p) %-7s %08lx              @ %s:%d.%d\n",
10427                         ins, tops(ins->op), ins->u.cval,
10428                         ins->filename, ins->line, ins->col);
10429         }
10430         else {
10431                 printf("(%p) %-7s %-10p %-10p @ %s:%d.%d\n",
10432                         ins, tops(ins->op), ins->left, ins->right,
10433                         ins->filename, ins->line, ins->col);
10434         }
10435         if (live) {
10436                 struct triple_reg_set *entry;
10437                 printf("        live:");
10438                 for(entry = live; entry; entry = entry->next) {
10439                         printf(" %-10p", entry->member);
10440                 }
10441                 printf("\n");
10442         }
10443         if (lr->edges) {
10444                 struct live_range_edge *entry;
10445                 printf("        edges:");
10446                 for(entry = lr->edges; entry; entry = entry->next) {
10447                         printf(" %-10p", entry->node->def);
10448                 }
10449                 printf("\n");
10450         }
10451         if (triple_is_branch(ins)) {
10452                 printf("\n");
10453         }
10454         return ins;
10455 }
10456
10457 #if DEBUG_COLOR_GRAPH > 1
10458 #define cgdebug_printf(...) fprintf(stdout, __VA_ARGS__)
10459 #define cgdebug_flush() fflush(stdout)
10460 #elif DEBUG_COLOR_GRAPH == 1
10461 #define cgdebug_printf(...) fprintf(stderr, __VA_ARGS__)
10462 #define cgdebug_flush() fflush(stderr)
10463 #else
10464 #define cgdebug_printf(...)
10465 #define cgdebug_flush()
10466 #endif
10467
10468 static void select_free_color(struct compile_state *state, 
10469         struct reg_state *rstate, struct live_range *range)
10470 {
10471         struct triple_set *entry;
10472         struct live_range *phi;
10473         struct live_range_edge *edge;
10474         char used[MAX_REGISTERS];
10475         struct triple **expr;
10476
10477         /* If a color is already assigned don't change it */
10478         if (range->color != REG_UNSET) {
10479                 return;
10480         }
10481         /* Instead of doing just the trivial color select here I try
10482          * a few extra things because a good color selection will help reduce
10483          * copies.
10484          */
10485
10486         /* Find the registers currently in use */
10487         memset(used, 0, sizeof(used));
10488         for(edge = range->edges; edge; edge = edge->next) {
10489                 if (edge->node->color == REG_UNSET) {
10490                         continue;
10491                 }
10492                 reg_fill_used(state, used, edge->node->color);
10493         }
10494 #if DEBUG_COLOR_GRAPH > 1
10495         {
10496                 int i;
10497                 i = 0;
10498                 for(edge = range->edges; edge; edge = edge->next) {
10499                         i++;
10500                 }
10501                 cgdebug_printf("\n%s edges: %d @%s:%d.%d\n", 
10502                         tops(range->def->op), i, 
10503                         range->def->filename, range->def->line, range->def->col);
10504                 for(i = 0; i < MAX_REGISTERS; i++) {
10505                         if (used[i]) {
10506                                 cgdebug_printf("used: %s\n",
10507                                         arch_reg_str(i));
10508                         }
10509                 }
10510         }       
10511 #endif
10512
10513         /* If I feed into an expression reuse it's color.
10514          * This should help remove copies in the case of 2 register instructions
10515          * and phi functions.
10516          */
10517         phi = 0;
10518         entry = range->def->use;
10519         for(;(range->color == REG_UNSET) && entry; entry = entry->next) {
10520                 struct live_range *lr;
10521                 lr = &rstate->lr[entry->member->id];
10522                 if (entry->member->id == 0) {
10523                         continue;
10524                 }
10525                 if (!phi && (lr->def->op == OP_PHI) && 
10526                         !interfere(rstate, range, lr)) {
10527                         phi = lr;
10528                 }
10529                 if ((lr->color == REG_UNSET) ||
10530                         ((lr->classes & range->classes) == 0) ||
10531                         (used[lr->color])) {
10532                         continue;
10533                 }
10534                 if (interfere(rstate, range, lr)) {
10535                         continue;
10536                 }
10537                 range->color = lr->color;
10538         }
10539         /* If I feed into a phi function reuse it's color of the color
10540          * of something else that feeds into the phi function.
10541          */
10542         if (phi) {
10543                 if (phi->color != REG_UNSET) {
10544                         if (used[phi->color]) {
10545                                 range->color = phi->color;
10546                         }
10547                 }
10548                 else {
10549                         expr = triple_rhs(state, phi->def, 0);
10550                         for(; expr; expr = triple_rhs(state, phi->def, expr)) {
10551                                 struct live_range *lr;
10552                                 lr = &rstate->lr[(*expr)->id];
10553                                 if ((lr->color == REG_UNSET) || 
10554                                         ((lr->classes & range->classes) == 0) ||
10555                                         (used[lr->color])) {
10556                                         continue;
10557                                 }
10558                                 if (interfere(rstate, range, lr)) {
10559                                         continue;
10560                                 }
10561                                 range->color = lr->color;
10562                         }
10563                 }
10564         }
10565         /* If I don't interfere with a rhs node reuse it's color */
10566         if (range->color == REG_UNSET) {
10567                 expr = triple_rhs(state, range->def, 0);
10568                 for(; expr; expr = triple_rhs(state, range->def, expr)) {
10569                         struct live_range *lr;
10570                         lr = &rstate->lr[(*expr)->id];
10571                         if ((lr->color == -1) || 
10572                                 ((lr->classes & range->classes) == 0) ||
10573                                 (used[lr->color])) {
10574                                 continue;
10575                         }
10576                         if (interfere(rstate, range, lr)) {
10577                                 continue;
10578                         }
10579                         range->color = lr->color;
10580                         break;
10581                 }
10582         }
10583         /* If I have not opportunitically picked a useful color
10584          * pick the first color that is free.
10585          */
10586         if (range->color == REG_UNSET) {
10587                 range->color = 
10588                         arch_select_free_register(state, used, range->classes);
10589         }
10590         if (range->color == REG_UNSET) {
10591                 int i;
10592                 for(edge = range->edges; edge; edge = edge->next) {
10593                         if (edge->node->color == REG_UNSET) {
10594                                 continue;
10595                         }
10596                         warning(state, edge->node->def, "reg %s", 
10597                                 arch_reg_str(edge->node->color));
10598                 }
10599                 warning(state, range->def, "classes: %x",
10600                         range->classes);
10601                 for(i = 0; i < MAX_REGISTERS; i++) {
10602                         if (used[i]) {
10603                                 warning(state, range->def, "used: %s",
10604                                         arch_reg_str(i));
10605                         }
10606                 }
10607 #if DEBUG_COLOR_GRAPH < 2
10608                 error(state, range->def, "too few registers");
10609 #else
10610                 internal_error(state, range->def, "too few registers");
10611 #endif
10612         }
10613         range->classes = arch_reg_regcm(state, range->color);
10614         return;
10615 }
10616
10617 static void color_graph(struct compile_state *state, struct reg_state *rstate)
10618 {
10619         struct live_range_edge *edge;
10620         struct live_range *range;
10621         if (rstate->low) {
10622                 cgdebug_printf("Lo: ");
10623                 range = rstate->low;
10624                 if (*range->group_prev != range) {
10625                         internal_error(state, 0, "lo: *prev != range?");
10626                 }
10627                 *range->group_prev = range->group_next;
10628                 if (range->group_next) {
10629                         range->group_next->group_prev = range->group_prev;
10630                 }
10631                 if (&range->group_next == rstate->low_tail) {
10632                         rstate->low_tail = range->group_prev;
10633                 }
10634                 if (rstate->low == range) {
10635                         internal_error(state, 0, "low: next != prev?");
10636                 }
10637         }
10638         else if (rstate->high) {
10639                 cgdebug_printf("Hi: ");
10640                 range = rstate->high;
10641                 if (*range->group_prev != range) {
10642                         internal_error(state, 0, "hi: *prev != range?");
10643                 }
10644                 *range->group_prev = range->group_next;
10645                 if (range->group_next) {
10646                         range->group_next->group_prev = range->group_prev;
10647                 }
10648                 if (&range->group_next == rstate->high_tail) {
10649                         rstate->high_tail = range->group_prev;
10650                 }
10651                 if (rstate->high == range) {
10652                         internal_error(state, 0, "high: next != prev?");
10653                 }
10654         }
10655         else {
10656                 return;
10657         }
10658         cgdebug_printf(" %d\n", range - rstate->lr);
10659         range->group_prev = 0;
10660         for(edge = range->edges; edge; edge = edge->next) {
10661                 struct live_range *node;
10662                 node = edge->node;
10663                 /* Move nodes from the high to the low list */
10664                 if (node->group_prev && (node->color == REG_UNSET) &&
10665                         (node->degree == regc_max_size(state, node->classes))) {
10666                         if (*node->group_prev != node) {
10667                                 internal_error(state, 0, "move: *prev != node?");
10668                         }
10669                         *node->group_prev = node->group_next;
10670                         if (node->group_next) {
10671                                 node->group_next->group_prev = node->group_prev;
10672                         }
10673                         if (&node->group_next == rstate->high_tail) {
10674                                 rstate->high_tail = node->group_prev;
10675                         }
10676                         cgdebug_printf("Moving...%d to low\n", node - rstate->lr);
10677                         node->group_prev  = rstate->low_tail;
10678                         node->group_next  = 0;
10679                         *rstate->low_tail = node;
10680                         rstate->low_tail  = &node->group_next;
10681                         if (*node->group_prev != node) {
10682                                 internal_error(state, 0, "move2: *prev != node?");
10683                         }
10684                 }
10685                 node->degree -= 1;
10686         }
10687         color_graph(state, rstate);
10688         cgdebug_printf("Coloring %d @%s:%d.%d:", 
10689                 range - rstate->lr,
10690                 range->def->filename, range->def->line, range->def->col);
10691         cgdebug_flush();
10692         select_free_color(state, rstate, range);
10693         if (range->color == -1) {
10694                 internal_error(state, range->def, "select_free_color did not?");
10695         }
10696         cgdebug_printf(" %s\n", arch_reg_str(range->color));
10697 }
10698
10699 static void color_triples(struct compile_state *state, struct reg_state *rstate)
10700 {
10701         struct live_range *lr;
10702         struct triple *first, *triple;
10703         first = state->main_function->left;
10704         triple = first;
10705         do {
10706                 if ((triple->id < 0) || (triple->id > rstate->ranges)) {
10707                         internal_error(state, triple, 
10708                                 "triple without a live range");
10709                 }
10710                 lr = &rstate->lr[triple->id];
10711                 triple->id = MK_REG_ID(lr->color, 0);
10712                 triple = triple->next;
10713         } while (triple != first);
10714 }
10715
10716 static void print_interference_block(
10717         struct compile_state *state, struct block *block, void *arg)
10718
10719 {
10720         struct reg_state *rstate = arg;
10721         struct reg_block *rb;
10722         struct triple *ptr;
10723         int phi_present;
10724         int done;
10725         rb = &rstate->blocks[block->vertex];
10726
10727         printf("\nblock: %p (%d), %p<-%p %p<-%p\n", 
10728                 block, 
10729                 block->vertex,
10730                 block->left, 
10731                 block->left && block->left->use?block->left->use->member : 0,
10732                 block->right, 
10733                 block->right && block->right->use?block->right->use->member : 0);
10734         if (rb->in) {
10735                 struct triple_reg_set *in_set;
10736                 printf("        in:");
10737                 for(in_set = rb->in; in_set; in_set = in_set->next) {
10738                         printf(" %-10p", in_set->member);
10739                 }
10740                 printf("\n");
10741         }
10742         phi_present = 0;
10743         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
10744                 done = (ptr == block->last);
10745                 if (ptr->op == OP_PHI) {
10746                         phi_present = 1;
10747                         break;
10748                 }
10749         }
10750         if (phi_present) {
10751                 int edge;
10752                 for(edge = 0; edge < block->users; edge++) {
10753                         printf("     in(%d):", edge);
10754                         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
10755                                 struct triple **slot;
10756                                 done = (ptr == block->last);
10757                                 if (ptr->op != OP_PHI) {
10758                                         continue;
10759                                 }
10760                                 slot = (struct triple **)(ptr->left);
10761                                 printf(" %-10p", slot[edge]);
10762                         }
10763                         printf("\n");
10764                 }
10765         }
10766         if (block->first->op == OP_LABEL) {
10767                 printf("%p:\n", block->first);
10768         }
10769         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
10770                 struct triple_set *user;
10771                 struct live_range *lr;
10772                 int op;
10773                 op = ptr->op;
10774                 done = (ptr == block->last);
10775                 lr = &rstate->lr[ptr->id];
10776                 
10777                 if (!IS_CONST_OP(op)) {
10778                         if (ptr->u.block != block) {
10779                                 internal_error(state, ptr, 
10780                                         "Wrong block pointer: %p",
10781                                         ptr->u.block);
10782                         }
10783                 }
10784                 if (op == OP_ADECL) {
10785                         for(user = ptr->use; user; user = user->next) {
10786                                 struct live_range *lr;
10787                                 lr = &rstate->lr[user->member->id];
10788                                 if (!user->member->u.block) {
10789                                         internal_error(state, user->member, 
10790                                                 "Use %p not in a block?",
10791                                                 user->member);
10792                                 }
10793                                 
10794                         }
10795                 }
10796                 if (op == OP_INTCONST) {
10797                         printf("(%p) %3d %-7s %08lx              @ %s:%d.%d\n",
10798                                 ptr, lr->color, tops(ptr->op), ptr->u.cval,
10799                                 ptr->filename, ptr->line, ptr->col);
10800                 }
10801                 else if (op == OP_PHI) {
10802                         struct triple **slot;
10803                         struct block *block;
10804                         int edge;
10805                         block = ptr->u.block;
10806                         slot  = (struct triple **)(ptr->left);
10807                         printf("(%p) %3d %-7s",
10808                                 ptr, lr->color, tops(ptr->op));
10809                         for(edge = 0; edge < block->users; edge++) {
10810                                 printf(" %-10p", slot[edge]);
10811                         }
10812                         printf(" @%s:%d.%d\n", 
10813                                 ptr->filename, ptr->line, ptr->col);
10814                 }
10815                 else {
10816                         printf("(%p) %3d %-7s %-10p %-10p @ %s:%d.%d\n",
10817                                 ptr, lr->color, tops(ptr->op), ptr->left, ptr->right,
10818                                 ptr->filename, ptr->line, ptr->col);
10819                 }
10820                 if (lr->edges > 0) {
10821                         struct live_range_edge *edge;
10822                         printf("           ");
10823                         for(edge = lr->edges; edge; edge = edge->next) {
10824                                 printf(" %-10p", edge->node->def);
10825                         }
10826                         printf("\n");
10827                 }
10828                 /* Do a bunch of sanity checks */
10829                 valid_op(state, ptr);
10830                 if ((ptr->id < 0) || (ptr->id > rstate->ranges)) {
10831                         internal_error(state, ptr, "Invalid triple id: %d",
10832                                 ptr->id);
10833                 }
10834                 for(user = ptr->use; user; user = user->next) {
10835                         struct triple *use;
10836                         struct live_range *ulr;
10837                         use = user->member;
10838                         valid_op(state, use);
10839                         if ((use->id < 0) || (use->id > rstate->ranges)) {
10840                                 internal_error(state, use, "Invalid triple id: %d",
10841                                         use->id);
10842                         }
10843                         ulr = &rstate->lr[user->member->id];
10844                         if (!IS_CONST_OP(user->member->op) &&
10845                                 !user->member->u.block) {
10846                                 internal_error(state, user->member,
10847                                         "Use %p not in a block?",
10848                                         user->member);
10849                         }
10850                 }
10851         }
10852         if (rb->out) {
10853                 struct triple_reg_set *out_set;
10854                 printf("       out:");
10855                 for(out_set = rb->out; out_set; out_set = out_set->next) {
10856                         printf(" %-10p", out_set->member);
10857                 }
10858                 printf("\n");
10859         }
10860         printf("\n");
10861 }
10862
10863 static struct live_range *merge_sort_lr(
10864         struct live_range *first, struct live_range *last)
10865 {
10866         struct live_range *mid, *join, **join_tail, *pick;
10867         size_t size;
10868         size = (last - first) + 1;
10869         if (size >= 2) {
10870                 mid = first + size/2;
10871                 first = merge_sort_lr(first, mid -1);
10872                 mid   = merge_sort_lr(mid, last);
10873                 
10874                 join = 0;
10875                 join_tail = &join;
10876                 /* merge the two lists */
10877                 while(first && mid) {
10878                         if (first->degree <= mid->degree) {
10879                                 pick = first;
10880                                 first = first->group_next;
10881                                 if (first) {
10882                                         first->group_prev = 0;
10883                                 }
10884                         }
10885                         else {
10886                                 pick = mid;
10887                                 mid = mid->group_next;
10888                                 if (mid) {
10889                                         mid->group_prev = 0;
10890                                 }
10891                         }
10892                         pick->group_next = 0;
10893                         pick->group_prev = join_tail;
10894                         *join_tail = pick;
10895                         join_tail = &pick->group_next;
10896                 }
10897                 /* Splice the remaining list */
10898                 pick = (first)? first : mid;
10899                 *join_tail = pick;
10900                 pick->group_prev = join_tail;
10901         }
10902         else {
10903                 if (!first->def) {
10904                         first = 0;
10905                 }
10906                 join = first;
10907         }
10908         return join;
10909 }
10910
10911 static void allocate_registers(struct compile_state *state)
10912 {
10913         struct reg_state rstate;
10914         struct live_range **point, **next;
10915         int i;
10916
10917         /* Clear out the reg_state */
10918         memset(&rstate, 0, sizeof(rstate));
10919
10920         /* Compute the variable lifetimes */
10921         rstate.blocks = compute_variable_lifetimes(state);
10922
10923         /* Allocate and initialize the live ranges */
10924         initialize_live_ranges(state, &rstate);
10925
10926         /* Compute the interference graph */
10927         walk_variable_lifetimes(
10928                 state, rstate.blocks, graph_ins, &rstate);
10929
10930         /* Display the interference graph if desired */
10931         if (state->debug & DEBUG_INTERFERENCE) {
10932                 printf("\nlive variables by block\n");
10933                 walk_blocks(state, print_interference_block, &rstate);
10934                 printf("\nlive variables by instruction\n");
10935                 walk_variable_lifetimes(
10936                         state, rstate.blocks, 
10937                         print_interference_ins, &rstate);
10938         }
10939
10940         /* Do not perform coalescing!  It is a neat idea but it limits what
10941          * we can do later.  It has no benefits that decrease register pressure.
10942          * It only decreases instruction count.
10943          *
10944          * It might be worth testing this reducing the number of
10945          * live_ragnes as opposed to splitting them seems to help.
10946          */
10947
10948         /* Build the groups low and high.  But with the nodes
10949          * first sorted by degree order.
10950          */
10951         rstate.low_tail  = &rstate.low;
10952         rstate.high_tail = &rstate.high;
10953         rstate.high = merge_sort_lr(&rstate.lr[1], &rstate.lr[rstate.ranges]);
10954         rstate.high->group_prev = &rstate.high;
10955         for(point = &rstate.high; *point; point = &(*point)->group_next)
10956                 ;
10957         rstate.high_tail = point;
10958         /* Walk through the high list and move everything that needs
10959          * to be onto low.
10960          */
10961         for(point = &rstate.high; *point; point = next) {
10962                 struct live_range *range;
10963                 next = &(*point)->group_next;
10964                 range = *point;
10965
10966                 /* If it has a low degree or it already has a color
10967                  * place the node in low.
10968                  */
10969                 if ((range->degree < regc_max_size(state, range->classes)) ||
10970                         (range->color != REG_UNSET)) {
10971                         cgdebug_printf("Lo: %5d degree %5d%s\n", 
10972                                 range - rstate.lr, range->degree,
10973                                 (range->color != REG_UNSET) ? " (colored)": "");
10974                         *range->group_prev = range->group_next;
10975                         if (range->group_next) {
10976                                 range->group_next->group_prev = range->group_prev;
10977                         }
10978                         if (&range->group_next == rstate.high_tail) {
10979                                 rstate.high_tail = range->group_prev;
10980                         }
10981                         range->group_prev  = rstate.low_tail;
10982                         range->group_next  = 0;
10983                         *rstate.low_tail   = range;
10984                         rstate.low_tail    = &range->group_next;
10985                         next = point;
10986                 }
10987                 else {
10988                         cgdebug_printf("hi: %5d degree %5d%s\n", 
10989                                 range - rstate.lr, range->degree,
10990                                 (range->color != REG_UNSET) ? " (colored)": "");
10991                 }
10992                 
10993         }
10994         /* Color the live_ranges */
10995         color_graph(state, &rstate);
10996
10997         /* Move the colors from the graph to the triples */
10998         color_triples(state, &rstate);
10999
11000         /* Free the edges on each node */
11001         for(i = 1; i <= rstate.ranges; i++) {
11002                 remove_live_edges(&rstate, &rstate.lr[i]);
11003         }
11004         xfree(rstate.lr);
11005
11006         /* Free the variable lifetime information */
11007         free_variable_lifetimes(state, rstate.blocks);
11008
11009 }
11010
11011 /* Sparce Conditional Constant Propogation
11012  * =========================================
11013  */
11014 struct ssa_edge;
11015 struct flow_block;
11016 struct lattice_node {
11017         struct triple *def;
11018         struct ssa_edge *out;
11019         struct flow_block *fblock;
11020         struct triple *val;
11021         /* lattice high   val && !is_const(val) 
11022          * lattice const  is_const(val)
11023          * lattice low    val == 0
11024          */
11025         struct triple scratch;
11026 };
11027 struct ssa_edge {
11028         struct lattice_node *src;
11029         struct lattice_node *dst;
11030         struct ssa_edge *work_next;
11031         struct ssa_edge *work_prev;
11032         struct ssa_edge *out_next;
11033 };
11034 struct flow_edge {
11035         struct flow_block *src;
11036         struct flow_block *dst;
11037         struct flow_edge *work_next;
11038         struct flow_edge *work_prev;
11039         struct flow_edge *in_next;
11040         struct flow_edge *out_next;
11041         int executable;
11042 };
11043 struct flow_block {
11044         struct block *block;
11045         struct flow_edge *in;
11046         struct flow_edge *out;
11047         struct flow_edge left, right;
11048 };
11049
11050 struct scc_state {
11051         struct lattice_node *lattice;
11052         struct ssa_edge     *ssa_edges;
11053         struct flow_block   *flow_blocks;
11054         struct flow_edge    *flow_work_list;
11055         struct ssa_edge     *ssa_work_list;
11056 };
11057
11058
11059 static void scc_add_fedge(struct compile_state *state, struct scc_state *scc, 
11060         struct flow_edge *fedge)
11061 {
11062         if (!scc->flow_work_list) {
11063                 scc->flow_work_list = fedge;
11064                 fedge->work_next = fedge->work_prev = fedge;
11065         }
11066         else {
11067                 struct flow_edge *ftail;
11068                 ftail = scc->flow_work_list->work_prev;
11069                 fedge->work_next = ftail->work_next;
11070                 fedge->work_prev = ftail;
11071                 fedge->work_next->work_prev = fedge;
11072                 fedge->work_prev->work_next = fedge;
11073         }
11074 }
11075
11076 static struct flow_edge *scc_next_fedge(
11077         struct compile_state *state, struct scc_state *scc)
11078 {
11079         struct flow_edge *fedge;
11080         fedge = scc->flow_work_list;
11081         if (fedge) {
11082                 fedge->work_next->work_prev = fedge->work_prev;
11083                 fedge->work_prev->work_next = fedge->work_next;
11084                 if (fedge->work_next != fedge) {
11085                         scc->flow_work_list = fedge->work_next;
11086                 } else {
11087                         scc->flow_work_list = 0;
11088                 }
11089         }
11090         return fedge;
11091 }
11092
11093 static void scc_add_sedge(struct compile_state *state, struct scc_state *scc,
11094         struct ssa_edge *sedge)
11095 {
11096         if (!scc->ssa_work_list) {
11097                 scc->ssa_work_list = sedge;
11098                 sedge->work_next = sedge->work_prev = sedge;
11099         }
11100         else {
11101                 struct ssa_edge *stail;
11102                 stail = scc->ssa_work_list->work_prev;
11103                 sedge->work_next = stail->work_next;
11104                 sedge->work_prev = stail;
11105                 sedge->work_next->work_prev = sedge;
11106                 sedge->work_prev->work_next = sedge;
11107         }
11108 }
11109
11110 static struct ssa_edge *scc_next_sedge(
11111         struct compile_state *state, struct scc_state *scc)
11112 {
11113         struct ssa_edge *sedge;
11114         sedge = scc->ssa_work_list;
11115         if (sedge) {
11116                 sedge->work_next->work_prev = sedge->work_prev;
11117                 sedge->work_prev->work_next = sedge->work_next;
11118                 if (sedge->work_next != sedge) {
11119                         scc->ssa_work_list = sedge->work_next;
11120                 } else {
11121                         scc->ssa_work_list = 0;
11122                 }
11123         }
11124         return sedge;
11125 }
11126
11127 static void initialize_scc_state(
11128         struct compile_state *state, struct scc_state *scc)
11129 {
11130         int ins_count, ssa_edge_count;
11131         int ins_index, ssa_edge_index, fblock_index;
11132         struct triple *first, *ins;
11133         struct block *block;
11134         struct flow_block *fblock;
11135
11136         memset(scc, 0, sizeof(*scc));
11137
11138         /* Inialize pass zero find out how much memory we need */
11139         first = state->main_function->left;
11140         ins = first;
11141         ins_count = ssa_edge_count = 0;
11142         do {
11143                 struct triple_set *edge;
11144                 ins_count += 1;
11145                 for(edge = ins->use; edge; edge = edge->next) {
11146                         ssa_edge_count++;
11147                 }
11148                 ins = ins->next;
11149         } while(ins != first);
11150 #if DEBUG_SCC
11151         fprintf(stderr, "ins_count: %d ssa_edge_count: %d vertex_count: %d\n",
11152                 ins_count, ssa_edge_count, state->last_vertex);
11153 #endif
11154         scc->lattice     = 
11155                 xcmalloc(sizeof(*scc->lattice)*(ins_count + 1), "lattice");
11156         scc->ssa_edges   = 
11157                 xcmalloc(sizeof(*scc->ssa_edges)*(ssa_edge_count + 1), "ssa_edges");
11158         scc->flow_blocks = 
11159                 xcmalloc(sizeof(*scc->flow_blocks)*(state->last_vertex + 1), 
11160                         "flow_blocks");
11161
11162         /* Initialize pass one collect up the nodes */
11163         fblock = 0;
11164         block = 0;
11165         ins_index = ssa_edge_index = fblock_index = 0;
11166         ins = first;
11167         do {
11168                 ins->id = 0;
11169                 if ((ins->op == OP_LABEL) && (block != ins->u.block)) {
11170                         block = ins->u.block;
11171                         if (!block) {
11172                                 internal_error(state, ins, "label without block");
11173                         }
11174                         fblock_index += 1;
11175                         block->vertex = fblock_index;
11176                         fblock = &scc->flow_blocks[fblock_index];
11177                         fblock->block = block;
11178                 }
11179                 {
11180                         struct lattice_node *lnode;
11181                         ins_index += 1;
11182                         ins->id = ins_index;
11183                         lnode = &scc->lattice[ins_index];
11184                         lnode->def = ins;
11185                         lnode->out = 0;
11186                         lnode->fblock = fblock;
11187                         lnode->val = ins; /* LATTICE HIGH */
11188                 }
11189                 ins = ins->next;
11190         } while(ins != first);
11191         /* Initialize pass two collect up the edges */
11192         block = 0;
11193         fblock = 0;
11194         ins = first;
11195         do {
11196                 if ((ins->op == OP_LABEL) && (block != ins->u.block)) {
11197                         struct flow_edge *fedge, **ftail;
11198                         struct block_set *bedge;
11199                         block = ins->u.block;
11200                         fblock = &scc->flow_blocks[block->vertex];
11201                         fblock->in = 0;
11202                         fblock->out = 0;
11203                         ftail = &fblock->out;
11204                         if (block->left) {
11205                                 fblock->left.dst = &scc->flow_blocks[block->left->vertex];
11206                                 if (fblock->left.dst->block != block->left) {
11207                                         internal_error(state, 0, "block mismatch");
11208                                 }
11209                                 fblock->left.out_next = 0;
11210                                 *ftail = &fblock->left;
11211                                 ftail = &fblock->left.out_next;
11212                         }
11213                         if (block->right) {
11214                                 fblock->right.dst = &scc->flow_blocks[block->right->vertex];
11215                                 if (fblock->right.dst->block != block->right) {
11216                                         internal_error(state, 0, "block mismatch");
11217                                 }
11218                                 fblock->right.out_next = 0;
11219                                 *ftail = &fblock->right;
11220                                 ftail = &fblock->right.out_next;
11221                         }
11222                         for(fedge = fblock->out; fedge; fedge = fedge->out_next) {
11223                                 fedge->src = fblock;
11224                                 fedge->work_next = fedge->work_prev = fedge;
11225                                 fedge->executable = 0;
11226                         }
11227                         ftail = &fblock->in;
11228                         for(bedge = block->use; bedge; bedge = bedge->next) {
11229                                 struct block *src_block;
11230                                 struct flow_block *sfblock;
11231                                 struct flow_edge *sfedge;
11232                                 src_block = bedge->member;
11233                                 sfblock = &scc->flow_blocks[src_block->vertex];
11234                                 sfedge = 0;
11235                                 if (src_block->left == block) {
11236                                         sfedge = &sfblock->left;
11237                                 } else {
11238                                         sfedge = &sfblock->right;
11239                                 }
11240                                 *ftail = sfedge;
11241                                 ftail = &sfedge->in_next;
11242                                 sfedge->in_next = 0;
11243                         }
11244                 }
11245                 {
11246                         struct triple_set *edge;
11247                         struct ssa_edge **stail;
11248                         struct lattice_node *lnode;
11249                         lnode = &scc->lattice[ins->id];
11250                         lnode->out = 0;
11251                         stail = &lnode->out;
11252                         for(edge = ins->use; edge; edge = edge->next) {
11253                                 struct ssa_edge *sedge;
11254                                 ssa_edge_index += 1;
11255                                 sedge = &scc->ssa_edges[ssa_edge_index];
11256                                 *stail = sedge;
11257                                 stail = &sedge->out_next;
11258                                 sedge->src = lnode;
11259                                 sedge->dst = &scc->lattice[edge->member->id];
11260                                 sedge->work_next = sedge->work_prev = sedge;
11261                                 sedge->out_next = 0;
11262                         }
11263                 }
11264                 ins = ins->next;
11265         } while(ins != first);
11266         /* Setup a dummy block 0 as a node above the start node */
11267         {
11268                 struct flow_block *fblock, *dst;
11269                 struct flow_edge *fedge;
11270                 fblock = &scc->flow_blocks[0];
11271                 fblock->block = 0;
11272                 fblock->in = 0;
11273                 fblock->out = &fblock->left;
11274                 dst = &scc->flow_blocks[state->first_block->vertex];
11275                 fedge = &fblock->left;
11276                 fedge->src        = fblock;
11277                 fedge->dst        = dst;
11278                 fedge->work_next  = fedge;
11279                 fedge->work_prev  = fedge;
11280                 fedge->in_next    = fedge->dst->in;
11281                 fedge->out_next   = 0;
11282                 fedge->executable = 0;
11283                 fedge->dst->in = fedge;
11284                 
11285                 /* Initialize the work lists */
11286                 scc->flow_work_list = 0;
11287                 scc->ssa_work_list  = 0;
11288                 scc_add_fedge(state, scc, fedge);
11289         }
11290 #if DEBUG_SCC
11291         fprintf(stderr, "ins_index: %d ssa_edge_index: %d fblock_index: %d\n",
11292                 ins_index, ssa_edge_index, fblock_index);
11293 #endif
11294 }
11295
11296         
11297 static void free_scc_state(
11298         struct compile_state *state, struct scc_state *scc)
11299 {
11300         xfree(scc->flow_blocks);
11301         xfree(scc->ssa_edges);
11302         xfree(scc->lattice);
11303 }
11304
11305 static struct lattice_node *triple_to_lattice(
11306         struct compile_state *state, struct scc_state *scc, struct triple *ins)
11307 {
11308         if (ins->id <= 0) {
11309                 internal_error(state, ins, "bad id");
11310         }
11311         return &scc->lattice[ins->id];
11312 }
11313
11314 static void scc_visit_phi(struct compile_state *state, struct scc_state *scc, 
11315         struct lattice_node *lnode)
11316 {
11317         struct lattice_node *tmp;
11318         struct triple **slot;
11319         struct flow_edge *fedge;
11320         int index;
11321         if (lnode->def->op != OP_PHI) {
11322                 internal_error(state, lnode->def, "not phi");
11323         }
11324         /* default to lattice high */
11325         lnode->val = lnode->def;
11326         slot = (struct triple **)lnode->def->left;
11327         index = 0;
11328         for(fedge = lnode->fblock->in; fedge; index++, fedge = fedge->in_next) {
11329                 if (!fedge->executable) {
11330                         continue;
11331                 }
11332                 if (!slot[index]) {
11333                         internal_error(state, lnode->def, "no phi value");
11334                 }
11335                 tmp = triple_to_lattice(state, scc, slot[index]);
11336                 /* meet(X, lattice low) = lattice low */
11337                 if (!tmp->val) {
11338                         lnode->val = 0;
11339                 }
11340                 /* meet(X, lattice high) = X */
11341                 else if (!tmp->val) {
11342                         lnode->val = lnode->val;
11343                 }
11344                 /* meet(lattice high, X) = X */
11345                 else if (!is_const(lnode->val)) {
11346                         lnode->val = tmp->val;
11347                 }
11348                 /* meet(const, const) = const or lattice low */
11349                 else if (!constants_equal(state, lnode->val, tmp->val)) {
11350                         lnode->val = 0;
11351                 }
11352                 if (!lnode->val) {
11353                         break;
11354                 }
11355         }
11356         /* Do I need to update any work lists here? */
11357 #if DEBUG_SCC
11358         fprintf(stderr, "phi: %d -> %s\n",
11359                 lnode->def->id,
11360                 (!lnode->val)? "lo": is_const(lnode->val)? "const": "hi");
11361 #endif
11362 }
11363
11364 static int compute_lnode_val(struct compile_state *state, struct scc_state *scc,
11365         struct lattice_node *lnode)
11366 {
11367         int changed;
11368         struct triple old_buf, *old;
11369         struct triple **dexpr, **vexpr;
11370         
11371         /* Store the original value */
11372         if (lnode->val) {
11373                 old = &old_buf;
11374                 memcpy(old, lnode->val, sizeof(*old));
11375         } else {
11376                 old = 0;
11377         }
11378         /* Reinitialize the value */
11379         memset(&lnode->scratch, 0, sizeof(lnode->scratch));
11380         lnode->val = &lnode->scratch;
11381         lnode->val->next     = &lnode->scratch;
11382         lnode->val->prev     = &lnode->scratch;
11383         lnode->val->use      = 0;
11384         lnode->val->type     = lnode->def->type;
11385         lnode->val->op       = lnode->def->op;
11386         lnode->val->left     = 0;
11387         lnode->val->right    = 0;
11388         lnode->val->filename = lnode->def->filename;
11389         lnode->val->line     = lnode->def->line;
11390         lnode->val->col      = lnode->def->col;
11391         if (lnode->def->op != OP_STORE) {
11392                 check_lhs(state,  lnode->def);
11393         }
11394         dexpr = triple_rhs(state, lnode->def, 0);
11395         vexpr = triple_rhs(state, lnode->val, 0);
11396         while(dexpr && vexpr) {
11397                 struct lattice_node *tmp;
11398                 tmp = triple_to_lattice(state, scc, *dexpr); 
11399                 *vexpr = (tmp->val)? tmp->val : tmp->def;
11400                 dexpr = triple_rhs(state, lnode->def, dexpr);
11401                 vexpr = triple_rhs(state, lnode->val, vexpr);
11402         }
11403         if (is_const(lnode->val)) {
11404                 memcpy(&lnode->val->u, &lnode->def->u, sizeof(lnode->def->u));
11405         }
11406         else if (lnode->val->op == OP_BRANCH) {
11407                 lnode->val->left = lnode->def->left;
11408                 lnode->val->next = lnode->def->next;
11409         }
11410         else if (lnode->val->op == OP_SDECL) {
11411                 lnode->val->left = lnode->def->left;
11412         }
11413         /* Recompute the value */
11414 #warning "FIXME see if simplify does anything bad"
11415         /* So far it looks like only the strength reduction
11416          * optimization are things I need to worry about.
11417          */
11418         simplify(state, lnode->val);
11419         /* Cleanup my value */
11420         if (lnode->scratch.use) {
11421                 internal_error(state, lnode->def, "scratch used?");
11422         }
11423         if ((lnode->scratch.prev != &lnode->scratch) ||
11424                 ((lnode->scratch.next != &lnode->scratch) && 
11425                         ((lnode->def->op != OP_BRANCH) ||
11426                                 (lnode->scratch.next != lnode->def->next)))) {
11427                 internal_error(state, lnode->def, "scratch in list?");
11428         }
11429         /* undo any uses... */
11430         vexpr = triple_rhs(state, lnode->val, 0);
11431         for(;vexpr;vexpr = triple_rhs(state, lnode->val, vexpr)) {
11432                 unuse_triple(*vexpr, lnode->val);
11433         }
11434         if (!is_const(lnode->val)) {
11435                 dexpr = triple_rhs(state, lnode->def, 0);
11436                 for(;dexpr;dexpr = triple_rhs(state, lnode->def, dexpr)) {
11437                         struct lattice_node *tmp;
11438                         tmp = triple_to_lattice(state, scc, *dexpr);
11439                         if (!tmp->val) {
11440                                 lnode->val = 0;
11441                         }
11442                 }
11443         }
11444         if (lnode->val && 
11445                 (lnode->val->op == lnode->def->op) &&
11446                 (lnode->val->left == lnode->def->left) &&
11447                 (lnode->val->right == lnode->def->right) &&
11448                 (((memcmp(&lnode->val->u, &lnode->def->u, sizeof(lnode->def->u)) == 0) &&
11449                         is_const(lnode->val)) || !is_const(lnode->val))) {
11450                 lnode->val = lnode->def;
11451         }
11452         /* Find the cases that are always lattice lo */
11453         if (lnode->val && 
11454                 triple_is_def(lnode->val) &&
11455                 !triple_is_pure(state, lnode->val)) {
11456                 lnode->val = 0;
11457         }
11458 #if 1
11459         if (lnode->val && 
11460                 (lnode->val->op == OP_SDECL) && 
11461                 (lnode->val != lnode->def)) {
11462                 internal_error(state, lnode->def, "bad sdecl");
11463         }
11464 #endif
11465         /* See if the lattice value has changed */
11466         changed = 1;
11467         if (!old && !lnode->val) {
11468                 changed = 0;
11469         }
11470         if (changed && lnode->val && !is_const(lnode->val)) {
11471                 changed = 0;
11472         }
11473         if (changed &&
11474                 lnode->val && old &&
11475                 (lnode->val->op == old->op) &&
11476                 (lnode->val->left == old->left) &&
11477                 (lnode->val->right == old->right) &&
11478                 (memcmp(&lnode->val->u, &old->u, sizeof(old->u)) == 0)) {
11479                 changed = 0;
11480         }
11481         return changed;
11482
11483 }
11484 static void scc_visit_branch(struct compile_state *state, struct scc_state *scc,
11485         struct lattice_node *lnode)
11486 {
11487         struct lattice_node *cond;
11488 #if DEBUG_SCC
11489         {
11490                 struct flow_edge *fedge;
11491                 fprintf(stderr, "branch: %d (",
11492                         lnode->def->id);
11493                 
11494                 for(fedge = lnode->fblock->out; fedge; fedge = fedge->out_next) {
11495                         fprintf(stderr, " %d", fedge->dst->block->vertex);
11496                 }
11497                 fprintf(stderr, " )");
11498                 if (lnode->def->right) {
11499                         fprintf(stderr, " <- %d",
11500                                 lnode->def->right->id);
11501                 }
11502                 fprintf(stderr, "\n");
11503         }
11504 #endif
11505         if (lnode->def->op != OP_BRANCH) {
11506                 internal_error(state, lnode->def, "not branch");
11507         }
11508         /* This only applies to conditional branches */
11509         if (lnode->def->right == 0) {
11510                 return;
11511         }
11512         cond = triple_to_lattice(state, scc, lnode->def->right);
11513         if (cond->val && !is_const(cond->val)) {
11514 #warning "FIXME do I need to do something here?"
11515                 warning(state, cond->def, "condition not constant?");
11516                 return;
11517         }
11518         if (cond->val == 0) {
11519                 scc_add_fedge(state, scc, cond->fblock->out);
11520                 scc_add_fedge(state, scc, cond->fblock->out->out_next);
11521         }
11522         else if (cond->val->u.cval) {
11523                 scc_add_fedge(state, scc, cond->fblock->out->out_next);
11524                 
11525         } else {
11526                 scc_add_fedge(state, scc, cond->fblock->out);
11527         }
11528
11529 }
11530
11531 static void scc_visit_expr(struct compile_state *state, struct scc_state *scc,
11532         struct lattice_node *lnode)
11533 {
11534         int changed;
11535
11536         changed = compute_lnode_val(state, scc, lnode);
11537 #if DEBUG_SCC
11538         {
11539                 struct triple **expr;
11540                 fprintf(stderr, "expr: %3d %10s (",
11541                         lnode->def->id, tops(lnode->def->op));
11542                 expr = triple_rhs(state, lnode->def, 0);
11543                 for(;expr;expr = triple_rhs(state, lnode->def, expr)) {
11544                         fprintf(stderr, " %d", (*expr)->id);
11545                 }
11546                 fprintf(stderr, " ) -> %s\n",
11547                         (!lnode->val)? "lo": is_const(lnode->val)? "const": "hi");
11548         }
11549 #endif
11550         if (lnode->def->op == OP_BRANCH) {
11551                 scc_visit_branch(state, scc, lnode);
11552
11553         }
11554         else if (changed) {
11555                 struct ssa_edge *sedge;
11556                 for(sedge = lnode->out; sedge; sedge = sedge->out_next) {
11557                         scc_add_sedge(state, scc, sedge);
11558                 }
11559         }
11560 }
11561
11562 static void scc_writeback_values(
11563         struct compile_state *state, struct scc_state *scc)
11564 {
11565         struct triple *first, *ins;
11566         first = state->main_function->left;
11567         ins = first;
11568         do {
11569                 struct lattice_node *lnode;
11570                 lnode = triple_to_lattice(state, scc, ins);
11571 #if DEBUG_SCC
11572                 if (lnode->val && !is_const(lnode->val)) {
11573                         warning(state, lnode->def, 
11574                                 "lattice node still high?");
11575                 }
11576 #endif
11577                 if (lnode->val && (lnode->val != ins)) {
11578                         /* See if it something I know how to write back */
11579                         switch(lnode->val->op) {
11580                         case OP_INTCONST:
11581                                 mkconst(state, ins, lnode->val->u.cval);
11582                                 break;
11583                         case OP_ADDRCONST:
11584                                 mkaddr_const(state, ins, 
11585                                         lnode->val->left, lnode->val->u.cval);
11586                                 break;
11587                         default:
11588                                 /* By default don't copy the changes,
11589                                  * recompute them in place instead.
11590                                  */
11591                                 simplify(state, ins);
11592                                 break;
11593                         }
11594                 }
11595                 ins = ins->next;
11596         } while(ins != first);
11597 }
11598
11599 static void scc_transform(struct compile_state *state)
11600 {
11601         struct scc_state scc;
11602
11603         initialize_scc_state(state, &scc);
11604
11605         while(scc.flow_work_list || scc.ssa_work_list) {
11606                 struct flow_edge *fedge;
11607                 struct ssa_edge *sedge;
11608                 struct flow_edge *fptr;
11609                 while((fedge = scc_next_fedge(state, &scc))) {
11610                         struct block *block;
11611                         struct triple *ptr;
11612                         struct flow_block *fblock;
11613                         int time;
11614                         int done;
11615                         if (fedge->executable) {
11616                                 continue;
11617                         }
11618                         if (!fedge->dst) {
11619                                 internal_error(state, 0, "fedge without dst");
11620                         }
11621                         if (!fedge->src) {
11622                                 internal_error(state, 0, "fedge without src");
11623                         }
11624                         fedge->executable = 1;
11625                         fblock = fedge->dst;
11626                         block = fblock->block;
11627                         time = 0;
11628                         for(fptr = fblock->in; fptr; fptr = fptr->in_next) {
11629                                 if (fptr->executable) {
11630                                         time++;
11631                                 }
11632                         }
11633 #if DEBUG_SCC
11634                         fprintf(stderr, "vertex: %d time: %d\n", 
11635                                 block->vertex, time);
11636                         
11637 #endif
11638                         done = 0;
11639                         for(ptr = block->first; !done; ptr = ptr->next) {
11640                                 struct lattice_node *lnode;
11641                                 done = (ptr == block->last);
11642                                 lnode = &scc.lattice[ptr->id];
11643                                 if (ptr->op == OP_PHI) {
11644                                         scc_visit_phi(state, &scc, lnode);
11645                                 }
11646                                 else if (time == 1) {
11647                                         scc_visit_expr(state, &scc, lnode);
11648                                 }
11649                         }
11650                         if (fblock->out && !fblock->out->out_next) {
11651                                 scc_add_fedge(state, &scc, fblock->out);
11652                         }
11653                 }
11654                 while((sedge = scc_next_sedge(state, &scc))) {
11655                         struct lattice_node *lnode;
11656                         struct flow_block *fblock;
11657                         lnode = sedge->dst;
11658                         fblock = lnode->fblock;
11659 #if DEBUG_SCC
11660                         fprintf(stderr, "sedge: %5d (%5d -> %5d)\n",
11661                                 sedge - scc.ssa_edges,
11662                                 sedge->src->def->id,
11663                                 sedge->dst->def->id);
11664 #endif
11665                         if (lnode->def->op == OP_PHI) {
11666                                 scc_visit_phi(state, &scc, lnode);
11667                         }
11668                         else {
11669                                 for(fptr = fblock->in; fptr; fptr = fptr->in_next) {
11670                                         if (fptr->executable) {
11671                                                 break;
11672                                         }
11673                                 }
11674                                 if (fptr) {
11675                                         scc_visit_expr(state, &scc, lnode);
11676                                 }
11677                         }
11678                 }
11679         }
11680         
11681         scc_writeback_values(state, &scc);
11682         /* FINISH ME move constants from scratch values into the tree */
11683         free_scc_state(state, &scc);
11684 }
11685
11686
11687 static void transform_to_arch_instructions(struct compile_state *state);
11688
11689
11690 static void optimize(struct compile_state *state)
11691 {
11692         if (state->debug & DEBUG_TRIPLES) {
11693                 print_triples(state);
11694         }
11695         /* Analize the intermediate code */
11696         setup_basic_blocks(state);
11697         analyze_idominators(state);
11698         analyze_ipdominators(state);
11699         /* Transform the code to ssa form */
11700         transform_to_ssa_form(state);
11701         /* Do strength reduction and simple constant optimizations */
11702         if (state->optimize >= 1) {
11703                 simplify_all(state);
11704         }
11705         /* Propogate constants throughout the code */
11706         if (state->optimize >= 2) {
11707                 scc_transform(state);
11708                 transform_from_ssa_form(state);
11709                 free_basic_blocks(state);
11710                 setup_basic_blocks(state);
11711                 analyze_idominators(state);
11712                 analyze_ipdominators(state);
11713                 transform_to_ssa_form(state);
11714                 
11715         }
11716 #warning "WISHLIST implement single use constants (least possible register pressure)"
11717 #warning "WISHLIST implement induction variable elimination"
11718 #warning "WISHLIST implement strength reduction"
11719         /* Select architecture instructions and an initial partial
11720          * coloring based on architecture constraints.
11721          */
11722         transform_to_arch_instructions(state);
11723         if (state->debug & DEBUG_ARCH_CODE) {
11724                 printf("After transform_to_arch_instructions\n");
11725                 print_blocks(state);
11726                 print_control_flow(state);
11727         }
11728         eliminate_inefectual_code(state);
11729         if (state->debug & DEBUG_CODE_ELIMINATION) {
11730                 printf("After eliminate_inefectual_code\n");
11731                 print_blocks(state);
11732                 print_control_flow(state);
11733         }
11734         /* Color all of the variables to see if they will fit in registers */
11735         insert_copies_to_phi(state);
11736         allocate_registers(state);
11737         if (state->debug & DEBUG_INTERMEDIATE_CODE) {
11738                 print_blocks(state);
11739         }
11740         if (state->debug & DEBUG_CONTROL_FLOW) {
11741                 print_control_flow(state);
11742         }
11743         /* Remove the optimization information.
11744          * This is more to check for memory consistency than to free memory.
11745          */
11746         free_basic_blocks(state);
11747 }
11748
11749 /* The x86 register classes */
11750 #define REGC_FLAGS   0
11751 #define REGC_GPR8    1
11752 #define REGC_GPR16   2
11753 #define REGC_GPR32   3
11754 #define REGC_GPR64   4
11755 #define REGC_MMX     5
11756 #define REGC_XMM     6
11757 #define REGC_GPR32_8 7
11758 #define REGC_GPR16_8 8
11759 #define LAST_REGC  REGC_GPR16_8
11760 #if LAST_REGC >= MAX_REGC
11761 #error "MAX_REGC is to low"
11762 #endif
11763
11764 /* Register class masks */
11765 #define REGCM_FLAGS   (1 << REGC_FLAGS)
11766 #define REGCM_GPR8    (1 << REGC_GPR8)
11767 #define REGCM_GPR16   (1 << REGC_GPR16)
11768 #define REGCM_GPR32   (1 << REGC_GPR32)
11769 #define REGCM_GPR64   (1 << REGC_GPR64)
11770 #define REGCM_MMX     (1 << REGC_MMX)
11771 #define REGCM_XMM     (1 << REGC_XMM)
11772 #define REGCM_GPR32_8 (1 << REGC_GPR32_8)
11773 #define REGCM_GPR16_8 (1 << REGC_GPR16_8)
11774
11775 /* The x86 registers */
11776 #define REG_EFLAGS  1
11777 #define REGC_FLAGS_FIRST REG_EFLAGS
11778 #define REGC_FLAGS_LAST  REG_EFLAGS
11779 #define REG_AL      2
11780 #define REG_BL      3
11781 #define REG_CL      4
11782 #define REG_DL      5
11783 #define REG_AH      6
11784 #define REG_BH      7
11785 #define REG_CH      8
11786 #define REG_DH      9
11787 #define REGC_GPR8_FIRST  REG_AL
11788 #if X86_4_8BIT_GPRS
11789 #define REGC_GPR8_LAST   REG_DL
11790 #else 
11791 #define REGC_GPR8_LAST   REG_DH
11792 #endif
11793 #define REG_AX     10
11794 #define REG_BX     11
11795 #define REG_CX     12
11796 #define REG_DX     13
11797 #define REG_SI     14
11798 #define REG_DI     15
11799 #define REG_BP     16
11800 #define REG_SP     17
11801 #define REGC_GPR16_FIRST REG_AX
11802 #define REGC_GPR16_LAST  REG_SP
11803 #define REG_EAX    18
11804 #define REG_EBX    19
11805 #define REG_ECX    20
11806 #define REG_EDX    21
11807 #define REG_ESI    22
11808 #define REG_EDI    23
11809 #define REG_EBP    24
11810 #define REG_ESP    25
11811 #define REGC_GPR32_FIRST REG_EAX
11812 #define REGC_GPR32_LAST  REG_ESP
11813 #define REG_EDXEAX 26
11814 #define REGC_GPR64_FIRST REG_EDXEAX
11815 #define REGC_GPR64_LAST  REG_EDXEAX
11816 #define REG_MMX0   27
11817 #define REG_MMX1   28
11818 #define REG_MMX2   29
11819 #define REG_MMX3   30
11820 #define REG_MMX4   31
11821 #define REG_MMX5   32
11822 #define REG_MMX6   33
11823 #define REG_MMX7   34
11824 #define REGC_MMX_FIRST REG_MMX0
11825 #define REGC_MMX_LAST  REG_MMX7
11826 #define REG_XMM0   35
11827 #define REG_XMM1   36
11828 #define REG_XMM2   37
11829 #define REG_XMM3   38
11830 #define REG_XMM4   39
11831 #define REG_XMM5   40
11832 #define REG_XMM6   41
11833 #define REG_XMM7   42
11834 #define REGC_XMM_FIRST REG_XMM0
11835 #define REGC_XMM_LAST  REG_XMM7
11836 #warning "WISHLIST figure out how to use pinsrw and pextrw to better use extended regs"
11837 #define LAST_REG   REG_XMM7
11838
11839 #define REGC_GPR32_8_FIRST REG_EAX
11840 #define REGC_GPR32_8_LAST  REG_EDX
11841 #define REGC_GPR16_8_FIRST REG_AX
11842 #define REGC_GPR16_8_LAST  REG_DX
11843
11844 #if LAST_REG >= MAX_REGISTERS
11845 #error "MAX_REGISTERS to low"
11846 #endif
11847
11848 static unsigned arch_regc_size(struct compile_state *state, int class)
11849 {
11850         static unsigned regc_size[LAST_REGC +1] = {
11851                 [REGC_FLAGS]   = REGC_FLAGS_LAST   - REGC_FLAGS_FIRST + 1,
11852                 [REGC_GPR8]    = REGC_GPR8_LAST    - REGC_GPR8_FIRST + 1,
11853                 [REGC_GPR16]   = REGC_GPR16_LAST   - REGC_GPR16_FIRST + 1,
11854                 [REGC_GPR32]   = REGC_GPR32_LAST   - REGC_GPR32_FIRST + 1,
11855                 [REGC_GPR64]   = REGC_GPR64_LAST   - REGC_GPR64_FIRST + 1,
11856                 [REGC_MMX]     = REGC_MMX_LAST     - REGC_MMX_FIRST + 1,
11857                 [REGC_XMM]     = REGC_XMM_LAST     - REGC_XMM_FIRST + 1,
11858                 [REGC_GPR32_8] = REGC_GPR32_8_LAST - REGC_GPR32_8_FIRST + 1,
11859                 [REGC_GPR16_8] = REGC_GPR16_8_LAST - REGC_GPR16_8_FIRST + 1,
11860         };
11861         if ((class < 0) || (class > LAST_REGC)) {
11862                 return 0;
11863         }
11864         return regc_size[class];
11865 }
11866 static int arch_regcm_intersect(unsigned regcm1, unsigned regcm2)
11867 {
11868         /* See if two register classes may have overlapping registers */
11869         unsigned gpr_mask = REGCM_GPR8 | REGCM_GPR16_8 | REGCM_GPR16 |
11870                 REGCM_GPR32_8 | REGCM_GPR32 | REGCM_GPR64;
11871
11872         return (regcm1 & regcm2) ||
11873                 ((regcm1 & gpr_mask) && (regcm2 & gpr_mask));
11874 }
11875
11876 static void arch_reg_equivs(
11877         struct compile_state *state, unsigned *equiv, int reg)
11878 {
11879         if ((reg < 0) || (reg > LAST_REG)) {
11880                 internal_error(state, 0, "invalid register");
11881         }
11882         *equiv++ = reg;
11883         switch(reg) {
11884         case REG_AL:
11885         case REG_AH:
11886                 *equiv++ = REG_AX;
11887                 *equiv++ = REG_EAX;
11888                 *equiv++ = REG_EDXEAX;
11889                 break;
11890         case REG_BL:  
11891         case REG_BH:
11892                 *equiv++ = REG_BX;
11893                 *equiv++ = REG_EBX;
11894                 break;
11895         case REG_CL:
11896         case REG_CH:
11897                 *equiv++ = REG_CX;
11898                 *equiv++ = REG_ECX;
11899                 break;
11900         case REG_DL:
11901         case REG_DH:
11902                 *equiv++ = REG_DX;
11903                 *equiv++ = REG_EDX;
11904                 *equiv++ = REG_EDXEAX;
11905                 break;
11906         case REG_AX:
11907                 *equiv++ = REG_AL;
11908                 *equiv++ = REG_AH;
11909                 *equiv++ = REG_EAX;
11910                 *equiv++ = REG_EDXEAX;
11911                 break;
11912         case REG_BX:
11913                 *equiv++ = REG_BL;
11914                 *equiv++ = REG_BH;
11915                 *equiv++ = REG_EBX;
11916                 break;
11917         case REG_CX:  
11918                 *equiv++ = REG_CL;
11919                 *equiv++ = REG_CH;
11920                 *equiv++ = REG_ECX;
11921                 break;
11922         case REG_DX:  
11923                 *equiv++ = REG_DL;
11924                 *equiv++ = REG_DH;
11925                 *equiv++ = REG_EDX;
11926                 *equiv++ = REG_EDXEAX;
11927                 break;
11928         case REG_SI:  
11929                 *equiv++ = REG_ESI;
11930                 break;
11931         case REG_DI:
11932                 *equiv++ = REG_EDI;
11933                 break;
11934         case REG_BP:
11935                 *equiv++ = REG_EBP;
11936                 break;
11937         case REG_SP:
11938                 *equiv++ = REG_ESP;
11939                 break;
11940         case REG_EAX:
11941                 *equiv++ = REG_AL;
11942                 *equiv++ = REG_AH;
11943                 *equiv++ = REG_AX;
11944                 *equiv++ = REG_EDXEAX;
11945                 break;
11946         case REG_EBX:
11947                 *equiv++ = REG_BL;
11948                 *equiv++ = REG_BH;
11949                 *equiv++ = REG_BX;
11950                 break;
11951         case REG_ECX:
11952                 *equiv++ = REG_CL;
11953                 *equiv++ = REG_CH;
11954                 *equiv++ = REG_CX;
11955                 break;
11956         case REG_EDX:
11957                 *equiv++ = REG_DL;
11958                 *equiv++ = REG_DH;
11959                 *equiv++ = REG_DX;
11960                 *equiv++ = REG_EDXEAX;
11961                 break;
11962         case REG_ESI: 
11963                 *equiv++ = REG_SI;
11964                 break;
11965         case REG_EDI: 
11966                 *equiv++ = REG_DI;
11967                 break;
11968         case REG_EBP: 
11969                 *equiv++ = REG_BP;
11970                 break;
11971         case REG_ESP: 
11972                 *equiv++ = REG_SP;
11973                 break;
11974         case REG_EDXEAX: 
11975                 *equiv++ = REG_AL;
11976                 *equiv++ = REG_AH;
11977                 *equiv++ = REG_DL;
11978                 *equiv++ = REG_DH;
11979                 *equiv++ = REG_AX;
11980                 *equiv++ = REG_DX;
11981                 *equiv++ = REG_EAX;
11982                 *equiv++ = REG_EDX;
11983                 break;
11984         }
11985         *equiv++ = REG_UNSET; 
11986 }
11987
11988
11989 static unsigned arch_reg_regcm(struct compile_state *state, int reg)
11990 {
11991         static const struct {
11992                 int first, last;
11993         } bound[LAST_REGC + 1] = {
11994                 [REGC_FLAGS]   = { REGC_FLAGS_FIRST,   REGC_FLAGS_LAST },
11995                 [REGC_GPR8]    = { REGC_GPR8_FIRST,    REGC_GPR8_LAST },
11996                 [REGC_GPR16]   = { REGC_GPR16_FIRST,   REGC_GPR16_LAST },
11997                 [REGC_GPR32]   = { REGC_GPR32_FIRST,   REGC_GPR32_LAST },
11998                 [REGC_GPR64]   = { REGC_GPR64_FIRST,   REGC_GPR64_LAST },
11999                 [REGC_MMX]     = { REGC_MMX_FIRST,     REGC_MMX_LAST },
12000                 [REGC_XMM]     = { REGC_XMM_FIRST,     REGC_XMM_LAST },
12001                 [REGC_GPR32_8] = { REGC_GPR32_8_FIRST, REGC_GPR32_8_LAST },
12002                 [REGC_GPR16_8] = { REGC_GPR16_8_FIRST, REGC_GPR16_8_LAST },
12003         };
12004         unsigned mask;
12005         int class;
12006         mask = 0;
12007         for(class = 0; class <= LAST_REGC; class++) {
12008                 if ((reg >= bound[class].first) &&
12009                         (reg <= bound[class].last)) {
12010                         mask |= (1 << class);
12011                 }
12012         }
12013         if (!mask) {
12014                 internal_error(state, 0, "reg %d not in any class", reg);
12015         }
12016         return mask;
12017 }
12018
12019 static int do_select_reg(struct compile_state *state, 
12020         char *used, int reg, unsigned classes)
12021 {
12022         unsigned mask;
12023         if (used[reg]) {
12024                 return REG_UNSET;
12025         }
12026         mask = arch_reg_regcm(state, reg);
12027         return (classes & mask) ? reg : REG_UNSET;
12028 }
12029
12030 static int arch_select_free_register(
12031         struct compile_state *state, char *used, int classes)
12032 {
12033         /* Preference: flags, 8bit gprs, 32bit gprs, other 32bit reg
12034          * other types of registers.
12035          */
12036         int i, reg;
12037         reg = REG_UNSET;
12038         for(i = REGC_FLAGS_FIRST; (reg == REG_UNSET) && (i <= REGC_FLAGS_LAST); i++) {
12039                 reg = do_select_reg(state, used, i, classes);
12040         }
12041         for(i = REGC_GPR8_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR8_LAST); i++) {
12042                 reg = do_select_reg(state, used, i, classes);
12043         }
12044         for(i = REGC_GPR32_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR32_LAST); i++) {
12045                 reg = do_select_reg(state, used, i, classes);
12046         }
12047         for(i = REGC_MMX_FIRST; (reg == REG_UNSET) && (i <= REGC_MMX_LAST); i++) {
12048                 reg = do_select_reg(state, used, i, classes);
12049         }
12050         for(i = REGC_XMM_FIRST; (reg == REG_UNSET) && (i <= REGC_XMM_LAST); i++) {
12051                 reg = do_select_reg(state, used, i, classes);
12052         }
12053         for(i = REGC_GPR16_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR16_LAST); i++) {
12054                 reg = do_select_reg(state, used, i, classes);
12055         }
12056         for(i = REGC_GPR64_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR64_LAST); i++) {
12057                 reg = do_select_reg(state, used, i, classes);
12058         }
12059         return reg;
12060 }
12061
12062 static unsigned arch_type_to_regcm(struct compile_state *state, struct type *type) 
12063 {
12064 #warning "FIXME force types smaller (if legal) before I get here"
12065         int use_mmx = 0;
12066         int use_sse = 0;
12067         unsigned avail_mask;
12068         unsigned mask;
12069         avail_mask = REGCM_GPR8 | REGCM_GPR16_8 | REGCM_GPR16 | 
12070                 REGCM_GPR32 | REGCM_GPR32_8 | REGCM_GPR64;
12071 #if 1
12072         /* Don't enable 8 bit values until I can force both operands
12073          * to be 8bits simultaneously.
12074          */
12075         avail_mask &= ~(REGCM_GPR8 | REGCM_GPR16_8 | REGCM_GPR16);
12076 #endif
12077         if (use_mmx) {
12078                 avail_mask |= REGCM_MMX;
12079         }
12080         if (use_sse) {
12081                 avail_mask |= REGCM_XMM;
12082         }
12083         mask = 0;
12084         switch(type->type & TYPE_MASK) {
12085         case TYPE_ARRAY:
12086         case TYPE_VOID: 
12087                 mask = 0; 
12088                 break;
12089         case TYPE_CHAR:
12090         case TYPE_UCHAR:
12091                 mask = REGCM_GPR8 | 
12092                         REGCM_GPR16_8 | REGCM_GPR16 | 
12093                         REGCM_GPR32 | REGCM_GPR32_8 |
12094                         REGCM_GPR64 |
12095                         REGCM_MMX | REGCM_XMM;
12096                 break;
12097         case TYPE_SHORT:
12098         case TYPE_USHORT:
12099                 mask = REGCM_GPR16 | REGCM_GPR16_8 |
12100                         REGCM_GPR32 | REGCM_GPR32_8 |
12101                         REGCM_GPR64 |
12102                         REGCM_MMX | REGCM_XMM;
12103                 break;
12104         case TYPE_INT:
12105         case TYPE_UINT:
12106         case TYPE_LONG:
12107         case TYPE_ULONG:
12108         case TYPE_POINTER:
12109                 mask = REGCM_GPR32 | REGCM_GPR32_8 |
12110                         REGCM_GPR64 | REGCM_MMX | REGCM_XMM;
12111                 break;
12112         default:
12113                 internal_error(state, 0, "no register class for type");
12114                 break;
12115         }
12116         mask &= avail_mask;
12117         return mask;
12118 }
12119
12120 static void get_imm32(struct triple *ins, struct triple **expr)
12121 {
12122         struct triple *imm;
12123         if ((*expr)->op != OP_COPY) {
12124                 return;
12125         }
12126         imm = (*expr)->left;
12127         while(imm->op == OP_COPY) {
12128                 imm = imm->left;
12129         }
12130         if (imm->op != OP_INTCONST) {
12131                 return;
12132         }
12133         *expr = imm;
12134         unuse_triple(*expr, ins);
12135         use_triple(*expr, ins);
12136 }
12137
12138 static void get_imm8(struct triple *ins, struct triple **expr)
12139 {
12140         struct triple *imm;
12141         if ((*expr)->op != OP_COPY) {
12142                 return;
12143         }
12144         imm = (*expr)->left;
12145         while(imm->op == OP_COPY) {
12146                 imm = imm->left;
12147         }
12148         if (imm->op != OP_INTCONST) {
12149                 return;
12150         }
12151         /* For imm8 only a sufficienlty small constant can be used */
12152         if (imm->u.cval > 0xff) {
12153                 return;
12154         }
12155         *expr = imm;
12156         unuse_triple(*expr, ins);
12157         use_triple(*expr, ins);
12158 }
12159
12160 static struct triple *pre_copy(struct compile_state *state, 
12161         struct triple *ins, struct triple **expr,
12162         unsigned reg, unsigned mask)
12163 {
12164         /* Carefully insert enough operations so that I can
12165          * enter any operation with a GPR32.
12166          */
12167         struct triple *in;
12168         /* See if I can directly reach the result from a GPR32 */
12169         if (mask & (REGCM_GPR32 | REGCM_GPR16 | REGCM_MMX | REGCM_XMM)) {
12170                 in = triple(state, OP_COPY, (*expr)->type, *expr,  0);
12171         }
12172         /* If it is a byte value force a earlier copy to a GPR32_8 */
12173         else if (mask & REGCM_GPR8) {
12174                 struct triple *tmp;
12175                 tmp = triple(state, OP_COPY, (*expr)->type, *expr, 0);
12176                 tmp->filename = ins->filename;
12177                 tmp->line     = ins->line;
12178                 tmp->col      = ins->col;
12179                 tmp->u.block  = ins->u.block;
12180                 tmp->id = MK_REG_ID(REG_UNSET, REGCM_GPR32_8 | REGCM_GPR16_8);
12181                 use_triple(tmp->left, tmp);
12182                 insert_triple(state, ins, tmp);
12183
12184                 in = triple(state, OP_COPY, tmp->type, tmp, 0);
12185         }
12186         else {
12187                 internal_error(state, ins, "bad copy type");
12188                 in = 0;
12189         }
12190         in->filename  = ins->filename;
12191         in->line      = ins->line;
12192         in->col       = ins->col;
12193         in->u.block   = ins->u.block;
12194         in->id        = MK_REG_ID(reg, mask);
12195         unuse_triple(*expr, ins);
12196         *expr = in;
12197         use_triple(in->left, in);
12198         use_triple(in, ins);
12199         insert_triple(state, ins, in);
12200         return in;
12201 }
12202
12203 static struct triple *post_copy(struct compile_state *state, struct triple *ins)
12204 {
12205         struct triple_set *entry, *next;
12206         struct triple *out, *label;
12207         struct block *block;
12208         label = ins;
12209         while(label->op != OP_LABEL) {
12210                 label = label->prev;
12211         }
12212         block = label->u.block;
12213         out = triple(state, OP_COPY, ins->type, ins, 0);
12214         out->filename = ins->filename;
12215         out->line     = ins->line;
12216         out->col      = ins->col;
12217         out->u.block  = block;
12218         out->id       = MK_REG_ID(REG_UNSET, 
12219                 arch_type_to_regcm(state, ins->type));
12220         use_triple(ins, out);
12221         insert_triple(state, ins->next, out);
12222         if (block->last == ins) {
12223                 block->last = out;
12224         }
12225         /* Get the users of ins to use out instead */
12226         for(entry = ins->use; entry; entry = next) {
12227                 next = entry->next;
12228                 if (entry->member == out) {
12229                         continue;
12230                 }
12231                 replace_rhs_use(state, ins, out, entry->member);
12232         }
12233         return out;
12234 }
12235
12236 static void fixup_branches(struct compile_state *state,
12237         struct triple *cmp, struct triple *use, int jmp_op)
12238 {
12239         struct triple_set *entry, *next;
12240         for(entry = use->use; entry; entry = next) {
12241                 next = entry->next;
12242                 if (entry->member->op == OP_COPY) {
12243                         fixup_branches(state, cmp, entry->member, jmp_op);
12244                 }
12245                 else if (entry->member->op == OP_BRANCH) {
12246                         struct triple *branch, *test;
12247                         branch = entry->member;
12248                         test = pre_triple(state, branch,
12249                                 cmp->op, cmp->type, cmp->left, cmp->right);
12250                         test->id = MK_REG_ID(REG_EFLAGS, REGCM_FLAGS);
12251                         unuse_triple(branch->right, branch);
12252                         branch->right = test;
12253                         branch->op = jmp_op;
12254                         use_triple(branch->right, branch);
12255                 }
12256         }
12257 }
12258
12259 static void bool_cmp(struct compile_state *state, 
12260         struct triple *ins, int cmp_op, int jmp_op, int set_op)
12261 {
12262         struct block *block;
12263         struct triple_set *entry, *next;
12264         struct triple *set, *tmp1, *tmp2;
12265
12266 #warning "WISHLIST implement an expression simplifier to reduce the use of set?"
12267
12268         block = ins->u.block;
12269
12270         /* Put a barrier up before the cmp which preceeds the
12271          * copy instruction.  If a set actually occurs this gives
12272          * us a chance to move variables in registers out of the way.
12273          */
12274
12275         /* Modify the comparison operator */
12276         ins->op = cmp_op;
12277         ins->id = MK_REG_ID(REG_EFLAGS, REGCM_FLAGS);
12278         if (cmp_op == OP_CMP) {
12279                 get_imm32(ins, &ins->right);
12280         }
12281         /* Generate the instruction sequence that will transform the
12282          * result of the comparison into a logical value.
12283          */
12284         tmp1 = triple(state, set_op, ins->type, ins, 0);
12285         tmp1->filename = ins->filename;
12286         tmp1->line     = ins->line;
12287         tmp1->col      = ins->col;
12288         tmp1->u.block  = block;
12289         tmp1->id       = MK_REG_ID(REG_UNSET, REGCM_GPR8);
12290         use_triple(ins, tmp1);
12291         insert_triple(state, ins->next, tmp1);
12292         
12293         tmp2 = triple(state, OP_COPY, ins->type, tmp1, 0);
12294         tmp2->filename = ins->filename;
12295         tmp2->line     = ins->line;
12296         tmp2->col      = ins->col;
12297         tmp2->u.block  = block;
12298         tmp2->id       = MK_REG_ID(REG_UNSET, 
12299                 REGCM_GPR32 | REGCM_GPR32_8 | REGCM_GPR16 | REGCM_GPR16_8 | REGCM_GPR8);
12300         use_triple(tmp1, tmp2);
12301         insert_triple(state, tmp1->next, tmp2);
12302
12303         if (block->last == ins) {
12304                 block->last = tmp2;
12305         }
12306
12307         set = tmp2;
12308         for(entry = ins->use; entry; entry = next) {
12309                 next = entry->next;
12310                 if (entry->member == tmp1) {
12311                         continue;
12312                 }
12313                 replace_rhs_use(state, ins, set, entry->member);
12314         }
12315         fixup_branches(state, ins, set, jmp_op);
12316 }
12317
12318
12319 static void transform_to_arch_instructions(struct compile_state *state)
12320 {
12321         /* Transform from generic 3 address instructions
12322          * to archtecture specific instructions.
12323          * And apply architecture specific constrains to instructions.
12324          * Copies are inserted to preserve the register flexibility
12325          * of 3 address instructions.
12326          */
12327         struct triple *ins, *first, *next;
12328         struct triple *in, *in2;
12329         first = state->main_function->left;
12330         ins = first;
12331         do {
12332                 next = ins->next;
12333                 ins->id = MK_REG_ID(REG_UNSET, arch_type_to_regcm(state, ins->type));
12334                 switch(ins->op) {
12335                 case OP_INTCONST:
12336                 case OP_ADDRCONST:
12337                         ins->id = 0;
12338                         post_copy(state, ins);
12339                         break;
12340                 case OP_NOOP:
12341                 case OP_SDECL:
12342                 case OP_BLOBCONST:
12343                 case OP_LABEL:
12344                         ins->id = 0;
12345                         break;
12346                         /* instructions that can be used as is */
12347                 case OP_COPY:
12348                 case OP_PHI:
12349                         break;
12350                 case OP_STORE:
12351                 {
12352                         unsigned mask;
12353                         ins->id = 0;
12354                         switch(ins->type->type & TYPE_MASK) {
12355                         case TYPE_CHAR:    case TYPE_UCHAR:
12356                                 mask = REGCM_GPR8;
12357                                 break;
12358                         case TYPE_SHORT:   case TYPE_USHORT:
12359                                 mask = REGCM_GPR16;
12360                                 break;
12361                         case TYPE_INT:     case TYPE_UINT:
12362                         case TYPE_LONG:    case TYPE_ULONG:
12363                         case TYPE_POINTER:
12364                                 mask  = REGCM_GPR32;
12365                                 break;
12366                         default:
12367                                 internal_error(state, ins, "unknown type in store");
12368                                 mask = 0;
12369                                 break;
12370                         }
12371                         in = pre_copy(state, ins, &ins->right, REG_UNSET, mask);
12372                         break;
12373                 }
12374                 case OP_LOAD:
12375                         switch(ins->type->type & TYPE_MASK) {
12376                         case TYPE_CHAR:   case TYPE_UCHAR:
12377                                 ins->id = MK_REG_ID(REG_UNSET, REGCM_GPR8);
12378                                 break;
12379                         case TYPE_SHORT:
12380                         case TYPE_USHORT:
12381                                 ins->id = MK_REG_ID(REG_UNSET, REGCM_GPR16);
12382                                 break;
12383                         case TYPE_INT:
12384                         case TYPE_UINT:
12385                         case TYPE_LONG:
12386                         case TYPE_ULONG:
12387                         case TYPE_POINTER:
12388                                 ins->id = MK_REG_ID(REG_UNSET, REGCM_GPR32);
12389                                 break;
12390                         default:
12391                                 internal_error(state, ins, "unknown type in load");
12392                                 break;
12393                         }
12394                         break;
12395                 case OP_ADD:
12396                 case OP_SUB:
12397                 case OP_AND:
12398                 case OP_XOR:
12399                 case OP_OR:
12400                         get_imm32(ins, &ins->right);
12401                         in = pre_copy(state, ins, &ins->left,
12402                                 alloc_virtual_reg(), ID_REG_CLASSES(ins->id));
12403                         ins->id = in->id;
12404                         break;
12405                 case OP_SL:
12406                 case OP_SSR:
12407                 case OP_USR:
12408                         get_imm8(ins, &ins->right);
12409                         in = pre_copy(state, ins, &ins->left,
12410                                 alloc_virtual_reg(), ID_REG_CLASSES(ins->id));
12411                         ins->id = in->id;
12412                         if (!IS_CONST_OP(ins->right->op)) {
12413                                 in2 = pre_copy(state, ins, &ins->right,
12414                                         REG_CL, REGCM_GPR8);
12415                         }
12416                         break;
12417                 case OP_INVERT:
12418                 case OP_NEG:
12419                         in = pre_copy(state, ins, &ins->left,
12420                                 alloc_virtual_reg(), ID_REG_CLASSES(ins->id));
12421                         ins->id = in->id;
12422                         break;
12423                 case OP_SMUL:
12424                         get_imm32(ins, &ins->right);
12425                         in = pre_copy(state, ins, &ins->left,
12426                                 alloc_virtual_reg(), ID_REG_CLASSES(ins->id));
12427                         ins->id = in->id;
12428                         if (!IS_CONST_OP(ins->right->op)) {
12429                                 in2 = pre_copy(state, ins, &ins->right,
12430                                         REG_UNSET, REGCM_GPR32);
12431                         }
12432                         break;
12433                 case OP_EQ: 
12434                         bool_cmp(state, ins, OP_CMP, OP_JMP_EQ, OP_SET_EQ); 
12435                         break;
12436                 case OP_NOTEQ:
12437                         bool_cmp(state, ins, OP_CMP, OP_JMP_NOTEQ, OP_SET_NOTEQ);
12438                         break;
12439                 case OP_SLESS:
12440                         bool_cmp(state, ins, OP_CMP, OP_JMP_SLESS, OP_SET_SLESS);
12441                         break;
12442                 case OP_ULESS:
12443                         bool_cmp(state, ins, OP_CMP, OP_JMP_ULESS, OP_SET_ULESS);
12444                         break;
12445                 case OP_SMORE:
12446                         bool_cmp(state, ins, OP_CMP, OP_JMP_SMORE, OP_SET_SMORE);
12447                         break;
12448                 case OP_UMORE:
12449                         bool_cmp(state, ins, OP_CMP, OP_JMP_UMORE, OP_SET_UMORE);
12450                         break;
12451                 case OP_SLESSEQ:
12452                         bool_cmp(state, ins, OP_CMP, OP_JMP_SLESSEQ, OP_SET_SLESSEQ);
12453                         break;
12454                 case OP_ULESSEQ:
12455                         bool_cmp(state, ins, OP_CMP, OP_JMP_ULESSEQ, OP_SET_ULESSEQ);
12456                         break;
12457                 case OP_SMOREEQ:
12458                         bool_cmp(state, ins, OP_CMP, OP_JMP_SMOREEQ, OP_SET_SMOREEQ);
12459                         break;
12460                 case OP_UMOREEQ:
12461                         bool_cmp(state, ins, OP_CMP, OP_JMP_UMOREEQ, OP_SET_UMOREEQ);
12462                         break;
12463                 case OP_LTRUE:
12464                         bool_cmp(state, ins, OP_TEST, OP_JMP_NOTEQ, OP_SET_NOTEQ);
12465                         break;
12466                 case OP_LFALSE:
12467                         bool_cmp(state, ins, OP_TEST, OP_JMP_EQ, OP_SET_EQ);
12468                         break;
12469                 case OP_BRANCH:
12470                         if (ins->right) {
12471                                 internal_error(state, ins, "bad branch test");
12472                         }
12473                         ins->op = OP_JMP;
12474                         break;
12475
12476                 case OP_INB:
12477                 case OP_INW:
12478                 case OP_INL:
12479                         get_imm8(ins, &ins->left);
12480                         switch(ins->op) {
12481                         case OP_INB: ins->id = MK_REG_ID(REG_AL,  REGCM_GPR8); break;
12482                         case OP_INW: ins->id = MK_REG_ID(REG_AX,  REGCM_GPR16); break;
12483                         case OP_INL: ins->id = MK_REG_ID(REG_EAX, REGCM_GPR32); break;
12484                         }
12485                         if (!IS_CONST_OP(ins->left->op)) {
12486                                 in = pre_copy(state, ins, &ins->left,
12487                                         REG_DX, REGCM_GPR16);
12488                         }
12489                         break;
12490                 case OP_OUTB:
12491                 case OP_OUTW:
12492                 case OP_OUTL:
12493                 {
12494                         unsigned reg, mask;
12495                         get_imm8(ins, &ins->right);
12496                         switch(ins->op) {
12497                         case OP_OUTB: reg = REG_AL;  mask = REGCM_GPR8; break;
12498                         case OP_OUTW: reg = REG_AX;  mask = REGCM_GPR16; break;
12499                         case OP_OUTL: reg = REG_EAX; mask = REGCM_GPR32; break;
12500                         default: reg = REG_UNSET; mask = 0; break;
12501                         }
12502                         in = pre_copy(state, ins, &ins->left, reg, mask);
12503                         if (!IS_CONST_OP(ins->right->op)) {
12504                                 in2 = pre_copy(state, ins, &ins->right,
12505                                         REG_DX, REGCM_GPR16);
12506                         }
12507                         break;
12508                 }
12509                 case OP_BSF:
12510                 case OP_BSR:
12511                         in = pre_copy(state, ins, &ins->left, 
12512                                 REG_UNSET, REGCM_GPR32);
12513                         ins->id = MK_REG_ID(REG_UNSET, REGCM_GPR32 | REGCM_GPR32_8);
12514                         break;
12515                         /* Already transformed instructions */
12516                 case OP_CMP:
12517                 case OP_TEST:
12518                         ins->id = MK_REG_ID(REG_EFLAGS, REGCM_FLAGS);
12519                         break;
12520                 case OP_JMP_EQ:      case OP_JMP_NOTEQ:
12521                 case OP_JMP_SLESS:   case OP_JMP_ULESS:
12522                 case OP_JMP_SMORE:   case OP_JMP_UMORE:
12523                 case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
12524                 case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
12525                 case OP_SET_EQ:      case OP_SET_NOTEQ:
12526                 case OP_SET_SLESS:   case OP_SET_ULESS:
12527                 case OP_SET_SMORE:   case OP_SET_UMORE:
12528                 case OP_SET_SLESSEQ: case OP_SET_ULESSEQ:
12529                 case OP_SET_SMOREEQ: case OP_SET_UMOREEQ:
12530                         break;
12531                 default:
12532                         internal_error(state, ins, "unhandled ins: %d %s\n",
12533                                 ins->op, tops(ins->op));
12534                         break;
12535                 }
12536                 ins = next;
12537         } while(ins != first);
12538 }
12539
12540
12541
12542 static void generate_local_labels(struct compile_state *state)
12543 {
12544         struct triple *first, *label;
12545         int label_counter;
12546         label_counter = 0;
12547         first = state->main_function->left;
12548         label = first;
12549         do {
12550                 if ((label->op == OP_LABEL) || 
12551                         (label->op == OP_SDECL)) {
12552                         if (label->use) {
12553                                 label->u.cval = ++label_counter;
12554                         } else {
12555                                 label->u.cval = 0;
12556                         }
12557                         
12558                 }
12559                 label = label->next;
12560         } while(label != first);
12561 }
12562
12563 static int check_reg(struct compile_state *state, 
12564         struct triple *triple, int classes)
12565 {
12566         unsigned mask;
12567         int reg;
12568         reg = ID_REG(triple->id);
12569         if (reg == REG_UNSET) {
12570                 internal_error(state, triple, "register not set");
12571         }
12572         if (ID_REG_CLASSES(triple->id)) {
12573                 internal_error(state, triple, "class specifier present");
12574         }
12575         mask = arch_reg_regcm(state, reg);
12576         if (!(classes & mask)) {
12577                 internal_error(state, triple, "reg %d in wrong class",
12578                         reg);
12579         }
12580         return reg;
12581 }
12582
12583 static const char *arch_reg_str(int reg)
12584 {
12585         static const char *regs[] = {
12586                 "%bad_register",
12587                 "%eflags",
12588                 "%al", "%bl", "%cl", "%dl", "%ah", "%bh", "%ch", "%dh",
12589                 "%ax", "%bx", "%cx", "%dx", "%si", "%di", "%bp", "%sp",
12590                 "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp",
12591                 "%edx:%eax",
12592                 "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7",
12593                 "%xmm0", "%xmm1", "%xmm2", "%xmm3", 
12594                 "%xmm4", "%xmm5", "%xmm6", "%xmm7",
12595         };
12596         if (!((reg >= REG_EFLAGS) && (reg <= REG_XMM7))) {
12597                 reg = 0;
12598         }
12599         return regs[reg];
12600 }
12601
12602 static const char *reg(struct compile_state *state, struct triple *triple,
12603         int classes)
12604 {
12605         int reg;
12606         reg = check_reg(state, triple, classes);
12607         return arch_reg_str(reg);
12608 }
12609
12610 const char *type_suffix(struct compile_state *state, struct type *type)
12611 {
12612         const char *suffix;
12613         switch(size_of(state, type)) {
12614         case 1: suffix = "b"; break;
12615         case 2: suffix = "w"; break;
12616         case 4: suffix = "l"; break;
12617         default:
12618                 internal_error(state, 0, "unknown suffix");
12619                 suffix = 0;
12620                 break;
12621         }
12622         return suffix;
12623 }
12624
12625 static void print_binary_op(struct compile_state *state,
12626         const char *op, struct triple *ins, FILE *fp) 
12627 {
12628         unsigned mask;
12629         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8;
12630         if (ins->left->id != ins->id) {
12631                 internal_error(state, ins, "invalid register assignment");
12632         }
12633         if (IS_CONST_OP(ins->right->op)) {
12634                 fprintf(fp, "\t%s $%lu, %s\n",
12635                         op,
12636                         ins->right->u.cval,
12637                         reg(state, ins->left, mask));
12638                 
12639         }
12640         else {
12641                 unsigned lmask, rmask;
12642                 int lreg, rreg;
12643                 lreg = check_reg(state, ins->left, mask);
12644                 rreg = check_reg(state, ins->right, mask);
12645                 lmask = arch_reg_regcm(state, lreg);
12646                 rmask = arch_reg_regcm(state, rreg);
12647                 mask = lmask & rmask;
12648                 fprintf(fp, "\t%s %s, %s\n",
12649                         op,
12650                         reg(state, ins->right, mask),
12651                         reg(state, ins->left, mask));
12652         }
12653 }
12654 static void print_unary_op(struct compile_state *state, 
12655         const char *op, struct triple *ins, FILE *fp)
12656 {
12657         unsigned mask;
12658         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8;
12659         fprintf(fp, "\t%s %s\n",
12660                 op,
12661                 reg(state, ins->left, mask));
12662 }
12663
12664 static void print_op_shift(struct compile_state *state,
12665         const char *op, struct triple *ins, FILE *fp)
12666 {
12667         unsigned mask;
12668         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8;
12669         if (ins->left->id != ins->id) {
12670                 internal_error(state, ins, "invalid register assignment");
12671         }
12672         if (IS_CONST_OP(ins->right->op)) {
12673                 fprintf(fp, "\t%s $%lu, %s\n",
12674                         op,
12675                         ins->right->u.cval,
12676                         reg(state, ins->left, mask));
12677                 
12678         }
12679         else {
12680                 fprintf(fp, "\t%s %s, %s\n",
12681                         op,
12682                         reg(state, ins->right, REGCM_GPR8),
12683                         reg(state, ins->left, mask));
12684         }
12685 }
12686
12687 static void print_op_in(struct compile_state *state, struct triple *ins, FILE *fp)
12688 {
12689         const char *op;
12690         int mask;
12691         int dreg;
12692         mask = 0;
12693         switch(ins->op) {
12694         case OP_INB: op = "inb", mask = REGCM_GPR8; break;
12695         case OP_INW: op = "inw", mask = REGCM_GPR16; break;
12696         case OP_INL: op = "inl", mask = REGCM_GPR32; break;
12697         default:
12698                 internal_error(state, ins, "not an in operation");
12699                 op = 0;
12700                 break;
12701         }
12702         dreg = check_reg(state, ins, mask);
12703         if (!reg_is_reg(state, dreg, REG_EAX)) {
12704                 internal_error(state, ins, "dst != %%eax");
12705         }
12706         if (IS_CONST_OP(ins->left->op)) {
12707                 fprintf(fp, "\t%s $%lu, %s\n",
12708                         op, ins->left->u.cval, 
12709                         reg(state, ins, mask));
12710         }
12711         else {
12712                 int addr_reg;
12713                 addr_reg = check_reg(state, ins->left, REGCM_GPR16);
12714                 if (!reg_is_reg(state, addr_reg, REG_DX)) {
12715                         internal_error(state, ins, "src != %%dx");
12716                 }
12717                 fprintf(fp, "\t%s %s, %s\n",
12718                         op, 
12719                         reg(state, ins->left, REGCM_GPR16),
12720                         reg(state, ins, mask));
12721         }
12722 }
12723
12724 static void print_op_out(struct compile_state *state, struct triple *ins, FILE *fp)
12725 {
12726         const char *op;
12727         int mask;
12728         int lreg;
12729         mask = 0;
12730         switch(ins->op) {
12731         case OP_OUTB: op = "outb", mask = REGCM_GPR8; break;
12732         case OP_OUTW: op = "outw", mask = REGCM_GPR16; break;
12733         case OP_OUTL: op = "outl", mask = REGCM_GPR32; break;
12734         default:
12735                 internal_error(state, ins, "not an out operation");
12736                 op = 0;
12737                 break;
12738         }
12739         lreg = check_reg(state, ins->left, mask);
12740         if (!reg_is_reg(state, lreg, REG_EAX)) {
12741                 internal_error(state, ins, "src != %%eax");
12742         }
12743         if (IS_CONST_OP(ins->right->op)) {
12744                 fprintf(fp, "\t%s %s, $%lu\n",
12745                         op, reg(state, ins->left, mask),
12746                         ins->right->u.cval);
12747         }
12748         else {
12749                 int addr_reg;
12750                 addr_reg = check_reg(state, ins->right, REGCM_GPR16);
12751                 if (!reg_is_reg(state, addr_reg, REG_DX)) {
12752                         internal_error(state, ins, "dst != %%dx");
12753                 }
12754                 fprintf(fp, "\t%s %s, %s\n",
12755                         op, 
12756                         reg(state, ins->left, mask),
12757                         reg(state, ins->right, REGCM_GPR16));
12758         }
12759 }
12760
12761 static void print_op_move(struct compile_state *state,
12762         struct triple *ins, FILE *fp)
12763 {
12764         /* op_move is complex because there are many types
12765          * of registers we can move between.
12766          */
12767         int omit_copy = 1; /* Is it o.k. to omit a noop copy? */
12768         struct triple *dst, *src;
12769         if (ins->op == OP_COPY) {
12770                 src = ins->left;
12771                 dst = ins;
12772         }
12773         else if (ins->op == OP_WRITE) {
12774                 dst = ins->left;
12775                 src = ins->right;
12776         }
12777         else {
12778                 internal_error(state, ins, "unknown move operation");
12779                 src = dst = 0;
12780         }
12781         if (!IS_CONST_OP(src->op)) {
12782                 int src_reg, dst_reg;
12783                 int src_regcm, dst_regcm;
12784                 src_reg = ID_REG(src->id);
12785                 dst_reg   = ID_REG(dst->id);
12786                 src_regcm = arch_reg_regcm(state, src_reg);
12787                 dst_regcm   = arch_reg_regcm(state, dst_reg);
12788                 /* If the class is the same just move the register */
12789                 if (src_regcm & dst_regcm & 
12790                         (REGCM_GPR8 | REGCM_GPR16 | REGCM_GPR32)) {
12791                         if ((src_reg != dst_reg) || !omit_copy) {
12792                                 fprintf(fp, "\tmov %s, %s\n",
12793                                         reg(state, src, src_regcm),
12794                                         reg(state, dst, dst_regcm));
12795                         }
12796                 }
12797                 /* Move 32bit to 16bit */
12798                 else if ((src_regcm & REGCM_GPR32) &&
12799                         (dst_regcm & REGCM_GPR16)) {
12800                         src_reg = (src_reg - REGC_GPR32_FIRST) + REGC_GPR16_FIRST;
12801                         if ((src_reg != dst_reg) || !omit_copy) {
12802                                 fprintf(fp, "\tmovw %s, %s\n",
12803                                         arch_reg_str(src_reg), 
12804                                         arch_reg_str(dst_reg));
12805                         }
12806                 }
12807                 /* Move 32bit to 8bit */
12808                 else if ((src_regcm & REGCM_GPR32_8) &&
12809                         (dst_regcm & REGCM_GPR8))
12810                 {
12811                         src_reg = (src_reg - REGC_GPR32_8_FIRST) + REGC_GPR8_FIRST;
12812                         if ((src_reg != dst_reg) || !omit_copy) {
12813                                 fprintf(fp, "\tmovb %s, %s\n",
12814                                         arch_reg_str(src_reg),
12815                                         arch_reg_str(dst_reg));
12816                         }
12817                 }
12818                 /* Move 16bit to 8bit */
12819                 else if ((src_regcm & REGCM_GPR16_8) &&
12820                         (dst_regcm & REGCM_GPR8))
12821                 {
12822                         src_reg = (src_reg - REGC_GPR16_8_FIRST) + REGC_GPR8_FIRST;
12823                         if ((src_reg != dst_reg) || !omit_copy) {
12824                                 fprintf(fp, "\tmovb %s, %s\n",
12825                                         arch_reg_str(src_reg),
12826                                         arch_reg_str(dst_reg));
12827                         }
12828                 }
12829                 /* Move 8/16bit to 16/32bit */
12830                 else if ((src_regcm & (REGCM_GPR8 | REGCM_GPR16)) &&
12831                         (dst_regcm & (REGC_GPR16 | REGCM_GPR32))) {
12832                         const char *op;
12833                         op = is_signed(src->type)? "movsx": "movzx";
12834                         fprintf(fp, "\t%s %s, %s\n",
12835                                 op,
12836                                 reg(state, src, src_regcm),
12837                                 reg(state, dst, dst_regcm));
12838                 }
12839                 /* Move between sse registers */
12840                 else if ((src_regcm & dst_regcm & REGCM_XMM)) {
12841                         if ((src_reg != dst_reg) || !omit_copy) {
12842                                 fprintf(fp, "\tmovdqa %s %s\n",
12843                                         reg(state, src, src_regcm),
12844                                         reg(state, dst, dst_regcm));
12845                         }
12846                 }
12847                 /* Move between mmx registers or mmx & sse  registers */
12848                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
12849                         (dst_regcm & (REGCM_MMX | REGCM_XMM))) {
12850                         if ((src_reg != dst_reg) || !omit_copy) {
12851                                 fprintf(fp, "\tmovq %s %s\n",
12852                                         reg(state, src, src_regcm),
12853                                         reg(state, dst, dst_regcm));
12854                         }
12855                 }
12856                 /* Move between 32bit gprs & mmx/sse registers */
12857                 else if ((src_regcm & (REGCM_GPR32 | REGCM_MMX | REGCM_XMM)) &&
12858                         (dst_regcm & (REGCM_GPR32 | REGCM_MMX | REGCM_XMM))) {
12859                         fprintf(fp, "\tmovd %s, %s\n",
12860                                 reg(state, src, src_regcm),
12861                                 reg(state, dst, dst_regcm));
12862                 }
12863                 else {
12864                         internal_error(state, ins, "unknown copy type");
12865                 }
12866         }
12867         else switch(src->op) {
12868         case OP_INTCONST:
12869         {
12870                 long_t value;
12871                 value = (long_t)(src->u.cval);
12872                 fprintf(fp, "\tmov $%ld, %s\n",
12873                         value,
12874                         reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8));
12875                 break;
12876         }
12877         case OP_ADDRCONST:
12878                 fprintf(fp, "\tmov $L%lu+%lu, %s\n",
12879                         src->left->u.cval,
12880                         src->u.cval,
12881                         reg(state, dst, REGCM_GPR32));
12882                 break;
12883         default:
12884                 internal_error(state, ins, "uknown copy operation");
12885         }
12886 }
12887
12888 static void print_op_load(struct compile_state *state,
12889         struct triple *ins, FILE *fp)
12890 {
12891         struct triple *dst, *src;
12892         dst = ins;
12893         src = ins->left;
12894         if (is_const(src) || is_const(dst)) {
12895                 internal_error(state, ins, "unknown load operation");
12896         }
12897         fprintf(fp, "\tmov (%s), %s\n",
12898                 reg(state, src, REGCM_GPR32),
12899                 reg(state, dst, REGCM_GPR8 | REGCM_GPR16 | REGCM_GPR32));
12900 }
12901
12902
12903 static void print_op_store(struct compile_state *state,
12904         struct triple *ins, FILE *fp)
12905 {
12906         struct triple *dst, *src;
12907         dst = ins->left;
12908         src = ins->right;
12909         if (is_const(src) && (src->op == OP_INTCONST)) {
12910                 long_t value;
12911                 value = (long_t)(src->u.cval);
12912                 fprintf(fp, "\tmov%s $%ld, (%s)\n",
12913                         type_suffix(state, src->type),
12914                         value,
12915                         reg(state, dst, REGCM_GPR32));
12916         }
12917         else if (is_const(dst) && (dst->op == OP_INTCONST)) {
12918                 fprintf(fp, "\tmov%s %s, 0x%08lx\n",
12919                         type_suffix(state, src->type),
12920                         reg(state, src, REGCM_GPR8 | REGCM_GPR16 | REGCM_GPR32),
12921                         dst->u.cval);
12922         }
12923         else {
12924                 if (is_const(src) || is_const(dst)) {
12925                         internal_error(state, ins, "unknown store operation");
12926                 }
12927                 fprintf(fp, "\tmov%s %s, (%s)\n",
12928                         type_suffix(state, src->type),
12929                         reg(state, src, REGCM_GPR8 | REGCM_GPR16 | REGCM_GPR32),
12930                         reg(state, dst, REGCM_GPR32));
12931         }
12932         
12933         
12934 }
12935
12936 static void print_op_smul(struct compile_state *state,
12937         struct triple *ins, FILE *fp)
12938 {
12939         if (!IS_CONST_OP(ins->right->op)) {
12940                 fprintf(fp, "\timul %s, %s\n",
12941                         reg(state, ins->right, REGCM_GPR32),
12942                         reg(state, ins->left, REGCM_GPR32));
12943         }
12944         else {
12945                 fprintf(fp, "\timul $%ld, %s\n",
12946                         ins->right->u.cval,
12947                         reg(state, ins->left, REGCM_GPR32));
12948         }
12949 }
12950
12951 static void print_op_cmp(struct compile_state *state,
12952         struct triple *ins, FILE *fp)
12953 {
12954         unsigned mask;
12955         int dreg;
12956         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8;
12957         dreg = check_reg(state, ins, REGCM_FLAGS);
12958         if (!reg_is_reg(state, dreg, REG_EFLAGS)) {
12959                 internal_error(state, ins, "bad dest register for cmp");
12960         }
12961         if (IS_CONST_OP(ins->right->op)) {
12962                 fprintf(fp, "\tcmp $%lu, %s\n",
12963                         ins->right->u.cval,
12964                         reg(state, ins->left, mask));
12965         }
12966         else {
12967                 unsigned lmask, rmask;
12968                 int lreg, rreg;
12969                 lreg = check_reg(state, ins->left, mask);
12970                 rreg = check_reg(state, ins->right, mask);
12971                 lmask = arch_reg_regcm(state, lreg);
12972                 rmask = arch_reg_regcm(state, rreg);
12973                 mask = lmask & rmask;
12974                 fprintf(fp, "\tcmp %s, %s\n",
12975                         reg(state, ins->right, mask),
12976                         reg(state, ins->left, mask));
12977         }
12978 }
12979
12980 static void print_op_test(struct compile_state *state,
12981         struct triple *ins, FILE *fp)
12982 {
12983         unsigned mask;
12984         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8;
12985         fprintf(fp, "\ttest %s, %s\n",
12986                 reg(state, ins->left, mask),
12987                 reg(state, ins->left, mask));
12988 }
12989
12990 static void print_op_branch(struct compile_state *state,
12991         struct triple *branch, FILE *fp)
12992 {
12993         const char *bop = "j";
12994         if (branch->op == OP_JMP) {
12995                 if (branch->right) {
12996                         internal_error(state, branch, "jmp with condition?");
12997                 }
12998                 bop = "jmp";
12999         }
13000         else {
13001                 if (!branch->right) {
13002                         internal_error(state, branch, "jmpcc without condition?");
13003                 }
13004                 check_reg(state, branch->right, REGCM_FLAGS);
13005                 if ((branch->right->op != OP_CMP) &&
13006                         (branch->right->op != OP_TEST)) {
13007                         internal_error(state, branch, "bad branch test");
13008                 }
13009 #warning "FIXME I have observed instructions between the test and branch instructions"
13010                 if (branch->right->next != branch) {
13011                         internal_error(state, branch, "branch does not follow test");
13012                 }
13013                 switch(branch->op) {
13014                 case OP_JMP_EQ:       bop = "jz";  break;
13015                 case OP_JMP_NOTEQ:    bop = "jnz"; break;
13016                 case OP_JMP_SLESS:    bop = "jl";  break;
13017                 case OP_JMP_ULESS:    bop = "jb";  break;
13018                 case OP_JMP_SMORE:    bop = "jg";  break;
13019                 case OP_JMP_UMORE:    bop = "ja";  break;
13020                 case OP_JMP_SLESSEQ:  bop = "jle"; break;
13021                 case OP_JMP_ULESSEQ:  bop = "jbe"; break;
13022                 case OP_JMP_SMOREEQ:  bop = "jge"; break;
13023                 case OP_JMP_UMOREEQ:  bop = "jae"; break;
13024                 default:
13025                         internal_error(state, branch, "Invalid branch op");
13026                         break;
13027                 }
13028                 
13029         }
13030         fprintf(fp, "\t%s L%lu\n",
13031                 bop, branch->left->u.cval);
13032 }
13033
13034 static void print_op_set(struct compile_state *state,
13035         struct triple *set, FILE *fp)
13036 {
13037         const char *sop = "set";
13038         if (!set->left) {
13039                 internal_error(state, set, "setcc without condition?");
13040         }
13041         check_reg(state, set->left, REGCM_FLAGS);
13042         if ((set->left->op != OP_CMP) &&
13043                 (set->left->op != OP_TEST)) {
13044                 internal_error(state, set, "bad set test");
13045         }
13046         if (set->left->next != set) {
13047                 internal_error(state, set, "set does not follow test");
13048         }
13049         switch(set->op) {
13050         case OP_SET_EQ:       sop = "setz";  break;
13051         case OP_SET_NOTEQ:    sop = "setnz"; break;
13052         case OP_SET_SLESS:    sop = "setl";  break;
13053         case OP_SET_ULESS:    sop = "setb";  break;
13054         case OP_SET_SMORE:    sop = "setg";  break;
13055         case OP_SET_UMORE:    sop = "seta";  break;
13056         case OP_SET_SLESSEQ:  sop = "setle"; break;
13057         case OP_SET_ULESSEQ:  sop = "setbe"; break;
13058         case OP_SET_SMOREEQ:  sop = "setge"; break;
13059         case OP_SET_UMOREEQ:  sop = "setae"; break;
13060         default:
13061                 internal_error(state, set, "Invalid set op");
13062                 break;
13063         }
13064         fprintf(fp, "\t%s %s\n",
13065                 sop, reg(state, set, REGCM_GPR8));
13066 }
13067
13068 static void print_op_bit_scan(struct compile_state *state, 
13069         struct triple *ins, FILE *fp) 
13070 {
13071         const char *op;
13072         switch(ins->op) {
13073         case OP_BSF: op = "bsf"; break;
13074         case OP_BSR: op = "bsr"; break;
13075         default: 
13076                 internal_error(state, ins, "unknown bit scan");
13077                 op = 0;
13078                 break;
13079         }
13080         fprintf(fp, 
13081                 "\t%s %s, %s\n"
13082                 "\tjnz 1f\n"
13083                 "\tmovl $-1, %s\n"
13084                 "1:\n",
13085                 op,
13086                 reg(state, ins->left, REGCM_GPR32),
13087                 reg(state, ins, REGCM_GPR32),
13088                 reg(state, ins, REGCM_GPR32));
13089 }
13090
13091 static void print_const(struct compile_state *state,
13092         struct triple *ins, FILE *fp)
13093 {
13094         switch(ins->op) {
13095         case OP_INTCONST:
13096                 switch(ins->type->type & TYPE_MASK) {
13097                 case TYPE_CHAR:
13098                 case TYPE_UCHAR:
13099                         fprintf(fp, ".byte 0x%02lx\n", ins->u.cval);
13100                         break;
13101                 case TYPE_SHORT:
13102                 case TYPE_USHORT:
13103                         fprintf(fp, ".short 0x%04lx\n", ins->u.cval);
13104                         break;
13105                 case TYPE_INT:
13106                 case TYPE_UINT:
13107                 case TYPE_LONG:
13108                 case TYPE_ULONG:
13109                         fprintf(fp, ".int %lu\n", ins->u.cval);
13110                         break;
13111                 default:
13112                         internal_error(state, ins, "Unknown constant type");
13113                 }
13114                 break;
13115         case OP_BLOBCONST:
13116         {
13117                 unsigned char *blob;
13118                 size_t size, i;
13119                 size = size_of(state, ins->type);
13120                 blob = ins->u.blob;
13121                 for(i = 0; i < size; i++) {
13122                         fprintf(fp, ".byte 0x%02x\n",
13123                                 blob[i]);
13124                 }
13125                 break;
13126         }
13127 #if 0
13128         case OP_ADDRCONST:
13129                 fprintf(fp, ".int $L%lu+%lu",
13130                         ins->left->u.cval,
13131                         ins->u.cval);
13132                 break;
13133 #endif
13134         default:
13135                 internal_error(state, ins, "Unknown constant type");
13136                 break;
13137         }
13138 }
13139
13140 static void print_sdecl(struct compile_state *state,
13141         struct triple *ins, FILE *fp)
13142 {
13143         fprintf(fp, ".section \".rom.data\"\n");
13144         fprintf(fp, ".balign %d\n", align_of(state, ins->type));
13145         fprintf(fp, "L%lu:\n", ins->u.cval);
13146         print_const(state, ins->left, fp);
13147         fprintf(fp, ".section \".rom.text\"\n");
13148                 
13149 }
13150
13151 static void print_instruction(struct compile_state *state,
13152         struct triple *ins, FILE *fp)
13153 {
13154         /* Assumption: after I have exted the register allocator
13155          * everything is in a valid register. 
13156          */
13157         switch(ins->op) {
13158         case OP_ADD:    print_binary_op(state, "add", ins, fp); break;
13159         case OP_SUB:    print_binary_op(state, "sub", ins, fp); break;
13160         case OP_AND:    print_binary_op(state, "and", ins, fp); break;
13161         case OP_XOR:    print_binary_op(state, "xor", ins, fp); break;
13162         case OP_OR:     print_binary_op(state, "or",  ins, fp); break;
13163         case OP_SL:     print_op_shift(state, "shl", ins, fp); break;
13164         case OP_USR:    print_op_shift(state, "shr", ins, fp); break;
13165         case OP_SSR:    print_op_shift(state, "sar", ins, fp); break;
13166         case OP_POS:    break;
13167         case OP_NEG:    print_unary_op(state, "neg", ins, fp); break;
13168         case OP_INVERT: print_unary_op(state, "not", ins, fp); break;
13169         case OP_INTCONST:
13170         case OP_ADDRCONST:
13171                 /* Don't generate anything here for constants */
13172         case OP_PHI:
13173                 /* Don't generate anything for variable declarations. */
13174                 break;
13175         case OP_SDECL:
13176                 print_sdecl(state, ins, fp);
13177                 break;
13178         case OP_WRITE: 
13179         case OP_COPY:   
13180                 print_op_move(state, ins, fp);
13181                 break;
13182         case OP_LOAD:
13183                 print_op_load(state, ins, fp);
13184                 break;
13185         case OP_STORE:
13186                 print_op_store(state, ins, fp);
13187                 break;
13188         case OP_SMUL:
13189                 print_op_smul(state, ins, fp);
13190                 break;
13191         case OP_CMP:    print_op_cmp(state, ins, fp); break;
13192         case OP_TEST:   print_op_test(state, ins, fp); break;
13193         case OP_JMP:
13194         case OP_JMP_EQ:      case OP_JMP_NOTEQ:
13195         case OP_JMP_SLESS:   case OP_JMP_ULESS:
13196         case OP_JMP_SMORE:   case OP_JMP_UMORE:
13197         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
13198         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
13199                 print_op_branch(state, ins, fp);
13200                 break;
13201         case OP_SET_EQ:      case OP_SET_NOTEQ:
13202         case OP_SET_SLESS:   case OP_SET_ULESS:
13203         case OP_SET_SMORE:   case OP_SET_UMORE:
13204         case OP_SET_SLESSEQ: case OP_SET_ULESSEQ:
13205         case OP_SET_SMOREEQ: case OP_SET_UMOREEQ:
13206                 print_op_set(state, ins, fp);
13207                 break;
13208         case OP_INB:  case OP_INW:  case OP_INL:
13209                 print_op_in(state, ins, fp); 
13210                 break;
13211         case OP_OUTB: case OP_OUTW: case OP_OUTL:
13212                 print_op_out(state, ins, fp); 
13213                 break;
13214         case OP_BSF:
13215         case OP_BSR:
13216                 print_op_bit_scan(state, ins, fp);
13217                 break;
13218         case OP_HLT:
13219                 fprintf(fp, "\thlt\n");
13220                 break;
13221         case OP_LABEL:
13222                 if (!ins->use) {
13223                         return;
13224                 }
13225                 fprintf(fp, "L%lu:\n", ins->u.cval);
13226                 break;
13227                 /* Operations I am not yet certain how to handle */
13228         case OP_UMUL:
13229         case OP_SDIV: case OP_UDIV:
13230         case OP_SMOD: case OP_UMOD:
13231                 /* Operations that should never get here */
13232         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
13233         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
13234         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
13235         default:
13236                 internal_error(state, ins, "unknown op: %d %s",
13237                         ins->op, tops(ins->op));
13238                 break;
13239         }
13240 }
13241
13242 static void print_instructions(struct compile_state *state)
13243 {
13244         struct triple *first, *ins;
13245         int print_location;
13246         int last_line;
13247         int last_col;
13248         const char *last_filename;
13249         FILE *fp;
13250         print_location = 1;
13251         last_line = -1;
13252         last_col  = -1;
13253         last_filename = 0;
13254         fp = stdout;
13255         fprintf(fp, ".section \".rom.text\"\n");
13256         first = state->main_function->left;
13257         ins = first;
13258         do {
13259                 if (print_location &&
13260                         ((last_filename != ins->filename) ||
13261                                 (last_line != ins->line) ||
13262                                 (last_col  != ins->col))) {
13263                         fprintf(fp, "\t/* %s:%d */\n",
13264                                 ins->filename, ins->line);
13265                         last_filename = ins->filename;
13266                         last_line = ins->line;
13267                         last_col  = ins->col;
13268                 }
13269
13270                 print_instruction(state, ins, fp);
13271                 ins = ins->next;
13272         } while(ins != first);
13273         
13274 }
13275 static void generate_code(struct compile_state *state)
13276 {
13277         generate_local_labels(state);
13278         print_instructions(state);
13279         
13280 }
13281
13282 static void print_tokens(struct compile_state *state)
13283 {
13284         struct token *tk;
13285         tk = &state->token[0];
13286         do {
13287 #if 1
13288                 token(state, 0);
13289 #else
13290                 next_token(state, 0);
13291 #endif
13292                 loc(stdout, state, 0);
13293                 printf("%s <- `%s'\n",
13294                         tokens[tk->tok],
13295                         tk->ident ? tk->ident->name :
13296                         tk->str_len ? tk->val.str : "");
13297                 
13298         } while(tk->tok != TOK_EOF);
13299 }
13300
13301 static void compile(char *filename, int debug, int opt)
13302 {
13303         int i;
13304         struct compile_state state;
13305         memset(&state, 0, sizeof(state));
13306         state.file = 0;
13307         for(i = 0; i < sizeof(state.token)/sizeof(state.token[0]); i++) {
13308                 memset(&state.token[i], 0, sizeof(state.token[i]));
13309                 state.token[i].tok = -1;
13310         }
13311         /* Remember the debug settings */
13312         state.debug = debug;
13313         state.optimize = opt;
13314         /* Prep the preprocessor */
13315         state.if_depth = 0;
13316         state.if_value = 0;
13317         /* register the C keywords */
13318         register_keywords(&state);
13319         /* register the keywords the macro preprocessor knows */
13320         register_macro_keywords(&state);
13321         /* Memorize where some special keywords are. */
13322         state.i_continue = lookup(&state, "continue", 8);
13323         state.i_break    = lookup(&state, "break", 5);
13324         /* Enter the globl definition scope */
13325         start_scope(&state);
13326         register_builtins(&state);
13327         compile_file(&state, filename, 1);
13328 #if 0
13329         print_tokens(&state);
13330 #endif  
13331         decls(&state);
13332         /* Exit the global definition scope */
13333         end_scope(&state);
13334
13335         /* Now that basic compilation has happened 
13336          * optimize the intermediate code 
13337          */
13338         optimize(&state);
13339         generate_code(&state);
13340         if (state.debug) {
13341                 fprintf(stderr, "done\n");
13342         }
13343 }
13344
13345 static void version(void)
13346 {
13347         printf("romcc " VERSION " released " RELEASE_DATE "\n");
13348 }
13349
13350 static void usage(void)
13351 {
13352         version();
13353         printf(
13354                 "Usage: romcc <source>.c\n"
13355                 "Compile a C source file without using ram\n"
13356         );
13357 }
13358
13359 static void arg_error(char *fmt, ...)
13360 {
13361         va_list args;
13362         va_start(args, fmt);
13363         vfprintf(stderr, fmt, args);
13364         va_end(args);
13365         usage();
13366         exit(1);
13367 }
13368
13369 int main(int argc, char **argv)
13370 {
13371         char *filename;
13372         int last_argc;
13373         int debug;
13374         int optimize;
13375         optimize = 0;
13376         debug = 0;
13377         last_argc = -1;
13378         while((argc > 1) && (argc != last_argc)) {
13379                 last_argc = argc;
13380                 if (strncmp(argv[1], "--debug=", 8) == 0) {
13381                         debug = atoi(argv[1] + 8);
13382                         argv++;
13383                         argc--;
13384                 }
13385                 else if ((strcmp(argv[1],"-O") == 0) ||
13386                         (strcmp(argv[1], "-O1") == 0)) {
13387                         optimize = 1;
13388                         argv++;
13389                         argc--;
13390                 }
13391                 else if (strcmp(argv[1],"-O2") == 0) {
13392                         optimize = 2;
13393                         argv++;
13394                         argc--;
13395                 }
13396         }
13397         if (argc != 2) {
13398                 arg_error("Wrong argument count %d\n", argc);
13399         }
13400         filename = argv[1];
13401         compile(filename, debug, optimize);
13402
13403         return 0;
13404 }